gateway/modules/routes/routeDataMandates.py
2025-12-09 23:25:06 +01:00

233 lines
7.9 KiB
Python

"""
Mandate routes for the backend API.
Implements the endpoints for mandate management.
"""
from fastapi import APIRouter, HTTPException, Depends, Body, Path, Request, Response, Query
from typing import List, Dict, Any, Optional
from fastapi import status
import logging
import json
# Import auth module
from modules.auth import limiter, getCurrentUser
# Import interfaces
import modules.interfaces.interfaceDbAppObjects as interfaceDbAppObjects
from modules.shared.attributeUtils import getModelAttributeDefinitions
# Import the model classes
from modules.datamodels.datamodelUam import Mandate, User
from modules.datamodels.datamodelPagination import PaginationParams, PaginatedResponse, PaginationMetadata
# Configure logger
logger = logging.getLogger(__name__)
# Model attributes for Mandate
mandateAttributes = getModelAttributeDefinitions(Mandate)
# Create a router for the mandate endpoints
router = APIRouter(
prefix="/api/mandates",
tags=["Manage Mandates"],
responses={404: {"description": "Not found"}}
)
@router.get("/", response_model=PaginatedResponse[Mandate])
@limiter.limit("30/minute")
async def get_mandates(
request: Request,
pagination: Optional[str] = Query(None, description="JSON-encoded PaginationParams object"),
currentUser: User = Depends(getCurrentUser)
) -> PaginatedResponse[Mandate]:
"""
Get mandates with optional pagination, sorting, and filtering.
Query Parameters:
- pagination: JSON-encoded PaginationParams object, or None for no pagination
Examples:
- GET /api/mandates/ (no pagination - returns all items)
- GET /api/mandates/?pagination={"page":1,"pageSize":10,"sort":[]}
"""
try:
# Parse pagination parameter
paginationParams = None
if pagination:
try:
paginationDict = json.loads(pagination)
paginationParams = PaginationParams(**paginationDict) if paginationDict else None
except (json.JSONDecodeError, ValueError) as e:
raise HTTPException(
status_code=400,
detail=f"Invalid pagination parameter: {str(e)}"
)
appInterface = interfaceDbAppObjects.getInterface(currentUser)
result = appInterface.getAllMandates(pagination=paginationParams)
# If pagination was requested, result is PaginatedResult
# If no pagination, result is List[Mandate]
if paginationParams:
return PaginatedResponse(
items=result.items,
pagination=PaginationMetadata(
currentPage=paginationParams.page,
pageSize=paginationParams.pageSize,
totalItems=result.totalItems,
totalPages=result.totalPages,
sort=paginationParams.sort,
filters=paginationParams.filters
)
)
else:
return PaginatedResponse(
items=result,
pagination=None
)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error getting mandates: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to get mandates: {str(e)}"
)
@router.get("/{mandateId}", response_model=Mandate)
@limiter.limit("30/minute")
async def get_mandate(
request: Request,
mandateId: str = Path(..., description="ID of the mandate"),
currentUser: User = Depends(getCurrentUser)
) -> Mandate:
"""Get a specific mandate by ID"""
try:
appInterface = interfaceDbAppObjects.getInterface(currentUser)
mandate = appInterface.getMandate(mandateId)
if not mandate:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Mandate with ID {mandateId} not found"
)
return mandate
except HTTPException:
raise
except Exception as e:
logger.error(f"Error getting mandate {mandateId}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to get mandate: {str(e)}"
)
@router.post("/", response_model=Mandate)
@limiter.limit("10/minute")
async def create_mandate(
request: Request,
mandateData: Mandate = Body(...),
currentUser: User = Depends(getCurrentUser)
) -> Mandate:
"""Create a new mandate"""
try:
appInterface = interfaceDbAppObjects.getInterface(currentUser)
# Create mandate
newMandate = appInterface.createMandate(
name=mandateData.name,
language=mandateData.language
)
if not newMandate:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to create mandate"
)
return newMandate
except HTTPException:
raise
except Exception as e:
logger.error(f"Error creating mandate: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to create mandate: {str(e)}"
)
@router.put("/{mandateId}", response_model=Mandate)
@limiter.limit("10/minute")
async def update_mandate(
request: Request,
mandateId: str = Path(..., description="ID of the mandate to update"),
mandateData: Mandate = Body(...),
currentUser: User = Depends(getCurrentUser)
) -> Mandate:
"""Update an existing mandate"""
try:
appInterface = interfaceDbAppObjects.getInterface(currentUser)
# Check if mandate exists
existingMandate = appInterface.getMandate(mandateId)
if not existingMandate:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Mandate with ID {mandateId} not found"
)
# Update mandate
updatedMandate = appInterface.updateMandate(mandateId, mandateData.model_dump())
if not updatedMandate:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to update mandate"
)
return updatedMandate
except HTTPException:
raise
except Exception as e:
logger.error(f"Error updating mandate {mandateId}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to update mandate: {str(e)}"
)
@router.delete("/{mandateId}", response_model=Dict[str, Any])
@limiter.limit("10/minute")
async def delete_mandate(
request: Request,
mandateId: str = Path(..., description="ID of the mandate to delete"),
currentUser: User = Depends(getCurrentUser)
) -> Dict[str, Any]:
"""Delete a mandate"""
try:
appInterface = interfaceDbAppObjects.getInterface(currentUser)
# Check if mandate exists
existingMandate = appInterface.getMandate(mandateId)
if not existingMandate:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Mandate {mandateId} not found"
)
# Delete mandate
try:
appInterface.deleteMandate(mandateId)
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e)
)
return {"message": f"Mandate {mandateId} deleted successfully"}
except HTTPException:
raise
except Exception as e:
logger.error(f"Error deleting mandate {mandateId}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to delete mandate: {str(e)}"
)