| from fastapi import APIRouter, HTTPException |
| from pydantic import BaseModel |
| from typing import Dict, Any, Optional |
| import uuid |
| import datetime |
|
|
| from backend.core.geo_engine import get_geo_engine |
| from backend.core.session_store import get_session_store |
|
|
| router = APIRouter() |
|
|
| |
| DEFAULT_SESSION_ID = "default-session" |
|
|
| class UserLayerRequest(BaseModel): |
| geojson: Dict[str, Any] |
| name: str = "User Draw" |
| description: Optional[str] = None |
|
|
| class UserLayerResponse(BaseModel): |
| id: str |
| name: str |
| display_name: str |
|
|
| |
| |
| |
| |
| @router.post("", response_model=UserLayerResponse) |
| @router.post("/", response_model=UserLayerResponse, include_in_schema=False) |
| async def register_user_layer(request: UserLayerRequest): |
| """ |
| Registers a new user-drawn layer. |
| Saves GeoJSON to backend and makes it available for SQL querying. |
| """ |
| try: |
| layer_id = str(uuid.uuid4()) |
| geo_engine = get_geo_engine() |
| session_store = get_session_store() |
| |
| |
| table_name = geo_engine.register_layer(layer_id, request.geojson) |
| |
| |
| layer_metadata = { |
| "id": layer_id, |
| "name": request.name, |
| "table_name": table_name, |
| "type": "user_draw", |
| "timestamp": datetime.datetime.now().isoformat(), |
| "description": request.description |
| } |
| |
| session_store.add_layer(DEFAULT_SESSION_ID, layer_metadata) |
| |
| return UserLayerResponse( |
| id=layer_id, |
| name=table_name, |
| display_name=request.name |
| ) |
| |
| except Exception as e: |
| import traceback |
| traceback.print_exc() |
| raise HTTPException(status_code=500, detail=str(e)) |
|
|
|
|
| @router.delete("/{layer_id}") |
| async def delete_user_layer(layer_id: str): |
| """ |
| Deletes a user-drawn layer from DuckDB and session store. |
| Frees backend resources and prevents agent from querying the layer. |
| """ |
| try: |
| geo_engine = get_geo_engine() |
| session_store = get_session_store() |
| |
| |
| dropped = geo_engine.drop_layer(layer_id) |
| |
| |
| removed = session_store.remove_layer(DEFAULT_SESSION_ID, layer_id) |
| |
| if not dropped and not removed: |
| raise HTTPException(status_code=404, detail=f"Layer {layer_id} not found") |
| |
| return {"status": "deleted", "layer_id": layer_id} |
| |
| except HTTPException: |
| raise |
| except Exception as e: |
| import traceback |
| traceback.print_exc() |
| raise HTTPException(status_code=500, detail=str(e)) |
|
|