feat: add optimistic concurrency guards for draft editor, pricing and publish flows

add optimistic concurrency guards via expected scheme version id

protect draft editor, pricing snapshot, remap and publish flows from stale mutations
protect version creation from stale current version state

keep backward compatibility with optional query guards

verify 409 conflict behavior for stale clients and 200 for valid flows
This commit is contained in:
greebo
2026-03-19 18:58:03 +03:00
parent 76710372c4
commit c7c9184a71
8 changed files with 410 additions and 70 deletions

View File

@@ -2,27 +2,21 @@ from fastapi import HTTPException, status
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.draft_guard import get_current_draft_context
from app.repositories.schemes import publish_scheme
from app.services.scheme_validation import build_scheme_validation_report
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,
scheme, version = await get_current_draft_context(
scheme_id=scheme_id,
expected_scheme_version_id=expected_scheme_version_id,
)
if scheme.status != "draft" or version.status != "draft":
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Current scheme version is not publishable because it is not in draft state",
)
validation = await build_scheme_validation_report(
scheme_id=scheme.scheme_id,
scheme_version_id=version.scheme_version_id,