154 lines
5.6 KiB
Markdown
154 lines
5.6 KiB
Markdown
# 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.
|