Fresh server data overrides a pinned brief; pin holds otherwise
Per the agreed model: the brief is server-authoritative and a client Replace is a soft override that yields when genuinely new data arrives. - build_daily_brief is now idempotent: if the composed selection is unchanged it leaves the brief (and its created_at) alone, so the timer's 15-min rebuilds are no-ops when no new data landed. - /api/brief exposes generated_at (the brief's created_at = a content-change stamp). The client pins its view against generated_at and keeps it across plain refreshes, but drops it and shows the fresh server brief when generated_at advances. Missed stories remain in the mood feeds. Tests: idempotent rebuild (no-op vs content change) — 93 total. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -159,6 +159,7 @@ class FeedResponse(BaseModel):
|
||||
class BriefResponse(BaseModel):
|
||||
brief_date: str | None
|
||||
title: str | None
|
||||
generated_at: str | None = None # freshness stamp: changes only when content changes
|
||||
items: list[Article]
|
||||
|
||||
|
||||
@@ -336,6 +337,7 @@ def create_app() -> FastAPI:
|
||||
return BriefResponse(
|
||||
brief_date=data["brief_date"],
|
||||
title=data["title"],
|
||||
generated_at=data.get("created_at"),
|
||||
items=[Article.from_row(r) for r in items],
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user