first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# routes/delete-me
## Purpose
`buildDeleteMeRoute` returns the `PluginRouteEntry` for `DELETE /me`.
The route is gated by the plugin's `allowSelfDelete` option — when
disabled, the handler raises `USER_SELF_DELETE_DISABLED` (403) so
the OpenAPI doc still advertises the path but the runtime refuses
the call. When enabled, the handler resolves Better-Auth's internal
adapter via `auth.$context` and invokes `deleteUser(id)` — the
adapter cascades the deletion across the `account` and `session`
tables so a subsequent `requireAuth()`-gated request from the same
session returns 401.
## Features
- `allowSelfDelete: false` produces a 403 with the canonical error
envelope; the OpenAPI doc still describes the route so consumers
can detect the disabled state programmatically.
- `auth.$context` is the canonical entry point into Better-Auth's
internal adapter; using it lets the plugin avoid any HTTP-layer
re-routing.
- `user.self_deletes_total` increments only on success so a
dashboard cannot mistake a disabled-state 403 for a real delete.
## Usage: Basic
```ts
const entry = buildDeleteMeRoute({ authService, allowSelfDelete: true });
```
## Usage: Advanced
The route can be mounted on a non-default path by destructuring the
returned entry:
```ts
const { route, handler } = buildDeleteMeRoute({
authService,
allowSelfDelete: false,
});
app.openapi({ ...route, path: "/account/delete" }, handler);
```
## API Reference
### `DeleteMeResponseSchema`
`z.object({ deleted: z.literal(true) })`.
### `DeleteMeResponse`
`z.infer<typeof DeleteMeResponseSchema>` — `{ deleted: true }`.
### `buildDeleteMeRoute({ authService, allowSelfDelete }): PluginRouteEntry`
`authService` MUST be the `@suaveplan/api-plugin-auth` service slot;
`allowSelfDelete` mirrors the plugin's resolved config.
## Implementation Notes
- The handler awaits `auth.$context` once per call — Better-Auth
caches the context internally so the round-trip is cheap.
- Failures from the internal adapter wrap into
`USER_PROFILE_UPDATE_FAILED` so the registry stays cohesive
(PROFILE_UPDATE = "any write to the user row failed").
- The 401 raise on missing principals mirrors the other route
handlers so the failure mode is identical end-to-end.