New alert service

This commit is contained in:
Urtzi Alfaro
2025-12-05 20:07:01 +01:00
parent 1fe3a73549
commit 667e6e0404
393 changed files with 26002 additions and 61033 deletions

View File

@@ -9,11 +9,15 @@ import structlog
import os
from app.api.dependencies import get_distribution_service
from shared.auth.tenant_access import verify_tenant_permission_dep
from shared.auth.tenant_access import verify_tenant_access_dep
from shared.routing.route_builder import RouteBuilder
from app.core.config import settings
logger = structlog.get_logger()
# Initialize route builder for distribution service
route_builder = RouteBuilder('distribution')
async def verify_internal_api_key(x_internal_api_key: str = Header(None)):
"""Verify internal API key for service-to-service communication"""
@@ -27,13 +31,13 @@ async def verify_internal_api_key(x_internal_api_key: str = Header(None)):
router = APIRouter()
@router.post("/tenants/{tenant_id}/distribution/plans/generate")
@router.post(route_builder.build_base_route("plans/generate"))
async def generate_daily_distribution_plan(
tenant_id: str,
target_date: date = Query(..., description="Date for which to generate distribution plan"),
vehicle_capacity_kg: float = Query(1000.0, description="Vehicle capacity in kg"),
distribution_service: object = Depends(get_distribution_service),
verified_tenant: str = Depends(verify_tenant_permission_dep)
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Generate daily distribution plan for internal transfers
@@ -75,14 +79,14 @@ async def generate_daily_distribution_plan(
raise HTTPException(status_code=500, detail=f"Failed to generate distribution plan: {str(e)}")
@router.get("/tenants/{tenant_id}/distribution/routes")
@router.get(route_builder.build_base_route("routes"))
async def get_delivery_routes(
tenant_id: str,
date_from: Optional[date] = Query(None, description="Start date for route filtering"),
date_to: Optional[date] = Query(None, description="End date for route filtering"),
status: Optional[str] = Query(None, description="Filter by route status"),
distribution_service: object = Depends(get_distribution_service),
verified_tenant: str = Depends(verify_tenant_permission_dep)
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get delivery routes with optional filtering
@@ -111,97 +115,16 @@ async def get_delivery_routes(
raise HTTPException(status_code=500, detail=f"Failed to get delivery routes: {str(e)}")
@router.get("/tenants/{tenant_id}/distribution/shipments")
async def get_shipments(
tenant_id: str,
date_from: Optional[date] = Query(None, description="Start date for shipment filtering"),
date_to: Optional[date] = Query(None, description="End date for shipment filtering"),
status: Optional[str] = Query(None, description="Filter by shipment status"),
distribution_service: object = Depends(get_distribution_service),
verified_tenant: str = Depends(verify_tenant_permission_dep)
):
"""
Get shipments with optional filtering
"""
try:
# If no date range specified, default to today
if not date_from and not date_to:
date_from = date.today()
date_to = date.today()
elif not date_to:
date_to = date_from
shipments = []
current_date = date_from
while current_date <= date_to:
daily_shipments = await distribution_service.get_shipments_for_date(tenant_id, current_date)
shipments.extend(daily_shipments)
current_date = current_date + timedelta(days=1)
if status:
shipments = [s for s in shipments if s.get('status') == status]
return {"shipments": shipments}
except Exception as e:
logger.error("Error getting shipments", error=str(e), exc_info=True)
raise HTTPException(status_code=500, detail=f"Failed to get shipments: {str(e)}")
@router.put("/tenants/{tenant_id}/distribution/shipments/{shipment_id}/status")
async def update_shipment_status(
tenant_id: str,
shipment_id: str,
status_update: dict, # Should be a Pydantic model in production
distribution_service: object = Depends(get_distribution_service),
verified_tenant: str = Depends(verify_tenant_permission_dep)
):
"""
Update shipment status
"""
try:
new_status = status_update.get('status')
if not new_status:
raise HTTPException(status_code=400, detail="Status is required")
user_id = "temp_user" # Would come from auth context
result = await distribution_service.update_shipment_status(
shipment_id=shipment_id,
new_status=new_status,
user_id=user_id,
metadata=status_update.get('metadata')
)
return result
except Exception as e:
logger.error("Error updating shipment status", error=str(e), exc_info=True)
raise HTTPException(status_code=500, detail=f"Failed to update shipment status: {str(e)}")
@router.post("/tenants/{tenant_id}/distribution/shipments/{shipment_id}/delivery-proof")
async def upload_delivery_proof(
tenant_id: str,
shipment_id: str,
delivery_proof: dict, # Should be a Pydantic model in production
distribution_service: object = Depends(get_distribution_service),
verified_tenant: str = Depends(verify_tenant_permission_dep)
):
"""
Upload delivery proof (signature, photo, etc.)
"""
try:
# Implementation would handle signature/photo upload
# This is a placeholder until proper models are created
raise HTTPException(status_code=501, detail="Delivery proof upload endpoint not yet implemented")
except Exception as e:
logger.error("Error uploading delivery proof", error=str(e), exc_info=True)
raise HTTPException(status_code=500, detail=f"Failed to upload delivery proof: {str(e)}")
@router.get("/tenants/{tenant_id}/distribution/routes/{route_id}")
@router.get(route_builder.build_base_route("routes/{route_id}"))
async def get_route_detail(
tenant_id: str,
route_id: str,
distribution_service: object = Depends(get_distribution_service),
verified_tenant: str = Depends(verify_tenant_permission_dep)
verified_tenant: str = Depends(verify_tenant_access_dep)
):
"""
Get delivery route details