"""Knowledge-base upload, preview, and confirmation endpoints.""" from __future__ import annotations from fastapi import APIRouter, Depends, Request from fastapi.responses import JSONResponse from service.knowledge_base.upload import KnowledgeUploadService, UploadValidationError from api.deps import require_knowledge_operator from model.sys_user import SysUser from utils.response import fail, success router = APIRouter() def _service(request: Request) -> KnowledgeUploadService: service = getattr(request.app.state, "knowledge_upload_service", None) if service is None: raise RuntimeError("knowledge upload service is not configured") return service def _optional_int(value): return None if value in (None, "") else int(value) @router.get("/documents") async def list_documents( request: Request, _: SysUser = Depends(require_knowledge_operator), ): return success(await _service(request).list_documents()) @router.get("/documents/{doc_id}") async def get_document( request: Request, doc_id: str, _: SysUser = Depends(require_knowledge_operator), ): try: result = await _service(request).get_document(doc_id) if result is None: response = fail(404, "文档不存在") return JSONResponse(status_code=404, content=response.model_dump()) return success(result) except (UploadValidationError, ValueError) as exc: response = fail(400, str(exc)) return JSONResponse(status_code=400, content=response.model_dump()) @router.post("/documents/preview") async def preview_document_upload( request: Request, _: SysUser = Depends(require_knowledge_operator), ): try: form = await request.form() upload = form.get("file") if upload is None or not hasattr(upload, "read"): raise UploadValidationError("缺少上传文件") result = await _service(request).preview( upload.filename, await upload.read(), strategy=form.get("strategy", ""), chunk_size=_optional_int(form.get("chunk_size")), chunk_overlap=_optional_int(form.get("chunk_overlap")), ) return success(result) except (UploadValidationError, ValueError) as exc: response = fail(400, str(exc)) return JSONResponse(status_code=400, content=response.model_dump()) @router.post("/documents/confirm") async def confirm_document_upload( request: Request, _: SysUser = Depends(require_knowledge_operator), ): try: body = await request.json() result = await _service(request).confirm( upload_id=body.get("upload_id", ""), title=body.get("title", ""), doc_id=body.get("doc_id", ""), collection_name=body.get("collection_name", ""), strategy=body.get("strategy", ""), chunk_size=body.get("chunk_size"), chunk_overlap=body.get("chunk_overlap"), ) return success(result) except (UploadValidationError, ValueError) as exc: response = fail(400, str(exc)) return JSONResponse(status_code=400, content=response.model_dump()) @router.delete("/documents/{doc_id}") async def delete_document( request: Request, doc_id: str, _: SysUser = Depends(require_knowledge_operator), ): try: result = await _service(request).delete_document(doc_id) return success(result) except (UploadValidationError, ValueError) as exc: response = fail(400, str(exc)) return JSONResponse(status_code=400, content=response.model_dump())