feat(backend): add publish readiness contract and pricing diagnostics

add backend readiness contract for publish prechecks

add pricing diagnostics to explain publish-blocking conditions
make publish decisions more explicit and easier to debug for clients
This commit is contained in:
greebo
2026-03-19 20:29:58 +03:00
parent 7b6c12f924
commit 8d4255181b
11 changed files with 251 additions and 301 deletions

View File

@@ -18,6 +18,7 @@ from app.repositories.schemes import (
rollback_scheme_to_version,
unpublish_scheme,
)
from app.schemas.publish_readiness import SchemePublishActionResponse
from app.schemas.scheme_registry import (
SchemeCurrentResponse,
SchemeDetailResponse,
@@ -33,6 +34,7 @@ from app.schemas.scheme_versions import (
SchemeVersionListResponse,
)
from app.security.auth import require_api_key
from app.services.api_errors import raise_conflict
from app.services.publish_service import publish_current_draft_scheme
from app.services.scheme_validation import build_scheme_validation_report
@@ -146,13 +148,14 @@ async def create_next_scheme_version_endpoint(
current_version_number=current_scheme.current_version_number,
)
if expected_current_scheme_version_id and expected_current_scheme_version_id != current_version.scheme_version_id:
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail={
"code": "stale_current_version",
"message": "Current scheme version changed. Reload scheme state before creating a new version.",
if (
expected_current_scheme_version_id
and expected_current_scheme_version_id != current_version.scheme_version_id
):
raise_conflict(
code="stale_current_version",
message="Current scheme version changed. Reload scheme state before creating a new version.",
details={
"expected_scheme_version_id": expected_current_scheme_version_id,
"actual_scheme_version_id": current_version.scheme_version_id,
},
@@ -212,7 +215,10 @@ async def get_publish_validation(scheme_id: str, role: str = Depends(require_api
}
@router.post(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/publish")
@router.post(
f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/publish",
response_model=SchemePublishActionResponse,
)
async def publish_scheme_endpoint(
scheme_id: str,
expected_scheme_version_id: str | None = Query(default=None),