POST /admin/users (Site-Admin guard) creates an account with the same
field rules as self-registration, but active immediately: the admin
vouches for the address, so the e-mail is marked verified and the
personal pond is provisioned exactly like the verify-email path does
(markEmailVerified alone would skip the pond).
The user manager gains a create dialog (useModalFocus/useDismissable,
Field wiring, flat RHF field names per the #322 lesson). New audit
action user.created_by_admin, catalogue bumped to 1.9.
Tests: api e2e-db (create + immediate login + personal pond, duplicate
username 409, non-admin 403), web e2e through the dialog, and the
admin a11y scan now opens the dialog too. Both packs verified locally
against a fresh stack.
Closes#331
The `never`/`you` keys had value == key in English; the sed that produced
the German file rewrote the key too. Restores the keys so `pnpm i18n:check`
(the CI test gate) passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
Instance operators get basic user administration for support, abuse handling,
and GDPR groundwork (security.md §Privacy).
- api `admin/`: Site-Admin-gated `/admin/users` — a searchable, paginated list
(username, e-mail, status, role, pond count, last login) plus lifecycle
actions: disable/enable (a disabled user is logged out everywhere and login
is refused with the distinct `account_disabled`), resend verification, delete,
and grant/revoke Site Admin. Guards: you cannot act on your own account
(`cannot_modify_self`) and the last Site Admin cannot be dropped
(`last_site_admin`). Every action is audit-logged with the actor.
- `PseudonymizationService`: account deletion scrubs the PII, removes all login
identities + sessions, and trashes the personal pond — the kept row is what
authorship references, so shared content the user authored shows as "Deleted
user" (no orphaned/cascaded content).
- web: the Admin area gains a 'Users' surface — search, pagination, and the
actions (destructive ones behind an inline two-step confirm; self-actions
hidden). New `users` i18n namespace (de+en).
- tests: `user-admin.e2e.db.test.ts` (disable → logout + login blocked; delete
→ pseudonymized authorship + personal pond trashed + credentials gone; last
Site Admin and self protected; Site-Admin gating); a non-destructive browser
`admin-users` pack proving disable-in-UI blocks login and enable restores it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1