Commit graph

10 commits

Author SHA1 Message Date
454f34d390 Add dow_align param to /forecast/revenue and /forecast/rooms
Allows callers to switch between 364-day DOW-aligned prior year
and same calendar-date prior year comparison.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 18:28:55 +00:00
185b2ec163 Fall back to DOW averages for dry/wet when spend settings not configured
Covers model returns data (covers * spend) but if resos spend settings are
absent the result is zero, which previously bypassed the DOW fallback. Now
fall back to DOW when the covers-based dry or wet is zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 18:17:42 +00:00
455396c965 Fix cascading InFailedSQLTransactionError in covers forecast
When forecast_rooms_for_date throws inside covers_model, asyncpg aborts the
whole transaction. The exception was being caught with a warning but no rollback,
so every subsequent query in the same request failed. Added db.rollback() in
all three exception handlers (breakfast pickupv2, dinner pickupv2, per-day loop)
and moved public.py's rollback into a finally block so it always fires even
when covers_model returns normally with a corrupted transaction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 16:50:09 +00:00
4bad66c91a Fix revenue endpoint 500 — rollback SQLAlchemy session after caught exceptions
When forecast_covers_range or forecast_revenue_for_date throw DB exceptions,
the swallowed exception leaves the async session in an aborted transaction state.
Subsequent queries (DOW averages, per-date accom) then fail with
InFailedSQLTransactionError. Adding db.rollback() in the except blocks
resets the session so the fallback path can continue cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 14:53:54 +00:00
da8c27d0de Add DOW-average fallback for dry/wet forecast when covers data is zero
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 12:41:53 +00:00
f0d4fb3beb Use occupied_rooms from occupancy report for past-date OTB, excluding overflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 12:37:28 +00:00
d8ad753a62 Fix available_rooms to use is_included flag from room category settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 12:32:45 +00:00
4e783bd508 Fix available_rooms query: use newbook_occupancy_report_data not daily_occupancy
The table is newbook_occupancy_report_data (per-category rows). Aggregate
SUM(available - maintenance) WHERE category_id != '5' to get the correct
available room count excluding overflow and maintenance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 11:32:35 +00:00
e04ae18711 Fix /public/forecast/rooms to use available_rooms excluding overflow
Replace static system_config.total_rooms (80, includes overflow) with
per-day available_rooms from daily_occupancy table. This ensures
occupancy % is calculated against the correct base (non-overflow rooms)
consistent with how the rest of the app reports occupancy. Falls back
to system_config.total_rooms when daily_occupancy has no data for a date.
Also adds available_rooms per-day to the response payload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 10:51:51 +00:00
75d2c1fa9d Forecasting app: hybrid port to HNF stack
Python FastAPI ML backend kept intact; auth replaced with central hnf_session cookie verification. Frontend rebuilt on React 18 + TS + Vite with stack design system, Plotly charts retained. Shared Postgres via DATABASE_URL; schema applied on startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-04 18:49:34 +00:00