Argon2id hash (memory/time/parallelism from env config).
role
TEXT
'admin' or 'player'. Default 'player'.
status
TEXT
'enabled' or 'disabled'. Default 'enabled'.
created_at
TEXT
ISO 8601 timestamp (strftime('%Y-%m-%dT%H:%M:%fZ','now')).
Constraints
Unique on username.
role is enforced application-side (see AdminService.updateUserRole).
status is checked by AuthService.login and AuthService.refresh
— disabled users cannot log in or refresh.
Invariants
The application enforces the last-admin invariant: at least one
enabled user with role = 'admin' must always exist. Attempts to
demote or delete the last admin are rejected by
UsersService.enforceLastAdminInvariant (used by
AdminService.updateUserRole and AdminService.deleteUser).
First-admin bootstrap
When the user table is empty of admins, POST /api/v1/auth/register-first-admin
is the only endpoint that can create one. After that, the endpoint
returns 409 SYSTEM_INITIALIZED.