From b1530e4a4f9866555d18c28069607369f505850a Mon Sep 17 00:00:00 2001 From: jay Date: Sat, 30 May 2026 16:01:12 +0000 Subject: [PATCH] Exclude duplicates from category counts so browse totals match the feed Co-Authored-By: Claude Opus 4.8 (1M context) --- goodnews/queries.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/goodnews/queries.py b/goodnews/queries.py index e7b203c..b6bdeb8 100644 --- a/goodnews/queries.py +++ b/goodnews/queries.py @@ -112,13 +112,19 @@ def brief(conn: sqlite3.Connection, brief_date: str | None = None, limit: int = def category_counts(conn: sqlite3.Connection, accepted_only: bool = True) -> list[dict]: - """Return per topic/flavor article counts for building browse UIs.""" - where = "WHERE s.accepted = 1" if accepted_only else "WHERE s.topic IS NOT NULL" + """Return per topic/flavor article counts for building browse UIs. + + Joins articles and excludes duplicates so the counts match exactly what the + feed endpoint will actually return for each topic/flavor. + """ + clauses = ["a.duplicate_of IS NULL"] + clauses.append("s.accepted = 1" if accepted_only else "s.topic IS NOT NULL") rows = conn.execute( f""" SELECT s.topic, s.flavor, COUNT(*) AS count FROM article_scores s - {where} + JOIN articles a ON a.id = s.article_id + WHERE {" AND ".join(clauses)} GROUP BY s.topic, s.flavor ORDER BY s.topic, s.flavor """