From ff0369dc4f025b9615ae8b907fc33cd647b358d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Thu, 11 Jun 2026 11:55:28 +0200 Subject: [PATCH] Backfill empty third-party fields on name dedupe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tracker policy document deduped third parties by name and kept the first-seen row wholesale. Org third parties are appended before catalog common vendors so user-editable data wins, but an org row may leave the description or privacy policy URL empty. In that case the early return discarded the later common-vendor row entirely, dropping metadata that would have completed the document. Track the kept row by name and backfill only its empty fields from later duplicates, so org data still wins while common-vendor metadata is no longer lost. Signed-off-by: Émile Ré --- pkg/probo/tracker_policy_document.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/pkg/probo/tracker_policy_document.go b/pkg/probo/tracker_policy_document.go index 86c1cd8f2..2458db344 100644 --- a/pkg/probo/tracker_policy_document.go +++ b/pkg/probo/tracker_policy_document.go @@ -325,23 +325,36 @@ func (s *GeneratedDocumentService) buildTrackerPolicyThirdParties( // Dedupe by name so a vendor present both as an org third party (one // pattern) and as a catalog entry (an unlinked pattern) is listed // once. Org third parties are appended first, so their richer - // (user-editable) data wins for a shared name. - seenName := make(map[string]struct{}, len(thirdParties)+len(commonParties)) + // (user-editable) data wins for a shared name. When the kept row left a + // field empty (e.g. an org third party with no privacy policy URL), a + // later duplicate backfills it from the catalog so common-vendor + // metadata is not dropped. + rowIndexByName := make(map[string]int, len(thirdParties)+len(commonParties)) addRow := func(name, description, privacyPolicyURL string) { name = strings.TrimSpace(name) + description = collapseWhitespace(description) + privacyPolicyURL = strings.TrimSpace(privacyPolicyURL) key := strings.ToLower(name) - if _, ok := seenName[key]; ok { + if idx, ok := rowIndexByName[key]; ok { + if rows[idx].Description == "" { + rows[idx].Description = description + } + + if rows[idx].PrivacyPolicyURL == "" { + rows[idx].PrivacyPolicyURL = privacyPolicyURL + } + return } - seenName[key] = struct{}{} + rowIndexByName[key] = len(rows) rows = append(rows, docgen.TrackerPolicyThirdParty{ Name: name, - Description: collapseWhitespace(description), - PrivacyPolicyURL: strings.TrimSpace(privacyPolicyURL), + Description: description, + PrivacyPolicyURL: privacyPolicyURL, }) }