Découpe par concern de l'ancien app/routers/collections.py (2 622 lignes, 53 endpoints / 52 fonctions) en package `app/routers/collections/` : - 10 modules de routes : crud 337 L (6 r.), properties 322 (8), linked 286 (7), structure 267 (8), dashboard_views 214 (3), meta 197 (5), views 187 (6), pages 184 (4), data_api 122 (2), boards 61 (3) - _common.py (220 L) : 8 helpers auth/permissions/validation - _renderers.py (667 L) : 15 rendus HTML des vues + CHART_MAX_GROUPS - __init__.py : ré-exports connus (_validate_page_properties pour automations ; _chart_values/_chart_aggregate/_fmt_number/_render_chart pour les tests) + __all__ Preuve contractuelle : docs/openapi-v2.json régénéré = IDENTIQUE byte-à-byte (509 chemins, ordre préservé). Pièges rattrapés : - docstring d'origine conservée dans le header copié → F404 (from __future__ après un statement) → slice [1:30] - décorateurs empilés (view_collection ×2) : segment sans def → skip du 2e décorateur (53 endpoints = 52 unités) - CHART_MAX_GROUPS hors détection des helpers (F821) → import ._renderers - test_csp_no_cdn_and_vendor lisait collections.py → balayage du package Reste A28 : board.py 2 101 L (lot 4). suite **1091/1091** · ruff OK · OpenAPI 509 identique · docs à jour
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""FlowDeck — Collections : boards.
|
|
|
|
Découpe A28 de l'ancien app/routers/collections.py (2 622 lignes, 53 routes) — un module par concern, contrat inchangé.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, HTTPException, Request
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter(tags=["collections"], prefix="/db")
|
|
|
|
|
|
|
|
|
|
# ── Gitea Board Compatibility (BEFORE {collection_id} wildcards) ──
|
|
|
|
|
|
@router.get("/boards/api")
|
|
def list_boards_as_collections(request: Request):
|
|
"""API: list all Gitea boards as pseudo-collections."""
|
|
from app.services.collection_adapter import GiteaBoardCompat
|
|
boards = GiteaBoardCompat.list_boards_as_collections()
|
|
return {"boards": boards}
|
|
|
|
|
|
|
|
|
|
@router.get("/board/{owner}/{repo}/api")
|
|
async def get_board_as_collection(request: Request, owner: str, repo: str):
|
|
"""API: get a specific Gitea board as a pseudo-collection."""
|
|
from app.services.collection_adapter import GiteaBoardCompat
|
|
coll = GiteaBoardCompat.get_board_as_collection(owner, repo)
|
|
if not coll:
|
|
raise HTTPException(status_code=404, detail="Board not found")
|
|
|
|
from app.services.gitea_client import gitea
|
|
issues = await gitea.get_issues(owner, repo, state="all")
|
|
cards = GiteaBoardCompat.get_board_cards(owner, repo, issues)
|
|
|
|
return {"collection": coll, "pages": cards}
|
|
|
|
|
|
|
|
|
|
@router.post("/board/{owner}/{repo}/sync")
|
|
async def sync_board_to_collection(request: Request, owner: str, repo: str):
|
|
"""Sync a Gitea board to a real collection."""
|
|
from app.services.collection_adapter import GiteaBoardCompat
|
|
from app.services.gitea_client import gitea
|
|
|
|
issues = await gitea.get_issues(owner, repo, state="all")
|
|
coll_id = GiteaBoardCompat.sync_to_collection(owner, repo, issues)
|
|
if coll_id is None:
|
|
raise HTTPException(status_code=404, detail="Board not found")
|
|
|
|
return {"collection_id": coll_id, "status": "synced"}
|
|
|
|
|
|
# ── Collection Properties (v1.4.0) ──
|