From 7b302a7d1547737322c9388b334a3ed6caef18e0 Mon Sep 17 00:00:00 2001 From: Tofik Hasanov Date: Mon, 6 Jul 2026 14:45:56 -0400 Subject: [PATCH] fix(trust-portal): restore soc3/pipeda/ccpa badge mappings (CS-688) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidating the public and admin badge logic into the shared cert-badge-mapper (CS-688) inadvertently dropped soc3, pipeda and ccpa — the public portal's original mapper recognized them but the admin mapper (which the shared version was based on) did not. Vendors with those certifications would lose their public Trust Centre badges after release. Restore all three to the shared mapper. Safe on both surfaces: the public portal renders them via label text (formatComplianceBadgeLabels already has the labels) and the admin UI skips badge types it has no icon for (`if (!IconComponent) return null`), so nothing breaks there. Addresses cubic P1 on the production-deploy PR. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01RgkStnwws7zZL39mJ79PeN --- apps/api/src/trust-portal/cert-badge-mapper.spec.ts | 9 +++++++++ apps/api/src/trust-portal/cert-badge-mapper.ts | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/apps/api/src/trust-portal/cert-badge-mapper.spec.ts b/apps/api/src/trust-portal/cert-badge-mapper.spec.ts index 6c849055de..32aee3eb1e 100644 --- a/apps/api/src/trust-portal/cert-badge-mapper.spec.ts +++ b/apps/api/src/trust-portal/cert-badge-mapper.spec.ts @@ -28,6 +28,15 @@ describe('mapCertificationToBadgeType', () => { ).toBe('pci_dss'); }); + // Regression: soc3 / pipeda / ccpa were supported by the public portal's + // original mapper. Consolidation must not drop them or affected vendors lose + // their public Trust Centre badges. + it('maps soc3 / pipeda / ccpa (restored after consolidation)', () => { + expect(mapCertificationToBadgeType('SOC 3')).toBe('soc3'); + expect(mapCertificationToBadgeType('PIPEDA')).toBe('pipeda'); + expect(mapCertificationToBadgeType('CCPA')).toBe('ccpa'); + }); + // The digits alone must not classify an unrelated identifier. it('does not misclassify ids that merely contain the standard digits', () => { expect(mapCertificationToBadgeType('Catalog 19001')).toBeNull(); diff --git a/apps/api/src/trust-portal/cert-badge-mapper.ts b/apps/api/src/trust-portal/cert-badge-mapper.ts index 2cc410d861..cbe6253826 100644 --- a/apps/api/src/trust-portal/cert-badge-mapper.ts +++ b/apps/api/src/trust-portal/cert-badge-mapper.ts @@ -48,6 +48,7 @@ export function mapCertificationToBadgeType(certType: string): string | null { const normalized = certType.toLowerCase().replace(/[^a-z0-9]/g, ''); if (normalized.includes('soc2')) return 'soc2'; + if (normalized.includes('soc3')) return 'soc3'; if (matchesIsoStandard(normalized, '27001')) return 'iso27001'; if (matchesIsoStandard(normalized, '42001')) return 'iso42001'; if (normalized.includes('gdpr')) return 'gdpr'; @@ -59,6 +60,12 @@ export function mapCertificationToBadgeType(certType: string): string | null { return 'pci_dss'; if (normalized.includes('nen7510')) return 'nen7510'; if (matchesIsoStandard(normalized, '9001')) return 'iso9001'; + // soc3 / pipeda / ccpa were supported by the public portal's original mapper + // before consolidation; keep them so those vendors don't lose their public + // Trust Centre badges. The public portal renders them via label text and the + // admin UI safely skips badge types it has no icon for. + if (normalized.includes('pipeda')) return 'pipeda'; + if (normalized.includes('ccpa')) return 'ccpa'; return null; }