add backend endpoint for publish readiness checks enforce publish gate contract before version publication make publish preconditions explicit and consistent for clients
82 lines
3.1 KiB
Python
82 lines
3.1 KiB
Python
from app.core.config import settings
|
|
from app.repositories.audit import create_audit_event
|
|
from app.repositories.scheme_version_pricing import replace_scheme_version_pricing_snapshot
|
|
from app.repositories.scheme_versions import get_current_scheme_version
|
|
from app.repositories.schemes import get_scheme_record_by_scheme_id, publish_scheme
|
|
from app.services.api_errors import raise_publish_not_ready
|
|
from app.services.publish_readiness import build_publish_readiness
|
|
|
|
|
|
async def publish_current_draft_scheme(
|
|
*,
|
|
scheme_id: str,
|
|
expected_scheme_version_id: str | None = None,
|
|
) -> dict:
|
|
scheme = await get_scheme_record_by_scheme_id(scheme_id)
|
|
version = await get_current_scheme_version(
|
|
scheme_id=scheme.scheme_id,
|
|
current_version_number=scheme.current_version_number,
|
|
)
|
|
|
|
if scheme.status != "draft" or version.status != "draft":
|
|
raise_publish_not_ready(
|
|
reason="Current scheme version is not publishable because it is not in draft state",
|
|
details={
|
|
"scheme_status": scheme.status,
|
|
"scheme_version_status": version.status,
|
|
"scheme_version_id": version.scheme_version_id,
|
|
},
|
|
)
|
|
|
|
if expected_scheme_version_id and expected_scheme_version_id != version.scheme_version_id:
|
|
raise_publish_not_ready(
|
|
reason="Draft scheme version is stale. Reload current draft state before publishing.",
|
|
details={
|
|
"expected_scheme_version_id": expected_scheme_version_id,
|
|
"actual_scheme_version_id": version.scheme_version_id,
|
|
},
|
|
)
|
|
|
|
snapshot = await replace_scheme_version_pricing_snapshot(
|
|
scheme_id=scheme.scheme_id,
|
|
scheme_version_id=version.scheme_version_id,
|
|
)
|
|
|
|
readiness = await build_publish_readiness(
|
|
scheme_id=scheme.scheme_id,
|
|
scheme_version_id=version.scheme_version_id,
|
|
require_full_pricing_coverage=settings.publish_require_full_pricing_coverage,
|
|
)
|
|
|
|
if not readiness["readiness"]["is_ready_to_publish"]:
|
|
raise_publish_not_ready(
|
|
reason="Scheme is not ready to publish",
|
|
details=readiness,
|
|
)
|
|
|
|
published_row = await publish_scheme(scheme.scheme_id)
|
|
|
|
await create_audit_event(
|
|
scheme_id=published_row.scheme_id,
|
|
event_type="scheme.published",
|
|
object_type="scheme",
|
|
object_ref=published_row.scheme_id,
|
|
details={
|
|
"current_version_number": published_row.current_version_number,
|
|
"status": published_row.status,
|
|
"pricing_snapshot": snapshot,
|
|
"scheme_version_id": version.scheme_version_id,
|
|
"publish_readiness": readiness,
|
|
},
|
|
)
|
|
|
|
return {
|
|
"scheme_id": published_row.scheme_id,
|
|
"scheme_version_id": version.scheme_version_id,
|
|
"status": published_row.status,
|
|
"current_version_number": published_row.current_version_number,
|
|
"published_at": published_row.published_at.isoformat() if published_row.published_at else None,
|
|
"pricing_snapshot": snapshot,
|
|
"publish_readiness": readiness,
|
|
}
|