"""Endpoints for finding similar content in the tenant library and draft notes.""" import logging from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.ext.asyncio import AsyncSession from app.api.rate_limit import check_read from app.db.database import get_db from app.models.schemas import SimilarContentRequest, SimilarContentResponse from app.services.content_similarity import scan_similar_content logger = logging.getLogger(__name__) router = APIRouter() @router.post( "/content/similar", response_model=SimilarContentResponse, summary="Find similar content (library + other sections)", ) async def find_similar_content( request: Request, body: SimilarContentRequest, db: AsyncSession = Depends(get_db), _: None = Depends(check_read), ) -> SimilarContentResponse: """Return semantically similar chunks from indexed uploads and lexical overlaps with other sections. Use this when the user adds or edits notes so they can reconcile duplicates or outdated guidance against material already in the system. Request fields: ``peer_sections``: map of section_code → draft bullets (from the client). ``exclude_document_ids``: optional list of upload UUIDs to skip in library hits (e.g. primary survey file so matches favour standalone guidance uploads). """ tenant_id: str = request.state.tenant_id try: return await scan_similar_content(db, tenant_id, body) except Exception as exc: # noqa: BLE001 logger.exception("content/similar failed: %s", exc) raise HTTPException(status_code=500, detail="Similarity search failed") from exc