"""GET /api/docs — the indexed document list (feeds the Sources page).""" from __future__ import annotations from fastapi import APIRouter, Depends from sqlalchemy import func, select from sqlalchemy.orm import Session from app.db import get_db from app.models import Chunk, Document from app.schemas import DocList, DocSummary router = APIRouter(tags=["kb"]) @router.get("/docs", response_model=DocList) def list_documents(db: Session = Depends(get_db)) -> DocList: # noqa: B008 """All indexed documents with per-document chunk counts. An empty list means the knowledge base has not been imported yet — the Sources page renders its designed empty state in that case. """ rows = db.execute( select( Document.id, Document.source, Document.path, Document.title, func.count(Chunk.id).label("chunks"), Document.indexed_at, ) .outerjoin(Chunk, Chunk.document_id == Document.id) .group_by(Document.id, Document.source, Document.path, Document.title, Document.indexed_at) .order_by(Document.source, Document.path) ).all() return DocList( documents=[ DocSummary( id=str(row.id), source=row.source, path=row.path, title=row.title, chunks=row.chunks, indexed_at=row.indexed_at.isoformat(), ) for row in rows ] )