126 lines
4.2 KiB
Python
126 lines
4.2 KiB
Python
"""FlowDeck — Collections : data_api.
|
|
|
|
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 json
|
|
import logging
|
|
|
|
from fastapi import APIRouter, Body, HTTPException, Request
|
|
|
|
from app.db import get_conn
|
|
from app.services.automations import fire_event, run_event_sync
|
|
from app.services.property_types import (
|
|
apply_auto_properties,
|
|
)
|
|
|
|
from ._common import (
|
|
_collection_properties,
|
|
_current_user,
|
|
_require_edit,
|
|
_require_view,
|
|
_session_user,
|
|
_validate_meta_keys,
|
|
_validate_page_properties,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter(tags=["collections"], prefix="/db")
|
|
|
|
|
|
|
|
|
|
@router.get("/{collection_id}/api")
|
|
def get_collection_api(request: Request, collection_id: int):
|
|
"""API: get a single collection with its pages."""
|
|
# v6.0.0: granular collection permissions — hide restricted collections.
|
|
_require_view(collection_id, _session_user(request))
|
|
with get_conn() as conn:
|
|
collection = conn.execute(
|
|
"SELECT * FROM collections WHERE id=?", (collection_id,)
|
|
).fetchone()
|
|
if not collection:
|
|
raise HTTPException(status_code=404, detail="Collection not found")
|
|
|
|
pages = conn.execute(
|
|
"SELECT * FROM collection_pages WHERE collection_id=? ORDER BY position",
|
|
(collection_id,),
|
|
).fetchall()
|
|
views = conn.execute(
|
|
"SELECT * FROM collection_views WHERE collection_id=? ORDER BY position",
|
|
(collection_id,),
|
|
).fetchall()
|
|
|
|
return {
|
|
"collection": dict(collection),
|
|
"pages": [dict(p) for p in pages],
|
|
"views": [dict(v) for v in views],
|
|
}
|
|
|
|
|
|
|
|
|
|
@router.post("/{collection_id}/pages/api")
|
|
def create_page_api(request: Request, collection_id: int, body: dict = Body(default={})):
|
|
"""API: create a page in a collection."""
|
|
# v6.0.0: granular collection permissions — viewer/commenter cannot create.
|
|
_require_view(collection_id, _session_user(request))
|
|
_require_edit(collection_id, _session_user(request))
|
|
|
|
title = body.get("title", "").strip()
|
|
if not title:
|
|
raise HTTPException(status_code=400, detail="title is required")
|
|
|
|
icon = body.get("icon", "📄")
|
|
property_values = body.get("properties", {})
|
|
cover_url = body.get("cover_url", "")
|
|
gitea_issue_id = body.get("gitea_issue_id")
|
|
gitea_issue_number = body.get("gitea_issue_number")
|
|
|
|
with get_conn() as conn:
|
|
coll = conn.execute("SELECT id FROM collections WHERE id=?", (collection_id,)).fetchone()
|
|
if not coll:
|
|
raise HTTPException(status_code=404, detail="Collection not found")
|
|
|
|
_validate_page_properties(conn, collection_id, property_values)
|
|
_validate_meta_keys(conn, collection_id, property_values)
|
|
apply_auto_properties(
|
|
_collection_properties(conn, collection_id),
|
|
property_values,
|
|
_current_user(request),
|
|
is_create=True,
|
|
)
|
|
|
|
max_pos = conn.execute(
|
|
"SELECT COALESCE(MAX(position), -1) + 1 FROM collection_pages WHERE collection_id=?",
|
|
(collection_id,),
|
|
).fetchone()[0]
|
|
|
|
cur = conn.execute(
|
|
"""INSERT INTO collection_pages
|
|
(collection_id, title, icon, cover_url, position, gitea_issue_id, gitea_issue_number, property_values_json)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
|
|
(collection_id, title, icon, cover_url, max_pos, gitea_issue_id, gitea_issue_number,
|
|
json.dumps(property_values)),
|
|
)
|
|
conn.commit()
|
|
page_id = cur.lastrowid
|
|
|
|
run_event_sync(fire_event("page.created", {
|
|
"page_id": page_id,
|
|
"collection_id": collection_id,
|
|
"title": title,
|
|
"icon": icon,
|
|
"properties": property_values,
|
|
}))
|
|
run_event_sync(fire_event("collection.page.created", {
|
|
"page_id": page_id,
|
|
"collection_id": collection_id,
|
|
"title": title,
|
|
}))
|
|
from app.services.agent_evenements import emettre, url_collection
|
|
emettre("flowdeck.page.created", f"page:{page_id}", title,
|
|
url=url_collection(collection_id), actor="user")
|
|
return {"id": page_id, "title": title, "status": "created"}
|