Initial commit: svg backend
This commit is contained in:
241
backend/app/api/routes/schemes.py
Normal file
241
backend/app/api/routes/schemes.py
Normal file
@@ -0,0 +1,241 @@
|
||||
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,
|
||||
)
|
||||
Reference in New Issue
Block a user