Files
skills/docs/api-stack/api/api-plugin-user/src/routes/delete-me.md
2026-05-29 08:20:56 +01:00

2.2 KiB

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

const entry = buildDeleteMeRoute({ authService, allowSelfDelete: true });

Usage: Advanced

The route can be mounted on a non-default path by destructuring the returned entry:

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.