- Flask API in
backend/app.py - PostgreSQL as source of truth for provisional and final auth state
- SQLAlchemy models auto-created on startup
- In-process background verification thread consumes queued verification tasks
- Client calls
POST /auth/optimistic-loginand immediately marks the user as authenticated locally. - API stores a
pendingsession/attempt row and enqueues async verification. - Verification updates the row to
activeorrolled_back. - Client polls
GET /auth/sessionor callsPOST /auth/verifyfor state reconciliation.
localAuth.phase:optimistic_pending | active | rolled_backlocalAuth.sessionId: provisional session identifierlocalAuth.rollbackReason: nullable server reason- Reconciliation rules:
pending=> keep optimistic UI and pollactive=> commit durable authenticated staterolled_back=> clear tokens/session and navigate to recovery UI
- Duplicate verification calls
- Retry storms from flaky networks
- Expired verification artifacts
- Invalid credentials/assertions/tokens
- Server status transitions are monotonic:
pending -> active|rolled_back POST /auth/verifyis idempotent and safe under retriesGET /auth/sessionalways returns authoritative status for page-refresh recovery
- Client can render authenticated shell instantly while verification is pending
- Verification can complete after request lifecycle through worker thread
- Poll interval should be tuned to avoid DB hot loops
- Optimistic state can temporarily expose privileged UI before verification result
- APIs must still guard protected data by authoritative server status checks
- Rollback must revoke provisional client state immediately
- Replay prevention depends on one-time tokens/consumption flags in DB
cp .env.example .env
docker compose up --buildRequest shape depends on this variant. Response example:
{"session_id":"b9d7...","status":"pending","optimistic":true}{"session_id":"b9d7..."}Response:
{"status":"active","attempts":1,"rollback_reason":null}Response:
{"session_id":"b9d7...","status":"pending"}See endpoint handlers in backend/app.py for exact required fields for this variant.