test(12-02): isSetupLocked() real impl + RED-first setup route tests
- Implement real isSetupLocked() in setupGuard.ts: reads app_config.setup_complete (returns true if value==='true'); else checks member_credentials row + VAPID env for effective-config branch (D-10) - Re-queries DB fresh every call — no module-level cache (D-10/Pitfall 8) - Convert Wave-0 it.todo() scaffolds into real integration tests (17 tests RED) - RED-first 423 guard test: POST /complete twice → first 200, second 423 (Pitfall 8) - D-10 effective-config tests: 423 when credRow AND VAPID env; NOT 423 otherwise - 2 'does NOT return 423' tests pass (404 ≠ 423); all others RED pending Task 2 router
This commit is contained in:
@@ -10,12 +10,30 @@
|
||||
* 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).
|
||||
* Two-branch lock logic (D-10):
|
||||
* 1. Explicit: app_config.setup_complete === 'true'
|
||||
* 2. Effective: a member_credentials row exists AND VAPID_PRIVATE_KEY + VAPID_PUBLIC_KEY env set
|
||||
*
|
||||
* Real implementation (Plan 02): reads app_config.setup_complete + checks
|
||||
* member_credentials + VAPID env (effective-config branch, D-10).
|
||||
*/
|
||||
|
||||
import { db } from '../db/client.js';
|
||||
import { appConfig, memberCredentials } from '../db/schema.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
/** Returns true if the wizard is already locked. Re-evaluated fresh — NEVER cache at module level. */
|
||||
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;
|
||||
// Check 1: explicit setup_complete flag in app_config
|
||||
const [flagRow] = await db
|
||||
.select({ value: appConfig.value })
|
||||
.from(appConfig)
|
||||
.where(eq(appConfig.key, 'setup_complete'))
|
||||
.limit(1);
|
||||
if (flagRow?.value === 'true') return true;
|
||||
|
||||
// Check 2: effective configuration — member_credentials row exists AND VAPID env set (D-10)
|
||||
const [credRow] = await db.select({ id: memberCredentials.id }).from(memberCredentials).limit(1);
|
||||
const vapidPresent = !!process.env.VAPID_PRIVATE_KEY && !!process.env.VAPID_PUBLIC_KEY;
|
||||
return !!credRow && vapidPresent;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user