fix: backfill symbol_demand for sidebar-added symbols + analyst ratings schema fix
- Add await ctx.cache.subscribe() to addSymbol mutation so symbols added via the sidebar get registered in symbol_demand and yfinance jobs are queued immediately - Backfill PEP, WYNN, STZ, CELH into symbol_demand + adapter_queue - Upgrade yahoo-finance2 3.15.3 -> 3.15.4 and pass validateResult:false to quoteSummary() to handle Yahoo schema drift - Add error detail logging for analyst ratings schema failures - Update .gitignore with common ignores
This commit is contained in:
@@ -21,7 +21,8 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
drawdown_tolerance REAL, -- onboarding max-drawdown % (beginner -20, etc.)
|
||||
convexity_posture TEXT NOT NULL DEFAULT 'off', -- off|covered_income|cash_secured_entry|insurance_sleeve|leaps_conviction
|
||||
backup_codes_hashed TEXT, -- JSON array of scrypt-hashed backup codes (slice 2)
|
||||
created_at TEXT NOT NULL
|
||||
status TEXT NOT NULL DEFAULT 'active', -- active|pending_approval|rejected (user provisioning)
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
@@ -112,7 +113,27 @@ CREATE TABLE IF NOT EXISTS institution_filings (
|
||||
value_usd REAL,
|
||||
reported_quarter TEXT NOT NULL, -- calendar quarter positions are "as of"
|
||||
filed_at TEXT NOT NULL,
|
||||
fetched_at TEXT NOT NULL
|
||||
fetched_at TEXT NOT NULL,
|
||||
put_call TEXT -- Put|Call|null for common stock (13F only)
|
||||
);
|
||||
|
||||
-- Idempotency for institution_filings: one row per (filer, symbol, quarter, form).
|
||||
-- Created in runMigrations (after legacy de-dupe) so it never fails on existing DBs.
|
||||
-- CREATE UNIQUE INDEX IF NOT EXISTS uq_inst_filings
|
||||
-- ON institution_filings(filer_cik, symbol, reported_quarter, form);
|
||||
|
||||
-- Data-quality lint reports (periodic gap/staleness detection).
|
||||
CREATE TABLE IF NOT EXISTS data_quality (
|
||||
symbol TEXT NOT NULL,
|
||||
kind TEXT NOT NULL, -- 'institution_filings' | 'insider_transactions'
|
||||
last_checked_at TEXT,
|
||||
stored_count INTEGER,
|
||||
discovered_count INTEGER,
|
||||
missing_count INTEGER,
|
||||
stale INTEGER NOT NULL DEFAULT 0, -- 1 if latest data is older than threshold
|
||||
status TEXT NOT NULL, -- ok | gaps_found | stale | error
|
||||
detail TEXT, -- JSON blob (notes)
|
||||
PRIMARY KEY (symbol, kind)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS insider_transactions (
|
||||
@@ -129,6 +150,7 @@ CREATE TABLE IF NOT EXISTS insider_transactions (
|
||||
classification TEXT NOT NULL, -- informed_buy|informed_sell|routine
|
||||
filed_at TEXT NOT NULL,
|
||||
fetched_at TEXT NOT NULL,
|
||||
accession TEXT, -- SEC accession number (enables lint diff by filing)
|
||||
PRIMARY KEY (form4_id, symbol, insider_name, tx_date)
|
||||
);
|
||||
|
||||
@@ -254,6 +276,27 @@ CREATE TABLE IF NOT EXISTS portfolio_holdings (
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_portfolio_owner_symbol
|
||||
ON portfolio_holdings(owner_id, symbol);
|
||||
|
||||
-- User-owned option legs (long calls/puts, covered calls, CSPs). Not chain cache.
|
||||
CREATE TABLE IF NOT EXISTS portfolio_option_legs (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
underlying TEXT NOT NULL,
|
||||
right TEXT NOT NULL, -- call | put
|
||||
side TEXT NOT NULL, -- long | short
|
||||
strike REAL NOT NULL,
|
||||
expiry TEXT NOT NULL, -- YYYY-MM-DD
|
||||
contracts REAL NOT NULL,
|
||||
premium REAL NOT NULL, -- avg premium per share
|
||||
multiplier INTEGER NOT NULL DEFAULT 100,
|
||||
role TEXT NOT NULL, -- long_call | long_put | covered_call | cash_secured_put | other
|
||||
status TEXT NOT NULL DEFAULT 'open', -- open | closed
|
||||
acquired_at TEXT NOT NULL,
|
||||
note TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_option_legs_owner_status
|
||||
ON portfolio_option_legs(owner_id, status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS trades (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
@@ -387,6 +430,23 @@ CREATE TABLE IF NOT EXISTS rotation_signals (
|
||||
verdict TEXT -- real|false_alarm (gamma two-stage)
|
||||
);
|
||||
|
||||
-- Daily snapshot of sector RS ranks (Market Outlook history).
|
||||
CREATE TABLE IF NOT EXISTS rotation_rank_snapshots (
|
||||
as_of_date TEXT NOT NULL, -- YYYY-MM-DD
|
||||
symbol TEXT NOT NULL,
|
||||
name TEXT,
|
||||
grp TEXT, -- UI group label
|
||||
rank_1m INTEGER,
|
||||
rs_1m REAL,
|
||||
rank_1w INTEGER,
|
||||
rs_1w REAL,
|
||||
leadership TEXT, -- leading|lagging|inline|unknown
|
||||
early_watch INTEGER NOT NULL DEFAULT 0,
|
||||
strength TEXT, -- none|weak|moderate|strong (market-wide)
|
||||
PRIMARY KEY (as_of_date, symbol)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_rotation_rank_date ON rotation_rank_snapshots(as_of_date DESC);
|
||||
|
||||
-- ===== Section 1.5 — LLM provenance (ADR-0006). Operator-managed, NOT user-editable. =====
|
||||
CREATE TABLE IF NOT EXISTS llm_providers (
|
||||
id TEXT PRIMARY KEY, -- 'local_ollama' | 'local_vllm' | 'zen_glm_5_2' | ...
|
||||
@@ -441,6 +501,32 @@ CREATE TABLE IF NOT EXISTS reddit_posts (
|
||||
CREATE INDEX IF NOT EXISTS idx_x_cookie_cashtag ON x_cookie_posts(cashtag, posted_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_reddit_subreddit ON reddit_posts(subreddit, posted_at DESC);
|
||||
|
||||
-- ===== X cookie credentials (operator-managed; never exposed to client) =====
|
||||
-- Singleton row (id = 'singleton') stores AES-256-GCM encrypted ct0 + auth_token.
|
||||
-- Health status is tracked here so the adapter can report degraded/failed state.
|
||||
CREATE TABLE IF NOT EXISTS x_credentials (
|
||||
id TEXT PRIMARY KEY DEFAULT 'singleton',
|
||||
ct0_enc TEXT, -- AES-256-GCM ciphertext (or NULL if unset)
|
||||
auth_token_enc TEXT, -- AES-256-GCM ciphertext (or NULL if unset)
|
||||
fred_api_key_enc TEXT, -- AES-256-GCM ciphertext (or NULL if unset)
|
||||
healthy INTEGER NOT NULL DEFAULT 0, -- 1 = healthy, 0 = degraded/failed
|
||||
last_error TEXT,
|
||||
updated_at TEXT -- ISO8601; when credentials were last stored or health last reported
|
||||
);
|
||||
|
||||
-- Per-symbol tracked X accounts (admin-managed). The overview page merges cashtag
|
||||
-- feed with timelines of these handles for a given symbol.
|
||||
CREATE TABLE IF NOT EXISTS x_accounts (
|
||||
id TEXT PRIMARY KEY, -- uuid
|
||||
symbol TEXT NOT NULL,
|
||||
handle TEXT NOT NULL, -- bare handle (no @)
|
||||
label TEXT, -- optional human-readable name
|
||||
created_at TEXT NOT NULL,
|
||||
UNIQUE(symbol, handle)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_x_accounts_symbol ON x_accounts(symbol);
|
||||
|
||||
-- ===== Indexes (existing) =====
|
||||
CREATE INDEX IF NOT EXISTS idx_pc_symbol_tf_ts ON price_candles(symbol, timeframe, ts);
|
||||
CREATE INDEX IF NOT EXISTS idx_quote_obs ON quotes(observed_at);
|
||||
@@ -550,3 +636,14 @@ CREATE TABLE IF NOT EXISTS theses (
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_theses_user ON theses(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_theses_symbol ON theses(symbol);
|
||||
|
||||
-- Rotation signal state (latest check result for alert dedup)
|
||||
CREATE TABLE IF NOT EXISTS rotation_state (
|
||||
id TEXT PRIMARY KEY DEFAULT 'singleton',
|
||||
signal TEXT NOT NULL DEFAULT 'none',
|
||||
spread REAL,
|
||||
inflow_avg REAL,
|
||||
outflow_avg REAL,
|
||||
sub_group TEXT, -- the strongest sub-group (e.g. "Financials")
|
||||
checked_at TEXT
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user