feat(chat): invalidate saved chats on sources sync — versioned stamps, stale marker, Regenerate against the new index
This commit is contained in:
+42
-1
@@ -23,7 +23,14 @@ Data model — see ``.agent/PLAN.md`` §Data Model:
|
||||
14 shape) — phase 50; ``/api/chat`` stays
|
||||
stateless; ``share_token`` (NULL = private,
|
||||
``uuid4`` = publicly readable at
|
||||
``/shared/<token>``) — phase 51.
|
||||
``/shared/<token>``) — phase 51; ``sources_version``
|
||||
(the KB generation the conversation was saved
|
||||
against; 0 = the pre-counter KB, stale on the
|
||||
first bump) — phase 53.
|
||||
* ``sources_meta`` — single-row sources-version counter: which
|
||||
generation of the knowledge base is current,
|
||||
bumped exactly once per KB-changing sync so saved
|
||||
chats can be marked stale (phase 53).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -146,6 +153,33 @@ class KbOverview(Base):
|
||||
)
|
||||
|
||||
|
||||
class SourcesMeta(Base):
|
||||
"""Single-row sources-version counter (phase 53).
|
||||
|
||||
Exactly one row (``id = 1``, seeded by migration 0010 — the
|
||||
``kb_overview`` id=1 precedent) holds the current **generation** of
|
||||
the knowledge base. ``version`` is bumped exactly once per sync that
|
||||
actually changed the KB (phase 53, task 02 — change-gated on
|
||||
``added + updated + pruned > 0``), so it doubles as the invalidation
|
||||
marker for saved chats: a ``saved_chats`` row stamped with an older
|
||||
generation is *stale* — its answers predate the current index and
|
||||
may be Regenerated against it (phase 53, tasks 03/05). The row is
|
||||
seeded by the migration (not lazily on first bump), so
|
||||
:func:`app.rag.sources_meta.current_sources_version` is a plain PK
|
||||
read.
|
||||
"""
|
||||
|
||||
__tablename__ = "sources_meta"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, server_default="1")
|
||||
#: The KB generation. 0 = the pre-counter KB (everything indexed
|
||||
#: before phase 53); incremented by one per KB-changing sync.
|
||||
version: Mapped[int] = mapped_column(Integer, server_default="0")
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
|
||||
|
||||
class GitSource(Base):
|
||||
"""One admin-managed source (phase 35; kind discriminator, phase 38).
|
||||
|
||||
@@ -203,6 +237,13 @@ class SavedChat(Base):
|
||||
share_token: Mapped[uuid.UUID | None] = mapped_column(
|
||||
UUID(as_uuid=True), unique=True, nullable=True
|
||||
)
|
||||
#: The sources version (KB generation) the conversation was saved
|
||||
#: against (phase 53): stamped by the API at save time. Existing
|
||||
#: rows (saved before the counter existed) stamp ``0`` — "the
|
||||
#: pre-counter KB" — and become stale on the first KB-changing sync
|
||||
#: (stale = ``sources_version < current``, computed server-side by
|
||||
#: the chats API, phase 53 task 03).
|
||||
sources_version: Mapped[int] = mapped_column(Integer, server_default="0")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
|
||||
Reference in New Issue
Block a user