feat: implement project relational data platform

This commit is contained in:
2026-07-30 11:51:46 +08:00
parent 506621966e
commit ada281862e
12 changed files with 2534 additions and 189 deletions

View File

@@ -21,6 +21,7 @@ from app.api.manual_ingest import router as manual_ingest_router
from app.api.ocr import router as ocr_router
from app.api.travel_assistant import public_router as travel_assistant_public_router
from app.api.travel_assistant import router as travel_assistant_router
from app.api.data_platform import router as data_platform_router
api_router = APIRouter(prefix="/v1/admin")
openapi_router = APIRouter(prefix="/v1/openapi")
@@ -65,6 +66,7 @@ api_router.include_router(evidence_router, tags=["evidence"])
api_router.include_router(manual_ingest_router, tags=["manual-ingest"])
api_router.include_router(travel_assistant_router, tags=["travel-assistant"])
api_router.include_router(ocr_router, tags=["ocr"])
api_router.include_router(data_platform_router, tags=["data-platform"])
# Agent call logs
from app.api.agent_call_logs import router as agent_call_logs_router # noqa: E402

91
app/api/data_platform.py Normal file
View File

@@ -0,0 +1,91 @@
"""Project database catalog and registered-table CRUD APIs."""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, HTTPException, Query
from app.auth import CurrentUser
from app.data_platform.record_service import (
create_record,
delete_record,
list_databases,
list_records,
list_tables,
update_record,
)
from app.data_platform.schema import ensure_all_project_databases
router = APIRouter(prefix="/data-platform")
@router.get("/databases")
async def databases(_user: CurrentUser):
return await list_databases()
@router.post("/databases/initialize")
async def initialize_databases(user: CurrentUser):
if "admin" not in user.get("roles", []):
raise HTTPException(403, "只有系统管理员可以初始化项目数据库")
await ensure_all_project_databases()
return {"ok": True}
@router.get("/databases/{project_id}/tables")
async def tables(project_id: str, _user: CurrentUser):
return await list_tables(project_id)
@router.get("/databases/{project_id}/tables/{table_code}/records")
async def records(
project_id: str,
table_code: str,
_user: CurrentUser,
page: int = Query(default=1, ge=1),
page_size: int = Query(default=50, ge=1, le=200),
search: str | None = None,
sort_field: str | None = None,
sort_order: str = Query(default="desc", pattern="^(asc|desc)$"),
):
return await list_records(
project_id,
table_code,
page=page,
page_size=page_size,
search=search,
sort_field=sort_field,
sort_order=sort_order,
)
@router.post("/databases/{project_id}/tables/{table_code}/records")
async def add_record(
project_id: str,
table_code: str,
body: dict[str, Any],
user: CurrentUser,
):
return await create_record(project_id, table_code, body, user["username"])
@router.patch("/databases/{project_id}/tables/{table_code}/records/{record_id}")
async def edit_record(
project_id: str,
table_code: str,
record_id: str,
body: dict[str, Any],
user: CurrentUser,
):
return await update_record(project_id, table_code, record_id, body, user["username"])
@router.delete("/databases/{project_id}/tables/{table_code}/records/{record_id}")
async def remove_record(
project_id: str,
table_code: str,
record_id: str,
user: CurrentUser,
):
return await delete_record(project_id, table_code, record_id, user["username"])

View File

@@ -184,6 +184,9 @@ async def create_project(body: dict, _user: CurrentUser):
)
row = await cur.fetchone()
await conn.commit()
from app.data_platform.schema import ensure_project_database
await ensure_project_database(project_id, tenant_id, display_name)
return row