feat(chat): invalidate saved chats on sources sync — versioned stamps, stale marker, Regenerate against the new index
This commit is contained in:
+16
-2
@@ -387,7 +387,7 @@ def _drop_absent_share_url(model: BaseModel, handler: SerializerFunctionWrapHand
|
||||
|
||||
class SavedChatOut(BaseModel):
|
||||
"""One saved chat, full payload (create/get/put response, phase 50;
|
||||
``share_url``, phase 51 task 02).
|
||||
``share_url``, phase 51 task 02; ``stale``, phase 53 task 03).
|
||||
|
||||
``messages`` round-trips the ``bor.chat.v1`` record list losslessly
|
||||
— the restore path is pixel-identical by construction.
|
||||
@@ -395,6 +395,13 @@ class SavedChatOut(BaseModel):
|
||||
``share_url`` (phase 51): ``"/shared/<token>"`` while the chat is
|
||||
shared, ABSENT from the JSON when unshared (``None`` → dropped by
|
||||
:func:`_drop_absent_share_url` — no ``null`` in the wire shape).
|
||||
|
||||
``stale`` (phase 53): true iff the row's ``sources_version`` stamp
|
||||
is behind the current ``sources_meta`` generation — the answer
|
||||
predates the latest KB-changing sync. Computed server-side (the
|
||||
client never does staleness math); ``SharedChatOut`` deliberately
|
||||
carries no staleness surface (the public snapshot is frozen by
|
||||
design, phase 51).
|
||||
"""
|
||||
|
||||
id: uuid.UUID
|
||||
@@ -404,6 +411,9 @@ class SavedChatOut(BaseModel):
|
||||
message_count: int
|
||||
messages: list[ChatMessage]
|
||||
share_url: str | None = None
|
||||
#: Required (no default): the API must always compute staleness
|
||||
#: server-side — there is no wire shape without the flag.
|
||||
stale: bool
|
||||
|
||||
@model_serializer(mode="wrap")
|
||||
def _serialize(self, handler: SerializerFunctionWrapHandler) -> Any:
|
||||
@@ -418,7 +428,9 @@ class SavedChatRow(BaseModel):
|
||||
(Title, Messages count, Updated). ``share_url`` is populated here so
|
||||
the History page's Share column renders straight from ``GET
|
||||
/api/chats`` — no second fetch per row (``None`` → absent, the same
|
||||
omission rule as :class:`SavedChatOut`).
|
||||
omission rule as :class:`SavedChatOut`). ``stale`` (phase 53) feeds
|
||||
the History page's Stale column the same way: one ``GET`` powers
|
||||
every column.
|
||||
"""
|
||||
|
||||
id: uuid.UUID
|
||||
@@ -426,6 +438,8 @@ class SavedChatRow(BaseModel):
|
||||
updated_at: datetime
|
||||
message_count: int
|
||||
share_url: str | None = None
|
||||
#: Required (no default) — see :attr:`SavedChatOut.stale`.
|
||||
stale: bool
|
||||
|
||||
@model_serializer(mode="wrap")
|
||||
def _serialize(self, handler: SerializerFunctionWrapHandler) -> Any:
|
||||
|
||||
Reference in New Issue
Block a user