from fastapi import APIRouter, Header, HTTPException, status from pydantic import BaseModel from backend.app.services.link_service import create_link, list_public_links, list_tags, update_link from backend.app.services.plugin_manager import plugin_manager from backend.app.services.token_service import validate_token router = APIRouter() class LinkCreate(BaseModel): title: str url: str comment: str = '' timestamp: str | None = None tags: list[str] = [] class LinkUpdate(BaseModel): title: str url: str comment: str = '' tags: list[str] = [] @router.get('/tags') def available_tags(): return list_tags() @router.post('/links', status_code=status.HTTP_201_CREATED) def create_link_endpoint(payload: LinkCreate, authorization: str | None = Header(default=None)): if not authorization or not authorization.startswith('Bearer '): raise HTTPException(status_code=401, detail='Missing or invalid Authorization header') token = authorization.replace('Bearer ', '', 1) info = validate_token(token) if info is None: raise HTTPException(status_code=401, detail='Token expired or invalid') try: record = create_link(info['user_id'], payload.title, payload.url, payload.comment, payload.timestamp, payload.tags) except ValueError as error: raise HTTPException(status_code=422, detail=str(error)) from error plugin_manager.dispatch({'type': 'link_created', **record}) return record @router.put('/links/{link_id}') def update_link_endpoint( link_id: str, payload: LinkUpdate, authorization: str | None = Header(default=None), ): if not authorization or not authorization.startswith('Bearer '): raise HTTPException(status_code=401, detail='Missing or invalid Authorization header') info = validate_token(authorization.replace('Bearer ', '', 1)) if info is None: raise HTTPException(status_code=401, detail='Token expired or invalid') try: record = update_link(link_id, info['user_id'], payload.title, payload.url, payload.comment, payload.tags) except ValueError as error: raise HTTPException(status_code=422, detail=str(error)) from error if record is None: raise HTTPException(status_code=404, detail='Link not found or not owned by user') return record @router.get('/links') def list_links(): return list_public_links()