""" LinkSyncServer - Collection CRUD Endpoints """ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List, Optional import uuid router = APIRouter(prefix="/api/collections", tags=["Collections"]) class CollectionCreate(BaseModel): name: str description: Optional[str] = None query_type: str # "static" or "dynamic" query_expression: Optional[dict] = None is_public: bool = False class CollectionUpdate(BaseModel): name: Optional[str] = None description: Optional[str] = None query_type: Optional[str] = None query_expression: Optional[dict] = None is_public: Optional[bool] = None class CollectionResponse(BaseModel): id: str name: str description: Optional[str] query_type: str query_expression: Optional[dict] is_public: bool created_at: str updated_at: str def mock_create_collection(data: CollectionCreate) -> CollectionResponse: """Create collection (mock implementation).""" return { "id": str(uuid.uuid4()), "name": data.name, "description": data.description, "query_type": data.query_type, "query_expression": data.query_expression, "is_public": data.is_public, "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z" } def mock_get_collections() -> List[CollectionResponse]: """Get all collections (mock implementation).""" return [ { "id": str(uuid.uuid4()), "name": "Work Links", "description": "Links for work use", "query_type": "dynamic", "query_expression": {"operation": "OR", "operands": [{"operation": "TERM", "value": "work"}]}, "is_public": False, "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z" } ] def mock_get_collection(collection_id: str) -> CollectionResponse | None: """Get collection by ID (mock implementation).""" if collection_id == "mock-id": return { "id": "mock-id", "name": "Work Links", "description": "Links for work use", "query_type": "dynamic", "query_expression": {"operation": "OR", "operands": [{"operation": "TERM", "value": "work"}]}, "is_public": False, "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z" } return None def mock_update_collection(collection_id: str, data: CollectionUpdate) -> CollectionResponse | None: """Update collection.""" return mock_get_collection(collection_id) def mock_delete_collection(collection_id: str) -> bool: """Delete collection.""" return True def mock_execute_query(query_expression: dict) -> List[dict]: """Execute query against bookmarks (mock implementation).""" return [ { "id": str(uuid.uuid4()), "url": "https://example.com/work", "title": "Work Example", "description": "An example", "notes": "", "tags": ["work"], "favicon_url": None, "path": "/Work", "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z", "visit_count": 0, "is_bookmarked": False, "source_set_id": None } ] @router.get("/", response_model=List[CollectionResponse]) async def list_collections(): """List all collections.""" return mock_get_collections() @router.get("/{collection_id}", response_model=CollectionResponse) async def get_collection(collection_id: str): """Get collection by ID.""" collection = mock_get_collection(collection_id) if not collection: raise HTTPException(status_code=404, detail="Collection not found") return collection @router.post("/", response_model=CollectionResponse, status_code=status.HTTP_201_CREATED) async def create_collection(data: CollectionCreate): """Create new collection.""" collection = mock_create_collection(data) return collection @router.put("/{collection_id}", response_model=CollectionResponse) async def update_collection( collection_id: str, data: CollectionUpdate ): """Update collection.""" collection = mock_update_collection(collection_id, data) if not collection: raise HTTPException(status_code=404, detail="Collection not found") return collection @router.delete("/{collection_id}", response_model=dict) async def delete_collection(collection_id: str): """Delete collection.""" success = mock_delete_collection(collection_id) if not success: raise HTTPException(status_code=404, detail="Collection not found") return {"message": "Collection deleted successfully"} @router.post("/{collection_id}/refresh", response_model=dict) async def refresh_collection(collection_id: str): """Refresh dynamic collection (re-evaluate query).""" return {"message": "Collection refreshed successfully"} @router.post("/execute", response_model=List[dict]) async def execute_query(query_expression: dict): """Execute query and return result set.""" return mock_execute_query(query_expression)