Add account self-delete and subscription lifecycle sync (#34)
CI / test (pull_request) Successful in 10s
Unit Tests / test (pull_request) Successful in 9s

Soft-delete DELETE /api/user/ for authenticated users (hide conversations,
blacklist tokens, block staff self-delete). Sync Stripe portal cancel/change
via subscription.updated/deleted webhooks and expose cancel_at_period_end for
Account UI (chat_web_app#75 companion).
This commit is contained in:
2026-08-01 14:15:09 -05:00
parent cc45ae5808
commit b3203f755d
12 changed files with 542 additions and 9 deletions
+25
View File
@@ -180,6 +180,31 @@ and frontend [chat_web_app#35](https://git.aimloperations.com/ai_ml_operations/c
Push/merge to `master` auto-deploys **beta** only. Prod requires the Gitea
**Run workflow** button on **Deploy Prod**. Deploy never runs on PRs.
## Frontend API notes
### Self-delete account ([#34](https://git.aimloperations.com/ai_ml_operations/chat_backend/issues/34))
| | |
|--|--|
| Method / path | `DELETE /api/user/` |
| Auth | JWT (authenticated user only; always deletes `request.user`) |
| Optional body | `{ "refresh_token": "<current refresh>" }` |
| Success | `200` `{ "detail": "Account deleted.", "deleted": true }` |
| Effects | Sets `deleted=True`, `is_active=False`; soft-deletes conversations; blacklists outstanding refresh tokens |
| Staff | Staff/superuser self-delete rejected (`400`, `code=staff_forbidden`) |
| Privacy v1 | Soft-delete only (no anonymization / hard purge) |
Post-delete UX: clear local tokens → redirect to sign-in. Subsequent
`/token/obtain/` fails. Do **not** send another user's id/email — ignored.
### Subscription change / cancel (portal + webhooks)
Plan change and cancel stay on Stripe Customer Portal
(`POST /api/finance/portal/`). Local state syncs via
`customer.subscription.updated` / `deleted` webhooks.
`GET /api/finance/subscription/` includes `cancel_at_period_end` and
`current_period_end` for Account UI messaging.
## Security note
Secrets previously hardcoded in `settings.py` (email password, captcha, Django