feat(mana-sync): per-app billing exemption — Cards bypasses sync gate

mana-sync's billing middleware short-circuited every push/pull with
402 for users without a sync subscription. Cards promises free Sync
in its Phase-1 GUIDELINES, so it shouldn't gate its own users on a
mana-credits subscription it never sells.

Implementation:
  • billing.NewChecker now takes an exemptApps slice. The middleware
    extracts {appId} from the URL path and short-circuits before the
    user lookup if the app is in the set.
  • Configurable via the BILLING_EXEMPT_APPS env var (comma-separated).
  • Set BILLING_EXEMPT_APPS=cards on the mana-sync container so the
    cards.mana.how Sync loop stops 402-ing.
  • Tests cover the exemption + the empty/whitespace edge cases. All
    other apps keep the original behaviour (fail-open if mana-credits
    is unreachable, 402 if it explicitly says inactive).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-07 15:01:54 +02:00
parent 6f1b0329f0
commit ceed8ccd64
5 changed files with 145 additions and 16 deletions

View file

@ -684,6 +684,9 @@ services:
CORS_ORIGINS: "https://mana.how,https://*.mana.how"
MANA_CREDITS_URL: http://mana-credits:3002
MANA_SERVICE_KEY: ${MANA_SERVICE_KEY}
# Apps that bypass the sync-subscription billing gate. Cards
# promises free Sync per its Phase-1 GUIDELINES.
BILLING_EXEMPT_APPS: cards
ports:
- "3010:3010"
healthcheck: