feat(kilo-pass): integrate Churnkey for cancel flow and pause/resume support#2113
feat(kilo-pass): integrate Churnkey for cancel flow and pause/resume support#2113
Conversation
…support Migrates feat/churnkey-integration to monorepo structure. Replaces custom cancel/feedback modals with Churnkey SDK, adds pause/resume subscription support with pause event tracking, streak preservation across pauses, and yearly issuance cap.
| : null; | ||
| await openPauseEvent(tx, { | ||
| kiloPassSubscriptionId, | ||
| pausedAt: dayjs().utc().toISOString(), |
There was a problem hiding this comment.
WARNING: Pause timestamps use webhook processing time
getPausedMonthSet() treats paused_at / resumed_at as the source of truth for streak reconstruction, but this code records the current server time instead of a Stripe-derived pause/resume timestamp. If the webhook is delayed, retried, or delivered out of order, the stored pause window shifts and monthly streak calculation can skip or count the wrong months.
| // Close the open pause event so the UI reflects the change immediately. | ||
| // The state query derives paused status from open pause events, so closing | ||
| // it is sufficient — no need to update the DB status column directly. | ||
| await closePauseEvent(db, { |
There was a problem hiding this comment.
WARNING: Closing the pause event does not immediately unpause state
getKiloPassStateForUser() falls back to the row's stored status when there is no open pause event. If this subscription already has status = 'paused' in kilo_pass_subscriptions, invalidating getState right after this mutation still returns paused until the webhook updates the row, so the UI can stay stuck in the paused state after a successful resume. This mutation needs to persist the resumed Stripe status as well.
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Fix these issues in Kilo Cloud Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)None. Files Reviewed (10 files)
Reviewed by gpt-5.4-20260305 · 1,716,273 tokens |
…support (#2113) Migrates feat/churnkey-integration to monorepo structure. Replaces custom cancel/feedback modals with Churnkey SDK, adds pause/resume subscription support with pause event tracking, streak preservation across pauses, and yearly issuance cap.
Summary
Migrates #1799 (
feat/churnkey-integration) to the new monorepo structure per the migration prompt. Supersedes #1799.kilo_pass_pause_eventstableresumeSubscription→resumeCancelledSubscriptionto distinguish from pause resumeKiloPassDetail.tsx(from feat(subscriptions): add subscription center with unified billing management #2047) to use renamed procedureChurnkey integration
apps/web/src/lib/churnkey/auth.ts— server-side HMAC-SHA256 auth hashapps/web/src/lib/churnkey/loader.ts— client-side SDK loader withshowCancelFlow()and fallbackgetChurnkeyAuthHashtRPC querywindow.confirm+ direct cancellation if SDK fails to loadNEXT_PUBLIC_CHURNKEY_APP_IDandCHURNKEY_API_SECRETenv varsPause/resume support
kilo_pass_pause_eventstable (migration0074) with partial unique index and CHECK constraintopenPauseEvent,closePauseEvent,getOpenPauseEvent,getPausedMonthSetpause_collectiontransitions in subscription webhook handlerresumePausedSubscriptionmutationresumesAtdate and resume buttonVerification
pnpm --filter web typecheck— passedpnpm --filter @kilocode/db typecheck— passedpnpm --filter web lint— 0 warnings, 0 errorspnpm run format:changed— cleanTest plan
window.confirmwhen Churnkey SDK is unavailable