From 8ffca5740d4d17fbf6b4771dc069289d91fe4908 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Tue, 1 Sep 2026 17:37:01 +0000 Subject: [PATCH] Add deploy_tablet_checkin(): LXC 132, staff-push guest check-in tablet Co-Authored-By: Claude Sonnet 5 --- install-stack.sh | 99 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/install-stack.sh b/install-stack.sh index 81347cd..415d59e 100755 --- a/install-stack.sh +++ b/install-stack.sh @@ -2503,6 +2503,99 @@ ${build_out}" npm_add_location "/weather/" "10.10.10.131" 3080 } +# Staff-push guest check-in tablet — contact details, car reg, marketing +# opt-in, T&Cs and signature capture, written back to NewBook. Fully internal +# (staff push + tablet are both trusted-network contexts, see project_checkin +# memory's "Network placement" decision) — no admin-VLAN NIC needed, same +# shape as deploy_calendar/deploy_plant. +deploy_tablet_checkin() { + msg_step "Tablet Check-In (LXC 132 · 10.10.10.132)" + + if [[ -z "${TABLET_CHECKIN_DB_PASS:-}" ]]; then + TABLET_CHECKIN_DB_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24) + printf '\nTABLET_CHECKIN_DB_PASS=%s\n' "$TABLET_CHECKIN_DB_PASS" >> "$CREDS_FILE" + msg_ok "Generated TABLET_CHECKIN_DB_PASS → ${CREDS_FILE}" + fi + + msg_info "Creating LXC 132" + create_lxc 132 "10.10.10.132" "tablet-checkin" 1024 1 + msg_ok "LXC 132 created" + + msg_info "Installing Docker" + install_docker 132 + install_mgmt_key 132 + msg_ok "Docker + SSH ready" + + msg_info "Creating tablet_checkin database" + pct exec 100 -- bash -c " + docker exec hotel-manage-postgres psql -U postgres -c \ + \"CREATE USER tablet_checkin WITH PASSWORD '${TABLET_CHECKIN_DB_PASS}';\" 2>/dev/null || true + docker exec hotel-manage-postgres psql -U postgres -c \ + \"CREATE DATABASE tablet_checkin_db OWNER tablet_checkin;\" 2>/dev/null || true + docker exec hotel-manage-postgres psql -U postgres -d tablet_checkin_db -c \ + \"GRANT ALL ON SCHEMA public TO tablet_checkin;\" 2>/dev/null || true + " &>/dev/null + msg_ok "Database tablet_checkin_db ready" + + msg_info "Deploying tablet-checkin" + deploy_service 132 "tablet-checkin" "${REPO_ROOT}/tablet-checkin" /opt/tablet-checkin + + # HOTEL_NAME (PDF header) and PUBLIC_BASE_URL (regcard_link write-back to + # NewBook, see backend/src/routes/checkin.js) both default sensibly if + # unset — the app still completes check-ins and generates PDFs either way, + # it just can't write a working link back into NewBook without the latter. + push_file 132 /opt/tablet-checkin/.env <&1"); then + msg_error "docker compose build failed in LXC 132: +${build_out}" + fi + + msg_info "Waiting for tablet-checkin" + wait_healthy 132 "http://localhost:3080/tablet-checkin/health" \ + && msg_ok "Tablet Check-In running at 10.10.10.132:3080" \ + || msg_warn "Tablet Check-In may need extra time — check LXC 132" + + msg_info "Seeding tablet-checkin into auth DB" + pct exec 100 -- docker exec hotel-manage-postgres psql -U postgres -d auth_db -c " + INSERT INTO apps (slug, name, description, base_path, icon, theme_color, category, internal_host, internal_port) + VALUES ('tablet-checkin', 'Tablet Check-In', 'Staff-push guest check-in tablet — contact details, car reg, marketing opt-in, T&Cs and signature capture', '/tablet-checkin', 'UserCheck', '#be123c', 'Hotel', '10.10.10.132', 3080) + ON CONFLICT (slug) DO UPDATE SET + name=EXCLUDED.name, description=EXCLUDED.description, base_path=EXCLUDED.base_path, + icon=EXCLUDED.icon, theme_color=EXCLUDED.theme_color, category=EXCLUDED.category, + internal_host=EXCLUDED.internal_host, internal_port=EXCLUDED.internal_port; + INSERT INTO app_capabilities (app_id, slug, name, description, sort_order) + SELECT a.id, c.slug, c.name, c.description, c.sort_order + FROM apps a, (VALUES + ('push','Push to Tablet','Push a booking to a check-in tablet (staff push trigger + manual test-push)',1), + ('admin','Admin','View check-in audit history, manage devices, terminals and marketing config',2), + ('settings','Settings','Configure tablet-checkin app settings',3) + ) AS c(slug, name, description, sort_order) + WHERE a.slug = 'tablet-checkin' + ON CONFLICT (app_id, slug) DO NOTHING; + " &>/dev/null \ + && msg_ok "tablet-checkin seeded into auth DB" \ + || msg_warn "Seed failed — run tablet-checkin/seed-app.js manually" + + npm_add_location "/tablet-checkin/" "10.10.10.132" 3080 + + msg_warn "tablet-checkin deployed but needs manual follow-up before it's fully usable: (1) set a Kiosk Password under Settings before any tablet can log in at /tablet-checkin/kiosk, (2) confirm/create the NewBook regcard-link custom field ID and set it under Settings, (3) create a Terminal API key under Terminals and paste it into the standalone push extension once that extension exists." +} + # ════════════════════════════════════════════════════════════════════════════ # NPM PROXY HOSTS (via API) # ════════════════════════════════════════════════════════════════════════════ @@ -2751,7 +2844,7 @@ SUMMARY # Sources existing credentials and redeploys just the named service. if [[ "${1:-}" == "--only" ]]; then ONLY="${2:-}" - VALID="postgres auth portal npm management noticeboard settings cashup hk-planner twin-optimiser room-planner maintenance forecasting rates reports kitchen kds wages utilities mqtt-broker hvac calendar plant tasks weather" + VALID="postgres auth portal npm management noticeboard settings cashup hk-planner twin-optimiser room-planner maintenance forecasting rates reports kitchen kds wages utilities mqtt-broker hvac calendar plant tasks weather tablet-checkin" [[ -z "$ONLY" ]] && msg_error "Usage: install-stack.sh --only (one of: ${VALID})" grep -qw "$ONLY" <<< "$VALID" || msg_error "Unknown service '${ONLY}'. Valid: ${VALID}" CREDS_FILE=/root/hotel-manage-credentials.txt @@ -2801,6 +2894,8 @@ if [[ "${1:-}" == "--only" ]]; then "$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)" [[ -z "${WEATHER_SECRET:-}" ]] && _append_secret WEATHER_SECRET \ "$(openssl rand -hex 32)" + [[ -z "${TABLET_CHECKIN_DB_PASS:-}" ]] && _append_secret TABLET_CHECKIN_DB_PASS \ + "$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)" USE_FORGEJO=true [[ -f /root/.ssh/hotel-manage_deploy.pub ]] \ @@ -2833,6 +2928,7 @@ if [[ "${1:-}" == "--only" ]]; then plant) deploy_plant ;; tasks) deploy_tasks ;; weather) deploy_weather ;; + tablet-checkin) deploy_tablet_checkin ;; esac exit 0 fi @@ -2869,5 +2965,6 @@ deploy_hvac deploy_calendar deploy_plant deploy_weather +deploy_tablet_checkin configure_npm_proxy_hosts print_summary