""" LinkSyncServer - Link 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/links", tags=["Links"]) class BookmarkCreate(BaseModel): url: str title: str description: Optional[str] = None notes: Optional[str] = None tags: Optional[List[str]] = None favicon_url: Optional[str] = None path: Optional[str] = None visit_count: int = 0 is_bookmarked: bool = False class BookmarkUpdate(BaseModel): url: Optional[str] = None title: Optional[str] = None description: Optional[str] = None notes: Optional[str] = None tags: Optional[List[str]] = None favicon_url: Optional[str] = None path: Optional[str] = None visit_count: Optional[int] = None is_bookmarked: Optional[bool] = None class BookmarkResponse(BaseModel): id: str url: str title: str description: Optional[str] notes: Optional[str] tags: List[str] favicon_url: Optional[str] path: Optional[str] created_at: str updated_at: str visit_count: int is_bookmarked: bool source_set_id: Optional[str] def get_db(): """Get database session.""" from models.base import get_engine db = get_engine() return db def mock_create_bookmark(data: BookmarkCreate) -> dict: """Create bookmark (mock implementation for demo).""" bookmark = { "id": str(uuid.uuid4()), "url": data.url, "title": data.title, "description": data.description, "notes": data.notes, "tags": data.tags or [], "favicon_url": data.favicon_url, "path": data.path, "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z", "visit_count": data.visit_count, "is_bookmarked": data.is_bookmarked, "source_set_id": None } return bookmark def mock_get_bookmarks() -> List[dict]: """Get all bookmarks (mock implementation).""" return [ { "id": str(uuid.uuid4()), "url": "https://example.com", "title": "Example", "description": "An example website", "notes": "", "tags": ["example", "demo"], "favicon_url": None, "path": "/Home", "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z", "visit_count": 0, "is_bookmarked": False, "source_set_id": None } ] def mock_get_bookmark(bookmark_id: str) -> dict | None: """Get single bookmark by ID.""" # Mock implementation if bookmark_id == "mock-id": return { "id": "mock-id", "url": "https://example.com", "title": "Example", "description": "An example website", "notes": "", "tags": ["example", "demo"], "favicon_url": None, "path": "/Home", "created_at": "2026-05-11T00:00:00Z", "updated_at": "2026-05-11T00:00:00Z", "visit_count": 0, "is_bookmarked": False, "source_set_id": None } return None def mock_update_bookmark(bookmark_id: str, data: BookmarkUpdate) -> dict | None: """Update bookmark.""" # Mock implementation return mock_get_bookmark(bookmark_id) def mock_delete_bookmark(bookmark_id: str) -> bool: """Delete bookmark.""" return True @router.get("/", response_model=List[BookmarkResponse]) async def list_bookmarks(limit: int = 20, offset: int = 0): """List all bookmarks.""" bookmarks = mock_get_bookmarks() return bookmarks[offset:offset + limit] @router.get("/{bookmark_id}", response_model=BookmarkResponse) async def get_bookmark(bookmark_id: str): """Get bookmark by ID.""" bookmark = mock_get_bookmark(bookmark_id) if not bookmark: raise HTTPException(status_code=404, detail="Bookmark not found") return bookmark @router.post("/", response_model=BookmarkResponse, status_code=status.HTTP_201_CREATED) async def create_bookmark(data: BookmarkCreate): """Create new bookmark.""" bookmark = mock_create_bookmark(data) return bookmark @router.put("/{bookmark_id}", response_model=BookmarkResponse) async def update_bookmark( bookmark_id: str, data: BookmarkUpdate ): """Update bookmark.""" bookmark = mock_update_bookmark(bookmark_id, data) if not bookmark: raise HTTPException(status_code=404, detail="Bookmark not found") return bookmark @router.delete("/{bookmark_id}", response_model=dict) async def delete_bookmark(bookmark_id: str): """Delete bookmark.""" success = mock_delete_bookmark(bookmark_id) if not success: raise HTTPException(status_code=404, detail="Bookmark not found") return {"message": "Bookmark deleted successfully"}