Spaces:
Sleeping
Sleeping
File size: 1,675 Bytes
0908f70 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | """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
|