Local-first Brief: the landing leads with good news from your home

Per the owner's call (overrides the earlier "Brief sacred" stance): when a home is
set, the homepage opens with local good news first, not global. This is the hook —
you land and see awesome stories from YOUR corner first.

- queries.home_brief: local-first highlights (high/medium-confidence near, blended
  out to country then world so it's always a full, strong set), preferring already-
  summarized stories so the calm read stays rich. Recent window, ranked within tier.
- /api/brief gains a `home` param: private/no-store when set; over-fetches + caps so
  dismissal/boundary filtering never thins it; falls back to global top-up if needed.
- Landing UI: a Local <-> Global toggle ("📍 Near you / 🌍 Everywhere") when a home
  is set, the calm picker invite when not (dismissible), and Change. Default leads
  local; one tap back to the global brief. No home set => exactly today's behavior.

Backend + frontend tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-19 21:36:18 -04:00
parent 2239549799
commit d2a6293a13
7 changed files with 1784 additions and 16 deletions
+45
View File
@@ -259,6 +259,51 @@ def reindex_search(conn: sqlite3.Connection) -> int:
return conn.execute("SELECT COUNT(*) FROM article_search").fetchone()[0]
def home_brief(conn: sqlite3.Connection, home_country: str, home_state: str | None = None,
limit: int = 7, window_days: int = 3) -> list[dict]:
"""Local-first landing highlights. Leads with high/medium-confidence local good news,
then blends out to your country and the world so the set is always full (never the
sad thin-local look), and prefers already-summarized stories so the calm read stays
rich. Brief-shaped rows (incl. summary) tagged with a section, best-first within tier.
"""
if home_state:
near = ("(g.confidence IN ('high','medium') AND EXISTS (SELECT 1 FROM article_places p "
"WHERE p.article_id = a.id AND p.country_code = ? AND p.state_code = ?))")
country = "EXISTS (SELECT 1 FROM article_places p WHERE p.article_id = a.id AND p.country_code = ?)"
section_case = f"CASE WHEN {near} THEN 0 WHEN {country} THEN 1 ELSE 2 END"
section_params = [home_country, home_state, home_country]
else:
near = ("(g.confidence IN ('high','medium') AND EXISTS (SELECT 1 FROM article_places p "
"WHERE p.article_id = a.id AND p.country_code = ?))")
section_case = f"CASE WHEN {near} THEN 0 ELSE 2 END" # no "country" tier without a state
section_params = [home_country]
rows = conn.execute(
f"""
SELECT {_ARTICLE_COLUMNS},
sm.summary AS summary,
{section_case} AS section_rank,
(sm.summary IS NOT NULL) AS has_summary
FROM articles a
JOIN sources src ON src.id = a.source_id
JOIN article_scores s ON s.article_id = a.id
LEFT JOIN article_geo g ON g.article_id = a.id
LEFT JOIN article_summaries sm ON sm.article_id = a.id
WHERE a.duplicate_of IS NULL AND src.content_visible = 1 AND s.accepted = 1
AND a.discovered_at >= datetime('now', ?)
ORDER BY section_rank ASC, has_summary DESC, rank_score DESC,
COALESCE(a.published_at, a.discovered_at) DESC
LIMIT ?
""",
section_params + [f"-{window_days} days", limit],
).fetchall()
out = []
for r in rows:
d = dict(r)
d["__section"] = {0: "near", 1: "country", 2: "world"}.get(d.pop("section_rank", 2), "world")
out.append(d)
return out
def brief(conn: sqlite3.Connection, brief_date: str | None = None, limit: int = 10) -> dict:
"""Return a stored daily brief (latest if no date) with its ranked items."""
target_date = brief_date or _latest_brief_date(conn)