Implement display artifacts, pricing integrity, draft base and publish preview bundle
This commit is contained in:
130
backend/app/services/structure_diff.py
Normal file
130
backend/app/services/structure_diff.py
Normal file
@@ -0,0 +1,130 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from app.repositories.scheme_groups import list_scheme_version_groups
|
||||
from app.repositories.scheme_seats import list_scheme_version_seats
|
||||
from app.repositories.scheme_sectors import list_scheme_version_sectors
|
||||
from app.services.baseline_selector import select_baseline_scheme_version
|
||||
|
||||
|
||||
def _serialize_sector(row) -> dict:
|
||||
return {
|
||||
"sector_record_id": row.sector_record_id,
|
||||
"element_id": row.element_id,
|
||||
"sector_id": row.sector_id,
|
||||
"name": row.name,
|
||||
"classes_raw": row.classes_raw,
|
||||
}
|
||||
|
||||
|
||||
def _serialize_group(row) -> dict:
|
||||
return {
|
||||
"group_record_id": row.group_record_id,
|
||||
"element_id": row.element_id,
|
||||
"group_id": row.group_id,
|
||||
"name": row.name,
|
||||
"classes_raw": row.classes_raw,
|
||||
}
|
||||
|
||||
|
||||
def _serialize_seat(row) -> dict:
|
||||
return {
|
||||
"seat_record_id": row.seat_record_id,
|
||||
"element_id": row.element_id,
|
||||
"seat_id": row.seat_id,
|
||||
"sector_id": row.sector_id,
|
||||
"group_id": row.group_id,
|
||||
"row_label": row.row_label,
|
||||
"seat_number": row.seat_number,
|
||||
}
|
||||
|
||||
|
||||
def _build_diff(before_map: dict, after_map: dict) -> list[dict]:
|
||||
keys = sorted(set(before_map.keys()) | set(after_map.keys()))
|
||||
result: list[dict] = []
|
||||
|
||||
for key in keys:
|
||||
before = before_map.get(key)
|
||||
after = after_map.get(key)
|
||||
|
||||
if before is None and after is not None:
|
||||
status = "added"
|
||||
elif before is not None and after is None:
|
||||
status = "removed"
|
||||
elif before != after:
|
||||
status = "changed"
|
||||
else:
|
||||
status = "unchanged"
|
||||
|
||||
result.append(
|
||||
{
|
||||
"key": key,
|
||||
"status": status,
|
||||
"before": before,
|
||||
"after": after,
|
||||
}
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
async def build_structure_diff(
|
||||
*,
|
||||
scheme_id: str,
|
||||
draft_scheme_version_id: str,
|
||||
baseline_override_scheme_version_id: str | None = None,
|
||||
) -> dict:
|
||||
baseline, baseline_strategy = await select_baseline_scheme_version(
|
||||
scheme_id=scheme_id,
|
||||
draft_scheme_version_id=draft_scheme_version_id,
|
||||
override_scheme_version_id=baseline_override_scheme_version_id,
|
||||
)
|
||||
|
||||
draft_sectors = await list_scheme_version_sectors(draft_scheme_version_id)
|
||||
draft_groups = await list_scheme_version_groups(draft_scheme_version_id)
|
||||
draft_seats = await list_scheme_version_seats(draft_scheme_version_id)
|
||||
|
||||
if baseline is None:
|
||||
baseline_sector_map = {}
|
||||
baseline_group_map = {}
|
||||
baseline_seat_map = {}
|
||||
baseline_scheme_version_id = None
|
||||
else:
|
||||
baseline_scheme_version_id = baseline.scheme_version_id
|
||||
baseline_sector_map = {
|
||||
row.sector_record_id: _serialize_sector(row)
|
||||
for row in await list_scheme_version_sectors(baseline.scheme_version_id)
|
||||
}
|
||||
baseline_group_map = {
|
||||
row.group_record_id: _serialize_group(row)
|
||||
for row in await list_scheme_version_groups(baseline.scheme_version_id)
|
||||
}
|
||||
baseline_seat_map = {
|
||||
row.seat_record_id: _serialize_seat(row)
|
||||
for row in await list_scheme_version_seats(baseline.scheme_version_id)
|
||||
}
|
||||
|
||||
draft_sector_map = {row.sector_record_id: _serialize_sector(row) for row in draft_sectors}
|
||||
draft_group_map = {row.group_record_id: _serialize_group(row) for row in draft_groups}
|
||||
draft_seat_map = {row.seat_record_id: _serialize_seat(row) for row in draft_seats}
|
||||
|
||||
sector_diff = _build_diff(baseline_sector_map, draft_sector_map)
|
||||
group_diff = _build_diff(baseline_group_map, draft_group_map)
|
||||
seat_diff = _build_diff(baseline_seat_map, draft_seat_map)
|
||||
|
||||
return {
|
||||
"baseline_scheme_version_id": baseline_scheme_version_id,
|
||||
"baseline_strategy": baseline_strategy,
|
||||
"summary": {
|
||||
"sectors_added": sum(1 for item in sector_diff if item["status"] == "added"),
|
||||
"sectors_removed": sum(1 for item in sector_diff if item["status"] == "removed"),
|
||||
"sectors_changed": sum(1 for item in sector_diff if item["status"] == "changed"),
|
||||
"groups_added": sum(1 for item in group_diff if item["status"] == "added"),
|
||||
"groups_removed": sum(1 for item in group_diff if item["status"] == "removed"),
|
||||
"groups_changed": sum(1 for item in group_diff if item["status"] == "changed"),
|
||||
"seats_added": sum(1 for item in seat_diff if item["status"] == "added"),
|
||||
"seats_removed": sum(1 for item in seat_diff if item["status"] == "removed"),
|
||||
"seats_changed": sum(1 for item in seat_diff if item["status"] == "changed"),
|
||||
},
|
||||
"sectors": sector_diff,
|
||||
"groups": group_diff,
|
||||
"seats": seat_diff,
|
||||
}
|
||||
Reference in New Issue
Block a user