feat(api): standardize REST contracts and auth
This commit is contained in:
@@ -1,17 +1,13 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from fastapi import (
|
||||
APIRouter,
|
||||
Body,
|
||||
Depends,
|
||||
File,
|
||||
Header,
|
||||
HTTPException,
|
||||
Path as ApiPath,
|
||||
Query,
|
||||
Request,
|
||||
UploadFile,
|
||||
status,
|
||||
@@ -24,7 +20,7 @@ from app.auth.metadata_dependencies import (
|
||||
from app.core.audit import AuditAction, log_audit_event
|
||||
from app.infra.db.metadb.repositories.metadata_repository import MetadataRepository
|
||||
from app.services.network_import import network_update
|
||||
from app.services.tjnetwork import ChangeSet, import_inp, run_inp
|
||||
from app.services.tjnetwork import run_inp
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -145,7 +141,7 @@ async def _apply_model_update(content: bytes) -> None:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/admin/projects/{project_id}/model/import",
|
||||
"/admin/projects/{project_id}/model-imports",
|
||||
summary="导入桌面端水力模型",
|
||||
)
|
||||
async def import_project_model(
|
||||
@@ -168,8 +164,8 @@ async def import_project_model(
|
||||
return {"project_id": str(project.id), "filename": filename, "result": result}
|
||||
|
||||
|
||||
@router.post(
|
||||
"/admin/projects/{project_id}/model/update",
|
||||
@router.patch(
|
||||
"/admin/projects/{project_id}/model-imports",
|
||||
summary="更新桌面端水力模型",
|
||||
)
|
||||
async def update_project_model(
|
||||
@@ -190,108 +186,3 @@ async def update_project_model(
|
||||
action="update",
|
||||
)
|
||||
return {"project_id": str(project.id), "filename": filename, "updated": True}
|
||||
|
||||
|
||||
@router.post("/importinp/", deprecated=True)
|
||||
async def legacy_import_inp(
|
||||
request: Request,
|
||||
network: str = Query(...),
|
||||
x_project_id: UUID = Header(..., alias="X-Project-Id"),
|
||||
current_user=Depends(get_current_metadata_admin),
|
||||
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
|
||||
):
|
||||
project = await _get_active_project(x_project_id, metadata_repo)
|
||||
if network != project.code:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Project scope denied",
|
||||
)
|
||||
payload = await request.json()
|
||||
inp_text = payload.get("inp") if isinstance(payload, dict) else None
|
||||
if not isinstance(inp_text, str):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Missing INP content",
|
||||
)
|
||||
_validate_inp_bytes(inp_text.encode("utf-8"), "model.inp")
|
||||
result = import_inp(network, ChangeSet({"inp": inp_text}))
|
||||
await _audit_model_change(
|
||||
request=request,
|
||||
current_user=current_user,
|
||||
metadata_repo=metadata_repo,
|
||||
project_id=project.id,
|
||||
action="import",
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/uploadinp/", deprecated=True)
|
||||
async def legacy_upload_inp(
|
||||
request: Request,
|
||||
content: bytes = Body(...),
|
||||
name: str = Query(...),
|
||||
x_project_id: UUID = Header(..., alias="X-Project-Id"),
|
||||
current_user=Depends(get_current_metadata_admin),
|
||||
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
|
||||
) -> bool:
|
||||
project = await _get_active_project(x_project_id, metadata_repo)
|
||||
safe_name = Path(name).name
|
||||
if safe_name != name:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid INP file name",
|
||||
)
|
||||
_validate_inp_bytes(content, safe_name)
|
||||
target_dir = Path("data")
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
(target_dir / safe_name).write_bytes(content)
|
||||
await _audit_model_change(
|
||||
request=request,
|
||||
current_user=current_user,
|
||||
metadata_repo=metadata_repo,
|
||||
project_id=project.id,
|
||||
action="upload",
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
@router.post("/network_project/", deprecated=True)
|
||||
async def legacy_network_project(
|
||||
request: Request,
|
||||
file: UploadFile = File(...),
|
||||
x_project_id: UUID = Header(..., alias="X-Project-Id"),
|
||||
current_user=Depends(get_current_metadata_admin),
|
||||
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
|
||||
):
|
||||
project = await _get_active_project(x_project_id, metadata_repo)
|
||||
content, _ = await _read_upload(file)
|
||||
result = await _run_uploaded_inp(content)
|
||||
await _audit_model_change(
|
||||
request=request,
|
||||
current_user=current_user,
|
||||
metadata_repo=metadata_repo,
|
||||
project_id=project.id,
|
||||
action="import",
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@router.post("/network_update/", deprecated=True)
|
||||
async def legacy_network_update(
|
||||
request: Request,
|
||||
file: UploadFile = File(...),
|
||||
x_project_id: UUID = Header(..., alias="X-Project-Id"),
|
||||
current_user=Depends(get_current_metadata_admin),
|
||||
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
|
||||
) -> str:
|
||||
project = await _get_active_project(x_project_id, metadata_repo)
|
||||
content, _ = await _read_upload(file)
|
||||
await _apply_model_update(content)
|
||||
await _audit_model_change(
|
||||
request=request,
|
||||
current_user=current_user,
|
||||
metadata_repo=metadata_repo,
|
||||
project_id=project.id,
|
||||
action="update",
|
||||
)
|
||||
return json.dumps({"message": "管网更新成功"})
|
||||
|
||||
Reference in New Issue
Block a user