CC3 R3 M4+: avatar upload, PUT /api/auth/me, /uploads mount

Backend (auth/auth_v2.py + pgz_sport_api.py):
- POST /api/auth/me/avatar  (multipart, jpeg/png/webp ≤5 MB) -> /uploads/avatars/{userid}_{ts}.ext
- DELETE /api/auth/me/avatar  (uklanja datoteku + briše users.avatar_url)
- PUT /api/auth/me  (UpdateMeReq: ime/prezime/full_name/telefon/phone/preferred_language/oib)
- GET /api/auth/me  proširen s avatar_url, two_factor_enabled, gdpr_consent_at, google_picture
- StaticFiles mount /uploads -> /opt/pgz-sport/uploads
- DB: ALTER TABLE pgz_sport.users ADD COLUMN avatar_url TEXT
- Audit: profile.update, profile.avatar_upload, profile.avatar_delete

Backups: _backups/auth_v2.py.cc3_pre_avatar.*, pgz_sport_api.py.cc3_pre_avatar.*

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Damir Radulić
2026-05-05 00:44:14 +02:00
parent ece556de11
commit cb3faee731
2 changed files with 111 additions and 1 deletions
+26
View File
@@ -1683,8 +1683,34 @@ def serve_platform():
if p.exists(): return FileResponse(p)
return {"error": "platform.html not found"}
@app.get("/app")
@app.get("/app/")
def serve_app():
p = HTML_DIR / "app.html"
return FileResponse(p) if p.exists() else {"error":"app.html not found"}
@app.get("/audit")
@app.get("/audit/")
def serve_audit():
p = HTML_DIR / "audit.html"
return FileResponse(p) if p.exists() else {"error":"audit.html not found"}
@app.get("/kpi")
@app.get("/kpi/")
def serve_kpi():
p = HTML_DIR / "kpi.html"
return FileResponse(p) if p.exists() else {"error":"kpi.html not found"}
app.mount("/static", StaticFiles(directory=str(HTML_DIR)), name="static")
# User-uploaded files (avatars, etc.) — served at /uploads/*
import pathlib as _pl
_UPLOAD_DIR = _pl.Path("/opt/pgz-sport/uploads")
_UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
(_UPLOAD_DIR / "avatars").mkdir(parents=True, exist_ok=True)
app.mount("/uploads", StaticFiles(directory=str(_UPLOAD_DIR)), name="uploads")
@app.get("/")
def root(request: Request):
host = request.headers.get("host", "")