feat(backend): harden pricing mutation contract and sync backend docs
- add typed response schemas for pricing write endpoints - add stale draft version guard for pricing mutations - unify pricing API contract around expected_scheme_version_id - update API route map - add smoke regression checklist for backend routes and artifact flows
This commit is contained in:
@@ -4,24 +4,17 @@ from app.repositories.scheme_versions import get_current_scheme_version
|
||||
from app.repositories.schemes import get_scheme_record_by_scheme_id
|
||||
|
||||
|
||||
def ensure_expected_scheme_version_id(
|
||||
def build_stale_draft_version_detail(
|
||||
*,
|
||||
expected_scheme_version_id: str,
|
||||
actual_scheme_version_id: str,
|
||||
expected_scheme_version_id: str | None,
|
||||
) -> None:
|
||||
if expected_scheme_version_id is None:
|
||||
return
|
||||
|
||||
if expected_scheme_version_id != actual_scheme_version_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail={
|
||||
"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,
|
||||
},
|
||||
)
|
||||
) -> 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(
|
||||
@@ -40,9 +33,27 @@ async def get_current_draft_context(
|
||||
detail="Current scheme version is not editable because it is not in draft state",
|
||||
)
|
||||
|
||||
ensure_expected_scheme_version_id(
|
||||
actual_scheme_version_id=version.scheme_version_id,
|
||||
expected_scheme_version_id=expected_scheme_version_id,
|
||||
)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user