--- title: Third-Party Services (TPSC) --- # Third-Party Services Catalog ```js const API = "http://127.0.0.1:8000"; let apiOk = true; const catalog = await fetch(`${API}/tpsc/catalog/`) .then(r => r.json()) .catch(() => { apiOk = false; return []; }); const gdprReport = await fetch(`${API}/tpsc/report/gdpr`) .then(r => r.json()) .catch(() => ({ warnings: [], by_maturity: {}, total_services: 0, warning_count: 0 })); const snapshots = await fetch(`${API}/tpsc/snapshots/`) .then(r => r.json()) .catch(() => []); ``` ```js // GDPR maturity colour coding (CNIL/IAPP scale) const maturityColor = { unknown: "#ef4444", // red non_compliant: "#dc2626", // deep red initial: "#f97316", // orange developing: "#eab308", // amber defined: "#84cc16", // lime managed: "#22c55e", // green certified: "#16a34a", // deep green }; const maturityLabel = { unknown: "Unknown", non_compliant: "Non-Compliant", initial: "Initial", developing: "Developing", defined: "Defined", managed: "Managed", certified: "Certified", }; const WARNING_LEVELS = new Set(["unknown", "non_compliant", "initial"]); ``` ```js // KPI summary const warningServices = catalog.filter(s => WARNING_LEVELS.has(s.gdpr_maturity)); const paidServices = catalog.filter(s => ["paid", "usage_based"].includes(s.pricing_model)); ```
| Service | Provider | Category | Pricing | GDPR Maturity | DPA |
|---|---|---|---|---|---|
| ${s.website_url ? html`${s.name}` : s.name} | ${s.provider || "—"} | ${s.category || "—"} | ${pricingBadge(s.pricing_model)} | ${maturityBadge(s.gdpr_maturity)} | ${s.dpa_available ? "✅" : "❌"} |
✅ No GDPR warnings across active repos.
`); } else { const warningCards = html`| Repo | Services | Ingested |
|---|---|---|
| ${repoSlug} | ${snap.entries.map(e => { const cat = catalogBySlug[e.service_slug]; const m = cat?.gdpr_maturity || "unknown"; const color = maturityColor[m] || "#9ca3af"; return html` ${e.service_slug} `; })} | ${new Date(snap.snapshot_at).toLocaleDateString()} |