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:
Fusion
2026-05-17 23:17:10 +02:00
parent 56f440db1b
commit 577b052c05
32 changed files with 1153 additions and 16 deletions
+30
View File
@@ -0,0 +1,30 @@
import { apiClient } from "./client";
import type { SessionUser } from "../types";
export type UserProfile = SessionUser;
export type ProfileUpdatePayload = {
name?: string;
email?: string;
};
export const getProfile = async (): Promise<UserProfile> => {
const response = await apiClient.get<UserProfile>("/users/me");
return response.data;
};
export const updateProfile = async (payload: ProfileUpdatePayload): Promise<UserProfile> => {
const response = await apiClient.put<UserProfile>("/users/me", payload);
return response.data;
};
export const uploadAvatar = async (file: File): Promise<UserProfile> => {
const formData = new FormData();
formData.append("file", file);
const response = await apiClient.post<UserProfile>("/users/me/avatar", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
return response.data;
};