Repository navigation
Retain deleted account history and preserve credits across signups - #202
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Changes needed for
Verification: all eight Verify jobs pass. Independent probes: 20 passed, four failed on these cases. Existing auth/billing 135, platform 1,814, web 109 and five browser checks passed. Builds/typecheck/docs passed. Tests used isolated local D1 and synthetic provider responses; no live billing or production validation. |
|
Changes needed for P2: An applied refund can leave Builder access enabled. billing.ts:513–526 still gates the entitlement downgrade on the latest metadata timestamp. Reproduced: payment October 1, active/cancel-at-period-end metadata October 3, refund October 2. The signed webhook returns 200, resets credits to 1,000 and records The four prior accounting/restoration failures now pass. Independent probes: 69 passed, two failed on this one issue. Existing platform 1,814, auth/billing 161 and storage 354 tests passed, plus build/typecheck/docs and all eight Verify jobs. Isolated local D1/synthetic provider tests; browser E2E verified in CI, no live billing or production validation. |
|
Changes needed for P2: An in-flight customer snapshot can restore Builder after refund. billing.ts:205–220 reads the refund lock before its write transaction. Reproduced deterministically: an October 3 active snapshot reads first, the October 2 refund commits Starter/1,000 credits, then the snapshot commits Builder. The actual guard allows deep imports again. Active and cancel-at-period-end variants both fail. Make the refund protection atomic with the snapshot write. Replay repairs access, but both original deliveries succeed, so replay is not guaranteed. Base/prior-head controls confirm this race is pre-existing, not introduced by this delta. All 71 previous cases pass unchanged, including the sequential entitlement fix. Additional probes: 20 passed, two failed on this race. Existing platform/auth/storage suites, build/typecheck/docs and all eight Verify jobs pass. Local synthetic fixtures only; browser E2E verified in CI, no live billing/production validation. |
|
Approve for The remaining P2 race is fixed at billing.ts:522–523: both unchanged reproductions now retain Starter/1,000 credits and reject deep imports, while newer fulfilled payments retain Builder access. Earlier carryover, duplicate-restoration, ordering and replay findings remain fixed. Verification: all 93 prior independent cases plus 17 new controls pass. Platform 1,814, auth/billing 170 and storage 354 tests pass, along with build/typecheck/docs and all eight Verify jobs. Local disposable fixtures and synthetic signed events; browser/container validation relied on CI. No live billing or production validation. |
Problem / Motivation
Deleting and recreating an account grants another 1,000 Starter credits. Admins lose the history needed to investigate deleted accounts. Delayed refunds can leave transferred paid credits spendable, while stale refunds can erase a newer payment.
What changed
Retain a permanent deletion record with email, dates, Polar reference, plan, balance and deletion actor. Admin email/ID search includes historical records. Returning signups claim the latest balance once, even after an admin email change.
Keep subscription cancellation, Polar anonymization, admin protection and existing cleanup intact. Shared assets remain available. Direct D1 deletion records history but bypasses external cleanup.
Refunds follow account-ID transfers. Live and deleted accounts use the same credit reconciliation. Receipts require evidence of an adjustment or a justified skip. Applied refunds revoke Builder access. Snapshot writes check the refund lock atomically, preserving newer fulfilled payments. Replay cannot refill spent credits.
Migration 0026 preserves existing paid grants and applied refunds. Ambiguous legacy payment timing returns a retryable error without marking the refund handled. Signed payment replay resolves timing even after anonymization, without granting credits again.
%%{init: {"themeVariables": {"sequenceNumber": "#ffffff", "sequenceNumberColor": "#ffffff", "signalColor": "#475569"}}}%% sequenceDiagram autonumber participant User participant App participant D1 Note over User,D1: Before: deletion erased identity and signup granted another 1,000 User->>App: Delete account with 340 credits App->>App: Existing cancellation, Polar and private cleanup App->>D1: Retain history and remove user atomically User->>App: Sign up with the same email App->>D1: Claim and restore 340 credits once Note over App,D1: Refunds follow the current credit ownerThe deletion record remains; private content is removed.
Tests
Platform build, 1,814 unit tests, 170 auth/billing integrations, 354 storage tests and documentation checks pass. Regressions cover signed webhooks, real upgrades, skipped writes, replay and concurrent deletion. No live billing writes.
Apply updated migration 0026 before the Worker. Deploy promptly. For ambiguous legacy ordering, replay the saved grants' signed payment events, then the refund. Erased history cannot be reconstructed. Production is unchanged.