feat(measurement-jobs): free-tier card gate (setup mode) + instant backfill drain (chat#1796)

Merged
SW
4mo ago
+115-8

Two in-scope refinements to the historical measurement-job path from chat#1796, both TDD.

1. Free-tier card-on-file link (was billing $99/mo)

The card gate was issuing createStripeSession — the paid subscription flow (mode: "subscription" on the $99/mo price, 30-day trial). New createCardOnFileSession uses Stripe Checkout mode: "setup": it collects a card for $0, no subscription, no price/product (so no Stripe dashboard/CLI work). The account saves a payment method and pays only for metered usage via the existing credits system (which auto-recharges off the saved card). Gate now points at it.

2. Instant drain (no 24h wait)

After a historical job enqueues, it now fires start(songstatsBackfillWorkflow) immediately — the same workflow the daily cron runs — so backfill begins right away. Safe by reuse, not new machinery:

  • the workflow's getBackfillBudgetStep caps it to the rolling Songstats quota (limit − reserve − 30-day ledger) and stops when dry — the rate-limit lesson is already enforced;
  • FOR UPDATE SKIP LOCKED claims prevent double-processing alongside the cron;
  • the daily cron stays as the backstop (multi-day draining when capped, retries, orphan reclaim);
  • only kicks when something was actually enqueued (all-skipped → no-op); fire-and-forget so a scheduling hiccup can't fail the job.

Testing

26 new/updated unit tests (setup-mode session, gate → setup session, instant-drain trigger fires when enqueued / not when all-skipped). Full research+stripe+workflows suite 453 green; tsc/lint/format clean.

Verify on preview: a cardless key on historical → 402 + a mode:setup ($0) checkout link; and the enqueued tracks should start draining within minutes (budget permitting) rather than next day.


Summary by cubic

Add a free‑tier card-on-file gate for historical measurement jobs and start backfills immediately after enqueue. This removes the paid subscription requirement and reduces the wait from up to 24h to minutes.

  • New Features
    • Free-tier card gate: use createCardOnFileSession (Stripe Checkout mode: "setup") to save a card for $0. Replaces the subscription checkout; 402 now returns a setup link when no card is on file.
    • Instant backfill: call start(songstatsBackfillWorkflow) right after enqueue. Only when items are enqueued; budget gate and SKIP LOCKED prevent double work; the daily cron remains the backstop.