fix(automations): re-check subscription entitlement before claiming a run - #69
Open
polylane[bot] wants to merge 1 commit into
Open
polylane[bot] wants to merge 1 commit into
polylane[bot] wants to merge 1 commit into
Conversation
… run Co-authored-by: polylane[bot] <277585245+polylane[bot]@users.noreply.github.com>
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: cache-app: paid automations keep running after a subscription lapses (no entitlement check on the scheduled run path)
Automations are sold as a paid capability, but the subscription was only checked when a user created, edited, or resumed one. A subscriber who canceled or whose payment failed kept having scheduled runs executed, consuming the metered Gen AI budget and sending email indefinitely. The scheduled path now re-checks the subscription before claiming a run and pauses the automation when the subscription is no longer active.
flowchart TD A["External cron GET /api/cron/automations"] --> B["claimDueAutomationRuns"] B --> C["claimAutomationRun transaction"] C --> D{"Owner subscription active?"} D -- yes --> E["Claim run and start durable workflow"] D -- no --> F["Pause automation, cancel run, delete pending runs, WARN"] E --> G["executeReadOnlyAutomationRun: Gen AI spend and email"] H["Before: gate only in create, update, resume"] -.-> CWhat caused this
Affected:
int_0b563423d00164u048hh0sykWhy this fix
The entitlement gate
requireCanUseAutomationsis reachable only fromcreateAutomation,updateAutomation, andresumeAutomation; nothing on the scheduled path (/api/cron/automations->claimDueAutomationRuns->automationRunWorkflow) consulted the subscription.claimDueAutomationRunsselected due runs onscheduledForUtcandstatus: pendingalone, so a lapsed user's runs kept being claimed and executed. The change evaluatesgetUserActiveSubscriptionStatus(run.userId, tx)inside the existing claim transaction, so a run is claimed only when the owner's subscription is active or trialing, and a lapsed owner's automation is paused with its pending runs removed in the same transaction. Pausing ends the recurring obligation rather than skipping one occurrence; the user restores it through the resume action, which already checks entitlement. A read error on the subscription lookup aborts the transaction, so a paying user's automation is never wrongly paused and no run is claimed.past_dueis treated as not entitled, matching the capability model already used at creation and resume; a grace period would be a separate product decision. The WARN line makes every pause visible, though the workspace has no log drain to collect it.Out of scope
past_duegrace period: it stays not-entitled, consistent with the existing capability model.2 files changed (+291/-1)
lib/intelligence/automations/service.test.ts: added, +224/-0lib/intelligence/automations/service.ts: modified, +67/-1Generated by Polylane. You can ask follow-ups by mentioning @polylane in a comment.