"""FlowDeck — v5.2.0 Projects API: list, register, manual sync + backups admin.""" from __future__ import annotations import logging from fastapi import APIRouter, Body, HTTPException, Request from app.auth.session import SessionManager from app.services import projects as projects_svc from app.services.backup import backup_db, list_backups logger = logging.getLogger(__name__) router = APIRouter(tags=["projects"], prefix="/api/projects") backups_router = APIRouter(tags=["backups"]) def _require_admin(request: Request) -> dict: user = SessionManager.decode_session(request.cookies.get("flowdeck_session", "")) if not user or not user.get("is_admin"): raise HTTPException(status_code=403, detail="Admin only") return user @router.get("") def list_projects(request: Request): """List all synced projects (optionally filtered by type).""" proj_type = request.query_params.get("type") or None return {"projects": projects_svc.list_projects(proj_type)} @router.post("") def create_project(request: Request, body: dict = Body(default={})): """Register a standalone (builtin) project.""" name = (body.get("name") or "").strip() if not name: raise HTTPException(status_code=400, detail="name required") project = projects_svc.create_builtin_project(name, body.get("owner", ""), body.get("description", "")) return {"status": "ok", "project": project} @router.post("/sync") async def sync_projects(request: Request): """Trigger an immediate forge sync for every connected account.""" _require_admin(request) stats = await projects_svc.sync_all_projects() return {"status": "ok", "stats": stats} # ═══════════ Backups (admin) ═══════════ @backups_router.post("/api/settings/backups/run") def run_backup_now(request: Request): """Admin: create a database backup immediately.""" _require_admin(request) filename = backup_db() if not filename: raise HTTPException(status_code=400, detail="Backups disabled or no database file") return {"status": "ok", "filename": filename} @backups_router.get("/api/settings/backups") def admin_list_backups(request: Request): """Admin: list stored backups.""" _require_admin(request) return {"backups": list_backups()}