Files
svg-backend/backend/app/api/routes/schemes.py
2026-03-19 13:39:32 +03:00

242 lines
9.3 KiB
Python

from fastapi import APIRouter, Depends, Query
from app.core.config import settings
from app.repositories.audit import create_audit_event
from app.repositories.scheme_groups import clone_scheme_version_groups
from app.repositories.scheme_seats import clone_scheme_version_seats
from app.repositories.scheme_sectors import clone_scheme_version_sectors
from app.repositories.scheme_versions import (
count_scheme_versions,
create_next_scheme_version_from_current,
get_current_scheme_version,
list_scheme_versions,
)
from app.repositories.schemes import (
count_scheme_records,
get_scheme_record_by_scheme_id,
list_scheme_records,
publish_scheme,
rollback_scheme_to_version,
unpublish_scheme,
)
from app.schemas.scheme_registry import (
SchemeCurrentResponse,
SchemeDetailResponse,
SchemeListItem,
SchemeListResponse,
SchemePublishResponse,
SchemeRollbackRequest,
SchemeRollbackResponse,
)
from app.schemas.scheme_versions import (
SchemeVersionCreateResponse,
SchemeVersionListItem,
SchemeVersionListResponse,
)
from app.security.auth import require_api_key
router = APIRouter()
@router.get(f"{settings.api_v1_prefix}/schemes", response_model=SchemeListResponse)
async def get_schemes(
limit: int = Query(default=50, ge=1, le=200),
offset: int = Query(default=0, ge=0),
role: str = Depends(require_api_key),
):
rows = await list_scheme_records(limit=limit, offset=offset)
total = await count_scheme_records()
items = [
SchemeListItem(
scheme_id=row.scheme_id,
source_upload_id=row.source_upload_id,
name=row.name,
status=row.status,
current_version_number=row.current_version_number,
published_at=row.published_at.isoformat() if row.published_at else None,
normalized_elements_count=row.normalized_elements_count,
normalized_seats_count=row.normalized_seats_count,
normalized_groups_count=row.normalized_groups_count,
normalized_sectors_count=row.normalized_sectors_count,
created_at=row.created_at.isoformat(),
)
for row in rows
]
return SchemeListResponse(items=items, total=total)
@router.get(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}", response_model=SchemeDetailResponse)
async def get_scheme(scheme_id: str, role: str = Depends(require_api_key)):
row = await get_scheme_record_by_scheme_id(scheme_id)
return SchemeDetailResponse(
scheme_id=row.scheme_id,
source_upload_id=row.source_upload_id,
name=row.name,
status=row.status,
current_version_number=row.current_version_number,
published_at=row.published_at.isoformat() if row.published_at else None,
normalized_elements_count=row.normalized_elements_count,
normalized_seats_count=row.normalized_seats_count,
normalized_groups_count=row.normalized_groups_count,
normalized_sectors_count=row.normalized_sectors_count,
created_at=row.created_at.isoformat(),
)
@router.get(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/current", response_model=SchemeCurrentResponse)
async def get_scheme_current(scheme_id: str, role: str = Depends(require_api_key)):
scheme = await get_scheme_record_by_scheme_id(scheme_id)
version = await get_current_scheme_version(
scheme_id=scheme.scheme_id,
current_version_number=scheme.current_version_number,
)
return SchemeCurrentResponse(
scheme_id=version.scheme_id,
scheme_version_id=version.scheme_version_id,
version_number=version.version_number,
status=version.status,
normalized_storage_path=version.normalized_storage_path,
normalized_elements_count=version.normalized_elements_count,
normalized_seats_count=version.normalized_seats_count,
normalized_groups_count=version.normalized_groups_count,
normalized_sectors_count=version.normalized_sectors_count,
created_at=version.created_at.isoformat(),
)
@router.get(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/versions", response_model=SchemeVersionListResponse)
async def get_scheme_versions(
scheme_id: str,
limit: int = Query(default=100, ge=1, le=200),
offset: int = Query(default=0, ge=0),
role: str = Depends(require_api_key),
):
rows = await list_scheme_versions(scheme_id=scheme_id, limit=limit, offset=offset)
total = await count_scheme_versions(scheme_id=scheme_id)
items = [
SchemeVersionListItem(
scheme_version_id=row.scheme_version_id,
scheme_id=row.scheme_id,
version_number=row.version_number,
status=row.status,
normalized_storage_path=row.normalized_storage_path,
normalized_elements_count=row.normalized_elements_count,
normalized_seats_count=row.normalized_seats_count,
normalized_groups_count=row.normalized_groups_count,
normalized_sectors_count=row.normalized_sectors_count,
created_at=row.created_at.isoformat(),
)
for row in rows
]
return SchemeVersionListResponse(items=items, total=total)
@router.post(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/versions", response_model=SchemeVersionCreateResponse)
async def create_next_scheme_version_endpoint(
scheme_id: str,
role: str = Depends(require_api_key),
):
current_scheme = await get_scheme_record_by_scheme_id(scheme_id)
current_version = await get_current_scheme_version(
scheme_id=current_scheme.scheme_id,
current_version_number=current_scheme.current_version_number,
)
new_version = await create_next_scheme_version_from_current(scheme_id)
await clone_scheme_version_sectors(
source_scheme_version_id=current_version.scheme_version_id,
target_scheme_version_id=new_version.scheme_version_id,
)
await clone_scheme_version_groups(
source_scheme_version_id=current_version.scheme_version_id,
target_scheme_version_id=new_version.scheme_version_id,
)
await clone_scheme_version_seats(
source_scheme_version_id=current_version.scheme_version_id,
target_scheme_version_id=new_version.scheme_version_id,
)
await create_audit_event(
scheme_id=scheme_id,
event_type="scheme.version.created",
object_type="scheme_version",
object_ref=new_version.scheme_version_id,
details={
"source_scheme_version_id": current_version.scheme_version_id,
"version_number": new_version.version_number,
"normalized_storage_path": new_version.normalized_storage_path,
},
)
return SchemeVersionCreateResponse(
scheme_id=new_version.scheme_id,
scheme_version_id=new_version.scheme_version_id,
version_number=new_version.version_number,
status=new_version.status,
normalized_storage_path=new_version.normalized_storage_path,
)
@router.post(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/publish", response_model=SchemePublishResponse)
async def publish_scheme_endpoint(scheme_id: str, role: str = Depends(require_api_key)):
row = await publish_scheme(scheme_id)
await create_audit_event(
scheme_id=row.scheme_id,
event_type="scheme.published",
object_type="scheme",
object_ref=row.scheme_id,
details={"current_version_number": row.current_version_number, "status": row.status},
)
return SchemePublishResponse(
scheme_id=row.scheme_id,
status=row.status,
current_version_number=row.current_version_number,
published_at=row.published_at.isoformat() if row.published_at else None,
)
@router.post(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/unpublish", response_model=SchemePublishResponse)
async def unpublish_scheme_endpoint(scheme_id: str, role: str = Depends(require_api_key)):
row = await unpublish_scheme(scheme_id)
await create_audit_event(
scheme_id=row.scheme_id,
event_type="scheme.unpublished",
object_type="scheme",
object_ref=row.scheme_id,
details={"current_version_number": row.current_version_number, "status": row.status},
)
return SchemePublishResponse(
scheme_id=row.scheme_id,
status=row.status,
current_version_number=row.current_version_number,
published_at=row.published_at.isoformat() if row.published_at else None,
)
@router.post(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/rollback", response_model=SchemeRollbackResponse)
async def rollback_scheme_endpoint(
scheme_id: str,
payload: SchemeRollbackRequest,
role: str = Depends(require_api_key),
):
row = await rollback_scheme_to_version(
scheme_id=scheme_id,
target_version_number=payload.target_version_number,
)
await create_audit_event(
scheme_id=row.scheme_id,
event_type="scheme.rolled_back",
object_type="scheme_version",
object_ref=str(payload.target_version_number),
details={"current_version_number": row.current_version_number, "status": row.status},
)
return SchemeRollbackResponse(
scheme_id=row.scheme_id,
status=row.status,
current_version_number=row.current_version_number,
published_at=row.published_at.isoformat() if row.published_at else None,
)