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,