from typing import Literal, Optional from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.dependencies import get_db from app.schemas.document import ( CreateDocumentRequest, DocumentListItem, DocumentResponse, Pagination, UpdateDocumentRequest, ) from app.services.document_service import DocumentService router = APIRouter(prefix="/documents", tags=["Documents"]) def _ok(data: dict) -> dict: return {"code": 0, "message": "Success", "data": data} # ------------------------------------------------------------------ # # POST /documents 创建文档 # ------------------------------------------------------------------ # @router.post("", summary="创建文档") async def create_document( body: CreateDocumentRequest, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) doc = await svc.create_document(body) return _ok( { "documentId": doc.id, "title": doc.title, "format": doc.format, "createdAt": int(doc.created_at.timestamp() * 1000), } ) # ------------------------------------------------------------------ # # GET /documents 获取文档列表 # ------------------------------------------------------------------ # @router.get("", summary="获取文档列表") async def list_documents( page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100, alias="pageSize"), session_id: Optional[str] = Query(None, alias="sessionId"), source: Optional[Literal["chat", "workflow"]] = None, sort_by: Literal["created_at", "updated_at"] = Query("updated_at", alias="sortBy"), sort_order: Literal["asc", "desc"] = Query("desc", alias="sortOrder"), db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) docs, total = await svc.list_documents( page=page, page_size=page_size, session_id=session_id, source=source, sort_by=sort_by, sort_order=sort_order, ) import math items = [ DocumentListItem.model_validate(d).model_dump(by_alias=True) for d in docs ] pagination = Pagination( page=page, page_size=page_size, total=total, total_pages=math.ceil(total / page_size) if page_size else 1, ).model_dump(by_alias=True) return _ok({"documents": items, "pagination": pagination}) # ------------------------------------------------------------------ # # GET /documents/{documentId} 获取文档详情 # ------------------------------------------------------------------ # @router.get("/{document_id}", summary="获取文档详情") async def get_document( document_id: str, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) doc = await svc.get_document(document_id) return _ok(DocumentResponse.model_validate(doc).model_dump(by_alias=True)) # ------------------------------------------------------------------ # # PUT /documents/{documentId} 更新文档 # ------------------------------------------------------------------ # @router.put("/{document_id}", summary="更新文档") async def update_document( document_id: str, body: UpdateDocumentRequest, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) doc = await svc.update_document(document_id, body) return _ok( { "documentId": doc.id, "updatedAt": int(doc.updated_at.timestamp() * 1000), } ) # ------------------------------------------------------------------ # # DELETE /documents/{documentId} 删除文档 # ------------------------------------------------------------------ # @router.delete("/{document_id}", summary="删除文档") async def delete_document( document_id: str, db: AsyncSession = Depends(get_db), ) -> dict: svc = DocumentService(db) await svc.delete_document(document_id) return {"code": 0, "message": "Document deleted successfully"}