From b14d3b414e911f8fb1f55650de17d54d0e3dac4b Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Sun, 5 Jul 2026 11:17:02 +0000 Subject: [PATCH] schema: add forecast_runs, pickup_snapshots, pickup_curves tables forecast_runs was missing, causing all manual/scheduled forecast jobs to fail on startup. pickup_snapshots and pickup_curves are referenced by the pickup model but were absent from schema.sql. Co-Authored-By: Claude Sonnet 4.6 --- backend/schema.sql | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/backend/schema.sql b/backend/schema.sql index 50b00e6..1b4af40 100644 --- a/backend/schema.sql +++ b/backend/schema.sql @@ -526,6 +526,24 @@ END $$; -- FORECASTING TABLES (for Prophet, XGBoost, CatBoost models) -- ============================================ +-- Tracks each forecast job run (scheduled or manual) +CREATE TABLE IF NOT EXISTS forecast_runs ( + id SERIAL PRIMARY KEY, + run_id VARCHAR(100) NOT NULL UNIQUE, + run_type VARCHAR(50) DEFAULT 'scheduled', + started_at TIMESTAMP DEFAULT NOW(), + completed_at TIMESTAMP, + status VARCHAR(20) DEFAULT 'running', + forecast_from DATE, + forecast_to DATE, + models_run TEXT, + triggered_by VARCHAR(100), + error_message TEXT +); + +CREATE INDEX IF NOT EXISTS idx_forecast_runs_started ON forecast_runs(started_at DESC); +CREATE INDEX IF NOT EXISTS idx_forecast_runs_status ON forecast_runs(status); + -- Forecast metrics configuration CREATE TABLE IF NOT EXISTS forecast_metrics ( id SERIAL PRIMARY KEY, @@ -670,6 +688,39 @@ CREATE TABLE IF NOT EXISTS pickup_explanations ( CREATE INDEX IF NOT EXISTS idx_pickup_explanations_date ON pickup_explanations(forecast_date, forecast_type); +-- Pickup model: daily OTB snapshots for each stay date +CREATE TABLE IF NOT EXISTS pickup_snapshots ( + id SERIAL PRIMARY KEY, + snapshot_date DATE NOT NULL, + stay_date DATE NOT NULL, + days_out INTEGER, + metric_type VARCHAR(50) NOT NULL, + otb_value DECIMAL(12,2), + otb_bookings INTEGER, + prior_year_otb DECIMAL(12,2), + prior_year_final DECIMAL(12,2), + pace_vs_prior_pct DECIMAL(8,2), + created_at TIMESTAMP DEFAULT NOW(), + UNIQUE(snapshot_date, stay_date, metric_type) +); + +CREATE INDEX IF NOT EXISTS idx_pickup_snapshots_stay ON pickup_snapshots(stay_date, metric_type); +CREATE INDEX IF NOT EXISTS idx_pickup_snapshots_snap ON pickup_snapshots(snapshot_date); + +-- Pickup model: historical booking pace curves per DOW/season +CREATE TABLE IF NOT EXISTS pickup_curves ( + id SERIAL PRIMARY KEY, + day_of_week INTEGER NOT NULL, + season VARCHAR(20) NOT NULL, + metric_type VARCHAR(50) NOT NULL, + days_out INTEGER NOT NULL, + avg_pct_of_final DECIMAL(8,4), + std_dev DECIMAL(8,4), + sample_count INTEGER, + updated_at TIMESTAMP DEFAULT NOW(), + UNIQUE(day_of_week, season, metric_type, days_out) +); + -- Monthly budgets from FD CREATE TABLE IF NOT EXISTS monthly_budgets ( id SERIAL PRIMARY KEY,