feat/subscription-gating
needs attentionviewing older commit6305b3c · incrementalPR #234reviewed 2026-07-04 03:53 UTC0H · 1M · 4L · 3I- Purpose
- Gate cost-incurring CFE downloads for organizations whose Stripe subscription is unpaid/canceled, while keeping reads, the billing page, and payment-status checks open.
- Goal
- Enforce subscription access policy at the download chokepoints using the existing organizations.subscription_status field — no new tables, sync, or migrations.
- Sub-goals
- SG-1: domain pure logic — decideFeatureAccess + SubscriptionInactiveError (402)
- SG-2: requireActiveSubscription middleware + tests
- SG-3: enforcement on cfe-jobs handler + public POST /v1/jobs + subscriber Lambda sweep filter
- SG-4: SubscriptionBanner UI (amber past_due / red canceled, CTA → billing)
- SG-5 (this commit): review nits — drop non-null assertion, add PaymentRequiredCode, harden log fallback
- What
- Single refactor commit: (1) replace org! non-null assertion with explicit !org guard in requireActiveSubscription — same behavior, no assertion; (2) export PaymentRequiredCode = CodesForStatus<402> alongside existing code aliases; (3) change subscription-access.ts fallback from raw UUID to '[unknown-org]' to prevent UUID leakage.
- Why
- Review nits from the prior review pass (f00e3ca0): drop the non-null assertion, add the missing type alias, make the log fallback safe against UUID leakage.
- Areas
- domains/core/src/billing+3−0apps/platform+5−0packages/api+5−0services/utility/bills/cfe+4−1docs/development+1−0
- Blast
- 24 files, +870/-5 cumulative vs main. Enforcement touches download endpoints only; reads, payment-status, and billing page are unaffected.
Findings · 8
correctness1
Comment claims null is handled via isOrgAllowed, but it is not
packages/api/src/middleware/require-active-subscription.ts:34
The comment reads 'Fail-open (null org → allowed) + exempt override, both via isOrgAllowed.' After the refactor, the `!org` short-circuit handles null before isOrgAllowed is called at all — isOrgAllowed never sees null in this path. The behaviour is correct but the comment misleads: a future reader would expect isOrgAllowed to be the null gate. Should read: null handled by explicit `!org`; exempt check via isOrgAllowed.
conventions2
Unreachable fallback '?? [unknown-org]' violates CLAUDE.md 'don't handle scenarios that can't happen'
services/utility/bills/cfe/src/domain/subscription-access.ts:43
The comment itself admits the fallback is unreachable ('Every blocked id was written to publicIdById in the same loop'). CLAUDE.md explicitly prohibits adding fallbacks or error handling for scenarios that cannot happen. The '?? "[unknown-org]"' branch, plus the three-line comment justifying it as a 'future refactor' guard, should be removed. Use a non-null assertion (publicIdById.get(id)!) or restructure to let TypeScript prove non-nullability, with no comment.
Comment misdescribes control flow: null is no longer handled via isOrgAllowed
packages/api/src/middleware/require-active-subscription.ts:34
The comment says 'Fail-open (null org → allowed) ... both via isOrgAllowed' but after the refactor the null case is caught by the explicit `!org` guard before isOrgAllowed is ever called. isOrgAllowed now handles only the exempt-override path for non-null orgs. The comment should reflect the actual split: `!org` → fail-open, `isOrgAllowed(org)` → exempt override.
tests3
Refactor preserves behavior — existing tests sufficient
packages/api/src/middleware/require-active-subscription.ts:34
The !org short-circuit is logically equivalent to the prior isOrgAllowed(null)===true path. Existing tests cover null-org, exempt, active, and inactive paths. No new tests needed.
PaymentRequiredCode is a pure type export — untestable at runtime
packages/api/src/responses/codes.ts:206
Type aliases have no runtime surface. No test needed.
Fallback sentinel '[unknown-org]' is on a structurally unreachable branch — no test needed
services/utility/bills/cfe/src/domain/subscription-access.ts:43
The blocked set and publicIdById map are populated in the same loop, so the ?? branch cannot fire with well-formed input.
improvement2
Unreachable fallback should be an invariant assertion, not a silent sentinel
services/utility/bills/cfe/src/domain/subscription-access.ts:40
The comment admits the fallback '[unknown-org]' is unreachable. A silent sentinel will silently corrupt log data if the invariant is ever broken by a refactor. Replace with an explicit invariant throw: `const pub = publicIdById.get(id); if (!pub) throw new Error('invariant: no publicId for orgId ' + id); return pub;` — this is the correct pattern for an impossible-at-runtime branch.
Comment explains the TypeScript compiler, not the business rule
packages/api/src/middleware/require-active-subscription.ts:34
The new comment documents TypeScript narrowing mechanics ('The `!org` short-circuit narrows org to non-null') rather than the non-obvious WHY. Per conventions, comments should explain why, not what. A one-liner like `// Null org is allowed (fail-open); exempt orgs are also allowed.` is sufficient.
History · 7 commits
- c807731needs attentionincremental0H · 6M · 8L2026-07-30 17:24
- 372882bneeds attentionincremental0H · 1M · 2L2026-07-21 17:31
- 1fac5adneeds attentionincremental0H · 5M · 4L2026-07-07 02:50
- 99bf169safeincremental0H · 0M · 1L2026-07-04 04:01
- 6305b3cneeds attentionincremental0H · 1M · 4L2026-07-04 03:53current
- f00e3caneeds attentionincremental0H · 7M · 16L2026-07-04 03:15
- 1ae74bdneeds attentionfull6H · 9M · 8L2026-07-04 02:36