Small joys backend: shared daily framework + On This Day engine
- goodnews/daily.py: shared helpers for the daily "small joys" (http_json, date-seeded deterministic pick, dedup key) so each joy is a small self-contained module. - goodnews/onthisday.py: harvest today's MM-DD from Wikimedia's On-this-day feed → tone-filter to good/neutral (keyword floor + optional LLM refine) → pool → deterministic daily pick (idempotent, respects blocked/featured) → cached row. Network/LLM before any DB write. Multi-source ready (source column). - db.py: onthisday_pool + daily_onthisday tables. - api.py: GET /api/onthisday/today (edge-cacheable). - cli.py: cycle step (run after Daily Art; --no-joys to skip), LLM client for tone refine. - tests/test_onthisday.py: 7 tests (filter+dedup, pick idempotent, blocked/featured, never-empty, empty-pool, LLM-narrow). 382 backend tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -274,6 +274,36 @@ CREATE TABLE IF NOT EXISTS daily_art (
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- "Small joys" daily features. On This Day: a good/neutral thing that happened on
|
||||
-- today's calendar date, harvested + tone-filtered into a pool, then one picked per day.
|
||||
CREATE TABLE IF NOT EXISTS onthisday_pool (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
source TEXT NOT NULL DEFAULT 'wikimedia', -- multi-source ready (wikimedia | admin | ...)
|
||||
md TEXT NOT NULL, -- 'MM-DD'
|
||||
year INTEGER,
|
||||
ckey TEXT NOT NULL UNIQUE, -- dedup hash so re-harvest never duplicates
|
||||
text TEXT NOT NULL,
|
||||
summary TEXT,
|
||||
image_url TEXT,
|
||||
page_url TEXT,
|
||||
shown_at TEXT, -- last date this was the pick (no-soon-repeat)
|
||||
blocked INTEGER NOT NULL DEFAULT 0, -- admin lever: never pick this
|
||||
featured INTEGER NOT NULL DEFAULT 0, -- admin lever: prefer this for its date
|
||||
added_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS daily_onthisday (
|
||||
feature_date TEXT PRIMARY KEY, -- 'YYYY-MM-DD'
|
||||
pool_id INTEGER NOT NULL,
|
||||
source TEXT NOT NULL DEFAULT 'wikimedia',
|
||||
md TEXT NOT NULL,
|
||||
year INTEGER,
|
||||
text TEXT,
|
||||
summary TEXT,
|
||||
image_url TEXT,
|
||||
page_url TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Privacy-respecting, first-party analytics. NO IP / user-agent / referrer / raw
|
||||
-- URL. visitor_hash is a hash of a random localStorage token (never email/IP).
|
||||
-- The UNIQUE key dedups to one row per (kind, article, visitor, day) — that both
|
||||
|
||||
Reference in New Issue
Block a user