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>
This commit is contained in:
jtricerolph 2026-09-01 18:11:35 +00:00
parent 3b2e25df3f
commit 4d3774ef0d
25 changed files with 3557 additions and 15 deletions

View file

@ -0,0 +1,67 @@
# Send to Check-In Tablet
Standalone Chrome extension — deliberately separate from `chrome-newbook-assistant`
(see `project_checkin` memory's "Standalone push extension" decision). Its one job:
detect a NewBook booking page and push that booking to a physical check-in tablet
running the [`tablet-checkin`](../tablet-checkin) app.
## How it works
- **Detection**: a background service worker watches for NewBook booking pages
(`bookings_view/<id>`, `bookings_edit/<id>`, `bookings_checkin/<id>` — confirmed real
URLs, 2026-09-01) and shows a badge on the toolbar icon when one's open. The
SPA-navigation handling (`webNavigation.onHistoryStateUpdated`) is lifted directly from
`chrome-newbook-assistant/background.js` (`~/laptop-archive`) — already proven against
real NewBook navigation, not guessed here.
- **Popup**: click the toolbar icon → shows the detected booking number, a device
picker (busy tablets shown disabled), and a "Send to Check-In Tablet" button.
- **Row-injected button**: on NewBook's "due for arrival" list
(`bookings_lists_checkin`), a content script adds a "Send to Tablet" button under each
row's own Check In button, with an inline device picker. Row detection and the
booking-ID extraction are built from a real sample row the user provided (2026-09-01,
see `project_checkin` memory) — deliberately doesn't rely on any `id` attribute from
NewBook's own markup, since its Check In button reuses the same `id` across every row
(`generic_button_1`), only class/attribute selectors scoped per row. A
`MutationObserver` re-scans for new rows since this page refreshes its table via AJAX
without a full reload.
- **NewBook login indicator**: the popup shows whether the browser looks logged into
NewBook (cookie-based check, also lifted from `chrome-newbook-assistant`'s
`AuthManager.checkNewBookAuth`). This is a **UX signal only** — it does not authorize
anything. The actual push call authenticates with a terminal API key (below), not the
NewBook cookie.
- **Auth**: the push call itself is authorized by a **terminal API key**, generated from
tablet-checkin's own Terminals admin page (`admin` capability) and pasted into this
extension's Settings page. This mirrors the same trust model already used for the
tablets themselves — hotel-owned hardware gets a device-level credential, not a
per-user login. See `project_checkin` memory's "Extension auth" section for the full
reasoning.
## Setup
1. Deploy `tablet-checkin` and note its base URL.
2. In tablet-checkin, go to **Terminals** (requires `admin` capability) → create a
terminal (e.g. "Reception PC 1") → copy the key shown (only shown once).
3. Load this extension unpacked: `chrome://extensions` → Developer mode → **Load
unpacked** → select this folder.
4. Click the extension icon → **Open Settings** (or right-click the icon → Options) →
enter the tablet-checkin base URL and the terminal key → Save → Test connection.
## Known TODOs before this is production-ready
- **Row-detection selectors on `bookings_lists_checkin` are built from a single sample
row** (2026-09-01) — robust in principle (class/attribute-based, not relying on
NewBook's non-unique ids), but only actually tested against one row's markup so far.
Worth confirming against a live page with multiple/varied rows (different booking
statuses, group bookings, etc.) before relying on it daily.
- `host_permissions` in `manifest.json` only covers the NewBook domains (needed for the
cookie-detection API) — tablet-checkin's own backend host isn't declared there since
its production URL isn't fixed yet. Cross-origin `fetch()` calls from the popup/options
pages generally work regardless, but add the real host once known if CORS issues show
up.
- Icons are placeholder-generated (simple crimson square + gold arrow, matching
tablet-checkin's theme color) — replace if a proper design is wanted.
- Not yet published anywhere (Chrome Web Store or otherwise) — currently load-unpacked
only, meaning it needs manually installing on every reception PC. tablet-checkin's own
Settings page has a download link (a bundled copy of this source, zipped on request) as
of 2026-09-01 — keep `backend/extension-src/` in that repo in sync with this folder,
they are not currently the same copy.