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, }