AI Implementation feature(847): First-Start Create Admin Modal 1.06 #9
+1
-1
@@ -3,7 +3,7 @@ type: api
|
||||
title: Setup Endpoint
|
||||
description: Dedicated POST /api/v1/setup/create-admin endpoint used only while no administrator exists.
|
||||
tags: [api, setup, bootstrap, first-admin]
|
||||
timestamp: 2026-07-21T17:18:08Z
|
||||
timestamp: 2026-07-21T17:37:18Z
|
||||
---
|
||||
|
||||
# Endpoint
|
||||
|
||||
+20
-4
@@ -3,7 +3,7 @@ type: database
|
||||
title: User Table
|
||||
description: The `user` table — accounts, roles, and statuses.
|
||||
tags: [database, user, auth]
|
||||
timestamp: 2026-07-21T14:43:00Z
|
||||
timestamp: 2026-07-21T17:37:18Z
|
||||
---
|
||||
|
||||
# Schema
|
||||
@@ -37,14 +37,30 @@ timestamp: 2026-07-21T14:43:00Z
|
||||
When the `user` table is empty of admins, the dedicated
|
||||
`POST /api/v1/setup/create-admin` endpoint (see
|
||||
[Setup Endpoint](/api/setup.md)) creates the very first admin and
|
||||
auto-issues a session. Once any admin row exists the endpoint becomes
|
||||
inert and returns `404 NOT_FOUND`, so the route is effectively hidden
|
||||
in production.
|
||||
auto-issues a session. Once any admin row exists the endpoint rejects
|
||||
further attempts with `409 SYSTEM_INITIALIZED`, so the route is
|
||||
effectively hidden in production.
|
||||
|
||||
The legacy `POST /api/v1/auth/register-first-admin` route is preserved
|
||||
for compatibility but the canonical first-admin flow now lives in the
|
||||
`SetupModule`.
|
||||
|
||||
# Concurrent bootstrap safety
|
||||
|
||||
Two near-simultaneous `POST /api/v1/setup/create-admin` requests cannot
|
||||
both succeed. `SetupService.createAdmin` serializes callers on an
|
||||
in-process promise chain (`#bootstrapChain` + private
|
||||
`runBootstrap()` in `backend/src/modules/setup/setup.service.ts:111-130`)
|
||||
so that the first request commits inside its `DataSource.transaction`
|
||||
before the second request's transaction executes. The loser's
|
||||
transaction observes `adminCount > 0` and throws
|
||||
`ApiError(SYSTEM_INITIALIZED, 409)`; the winner is the only request that
|
||||
creates a `UserEntity(role='admin')` row and mints a refresh token.
|
||||
The lock is per-process; multi-replica deployments rely on the unique
|
||||
index and transaction guard, not on this chain. The regression test is
|
||||
`tests/backend/setup-create-admin.spec.ts` ("only one of two concurrent
|
||||
first-admin requests succeeds").
|
||||
|
||||
# See also
|
||||
|
||||
- [Auth and Settings Tables](/database/auth-settings.md)
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ scoreboard, an event window with a public countdown, theming, and admin
|
||||
controls.
|
||||
|
||||
The docs below are organized by purpose so agents can pull just the slice
|
||||
they need. Last regenerated 2026-07-21T17:18:08Z.
|
||||
they need. Last regenerated 2026-07-21T17:37:18Z.
|
||||
|
||||
# Architecture
|
||||
|
||||
|
||||
Reference in New Issue
Block a user