from fastapi import APIRouter, Depends from sqlalchemy import or_, text from app.db.session import get_db from app.pipeline.enricher import Enricher router = APIRouter(prefix="/api") enricher = Enricher() @router.get("/search") def search(q: str = "", category: str = None, person: str = None, date: str = None, page: int = None, job_id: int = None, semantic: bool = False, db=Depends(get_db)): from app.db.models import Article query = db.query(Article) if category: query = query.filter(Article.category == category) if date: query = query.filter(Article.date == date) if page: query = query.filter(Article.page == page) if job_id: query = query.filter(Article.upload_job_id == job_id) if person: query = query.filter(Article.persons.any(person)) if q and not semantic: query = query.filter(or_(Article.headline.ilike(f"%{q}%"), Article.text.ilike(f"%{q}%"))) return query.limit(50).all() if semantic and q: vec = enricher.embed(q) # pgvector cosine distance return db.execute(text(""" SELECT * FROM articles ORDER BY embedding <=> :v LIMIT 30 """), {"v": str(vec)}).fetchall() return query.limit(50).all()