Validated on current origin/main (5139377).
Finding:
- Convex payment state updates entitlements when Dodo webhook events arrive.
subscription.renewed updates subscriptions.currentPeriodEnd and recomputes entitlements in convex/payments/subscriptionHelpers.ts.
convex/crons.ts has maintenance crons, but no subscription-renewal reconciliation cron that queries Dodo for active subscriptions whose local currentPeriodEnd has passed.
Impact:
- If a renewal webhook is missed or exhausted after retries, a paying subscriber can be silently downgraded once the stale local
validUntil expires, even if Dodo still considers the subscription active.
Suggested fix:
- Add a daily reconciliation job for active subscriptions with
currentPeriodEnd < now.
- Query Dodo for authoritative state, refresh subscription rows, and recompute entitlements.
- Add a regression test covering an active remote subscription with stale local period end and no recent webhook.
Validated on current origin/main (5139377).
Finding:
subscription.renewedupdatessubscriptions.currentPeriodEndand recomputes entitlements inconvex/payments/subscriptionHelpers.ts.convex/crons.tshas maintenance crons, but no subscription-renewal reconciliation cron that queries Dodo for active subscriptions whose localcurrentPeriodEndhas passed.Impact:
validUntilexpires, even if Dodo still considers the subscription active.Suggested fix:
currentPeriodEnd < now.