Add Directors Forecast interactive report section

Embeds a Directors Forecast section in the Reports sidebar (hard-coded
under "Directors Reports"). Worksheet tab: day-by-day OTB grid with
editable pickup rooms, dry/wet overrides, ML suggestion column and live
forecast recalculation. Report tab: forecast vs budget vs last-year
comparison, occupancy summary, weekly revenue bands and snapshot tracking.

Backend: forecast-db.js (read-only pool to forecasting_db), new tables
(forecast_sessions, day_overrides, forecast_snapshots) and full REST
routes under /api/directors-forecast. docker-compose FORECAST_DATABASE_URL
added.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-20 10:24:47 +00:00
parent 92e2c48f48
commit 018957123f
10 changed files with 1128 additions and 5 deletions

View file

@ -29,3 +29,31 @@ export function runReport(id: string, dateFrom: string, dateTo: string): Promise
body: JSON.stringify({ dateFrom, dateTo }),
})
}
// ── Directors Forecast API ──────────────────────────────────────────────────
export function dfGetWorksheet(year: number, month: number) {
return request(`/directors-forecast/worksheet/${year}/${month}`)
}
export function dfSaveWorksheet(year: number, month: number, data: { pickup_avg_rate: number; overrides: object[] }) {
return request(`/directors-forecast/worksheet/${year}/${month}`, {
method: 'PUT', body: JSON.stringify(data),
})
}
export function dfGetReport(year: number, month: number) {
return request(`/directors-forecast/report/${year}/${month}`)
}
export function dfSaveSnapshot(year: number, month: number, data: object) {
return request(`/directors-forecast/report/${year}/${month}/snapshot`, {
method: 'POST', body: JSON.stringify(data),
})
}
export function dfDeleteSnapshot(year: number, month: number, id: number) {
return request(`/directors-forecast/report/${year}/${month}/snapshot/${id}`, {
method: 'DELETE',
})
}