Account Deletion
One endpoint that removes the user and cascades every piece of owned data.
Account deletion is a single authenticated endpoint that removes the user's stored files and then the user row itself, letting database cascades clear everything the account owns. It is the only deletion path — there is no second, partial way to delete an account.
DELETE /api/app/v1/account
→ { "success": true, "data": { "deleted": true } }What gets deleted
src/server/app/account/accountService.ts runs two steps:
Uploaded files
All objects under the user's storage prefix (uploads/<userId>/) are deleted
from the object storage — files are the one thing a database cascade cannot
reach. If storage cleanup fails, deletion still proceeds and the failure is
logged for a manual sweep, so a storage outage can't hold the account hostage.
The user row + cascades
The Better Auth user row is deleted. Every owned table references
user.id with ON DELETE CASCADE, so this clears:
sessionandaccount(auth sessions, OAuth links)todosdevice_tokenssubscription(the entitlement snapshot)payment(order records)
Design notes
- Server-side identity only. The route uses
authedRoute, so the deleted account is always the session's — there is no user-ID parameter. - Better Auth's
delete-userendpoint is not enabled. A second public deletion path would skip file cleanup and the cascade guarantees; keeping one path keeps the cleanup complete. - Native clients call this endpoint with their Bearer session, then clear the Keychain and local state.
- Deleting the account does not cancel an App Store subscription — Apple billing is between the user and Apple. The local snapshot row is removed; advise users to cancel via Apple's subscription settings first.
