Source management console: pause/resume, flag/clear, decision metrics

Turn the Sources tab into a real management console (per Codex):

* source_health now lists ALL sources (active + paused) with backing metrics:
  served / accepted_total / total_articles / duplicates + acceptance & duplicate
  rates + review_reason, alongside last success/attempt, next poll, failures.
* Admin endpoints (gated, 404 on missing): POST sources/{id}/active (pause/
  resume) and /review (flag/clear with reason).
* Pausing only stops future polling — the feed query has no active filter, so a
  paused source's accepted articles stay live.
* Frontend: metric table + Paused filter + per-row Pause/Resume & Flag/Clear
  (optimistic, revert on failure). Attention 'resting' now scoped to active.

Retire/Delete intentionally deferred (distinct lifecycle state, later).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-08 14:04:40 -04:00
parent f90324c5a6
commit 84bc5b0267
5 changed files with 160 additions and 25 deletions
+3 -3
View File
@@ -53,9 +53,9 @@ def test_attention_flags_resting_flagged_and_brief():
from goodnews import queries
content = {"served": 100, "with_image": 90, "latest_brief_size": 5}
sources = [
{"failures": 3, "review_flag": 0},
{"failures": 0, "review_flag": 1},
{"failures": 0, "review_flag": 0},
{"active": 1, "failures": 3, "review_flag": 0},
{"active": 1, "failures": 0, "review_flag": 1},
{"active": 1, "failures": 0, "review_flag": 0},
]
items = queries._attention(content, sources, feedback_unread=2)
texts = " | ".join(i["text"] for i in items)