feat(chat): invalidate saved chats on sources sync — versioned stamps, stale marker, Regenerate against the new index
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""Sources-version counter (phase 53, task 01).
|
||||
|
||||
The single-row ``sources_meta`` table (migration 0010, the
|
||||
``kb_overview`` id=1 precedent) records **which generation of the
|
||||
knowledge base** is current. ``version`` is bumped exactly once per
|
||||
sync that actually changed the KB (task 02 — change-gated on
|
||||
``added + updated + pruned > 0``; a failed sync never bumps), so it
|
||||
doubles as the invalidation marker for saved chats: the chats API
|
||||
stamps each saved row with the current version at save time (task 03)
|
||||
and flags rows stamped with an older generation *stale* — their
|
||||
answers predate the current index and may be Regenerated against it
|
||||
(task 05).
|
||||
|
||||
Session convention (phase 53): :func:`bump_sources_version` only
|
||||
*flushes* — the **caller** commits. The two sync paths (the admin Sync
|
||||
button, ``scripts/import_docs``) each own their session, and the bump
|
||||
must land in the same transaction as the KB changes it records.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models import SourcesMeta
|
||||
|
||||
|
||||
def current_sources_version(db: Session) -> int:
|
||||
"""The current KB generation (one PK read of the seeded row).
|
||||
|
||||
Returns ``0`` when the row is absent — defensive, never raises
|
||||
(the migration seeds the row, so absence only happens if someone
|
||||
deleted it out-of-band).
|
||||
"""
|
||||
row = db.get(SourcesMeta, 1)
|
||||
if row is None:
|
||||
return 0
|
||||
return row.version
|
||||
|
||||
|
||||
def bump_sources_version(db: Session) -> int:
|
||||
"""Advance the KB generation by one; return the new version.
|
||||
|
||||
Upserts the single row (creating it if it was ever deleted),
|
||||
increments ``version`` by one, and ``flush``es — the **caller**
|
||||
commits, because each of the two sync paths owns its session and
|
||||
the bump must commit together with the KB changes it witnessed.
|
||||
"""
|
||||
row = db.get(SourcesMeta, 1)
|
||||
if row is None:
|
||||
row = SourcesMeta(id=1, version=0)
|
||||
db.add(row)
|
||||
row.version += 1
|
||||
db.flush()
|
||||
return row.version
|
||||
Reference in New Issue
Block a user