242 lines
9.3 KiB
Python
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,
|
|
)
|