feat: account management panel — /accounts + /api/users/me
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped

- Page /accounts: profil utilisateur éditable, comptes connectés, workspace members
- API GET/PUT /api/users/me: lecture/écriture profil local (full_name, email)
- Users list from local DB, auth via Gitea OAuth2
- Imports SessionManager clean dans api.py
This commit is contained in:
2026-07-08 16:09:20 -04:00
parent 4c49d43c66
commit aa3d5d87c8
3 changed files with 180 additions and 0 deletions
+35
View File
@@ -13,6 +13,7 @@ from app.config import settings
from app.db import get_conn
from app.routers.board import _issue_column, _map_issue_to_card, STATUS_COLORS, STATUS_LABELS
from app.services.gitea_client import gitea
from app.auth.session import SessionManager
logger = logging.getLogger(__name__)
router = APIRouter(tags=["api"], prefix="/api")
@@ -538,6 +539,40 @@ async def delete_checklist(checklist_id: int):
return {"status": "ok"}
# ── v1.0.0: User management ──
@router.get("/users/me")
async def get_my_profile(request: Request):
"""Get current user profile."""
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
if not user:
return {"login": "guest", "full_name": "Guest", "email": ""}
with get_conn() as conn:
row = conn.execute(
"SELECT * FROM users WHERE login=?", (user.get("login", ""),)
).fetchone()
if row:
return dict(row)
return {"login": user.get("login", ""), "full_name": "", "email": ""}
@router.put("/users/me")
async def update_my_profile(request: Request, full_name: str = Query(default=""),
email: str = Query(default="")):
"""Update current user's local profile."""
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
if not user:
raise HTTPException(401, "Not authenticated")
login = user.get("login", "")
with get_conn() as conn:
conn.execute(
"UPDATE users SET full_name=?, email=? WHERE login=?",
(full_name, email, login),
)
conn.commit()
return {"status": "ok"}
# ── v0.5.0: Card priority & due date ──
@router.post("/card/{owner}/{repo}/{issue_id}")
+14
View File
@@ -82,6 +82,20 @@ async def view_page_root(request: Request, page_id: int):
return template.render(**ctx)
@router.get("/accounts", response_class=HTMLResponse)
async def accounts_page(request: Request):
"""Account management panel."""
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader("app/templates"))
sidebar = _sidebar_data(request, [])
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
with get_conn() as conn:
users = conn.execute("SELECT * FROM users ORDER BY created_at DESC").fetchall()
ctx = {**sidebar, "user": user, "users": [dict(u) for u in users]}
template = env.get_template("accounts.html")
return template.render(**ctx)
@router.get("/", response_class=HTMLResponse)
async def dashboard(
request: Request,