Skip to content

Add admin user deletion and protect account cleanup - #201

Merged
devhims merged 4 commits into
mainfrom
fix/account-deletion-cleanup
Oct 15, 2026
Merged

devhims merged 4 commits into
mainfrom
fix/account-deletion-cleanup

Conversation

@devhims

@devhims devhims commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Problem / Motivation

Admins need to find and delete accounts without leaving Polar customers or private data behind. Older sessions could fail deletion, while checkout and queued emails could leave orphaned data.

What changed

Add admin user-ID/email search, pagination and email-typing deletion confirmation. Require live admin authentication and the dashboard Origin. Reject changed account identities. Protect admin-role and bootstrap operator accounts from both deletion endpoints.

Admin and self-service deletion share one cleanup service. Renewing subscriptions must be cancelled first, with an error toast when blocked. Anonymize the Polar customer, clear private sessions, sources and files, and remove the D1 user last. Preserve shared transcripts, storyboards and catalog assets. Initialize legacy session schemas, retry private search deletion, and clear the deleted user's stored sessions while retaining the admin login.

Coordinate checkout and deletion through durable per-account claims. Existing checkout requests block deletion; deletion blocks replacement customers and checkouts. Unconfirmed Polar writes retain a durable fence until operator reconciliation; POST retries are disabled. Queued magic links require their exact unexpired verification record, including after re-registration.

%%{init: {"themeVariables": {"sequenceNumber": "#ffffff", "signalColor": "#4b5563"}}}%%
sequenceDiagram
    autonumber
    participant App
    participant Gate as Account billing gate
    participant Polar
    participant Private as Private storage
    participant D1
    App->>Gate: Fence checkout before deletion
    Gate-->>App: Reject in-flight or unresolved checkout
    App->>Polar: Check cancellation and anonymize customer
    App->>Private: Delete sessions, sources and files
    Note over Private: Shared video assets retained
    App->>App: Queue private search deletion
    App->>D1: Delete user and metadata last
Loading

Unconfirmed writes block both checkout and deletion, including after restart.

Tests

Platform build, 1,814 unit tests and all 123 auth/billing integrations pass. Real-SDK regressions simulate late commits after resets, timeouts and malformed responses, verify safe reconciliation, and cover definitive rejections. No live Polar writes were performed.

Deployment requires subscriptions:read and customer write permissions. No D1 migration is needed. Legacy queued magic links require re-requesting. Uncertain billing writes require manual reconciliation. Production deployment remains pending.

@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
video2ctx-web Ready Ready Preview Oct 15, 2026 10:17am UTC

devhims commented Oct 15, 2026

Copy link
Copy Markdown
Owner Author

Changes needed for b8f4303.

  • [P2] Fence checkout before closing billing (session.index.ts:647–651). While local cleanup waits after Polar deletion, another authenticated checkout can create a replacement customer and checkout. Deletion then returns 204, leaving both behind for a deleted account. The same regression passes on base and fails on this head and the synthetic merge. Coordinate checkout with deletion, including in-flight requests.
  • [P2] Cover queued magic links in email suppression (queues.ts:45–53). Better Auth queues these without userId, so the NULL branch permits delivery after account deletion and recreates recipient-hash metadata. Reproduced using a real signInMagicLink payload and local D1; its verification token was correctly deleted.

All eight Verify jobs pass. Independent builds, integration/unit/browser checks and PR #200 merge/readiness controls passed. Polar was mocked; replacement-customer behavior was checked against Polar’s soft-delete implementation. No live billing or production deletion was exercised.

@devhims
devhims force-pushed the fix/account-deletion-cleanup branch from b8f4303 to ec29a8f Compare October 15, 2026 09:28
@devhims devhims changed the title Fix account deletion and require subscription cancellation Add admin user deletion and protect account cleanup Oct 15, 2026

devhims commented Oct 15, 2026

Copy link
Copy Markdown
Owner Author

Changes needed for 36d36ac.

  • [P2] Preserve the checkout fence after an ambiguous customer-create failure (polar-checkout.ts:53–54). finally releases the claim after ECONNRESET/504 even though Polar may still commit the accepted POST. Deletion can then return 204 before that POST creates an orphan customer for the deleted user. Retain the fence until the write’s outcome is reconciled. Both failure variants reproduce with the real SDK, D1 and Durable Object; remote timing is simulated, not live Polar evidence.

Both original regressions now pass. Independent builds, admin/email/lifecycle tests, browser checks and combined-main PR #199/#200 controls passed apart from this finding. All eight required Verify jobs pass. No live billing or production deletion was exercised.

devhims commented Oct 15, 2026

Copy link
Copy Markdown
Owner Author

Approve for 34c3334. No remaining material findings.

The previous P2 is fixed: billing-gate.ts:19–22 retains the claim after uncertain writes. Nine independent recovery controls pass, including late commits, wrong-claim isolation and safe deletion after confirmed reconciliation. Earlier checkout-concurrency/magic-link regressions, 123 integrations, 32 focused unit tests and build/typecheck/docs checks pass. The two unchanged ambiguity tests stop at obsolete expected-500 assertions; separate controls verify the new 409 behavior and safety invariant.

All eight required Verify jobs pass. Tests used real SDK/auth/local D1/DO with simulated remote timing. Persistence was checked by reopening the gate, not killing a Worker. No live Polar operations were exercised.

@devhims
devhims merged commit aa2d3cd into main Oct 15, 2026
11 checks passed
@devhims
devhims deleted the fix/account-deletion-cleanup branch October 15, 2026 10:37

This branch was successfully deployed

1 active deployment
Preview — 34c33346 Deployed Oct 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant