fix(products): source products and entitlements from the registry, not hard-coded ids #25

Merged
sharang merged 1 commits from fix/product-key-mismatch into main 2026-09-02 09:47:53 +00:00
1 Commits
Author SHA1 Message Date
Sharang ParnerkarandClaude Fable 5 be7c59aa0f fix(products): source products and entitlements from the registry, not hard-coded ids
ci / test (pull_request) Successful in 10m23s
ci / e2e (pull_request) Blocked by required conditions
ci / shared (pull_request) Failing after 13s
ci / image (pull_request) Skipped
A started trial never showed as entitled. Two causes, both fixed here.

1. The live path never fetched entitlements at all. loadTenantForShell resolves
   fixture tenants first and, for a REAL tenant, returned a shim with
   `entitled: []` and `products: []` hard-coded — so `entitled.includes(p.id)`
   was false for everything no matter what the registry said. It now fetches
   /v1/catalog and /v1/entitlements (both best-effort: a failure degrades to an
   empty grid rather than 404-ing the whole page) and filters entitlements to
   enabled + not expired.

2. The ids could not match even in principle. The registry catalog offers
   `certifai` and `compliance`; the portal's hard-coded list used
   `compliance-scanner` — a different product entirely (it lives in
   ~/workspace/compliance-scanner and is not in this catalog). The findings
   filter hard-coded the same wrong id.

The fix removes the class of bug rather than renaming one constant: products are
now derived from the registry catalog, and `entitled` is built from the SAME
registry keys, so the two sides cannot drift apart. The findings filter is
likewise derived from the tenant's own products.

Verified against the live dev registry: catalog returns
[certifai, compliance]; after starting a trial for acme, entitlements returns
`compliance` (enabled, expires 2026-09-16), and the mapping yields
entitled=[compliance] with entitled.includes("compliance")=true and
certifai=false. tsc --noEmit 0, next build 0.

Fixture tenants are unaffected — they still carry their own products, and the
derived filter uses those.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CNdLL9BdsWm7MCyui5ffPD
2026-09-02 10:46:12 +02:00