feat: implement user profile management and oauth/traefik integration
User Profile (US-004): - Add authenticated profile endpoints (GET/PUT /users/me) - Add avatar upload with file validation (PNG/JPEG, max 2MB) - Create frontend profile page with edit form and avatar upload - Update app shell to link to profile page OAuth/Traefik Integration: - Externalize all Authentik URLs to environment variables - Add domain configuration (API_DOMAIN, WEB_DOMAIN, AUTHENTIK_DOMAIN) - Create docker-compose.traefik.yml for reverse proxy deployment - Update OAuth redirect/callback URLs to use configured domains - Add VITE_APP_URL for frontend public URL configuration Quality gates: pytest (50 passed), ruff, mypy, npm test (12 passed), typecheck, lint, build
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
## Context
|
||||
|
||||
The user-profile spec requires authenticated users to view and update their profile (name, email, avatar). The User model already has `email`, `name`, and `avatar_url` fields. The auth system provides cookie-based JWT authentication. This change connects those pieces into a working profile management flow.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Provide `GET /users/me` to retrieve the current user's profile.
|
||||
- Provide `PUT /users/me` to update name and email with validation.
|
||||
- Provide `POST /users/me/avatar` to upload an avatar image (PNG/JPG, max 2MB).
|
||||
- Store uploaded avatars locally under `apps/api/uploads/avatars/`.
|
||||
- Add a frontend `/profile` page with edit form and avatar upload UI.
|
||||
- Update the app shell to link to the profile page.
|
||||
|
||||
**Non-Goals:**
|
||||
- Social features or public profile pages.
|
||||
- External avatar providers (Gravatar, etc.).
|
||||
- Image resizing or cropping.
|
||||
|
||||
## Decisions
|
||||
|
||||
1. **Add a dedicated `/users` router instead of extending `/auth/me`**
|
||||
- Rationale: cleaner separation of concerns; auth routes handle login/logout, user routes handle profile data.
|
||||
- Alternative: extend `/auth/me` to support PUT. Rejected to keep auth router focused.
|
||||
|
||||
2. **Use `UploadFile` from FastAPI for avatar uploads**
|
||||
- Rationale: standard FastAPI pattern, handles multipart parsing and streaming.
|
||||
- Alternative: raw bytes in JSON body. Rejected as it complicates client and server.
|
||||
|
||||
3. **Store avatars as files locally, not in the database**
|
||||
- Rationale: keeps the database lightweight; files are served statically.
|
||||
- Alternative: bytea/blob column. Rejected for performance and simplicity.
|
||||
|
||||
4. **Use a simple form-based profile page in the frontend**
|
||||
- Rationale: consistent with existing project pages and forms.
|
||||
- Alternative: modal or inline editing. Rejected to keep implementation straightforward.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **[File storage path]** -> use an environment-configurable upload directory; default to `apps/api/uploads/avatars`.
|
||||
- **[Filename collisions]** -> use UUID-based filenames to avoid collisions.
|
||||
- **[Unauthorized access to avatars]** -> for now, serve via static mount; later can add auth if needed.
|
||||
- **[Frontend state sync]** -> after profile update, refresh auth context so the app shell shows updated name.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Create backend users router with GET/PUT/avatar endpoints.
|
||||
2. Register router in main.py.
|
||||
3. Create frontend profile page, API methods, and routing.
|
||||
4. Update app shell with profile link.
|
||||
5. Run quality gates (pytest, mypy, ruff, typecheck, lint).
|
||||
|
||||
Rollback:
|
||||
- Remove users router and frontend page; no database changes needed.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should old avatars be deleted on new upload? (Yes, to avoid disk bloat.)
|
||||
Reference in New Issue
Block a user