From 02768ce5f59bbaa57807dc244defbe3df5d2addf Mon Sep 17 00:00:00 2001 From: ssavutu Date: Thu, 3 Sep 2026 06:10:54 -0400 Subject: [PATCH] Raise the breaking-news banner from the article that is breaking Any editor could already tick "Breaking news" on their article, and the flag did nothing: it was stored, returned by the API, and read by no one. The banner it should have driven was a separate admin-only setting with hand-typed text, so raising one meant messaging an admin and having them retype the headline. Wire the flag to the banner, and derive the banner rather than storing a second copy of the decision. GetBreakingNewsState resolves it on read from the newest published article flagged breaking, falling back to the manual banner when there is none. Deriving it is what makes scheduling work. The published predicate is the same one every other public read uses, so a story scheduled for 11am starts driving the banner at the instant it starts being readable -- there is no publish hook that could fire early, late, or not at all, and unticking the flag takes the banner down just as directly. The public cache is 60s and the scheduler ticks at 60s, so the banner lands within a tick of the story. An article wins over the manual banner: it is the more specific and more recent signal, and "this story is the breaking story now" is the flow the flag exists for. The manual banner is kept separate in the API response so Settings can still edit it while an article overrides it -- binding the form to the effective value would overwrite an admin's text with a headline on their next save. The banner carries the article's slug, not a path: the public site owns its URL shape and already composes links this way for developing stories. Admins can also set a limit after which a flagged article stops holding the homepage. It is off by default, so nothing takes a banner down on an editor's behalf unless someone asked for that. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01ES8gPZxe6sb5xSLrBZ7AGk --- frontend/src/pages/editArticleView.tsx | 8 +- frontend/src/pages/settingsPage.tsx | 152 ++++++++-- server/docs/docs.go | 22 ++ server/docs/swagger.json | 22 ++ server/docs/swagger.yaml | 17 ++ .../breaking_news_integration_test.go | 272 ++++++++++++++++++ .../internal/database/breaking_news_test.go | 27 ++ server/internal/database/settings.go | 151 +++++++++- server/internal/database/users.go | 19 ++ ...breaking_news_settings_integration_test.go | 178 ++++++++++++ server/internal/handlers/settings.go | 44 ++- server/internal/models/api_responses.go | 52 +++- server/main.go | 3 + 13 files changed, 928 insertions(+), 39 deletions(-) create mode 100644 server/internal/database/breaking_news_integration_test.go create mode 100644 server/internal/database/breaking_news_test.go create mode 100644 server/internal/handlers/breaking_news_settings_integration_test.go diff --git a/frontend/src/pages/editArticleView.tsx b/frontend/src/pages/editArticleView.tsx index 3ffd6f3..7234fa9 100644 --- a/frontend/src/pages/editArticleView.tsx +++ b/frontend/src/pages/editArticleView.tsx @@ -1545,7 +1545,13 @@ function EditArticleView() { onChange={(e) => setBreakingNews(e.target.checked)} type="checkbox" /> - Breaking news + + Breaking news + + Raises the red banner across the top of the homepage, with this headline, from the moment the article + publishes -- scheduled stories included. Untick it to take the banner down. + +