feat: add governed cross-module reporting
This commit is contained in:
@@ -44,12 +44,23 @@ from govoplan_reporting.backend.operations import (
|
||||
upsert_saved_view,
|
||||
upsert_schedule,
|
||||
)
|
||||
from govoplan_reporting.backend.provider_reports import (
|
||||
ProviderReportError,
|
||||
execute_provider_report,
|
||||
export_provider_execution,
|
||||
get_provider_execution,
|
||||
list_provider_exports,
|
||||
list_provider_reports,
|
||||
provider_parameter_options,
|
||||
)
|
||||
from govoplan_reporting.backend.query_engine import ReportingQueryError
|
||||
from govoplan_reporting.backend.schemas import (
|
||||
DefinitionUpdateRequest,
|
||||
DefinitionWriteRequest,
|
||||
ImportAssessmentRequest,
|
||||
PublicationRequest,
|
||||
ProviderReportExecutionRequest,
|
||||
ProviderReportExportRequest,
|
||||
QualityRunRequest,
|
||||
ReportExecutionRequest,
|
||||
SavedViewWriteRequest,
|
||||
@@ -60,6 +71,138 @@ from govoplan_reporting.backend.schemas import (
|
||||
def create_router(registry: object | None) -> APIRouter:
|
||||
router = APIRouter(prefix="/reporting", tags=["reporting"])
|
||||
|
||||
@router.get("/provider-reports")
|
||||
def api_list_provider_reports(
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> dict[str, object]:
|
||||
_require(principal, READ_SCOPE)
|
||||
try:
|
||||
return list_provider_reports(session, principal, registry=registry)
|
||||
except (ProviderReportError, TypeError, ValueError) as exc:
|
||||
raise _error(exc) from exc
|
||||
|
||||
@router.get(
|
||||
"/provider-reports/{provider_id}/{report_id}/parameters/{parameter_key}/options"
|
||||
)
|
||||
def api_provider_parameter_options(
|
||||
provider_id: str,
|
||||
report_id: str,
|
||||
parameter_key: str,
|
||||
query: str = "",
|
||||
limit: int = Query(default=100, ge=1, le=200),
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> dict[str, object]:
|
||||
_require(principal, READ_SCOPE)
|
||||
try:
|
||||
options = provider_parameter_options(
|
||||
session,
|
||||
principal,
|
||||
registry=registry,
|
||||
provider_id=provider_id,
|
||||
report_id=report_id,
|
||||
parameter_key=parameter_key,
|
||||
query=query,
|
||||
limit=limit,
|
||||
)
|
||||
except (ProviderReportError, PermissionError, LookupError) as exc:
|
||||
raise _error(exc) from exc
|
||||
return {"options": [item.to_dict() for item in options]}
|
||||
|
||||
@router.post("/provider-reports/{provider_id}/{report_id}/executions")
|
||||
def api_execute_provider_report(
|
||||
provider_id: str,
|
||||
report_id: str,
|
||||
payload: ProviderReportExecutionRequest,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> dict[str, object]:
|
||||
_require(principal, RUN_SCOPE)
|
||||
try:
|
||||
result = execute_provider_report(
|
||||
session,
|
||||
principal,
|
||||
registry=registry,
|
||||
provider_id=provider_id,
|
||||
report_id=report_id,
|
||||
**payload.model_dump(),
|
||||
)
|
||||
session.commit()
|
||||
except (ProviderReportError, PermissionError, LookupError, ValueError) as exc:
|
||||
session.rollback()
|
||||
raise _error(exc) from exc
|
||||
return result
|
||||
|
||||
@router.get("/provider-executions/{execution_id}")
|
||||
def api_get_provider_execution(
|
||||
execution_id: str,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> dict[str, object]:
|
||||
_require(principal, RUN_SCOPE)
|
||||
try:
|
||||
result = get_provider_execution(
|
||||
session,
|
||||
principal,
|
||||
registry=registry,
|
||||
execution_id=execution_id,
|
||||
)
|
||||
except (ProviderReportError, PermissionError, LookupError) as exc:
|
||||
raise _error(exc) from exc
|
||||
if result is None:
|
||||
raise HTTPException(
|
||||
status_code=404, detail="Provider report execution not found"
|
||||
)
|
||||
return result
|
||||
|
||||
@router.get("/provider-executions/{execution_id}/exports")
|
||||
def api_list_provider_exports(
|
||||
execution_id: str,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> dict[str, object]:
|
||||
_require(principal, RUN_SCOPE)
|
||||
try:
|
||||
return {
|
||||
"exports": list(
|
||||
list_provider_exports(
|
||||
session,
|
||||
principal,
|
||||
registry=registry,
|
||||
execution_id=execution_id,
|
||||
)
|
||||
)
|
||||
}
|
||||
except (ProviderReportError, PermissionError, LookupError) as exc:
|
||||
raise _error(exc) from exc
|
||||
|
||||
@router.post("/provider-executions/{execution_id}/exports")
|
||||
def api_export_provider_execution(
|
||||
execution_id: str,
|
||||
payload: ProviderReportExportRequest,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> Response:
|
||||
_require(principal, RUN_SCOPE)
|
||||
try:
|
||||
content, media_type, filename = export_provider_execution(
|
||||
session,
|
||||
principal,
|
||||
registry=registry,
|
||||
execution_id=execution_id,
|
||||
**payload.model_dump(),
|
||||
)
|
||||
session.commit()
|
||||
except (ProviderReportError, PermissionError, LookupError) as exc:
|
||||
session.rollback()
|
||||
raise _error(exc) from exc
|
||||
return Response(
|
||||
content=content,
|
||||
media_type=media_type,
|
||||
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
|
||||
)
|
||||
|
||||
@router.get("/definitions")
|
||||
def api_list_definitions(
|
||||
definition_kind: list[str] | None = Query(default=None),
|
||||
|
||||
Reference in New Issue
Block a user