add backend read endpoints for single draft records support direct fetch of individual draft entities improve draft inspection and targeted editor workflows
192 lines
6.1 KiB
Python
192 lines
6.1 KiB
Python
from uuid import uuid4
|
|
|
|
from fastapi import HTTPException, status
|
|
from sqlalchemy import asc, select
|
|
|
|
from app.db.session import AsyncSessionLocal
|
|
from app.models.scheme_sector import SchemeSectorRecord
|
|
from app.models.scheme_seat import SchemeSeatRecord
|
|
|
|
|
|
async def replace_scheme_version_sectors(
|
|
*,
|
|
scheme_id: str,
|
|
scheme_version_id: str,
|
|
sectors: list[dict],
|
|
) -> None:
|
|
async with AsyncSessionLocal() as session:
|
|
existing_result = await session.execute(
|
|
select(SchemeSectorRecord).where(SchemeSectorRecord.scheme_version_id == scheme_version_id)
|
|
)
|
|
existing_rows = list(existing_result.scalars().all())
|
|
|
|
for row in existing_rows:
|
|
await session.delete(row)
|
|
|
|
for item in sectors:
|
|
row = SchemeSectorRecord(
|
|
sector_record_id=item["sector_record_id"] if "sector_record_id" in item and item["sector_record_id"] else uuid4().hex,
|
|
scheme_id=scheme_id,
|
|
scheme_version_id=scheme_version_id,
|
|
element_id=item.get("id"),
|
|
sector_id=item.get("sector_id"),
|
|
name=item.get("sector_id"),
|
|
classes_raw=str(item.get("classes")),
|
|
)
|
|
session.add(row)
|
|
|
|
await session.commit()
|
|
|
|
|
|
async def clone_scheme_version_sectors(
|
|
*,
|
|
source_scheme_version_id: str,
|
|
target_scheme_version_id: str,
|
|
) -> None:
|
|
async with AsyncSessionLocal() as session:
|
|
result = await session.execute(
|
|
select(SchemeSectorRecord).where(SchemeSectorRecord.scheme_version_id == source_scheme_version_id)
|
|
)
|
|
rows = list(result.scalars().all())
|
|
|
|
for row in rows:
|
|
cloned = SchemeSectorRecord(
|
|
sector_record_id=uuid4().hex,
|
|
scheme_id=row.scheme_id,
|
|
scheme_version_id=target_scheme_version_id,
|
|
element_id=row.element_id,
|
|
sector_id=row.sector_id,
|
|
name=row.name,
|
|
classes_raw=row.classes_raw,
|
|
)
|
|
session.add(cloned)
|
|
|
|
await session.commit()
|
|
|
|
|
|
async def list_scheme_version_sectors(scheme_version_id: str) -> list[SchemeSectorRecord]:
|
|
async with AsyncSessionLocal() as session:
|
|
result = await session.execute(
|
|
select(SchemeSectorRecord)
|
|
.where(SchemeSectorRecord.scheme_version_id == scheme_version_id)
|
|
.order_by(asc(SchemeSectorRecord.created_at), asc(SchemeSectorRecord.id))
|
|
)
|
|
return list(result.scalars().all())
|
|
|
|
|
|
async def update_scheme_version_sector_by_record_id(
|
|
*,
|
|
scheme_version_id: str,
|
|
sector_record_id: str,
|
|
sector_id: str | None,
|
|
name: str | None,
|
|
) -> tuple[SchemeSectorRecord, str | None]:
|
|
async with AsyncSessionLocal() as session:
|
|
result = await session.execute(
|
|
select(SchemeSectorRecord).where(
|
|
SchemeSectorRecord.scheme_version_id == scheme_version_id,
|
|
SchemeSectorRecord.sector_record_id == sector_record_id,
|
|
)
|
|
)
|
|
row = result.scalar_one_or_none()
|
|
|
|
if row is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Sector record not found in current draft version",
|
|
)
|
|
|
|
old_sector_id = row.sector_id
|
|
row.sector_id = sector_id
|
|
row.name = name
|
|
|
|
await session.commit()
|
|
await session.refresh(row)
|
|
return row, old_sector_id
|
|
|
|
|
|
async def create_scheme_version_sector(
|
|
*,
|
|
scheme_id: str,
|
|
scheme_version_id: str,
|
|
element_id: str | None,
|
|
sector_id: str,
|
|
name: str | None,
|
|
classes_raw: str | None,
|
|
) -> SchemeSectorRecord:
|
|
async with AsyncSessionLocal() as session:
|
|
row = SchemeSectorRecord(
|
|
sector_record_id=uuid4().hex,
|
|
scheme_id=scheme_id,
|
|
scheme_version_id=scheme_version_id,
|
|
element_id=element_id,
|
|
sector_id=sector_id,
|
|
name=name,
|
|
classes_raw=classes_raw,
|
|
)
|
|
session.add(row)
|
|
await session.commit()
|
|
await session.refresh(row)
|
|
return row
|
|
|
|
|
|
async def delete_scheme_version_sector_by_record_id(
|
|
*,
|
|
scheme_version_id: str,
|
|
sector_record_id: str,
|
|
) -> None:
|
|
async with AsyncSessionLocal() as session:
|
|
sector_result = await session.execute(
|
|
select(SchemeSectorRecord).where(
|
|
SchemeSectorRecord.scheme_version_id == scheme_version_id,
|
|
SchemeSectorRecord.sector_record_id == sector_record_id,
|
|
)
|
|
)
|
|
sector = sector_result.scalar_one_or_none()
|
|
|
|
if sector is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Sector record not found in current draft version",
|
|
)
|
|
|
|
if sector.sector_id:
|
|
seats_result = await session.execute(
|
|
select(SchemeSeatRecord).where(
|
|
SchemeSeatRecord.scheme_version_id == scheme_version_id,
|
|
SchemeSeatRecord.sector_id == sector.sector_id,
|
|
)
|
|
)
|
|
seats = list(seats_result.scalars().all())
|
|
if seats:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_409_CONFLICT,
|
|
detail="Cannot delete sector while seats still reference it",
|
|
)
|
|
|
|
await session.delete(sector)
|
|
await session.commit()
|
|
|
|
|
|
async def get_scheme_version_sector_by_record_id(
|
|
*,
|
|
scheme_version_id: str,
|
|
sector_record_id: str,
|
|
) -> SchemeSectorRecord:
|
|
async with AsyncSessionLocal() as session:
|
|
result = await session.execute(
|
|
select(SchemeSectorRecord).where(
|
|
SchemeSectorRecord.scheme_version_id == scheme_version_id,
|
|
SchemeSectorRecord.sector_record_id == sector_record_id,
|
|
)
|
|
)
|
|
row = result.scalar_one_or_none()
|
|
|
|
if row is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Sector record not found in current draft version",
|
|
)
|
|
|
|
return row
|