Harden RC7 API response contracts
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-18 05:07:35 +02:00
parent 8e49b857dd
commit 0fae53a7de
36 changed files with 886 additions and 153 deletions
+21 -8
View File
@@ -7,14 +7,24 @@ from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from app.db.session import get_db
from app.schemas.export import GeoJsonExportRequest, MapResultExportRequest, MetadataExportRequest, ReportExportRequest
from app.schemas import Envelope
from app.schemas.export import (
ExportContentResponse,
ExportCreateResponse,
ExportListResponse,
ExportRead,
GeoJsonExportRequest,
MapResultExportRequest,
MetadataExportRequest,
ReportExportRequest,
)
from app.services.export_service import ExportService
from app.utils.response import envelope
router = APIRouter(prefix="/exports", tags=["exports"])
@router.post("/geojson", response_model=dict)
@router.post("/geojson", response_model=Envelope[ExportCreateResponse])
def export_geojson(payload: GeoJsonExportRequest, db: Session = Depends(get_db)):
if payload.export_kind == "vector_selection" and payload.dataset_id is not None and payload.bbox is not None:
return envelope(
@@ -40,22 +50,25 @@ def export_geojson(payload: GeoJsonExportRequest, db: Session = Depends(get_db))
return envelope({})
@router.post("/metadata", response_model=dict)
@router.post("/metadata", response_model=Envelope[ExportCreateResponse])
def export_project_metadata(payload: MetadataExportRequest, db: Session = Depends(get_db)):
return envelope(ExportService.export_project_metadata(db, payload.project_id, payload.name).model_dump(mode="json"))
@router.post("/report", response_model=dict)
@router.post("/report", response_model=Envelope[ExportCreateResponse])
def export_project_report(payload: ReportExportRequest, db: Session = Depends(get_db)):
return envelope(ExportService.export_project_report(db, payload.project_id, payload.name).model_dump(mode="json"))
@router.post("/map-result", response_model=dict)
@router.post("/map-result", response_model=Envelope[ExportCreateResponse])
def export_map_result(payload: MapResultExportRequest, db: Session = Depends(get_db)):
return envelope(ExportService.export_map_result(db, payload).model_dump(mode="json"))
@router.get("/projects/{project_id}/exports", response_model=dict)
@router.get(
"/projects/{project_id}/exports",
response_model=Envelope[ExportListResponse],
)
def list_project_exports(
project_id: UUID,
limit: int = Query(default=50, ge=1, le=100),
@@ -65,7 +78,7 @@ def list_project_exports(
return envelope(ExportService.list_project_exports(db, project_id, limit=limit, offset=offset).model_dump(mode="json"))
@router.get("/{export_id}", response_model=dict)
@router.get("/{export_id}", response_model=Envelope[ExportRead])
def get_export(export_id: UUID, db: Session = Depends(get_db)):
return envelope(ExportService.get_export(db, export_id).model_dump(mode="json"))
@@ -77,6 +90,6 @@ def download_export(export_id: UUID, db: Session = Depends(get_db)):
return FileResponse(path, filename=path.name, media_type=media_type)
@router.get("/{export_id}/content", response_model=dict)
@router.get("/{export_id}/content", response_model=Envelope[ExportContentResponse])
def get_export_content(export_id: UUID, db: Session = Depends(get_db)):
return envelope(ExportService.get_export_content(db, export_id).model_dump(mode="json"))