feat(backend): prevent duplicate draft sector and group bindings
reject duplicate sector and group bindings within draft mutations harden draft structure consistency at the backend layer prevent conflicting bindings before they reach publish flow
This commit is contained in:
@@ -49,6 +49,8 @@ from app.services.draft_guard import get_current_draft_context
|
||||
from app.services.editor_validation import (
|
||||
validate_bulk_seat_patch_references,
|
||||
validate_bulk_seat_patch_uniqueness,
|
||||
validate_create_group_uniqueness,
|
||||
validate_create_sector_uniqueness,
|
||||
validate_group_patch_uniqueness,
|
||||
validate_sector_patch_uniqueness,
|
||||
validate_single_seat_patch_references,
|
||||
@@ -162,6 +164,12 @@ async def create_draft_sector(
|
||||
expected_scheme_version_id=expected_scheme_version_id,
|
||||
)
|
||||
|
||||
await validate_create_sector_uniqueness(
|
||||
scheme_version_id=version.scheme_version_id,
|
||||
sector_id=payload.sector_id,
|
||||
element_id=payload.element_id,
|
||||
)
|
||||
|
||||
row = await create_scheme_version_sector(
|
||||
scheme_id=scheme.scheme_id,
|
||||
scheme_version_id=version.scheme_version_id,
|
||||
@@ -205,6 +213,12 @@ async def create_draft_group(
|
||||
expected_scheme_version_id=expected_scheme_version_id,
|
||||
)
|
||||
|
||||
await validate_create_group_uniqueness(
|
||||
scheme_version_id=version.scheme_version_id,
|
||||
group_id=payload.group_id,
|
||||
element_id=payload.element_id,
|
||||
)
|
||||
|
||||
row = await create_scheme_version_group(
|
||||
scheme_id=scheme.scheme_id,
|
||||
scheme_version_id=version.scheme_version_id,
|
||||
|
||||
@@ -147,6 +147,78 @@ async def validate_group_patch_uniqueness(
|
||||
)
|
||||
|
||||
|
||||
async def validate_create_sector_uniqueness(
|
||||
*,
|
||||
scheme_version_id: str,
|
||||
sector_id: str,
|
||||
element_id: str | None,
|
||||
) -> None:
|
||||
rows = await list_scheme_version_sectors(scheme_version_id)
|
||||
|
||||
for row in rows:
|
||||
if row.sector_id == sector_id:
|
||||
_raise_uniqueness_error(
|
||||
f"Sector id already exists in current draft version: {sector_id}",
|
||||
{
|
||||
"code": "duplicate_sector_id",
|
||||
"message": "Sector id already exists in current draft version",
|
||||
"sector_id": sector_id,
|
||||
"conflict_sector_record_id": row.sector_record_id,
|
||||
},
|
||||
)
|
||||
|
||||
if element_id is None:
|
||||
return
|
||||
|
||||
for row in rows:
|
||||
if row.element_id == element_id:
|
||||
_raise_uniqueness_error(
|
||||
f"Sector element binding already exists in current draft version: {element_id}",
|
||||
{
|
||||
"code": "duplicate_sector_element_id",
|
||||
"message": "Sector element binding already exists in current draft version",
|
||||
"element_id": element_id,
|
||||
"conflict_sector_record_id": row.sector_record_id,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def validate_create_group_uniqueness(
|
||||
*,
|
||||
scheme_version_id: str,
|
||||
group_id: str,
|
||||
element_id: str | None,
|
||||
) -> None:
|
||||
rows = await list_scheme_version_groups(scheme_version_id)
|
||||
|
||||
for row in rows:
|
||||
if row.group_id == group_id:
|
||||
_raise_uniqueness_error(
|
||||
f"Group id already exists in current draft version: {group_id}",
|
||||
{
|
||||
"code": "duplicate_group_id",
|
||||
"message": "Group id already exists in current draft version",
|
||||
"group_id": group_id,
|
||||
"conflict_group_record_id": row.group_record_id,
|
||||
},
|
||||
)
|
||||
|
||||
if element_id is None:
|
||||
return
|
||||
|
||||
for row in rows:
|
||||
if row.element_id == element_id:
|
||||
_raise_uniqueness_error(
|
||||
f"Group element binding already exists in current draft version: {element_id}",
|
||||
{
|
||||
"code": "duplicate_group_element_id",
|
||||
"message": "Group element binding already exists in current draft version",
|
||||
"element_id": element_id,
|
||||
"conflict_group_record_id": row.group_record_id,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def validate_single_seat_patch_references(
|
||||
*,
|
||||
scheme_version_id: str,
|
||||
|
||||
Reference in New Issue
Block a user