"""Map items router for CRUD operations.""" from typing import List from uuid import UUID from fastapi import APIRouter, Depends, status from sqlalchemy.orm import Session from app.database import get_db from app.dependencies import get_current_user, get_optional_current_user from app.models.user import User from app.schemas.map_item import MapItemCreate, MapItemUpdate, MapItemResponse from app.services import item_service from app.services.item_service import geography_to_geojson from app.websocket.connection_manager import manager router = APIRouter(prefix="/api/maps/{map_id}/items", tags=["map-items"]) def format_item_response(item) -> dict: """Format map item for response with GeoJSON geometry.""" return { "id": str(item.id), "map_id": str(item.map_id), "type": item.type, "geometry": geography_to_geojson(item.geometry), "properties": item.properties, "created_at": item.created_at.isoformat(), "updated_at": item.updated_at.isoformat(), "created_by": str(item.created_by) if item.created_by else None, "updated_by": str(item.updated_by) if item.updated_by else None, } @router.get("", response_model=List[dict]) async def list_map_items( map_id: UUID, current_user: User = Depends(get_optional_current_user), db: Session = Depends(get_db) ): """Get all items for a map.""" items = item_service.get_map_items(db, map_id, current_user) return [format_item_response(item) for item in items] @router.post("", response_model=dict, status_code=status.HTTP_201_CREATED) async def create_map_item( map_id: UUID, item_data: MapItemCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Create a new map item.""" item = item_service.create_map_item(db, map_id, item_data, current_user) response = format_item_response(item) # Broadcast to WebSocket clients await manager.send_item_created(map_id, response) return response @router.get("/{item_id}", response_model=dict) async def get_map_item( map_id: UUID, item_id: UUID, current_user: User = Depends(get_optional_current_user), db: Session = Depends(get_db) ): """Get a specific map item.""" item = item_service.get_map_item_by_id(db, item_id, current_user) return format_item_response(item) @router.patch("/{item_id}", response_model=dict) async def update_map_item( map_id: UUID, item_id: UUID, item_data: MapItemUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Update a map item.""" item = item_service.update_map_item(db, item_id, item_data, current_user) response = format_item_response(item) # Broadcast to WebSocket clients await manager.send_item_updated(map_id, response) return response @router.delete("/{item_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_map_item( map_id: UUID, item_id: UUID, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Delete a map item.""" item_service.delete_map_item(db, item_id, current_user) # Broadcast to WebSocket clients await manager.send_item_deleted(map_id, str(item_id)) return None