from fastapi import HTTPException, status from app.repositories.scheme_versions import get_current_scheme_version from app.repositories.schemes import get_scheme_record_by_scheme_id def build_stale_draft_version_detail( *, expected_scheme_version_id: str, actual_scheme_version_id: str, ) -> dict: return { "code": "stale_draft_version", "message": "Draft scheme version is stale. Reload current draft state before applying mutation.", "expected_scheme_version_id": expected_scheme_version_id, "actual_scheme_version_id": actual_scheme_version_id, } async def get_current_draft_context( scheme_id: str, expected_scheme_version_id: str | None = None, ): 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 version.status != "draft" or scheme.status != "draft": raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Current scheme version is not editable because it is not in draft state", ) if expected_scheme_version_id and expected_scheme_version_id != version.scheme_version_id: raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail=build_stale_draft_version_detail( expected_scheme_version_id=expected_scheme_version_id, actual_scheme_version_id=version.scheme_version_id, ), ) return scheme, version async def validate_expected_draft_version_if_provided( scheme_id: str, expected_scheme_version_id: str | None, ): if not expected_scheme_version_id: return None scheme, version = await get_current_draft_context( scheme_id=scheme_id, expected_scheme_version_id=expected_scheme_version_id, ) return scheme, version