- Migration 0002: rating_events, article_embeddings, interest_embeddings, article_assessments, candidate_runs, runs.config_json/provider_costs_json, issue_articles.why; copies ratings into rating_events and drops ratings and feed_priors (scores stays until step 4). - Vote is Loved | Good | NotForMe; legacy `up` links still verify as Loved. - Footer offers Loved it / Good / Not for me; the confirmation page offers the other two so a mis-tap can be corrected. handle_rating appends one event. - db::current_ratings implements the latest-explicit-event rule with summaries and facets; `ratings list|set|clear` CLI appends source='cli' events. - data/profile.md replaces the hard-coded reader prose; the system prompt is rebuilt every run in the §8.4 order with a recent-verdicts block. - Weekly rebuild reads summaries, facets and notes; feed priors removed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1rCLQeKBgnBo3oTgHuTMe
97 lines
3.1 KiB
SQL
97 lines
3.1 KiB
SQL
-- Personalized curation v2 schema (plan 2026-09-02 §7).
|
|
-- `scores` intentionally remains until migration 0003 (step 4).
|
|
|
|
CREATE TABLE rating_events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
article_id INTEGER NOT NULL REFERENCES articles(id) ON DELETE CASCADE,
|
|
issue_date TEXT,
|
|
kind TEXT NOT NULL CHECK (kind IN ('explicit', 'implicit')),
|
|
source TEXT NOT NULL,
|
|
label TEXT NOT NULL,
|
|
value REAL NOT NULL,
|
|
note TEXT,
|
|
event_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE INDEX idx_rating_events_article ON rating_events(article_id, event_at);
|
|
CREATE INDEX idx_rating_events_at ON rating_events(event_at);
|
|
|
|
-- Filled in by step 3.
|
|
CREATE TABLE article_embeddings (
|
|
article_id INTEGER PRIMARY KEY REFERENCES articles(id) ON DELETE CASCADE,
|
|
model TEXT NOT NULL,
|
|
dimension INTEGER NOT NULL,
|
|
input_hash TEXT NOT NULL,
|
|
embedding BLOB NOT NULL,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
-- Filled in by step 3.
|
|
CREATE TABLE interest_embeddings (
|
|
interest TEXT PRIMARY KEY,
|
|
model TEXT NOT NULL,
|
|
dimension INTEGER NOT NULL,
|
|
embedding BLOB NOT NULL,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
-- Triage rows are filled in by step 4; deep rows by step 5.
|
|
CREATE TABLE article_assessments (
|
|
article_id INTEGER NOT NULL REFERENCES articles(id) ON DELETE CASCADE,
|
|
stage TEXT NOT NULL CHECK (stage IN ('triage', 'deep')),
|
|
model TEXT NOT NULL,
|
|
prompt_version INTEGER NOT NULL,
|
|
profile_version INTEGER,
|
|
score REAL,
|
|
fit REAL,
|
|
kind TEXT,
|
|
facets_json TEXT,
|
|
rationale TEXT,
|
|
category TEXT,
|
|
paywalled_guess INTEGER NOT NULL DEFAULT 0,
|
|
assessed_at TEXT NOT NULL,
|
|
PRIMARY KEY (article_id, stage)
|
|
);
|
|
|
|
CREATE INDEX idx_article_assessments_at ON article_assessments(assessed_at);
|
|
|
|
-- Filled in by step 3.
|
|
CREATE TABLE candidate_runs (
|
|
run_id INTEGER NOT NULL REFERENCES runs(id) ON DELETE CASCADE,
|
|
article_id INTEGER NOT NULL REFERENCES articles(id) ON DELETE CASCADE,
|
|
stage TEXT NOT NULL,
|
|
excluded_reason TEXT,
|
|
admitted_by TEXT,
|
|
signals_json TEXT NOT NULL,
|
|
utility REAL,
|
|
rank_utility INTEGER,
|
|
cluster_id INTEGER,
|
|
cluster_rank INTEGER,
|
|
editor_why TEXT,
|
|
PRIMARY KEY (run_id, article_id)
|
|
);
|
|
|
|
CREATE INDEX idx_candidate_runs_article ON candidate_runs(article_id);
|
|
CREATE INDEX idx_candidate_runs_run_stage ON candidate_runs(run_id, stage);
|
|
|
|
-- Filled in by later telemetry/provider steps.
|
|
ALTER TABLE runs ADD COLUMN config_json TEXT;
|
|
ALTER TABLE runs ADD COLUMN provider_costs_json TEXT;
|
|
-- Filled in by step 2.
|
|
ALTER TABLE issue_articles ADD COLUMN why TEXT;
|
|
|
|
INSERT INTO rating_events
|
|
(article_id, issue_date, kind, source, label, value, note, event_at)
|
|
SELECT article_id,
|
|
issue_date,
|
|
'explicit',
|
|
'migration',
|
|
CASE vote WHEN 1 THEN 'loved' ELSE 'not_for_me' END,
|
|
CASE vote WHEN 1 THEN 1.0 ELSE -1.0 END,
|
|
NULL,
|
|
rated_at
|
|
FROM ratings;
|
|
|
|
DROP TABLE ratings;
|
|
DROP TABLE feed_priors;
|