Zum Hauptinhalt springen

Administering users — ban, role assignment, and impersonation. Every action here is a fixture-only mock.

Users (sandbox)

Sandbox
User Role Status Actions
Ada (demo)
ada@example.com
Active
Lin (demo)
lin@example.com
Active
How this works

These rows are fabricated and every action is local state — navigate away and back and it all resets. Nothing is ever written to a database.

Audit log (recorded)

Recorded

admin.audit_log has no FK on actor_id, plus a denormalized actor_email.

Action Actor Target When
user.ban admin@example.com user/demo_user_02 2026-05-18T16:40:00.000Z
user.role.set admin@example.com user/demo_user_02 2026-05-12T10:15:00.000Z
user.impersonate.start admin@example.com user/demo_user_02 2026-05-19T11:30:00.000Z
auth.signin ada@example.com session/demo_sess_active 2026-05-19T09:00:00.000Z

Data model (recorded)

Recorded

Custom user data lives in app.user_preferences (PK is the FK → strict 1:1, cascade) — never by editing the Better-Auth-generated auth.user.

Auth data model
auth.user
  • id PK text
  • email text
  • role text
  • banned boolean
auth.session
  • id PK text
  • user_id FK text
  • token 🔒 text
  • impersonated_by text
auth.account
  • id PK text
  • user_id FK text
  • access_token 🔒 text
  • password 🔒 text
auth.verification
  • id PK text
  • identifier text
  • value 🔒 text
  • expires_at timestamp
app.user_preferences
  • user_id PK FK text
  • theme enum
  • locale text
  • user session ON DELETE cascade Sessions vanish with the user.
  • user account ON DELETE cascade OAuth/credential links vanish with the user.
  • user user_preferences ON DELETE cascade PK is the FK — strict 1:1, dies with the parent.
  • user verification ON DELETE no action (no FK) Verification rows are TTL-reaped, not FK-bound — orphans survive a user delete.
  • user audit_log ON DELETE no action (no FK) Audit trail must outlive the actor; actor_email is denormalized for that reason.

Geht dieses Pattern noch besser? Sag uns, wie.

Feedback geben