feat/subscription-gating
safeviewing older commit99bf169 · incrementalPR #234reviewed 2026-07-04 04:01 UTC0H · 0M · 1LThe branch
- Purpose
- Block cost-incurring CFE downloads for orgs with inactive Stripe subscriptions (canceled/unpaid), while keeping reads, the billing page, and payment-status checks open so customers can self-cure.
- Goal
- Gate collect/download job creation behind subscription_status, enforce 402 on inactive orgs, show amber/red subscription banner in dashboard.
- Sub-goals
- SG-1: decideFeatureAccess pure function + SubscriptionInactiveError (402)
- SG-2: requireActiveSubscription middleware guard
- SG-3: Enforcement on cfe-jobs handlers + public POST /v1/jobs + CFE subscriber Lambda
- SG-4: SubscriptionBanner in dashboard layout (es/en)
The changes (whole branch)
- What
- Refactored partitionGroupsByAccess to capture blockedPublicIds inline in the same branch that sets blocked, removing the separate publicIdById Map and the now-dead ?? '[unknown-org]' fallback.
- Why
- The old two-phase approach (build Map → post-loop lookup) had a fallback that was already documented as unreachable. Inline capture makes the invariant structural.
- Areas
- apps/platform+131−2domains/core/src/billing+237−1packages/api/src/middleware+103−0packages/api/src/responses+7−0services/utility/bills/cfe+146−9docs/development+209−0
- Blast
- 26 files, +841/−12 across billing domain, API middleware, CFE Lambda subscriber, platform handlers, and dashboard UI. No migration.
billing-gating no-migration fail-open pure-function-refactor
➖CI· no CI status available for this SHA➖coderabbit· no .coderabbit.yaml in repo✅tests· 6/6 unit tests pass
Findings · 1
conventions1
low
Inline comment explains WHAT, not WHY
services/utility/bills/cfe/src/domain/subscription-access.ts:37
Comment `// internal id → group matching` describes the value type, not the reason for inline capture. Remove or fold into the adjacent WHY comment.
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:01current
- 6305b3cneeds attentionincremental0H · 1M · 4L2026-07-04 03:53
- f00e3caneeds attentionincremental0H · 7M · 16L2026-07-04 03:15
- 1ae74bdneeds attentionfull6H · 9M · 8L2026-07-04 02:36