Commit graph

6 commits

Author SHA1 Message Date
fbd1443e35 Extension: inject Send-to-Tablet next to the arrival reminder banner too
New injection point on bookings_view pages — NewBook's own 'This Booking
is due to Arrive today. Do you want to go to Check-In?' banner
(.newbook_message.plain), confirmed from a real sample 2026-09-01. Shares
the row-injection's button/panel logic rather than duplicating it;
makeSendButton/togglePanel now take a variant ('block' for the list row's
table cell, 'inline' for this banner's flowing text context). Booking ID
extraction differs per shape: the list row has a checkbox value, this
banner's Check In button only carries it inside its onclick attribute's
URL, no separate structured attribute.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 20:30:18 +00:00
82f926d736 Kiosk: self-heal a busy device on fresh page load
A browser refresh mid-checkin bypasses the Cancel button entirely (no
React unmount cleanup runs), so a device stayed locked 'busy' with no
route back except a manual admin reset — hit for real 2026-09-01.
registerAndGoIdle() only runs on a genuine fresh mount, so if the device
comes back 'busy' at exactly that moment, nothing on this browser is
actually mid-checkin (state was just initialized) — self-correct via the
same reset the Cancel button already uses, rather than trusting stale
server-side status. Uses kioskReset (krequest, throws KioskSessionError
on 401) not resetDevice (request, redirects to the staff /login page on
401) — the latter would be wrong on a kiosk tablet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 19:20:10 +00:00
f4625e0860 Fix nginx trailing-slash mixed-content redirect, add self-healing device reclaim
- location /tablet-checkin/api/devices/ (trailing slash, proxy_pass) made
  nginx auto-redirect the bare /api/devices list endpoint, and since this
  inner nginx sits behind NPM's TLS termination it built that redirect as
  http:// even over an https:// request — browsers block that as mixed
  content, surfacing as a bare 'Failed to fetch' on the Devices admin page
  with no other clue. Dropped the trailing slash on both the location
  pattern and proxy_pass target; still correctly prefix-matches every
  /devices/:id/... sub-route, no more auto-redirect at all.
- pushNavigate/send() now only reports delivered:true if a write
  demonstrably succeeded, not just because a stream entry exists for the
  device — a stale-but-not-formally-closed connection can silently accept
  a write that never reaches the far end.
- pushBookingToDevice can now self-heal a device stuck 'busy' with no live
  session behind it (session already expired unused) rather than requiring
  an admin to manually click Reset first. Real failure mode hit testing on
  a physical tablet 2026-09-01: two pushes worked end-to-end, a third's
  navigate event never reached the tablet (SSE connection silently died
  during an idle gap), leaving the device stuck with no way to recover
  except a manual admin reset.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 19:05:53 +00:00
28d3db8039 Extension: request host permission dynamically instead of relying on CORS
Backend CORS is disabled by default (origin: false), and an unpacked
extension's ID isn't fixed/predictable per install anyway, so allowlisting
it server-side would be awkward. options.js now calls
chrome.permissions.request() for the entered base URL on Save — once
granted, the extension's own fetches bypass CORS entirely for that origin.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 18:49:28 +00:00
4d3774ef0d Fix NewBook write mechanism, bundle push extension, remove vestigial hotel_id
- setBookingCustomFields: use bookings_update's own custom_fields array
  (confirmed from the real legacy plugin code) instead of
  instance_custom_fields_set, which was only ever proven for a different,
  unrelated plugin
- online_checkin_complete is now a configurable per-hotel custom field
  (online_checkin_complete_custom_field_id setting), not a bogus top-level
  bookings_update field NewBook would silently ignore
- Fix field-name mismatches vs a real live NewBook booking response:
  booking_arrival/departure/length, guest address (street/city/state/
  postcode/country, not a single field), phone/mobile (in contact_details,
  not top-level), and pickPrimaryGuest now checks primary_client (was
  checking fields that don't exist in the real API)
- Bundle the standalone push extension into backend/extension-src/, add
  GET /api/extension/download (zips on request via archiver) and a
  download button on the Settings page
- Remove newbook_hotel_id — vestigial from the legacy system's multi-hotel
  routing model, never actually reached NewBook's API, this stack is
  single-hotel-per-deployment so there's nothing to route between

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 18:11:35 +00:00
3b2e25df3f Initial scaffold: tablet-checkin app
Staff-push guest check-in tablet. Fastify backend + React/Vite frontend,
three-tier auth (staff JWT, terminal API key, kiosk cookie), NewBook
integration via bookings_get/guests_update/bookings_update, pdfkit-based
regcard generation, marketing opt-in with Sendy/Mailchimp adapters.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 17:35:39 +00:00