Files
2026-05-22 14:33:20 +02:00

5.6 KiB

Phase 2: Users & Authentication - Discussion Log

Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

Date: 2026-05-22 Phase: 2-Users & Authentication Areas discussed: Email transport, Admin bootstrap, API auth scope, Frontend auth UX


Email Transport

Option Description Selected
SMTP via env vars SMTP_HOST/PORT/USER/PASSWORD/FROM env vars; dev fallback to stdout
Resend / Mailgun API Third-party transactional email API; one env var (API key)
Console-only for now Print reset link to stdout only; not production-ready

User's choice: SMTP via env vars


Option Description Selected
Log reset link to stdout Developer sees link in docker compose logs; zero extra config
Return token in API response Token in JSON response when SMTP not set; easier for testing
Return 503 Hard failure if SMTP not configured; breaks local dev

User's choice: Log the reset link to backend stdout when SMTP not configured


Option Description Selected
Celery task (async) Email enqueued; API returns 202 immediately; Redis already wired
Synchronous inline Email sent during request; SMTP timeout blocks user

User's choice: Celery task — async dispatch, 202 returned immediately


Admin Bootstrap

Option Description Selected
ENV-var bootstrap on startup ADMIN_EMAIL + ADMIN_PASSWORD; seeded on startup if no users exist; idempotent
Alembic seed migration Admin row inserted in migration; credentials from env at migration time
CLI management command Manual python manage.py create-admin step after deploy
First-user-is-admin First registered user becomes admin; race-condition risk

User's choice: ENV-var bootstrap on startup


Option Description Selected
Skip silently if not set App starts normally; admin can be created later
Warn in startup logs if not set WARNING logged; app starts; helpful reminder
Refuse to start if not set Startup fails; blocks headless/CI environments

User's choice: Warn in startup logs (app still starts)


Option Description Selected
Same 100 MB default quota Consistent; every users row gets a quotas row
Unlimited quota for admin Signals admins are operators, not subject to storage limits
No quota row for admin Admin doesn't upload; but requires special-casing in enforcement

User's choice: Same 100 MB default quota as regular users


API Auth Scope

Option Description Selected
Only new auth endpoints; existing stay public Phase 2 ships /api/auth/* only; D-03 nullable user_id preserved
Lock down all endpoints in Phase 2 All endpoints get get_current_user + NOT NULL migration

User's choice: Only new auth endpoints; existing document/topics/settings stay public


Option Description Selected
/api/admin/* prefix All admin under /api/admin/; get_current_admin on every handler
/api/users/* with role check Shared prefix, role-based access control
/admin/* separate mount Separate path, possible separate FastAPI sub-application

User's choice: /api/admin/* prefix with get_current_admin dependency


Option Description Selected
CORS_ORIGINS env var (comma-separated) Pydantic parses as list; default localhost:5173
Hardcode origins per environment Config file per environment or build-time injection
Keep allow_origins=['*'] Not recommended with auth cookies now in play

User's choice: CORS_ORIGINS env var, comma-separated


Frontend Auth UX

Option Description Selected
Full auth wall beforeEach guard redirects to /login if no access token
Partial — auth only gates account/admin Documents/topics still accessible without login

User's choice: Full auth wall — entire app requires login


Option Description Selected
useAuthStore + fetch interceptor In-memory token; auto-refresh on 401; redirect on refresh failure
Token in composable with manual headers More explicit but repetitive across API calls
You decide Defer to downstream agents

User's choice: useAuthStore with in-memory token + fetch interceptor


Option Description Selected
/admin route, separate AdminView Route guard (role=admin); sub-navigation; sidebar link conditionally shown
Integrated into /settings as Admin tab Mixes admin and personal settings
You decide Defer to UI researcher

User's choice: /admin route with dedicated AdminView; sidebar link visible for admin role only


Option Description Selected
Full TOTP enrollment UI in Phase 2 QR code + backup codes + acknowledgment; aligned with success criteria
Backend-only; UI deferred to Phase 3 Misaligns with Phase 2 success criterion #2

User's choice: Full TOTP enrollment UI in Phase 2


Claude's Discretion

None — all areas had a clear user preference.

Deferred Ideas

None — discussion stayed within phase scope.