Implement display artifacts, pricing integrity, draft base and publish preview bundle

This commit is contained in:
greebo
2026-03-19 17:58:17 +03:00
parent 85fb2f4bb9
commit c91c5abf15
35 changed files with 3283 additions and 302 deletions

View 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,
}