feat(12-01): stub setupGuard.ts + setup.ts router — Wave-0 import targets
- Add apps/api/src/lib/setupGuard.ts exporting isSetupLocked(): Promise<boolean> (Wave-0 stub returns false; real DB impl ships in Plan 02) Doc comment enforces D-10: re-evaluate fresh on every call, never module-cache - Add apps/api/src/routes/setup.ts exporting setupRouter = new Hono() (empty router; handlers + index.ts mount added in Plan 02) Doc comment notes pre-auth surface position — before /api/* OIDC chain
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* setupGuard.ts — Phase 12 setup-wizard lock gate.
|
||||
*
|
||||
* Exports: isSetupLocked() — returns true when the setup wizard has already been
|
||||
* completed and no further calls to the /api/setup/* surface should be accepted.
|
||||
*
|
||||
* Key constraint (D-10): NEVER cache the result at module level.
|
||||
* This function MUST be called fresh at the top of every /api/setup/* handler so
|
||||
* that a concurrent POST /api/setup/complete (Pitfall 8 / SETUP-04) is reflected
|
||||
* immediately on the next call — even if two requests arrive within the same
|
||||
* event-loop tick. The per-call freshness pattern mirrors db.select() in health.ts.
|
||||
*
|
||||
* Wave-0 stub (Plan 01): returns false (setup always appears incomplete).
|
||||
* Real implementation (Plan 02): reads app_config.setup_complete + checks
|
||||
* member_credentials + VAPID env (effective-config branch, D-10).
|
||||
*/
|
||||
export async function isSetupLocked(): Promise<boolean> {
|
||||
// STUB — Wave-0 placeholder. Real impl: Plan 02.
|
||||
// Re-evaluated fresh on every call — NEVER cache at module level (D-10).
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* setup.ts — /api/setup/* route surface (Phase 12 initial-setup wizard).
|
||||
*
|
||||
* Mounted in index.ts: app.route('/api/setup', setupRouter)
|
||||
* Mount position: BEFORE app.use('/api/*', devAuthBypass()) so the wizard
|
||||
* is reachable pre-authentication — same pre-auth surface as /health (T-01-03).
|
||||
*
|
||||
* Wave-0 stub (Plan 01): empty router — all handlers are added in Plan 02.
|
||||
* Plan 02 owns the index.ts mount as well, to keep file-ownership clean.
|
||||
*
|
||||
* Security note: every handler added in Plan 02 MUST call isSetupLocked() as
|
||||
* its first statement and return 423 if locked (SETUP-04 / Pitfall 8 / D-10).
|
||||
*/
|
||||
|
||||
import { Hono } from 'hono';
|
||||
|
||||
export const setupRouter = new Hono();
|
||||
Reference in New Issue
Block a user