-- newsfeed initial schema (SQLite).
--
-- Conventions for this datastore:
--   * ids            TEXT  — hyphenated UUIDv4
--   * timestamps     TEXT  — RFC3339 / ISO8601 (UTC)
--   * booleans       INTEGER — 0/1
--   * json blobs     TEXT  — serde_json arrays/objects
--
-- Every user-owned row carries user_id and cascades on user deletion, because each
-- user is wholly in control of — and isolated within — their own feed.

CREATE TABLE users (
    id            TEXT PRIMARY KEY,
    username      TEXT NOT NULL UNIQUE,
    email         TEXT NOT NULL UNIQUE,
    password_hash TEXT NOT NULL,
    created_at    TEXT NOT NULL
);

CREATE TABLE sessions (
    id         TEXT PRIMARY KEY,
    user_id    TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    token_hash TEXT NOT NULL UNIQUE,
    created_at TEXT NOT NULL,
    expires_at TEXT NOT NULL
);
CREATE INDEX idx_sessions_user ON sessions(user_id);

CREATE TABLE api_tokens (
    id           TEXT PRIMARY KEY,
    user_id      TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name         TEXT NOT NULL,
    prefix       TEXT NOT NULL,
    token_hash   TEXT NOT NULL UNIQUE,
    created_at   TEXT NOT NULL,
    last_used_at TEXT,
    revoked_at   TEXT
);
CREATE INDEX idx_api_tokens_user ON api_tokens(user_id);

CREATE TABLE sources (
    id             TEXT PRIMARY KEY,
    user_id        TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    kind           TEXT NOT NULL,               -- 'rss' | 'agentic'
    name           TEXT NOT NULL,
    url            TEXT,
    weight         REAL NOT NULL DEFAULT 1.0,
    enabled        INTEGER NOT NULL DEFAULT 1,
    last_polled_at TEXT,
    created_at     TEXT NOT NULL,
    UNIQUE(user_id, name)
);
CREATE INDEX idx_sources_user ON sources(user_id);

CREATE TABLE interests (
    id         TEXT PRIMARY KEY,
    user_id    TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    label      TEXT NOT NULL,
    weight     REAL NOT NULL,
    created_at TEXT NOT NULL,
    UNIQUE(user_id, label)
);
CREATE INDEX idx_interests_user ON interests(user_id);

CREATE TABLE items (
    id           TEXT PRIMARY KEY,
    user_id      TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    source_id    TEXT REFERENCES sources(id) ON DELETE SET NULL,
    external_id  TEXT NOT NULL,
    url          TEXT,
    title        TEXT NOT NULL,
    summary      TEXT,
    author       TEXT,
    tags         TEXT NOT NULL DEFAULT '[]',   -- json array of strings
    media        TEXT NOT NULL DEFAULT '[]',   -- json array of Media
    published_at TEXT,
    ingested_at  TEXT NOT NULL,
    state        TEXT NOT NULL DEFAULT 'candidate',
    score        REAL NOT NULL DEFAULT 0.0,
    UNIQUE(user_id, external_id)
);
-- Feed reads order by score within a user's live items.
CREATE INDEX idx_items_feed ON items(user_id, state, score DESC, id DESC);

CREATE TABLE signals (
    id         TEXT PRIMARY KEY,
    user_id    TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    item_id    TEXT NOT NULL REFERENCES items(id) ON DELETE CASCADE,
    action     TEXT NOT NULL,                  -- 'view' | 'click' | 'save' | 'dismiss'
    created_at TEXT NOT NULL
);
CREATE INDEX idx_signals_item ON signals(item_id);
