"""Context fact and document CRUD — MIT licensed.""" from __future__ import annotations import uuid from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path from app.db import get_conn, resolve_tenant_id @dataclass(frozen=True) class ContextFact: id: str category: str key: str value: str source: str | None created_at: str @dataclass(frozen=True) class ContextDocument: id: str filename: str doc_type: str full_text: str file_size: int | None uploaded_at: str def add_fact(db_path: Path, category: str, key: str, value: str, source: str | None = None) -> ContextFact: tid = resolve_tenant_id() fact = ContextFact( id=str(uuid.uuid4()), category=category, key=key, value=value, source=source, created_at=datetime.now(timezone.utc).isoformat(), ) with get_conn(db_path) as conn: conn.execute( "INSERT INTO context_facts(id, tenant_id, category, key, value, source, created_at) VALUES (?,?,?,?,?,?,?)", (fact.id, tid, fact.category, fact.key, fact.value, fact.source, fact.created_at), ) conn.commit() return fact def list_facts(db_path: Path, category: str | None = None) -> list[ContextFact]: tid = resolve_tenant_id() with get_conn(db_path) as conn: if category: rows = conn.execute( "SELECT * FROM context_facts WHERE category=? AND (tenant_id=? OR tenant_id='') ORDER BY created_at", (category, tid), ).fetchall() else: rows = conn.execute( "SELECT * FROM context_facts WHERE (tenant_id=? OR tenant_id='') ORDER BY category, created_at", (tid,), ).fetchall() return [ ContextFact( id=r["id"], category=r["category"], key=r["key"], value=r["value"], source=r["source"], created_at=r["created_at"], ) for r in rows ] def delete_fact(db_path: Path, fact_id: str) -> bool: tid = resolve_tenant_id() with get_conn(db_path) as conn: cursor = conn.execute( "DELETE FROM context_facts WHERE id=? AND (tenant_id=? OR tenant_id='')", (fact_id, tid), ) conn.commit() return cursor.rowcount > 0 def add_document( db_path: Path, filename: str, doc_type: str, full_text: str, file_size: int | None = None, ) -> ContextDocument: tid = resolve_tenant_id() doc = ContextDocument( id=str(uuid.uuid4()), filename=filename, doc_type=doc_type, full_text=full_text, file_size=file_size, uploaded_at=datetime.now(timezone.utc).isoformat(), ) with get_conn(db_path) as conn: conn.execute( "INSERT INTO context_documents(id, tenant_id, filename, doc_type, full_text, file_size, uploaded_at)" " VALUES (?,?,?,?,?,?,?)", (doc.id, tid, doc.filename, doc.doc_type, doc.full_text, doc.file_size, doc.uploaded_at), ) conn.commit() return doc def list_documents(db_path: Path) -> list[ContextDocument]: tid = resolve_tenant_id() with get_conn(db_path) as conn: rows = conn.execute( "SELECT id, filename, doc_type, full_text, file_size, uploaded_at" " FROM context_documents WHERE (tenant_id=? OR tenant_id='') ORDER BY uploaded_at DESC", (tid,), ).fetchall() return [ ContextDocument( id=r["id"], filename=r["filename"], doc_type=r["doc_type"], full_text=r["full_text"], file_size=r["file_size"], uploaded_at=r["uploaded_at"], ) for r in rows ] def delete_document(db_path: Path, doc_id: str) -> bool: tid = resolve_tenant_id() with get_conn(db_path) as conn: cursor = conn.execute( "DELETE FROM context_documents WHERE id=? AND (tenant_id=? OR tenant_id='')", (doc_id, tid), ) conn.commit() return cursor.rowcount > 0