feat(sofiia-console): add runbooks index status endpoint
GET /api/runbooks/status returns docs_root, indexed_files, indexed_chunks, last_indexed_at, fts_available; docs_index_meta table and set on rebuild Made-with: Cursor
This commit is contained in:
@@ -37,15 +37,63 @@ def _extract_title(content: str, path: str) -> str:
|
||||
|
||||
|
||||
async def clear_docs_index() -> None:
|
||||
"""Remove all docs_files, docs_chunks, and FTS rows."""
|
||||
"""Remove all docs_files, docs_chunks, FTS rows, and index meta."""
|
||||
conn = await _db.get_db()
|
||||
await conn.execute("DELETE FROM docs_chunks_fts")
|
||||
await conn.execute("DELETE FROM docs_chunks")
|
||||
await conn.execute("DELETE FROM docs_files")
|
||||
await conn.execute("DELETE FROM docs_index_meta")
|
||||
await conn.commit()
|
||||
logger.info("Docs index cleared.")
|
||||
|
||||
|
||||
async def set_docs_index_meta(docs_root: str, last_indexed_at: str, sha: str = "") -> None:
|
||||
"""Write meta after rebuild. last_indexed_at: ISO or epoch string."""
|
||||
conn = await _db.get_db()
|
||||
for key, value in [("docs_root", docs_root), ("last_indexed_at", last_indexed_at), ("sha", sha)]:
|
||||
await conn.execute(
|
||||
"INSERT OR REPLACE INTO docs_index_meta(key, value) VALUES (?,?)",
|
||||
(key, value),
|
||||
)
|
||||
await conn.commit()
|
||||
|
||||
|
||||
async def get_docs_index_status() -> Dict[str, Any]:
|
||||
"""Return indexed_files, indexed_chunks, last_indexed_at, docs_root, fts_available."""
|
||||
conn = await _db.get_db()
|
||||
files_row = None
|
||||
chunks_row = None
|
||||
async with conn.execute("SELECT COUNT(*) FROM docs_files") as cur:
|
||||
files_row = await cur.fetchone()
|
||||
async with conn.execute("SELECT COUNT(*) FROM docs_chunks") as cur:
|
||||
chunks_row = await cur.fetchone()
|
||||
indexed_files = int(files_row[0]) if files_row else 0
|
||||
indexed_chunks = int(chunks_row[0]) if chunks_row else 0
|
||||
|
||||
meta = {}
|
||||
async with conn.execute("SELECT key, value FROM docs_index_meta") as cur:
|
||||
async for row in cur:
|
||||
meta[row[0]] = row[1]
|
||||
last_indexed_at = meta.get("last_indexed_at") or None
|
||||
docs_root = meta.get("docs_root") or ""
|
||||
|
||||
fts_available = False
|
||||
if indexed_chunks > 0:
|
||||
try:
|
||||
async with conn.execute("SELECT 1 FROM docs_chunks_fts LIMIT 1") as cur:
|
||||
fts_available = (await cur.fetchone()) is not None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {
|
||||
"docs_root": docs_root,
|
||||
"indexed_files": indexed_files,
|
||||
"indexed_chunks": indexed_chunks,
|
||||
"last_indexed_at": last_indexed_at,
|
||||
"fts_available": fts_available,
|
||||
}
|
||||
|
||||
|
||||
async def insert_docs_file(path: str, mtime: float, content: str) -> None:
|
||||
"""Register one file and its chunks. Caller ensures path is normalized."""
|
||||
conn = await _db.get_db()
|
||||
|
||||
Reference in New Issue
Block a user