AI insights now fetches the Claude API key from the central settings
service instead of storing its own encrypted copy, so wages and other
apps can share the same key. Also wires up the update-available banner
using the existing version-check hook pattern.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Live-tested again: 800 tokens still wasn't enough for Sonnet's bullet density
(6 dense bullets, cut off mid-sentence again). Capped bullet count to 4-5,
added a hard 35-word single-sentence limit per bullet, told it not to add a
closing summary, and raised the cap to 1200 for genuine headroom.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Live-tested on the dev stack: with the more verbose Sonnet model, the old
550-token cap cut the last bullet off mid-sentence. Bumped to 800 and told
the model to keep each bullet to 1-2 sentences so it isn't relying on the
cap alone to stay in bounds.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Fix gather_competitor_data() tier filter: it queried tier IN ('primary','secondary'),
values that never exist (real values are 'own'/'competitor'/'market'), so the
cheapest-competitor comparison has always silently returned nothing.
- Feed the previous insight back into the prompt so the model can note what's
changed/resolved instead of repeating itself.
- Extend forecast horizon from 14 to 30 days; add a per-day revenue table
alongside the existing occupancy table.
- Annotate the occupancy table with UK (England) bank holidays.
- Add a same-channel market-movement section (B.com vs B.com, rack vs rack)
diffing rates against the last insight's snapshot, threshold £3.
- Add a parsed headline field + insight history list on the Dashboard,
collapsed to headline/age and expandable to full content.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fetches daily ERA5 weather from Open-Meteo (no API key).
Configurable location, timezone and sync time via Settings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consolidates to single sync path: resos_bookings_sync.py →
resos_bookings_data table. Removes sync_resos_data(), duplicate
load_resos_custom_field_mappings(), resos_api_key and
sync_resos_enabled seed rows, and the dead resos_sync scheduler job.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Yield to event loop after each booking DB commit so FastAPI can
respond to Docker health checks during long syncs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the standalone resos_api_key from the forecasting app's own
system_config table. All credential fetches now go through
central_settings.get_resos_credentials() / get_resos_credentials_sync()
which pull from the Settings app (LXC 116) via the internal integration
endpoint — the same pattern already used for NewBook. The Resos API
Config section is removed from the forecasting Settings page; users
manage the key in the central Settings app instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stack-wide NewBook config lives in the Settings app (LXC 116) and is
fetched live via SETTINGS_URL/SETTINGS_SECRET — same pattern as cashup,
room-planner and maintenance. App-local system_config credentials remain
as a fallback for standalone/dev use. The app's Settings → Newbook page
no longer edits credentials; it points to the central app and keeps
Test Connection.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>