﻿# ellich Station Deployment Runbook

Created: 2026-04-30

This runbook covers the installed station package flow for Windows and Android.

## Windows Installer

Working directory: `apps/windows-station`

1. Install dependencies:
   - `npm install`
2. Build the local station UI:
   - `npm run dist:ui`
3. Build distributable Windows artifacts:
   - `npm run build:installer`
4. Expected outputs:
   - `artifacts/station-release/windows-installer/ellich-Station-0.10.1-x64.exe`
   - final release preparation must publish role-specific customer-facing installer filenames:
     - `ellich-POS-Station-0.10.1-windows-x64.exe`
     - `ellich-Kiosk-Station-0.10.1-windows-x64.exe`
     - `ellich-KDS-Station-0.10.1-windows-x64.exe`
     - `ellich-Customer-Display-Station-0.10.1-windows-x64.exe`
     - `ellich-Operations-Board-Station-0.10.1-windows-x64.exe`
     - `ellich-Table-Order-Kiosk-Station-0.10.1-windows-x64.exe`
5. Field smoke:
   - install on a clean Windows tablet or terminal
   - confirm fullscreen boot
   - confirm pairing wizard can start with `api` and `claim` query bootstrap
   - confirm local reset clears stored assignment
   - local automation: `npm run station:smoke:windows`
6. Final delivery bundle:
   - `npm run station:release:prepare`
   - `npm run station:release:verify`
7. Full release gate:
   - `npm run station:release:gate`
   - output report: `artifacts/station-release/final/release-gate-report.md`
8. Production-only gate:
   - `npm run station:release:gate:production`
   - this fails on QA/test signing profiles and should be the final pre-deployment command
9. Release readiness summary:
   - `npm run station:release:status`
   - status JSON: `artifacts/station-release/final/release-readiness.json`

## Android Native Project

Working directory: `apps/android-station`

1. Install dependencies:
   - `npm install`
2. Generate the native Capacitor project:
   - `npm run native:init`
3. Sync the local station UI into Android:
   - `npm run sync:android`
4. Open Android Studio if needed:
   - `npm run open:android`
5. Release build:
   - `npm run build:apk`
   - production signed APK: `npm run build:apk:signed`
   - production signed AAB: `npm run build:aab:signed`
6. Expected release artifacts after Java/Android SDK setup:
   - `apps/android-station/android/app/build/outputs/apk/release/app-release-unsigned.apk`
   - `artifacts/station-release/final/ellich-Station-0.10.1-android-release.apk`
   - `apps/android-station/android/app/build/outputs/apk/release/app-release.apk` when release signing is configured
   - `apps/android-station/android/app/build/outputs/bundle/release/app-release.aab` when bundle build is run
7. Emulator smoke:
   - keep an emulator booted on `emulator-5554`
   - run `npm run station:smoke:android`
   - production APK smoke: set `ELLICH_ANDROID_APK_PATH=<signed apk path>` before running `npm run station:smoke:android`

## Android Signing Note

- Current repo automation still produces a QA-signed APK for install smoke.
- Production signing can be supplied in either of these ways:
  - `apps/android-station/android/signing.properties`
  - environment variables:
    - `ELLICH_ANDROID_KEYSTORE_PATH`
    - `ELLICH_ANDROID_KEYSTORE_PASSWORD`
    - `ELLICH_ANDROID_KEY_ALIAS`
    - `ELLICH_ANDROID_KEY_PASSWORD`
- A sample file lives at `apps/android-station/android/signing.properties.example`.
- Once release signing is configured, Gradle release builds emit signed artifacts directly.
- Replace the QA keystore with the production release keystore before field deployment or Play/App distribution.
- `station:release:gate:production` enforces that rule automatically.

## Required Tooling For Android

- Java 17 or newer on `PATH`
- Android Studio
- Android SDK platform + build tools
- Gradle wrapper files inside `apps/android-station/android`
- release build scripts will auto-detect a local JDK on common Windows install paths, but `JAVA_HOME` is still preferred for clean CI and field handoff

## Pairing Bootstrap Inputs

Both shells accept these optional first-run query parameters:

- `api`: ellich API base URL
- `claim`: signed enrollment claim token
- `tenant`: tenant ID fallback
- `role`: device role such as `POS_TERMINAL`, `KDS_SCREEN`
- `name`: device name hint

## New Tenant Main POS First Run

For a newly created tenant, the cloud signup flow seeds the initial POS runtime configuration:

- POS is enabled immediately for the main store location.
- Kiosk, KDS, and display are not silently enabled during signup.
- The main location id is stored in runtime settings.
- Kitchen fulfillment mode starts as `KDS_AND_PRINT`.

First field install sequence:

1. Download the POS / Store Edge package from tenant admin:
   - `/adm/pos/hardware?section=installers`
2. Open the tenant-generated `Multi-device field install plan` on the installer tab.
3. Click `Download worksheet` to hand the field team a tenant-prefilled CSV row for every required physical device.
4. Install the POS / Store Edge package on the first store machine.
5. Log in with a tenant owner, admin, or manager account.
6. Activate the machine as Main POS / Store Edge.
7. Confirm runtime sync loads tenant id, location id, POS flags, tax settings, branding, and kitchen fulfillment mode.
8. Download and install the role-specific package for each secondary Windows device: Kiosk, KDS, Customer Display, Operations Board, or Table Order Kiosk.
9. Pair additional POS, kiosk, KDS, customer display, printer agent, operating board, and signage devices from the trusted Main POS/admin hardware flow.

The Main POS installer/admin login is only for device setup and runtime sync. POS floor actions still require staff PIN and role permissions.

Each new station release version must include the complete installer family. Do not hand off only `ellich-Station-...` or any other single generic Windows installer. The installed shell can still show Station during setup, but the customer-facing download filename, manifest id, checksum, and installer label must identify the target device role.

Admin fleet `Run check` is available to tenant owner/admin users from the hardware UI. It confirms whether the registered device has actually launched its assigned app or printer target; it should not mark a newly registered POS/kiosk/KDS/customer display as Ready until that device sends its first heartbeat.

Main POS first-run heartbeat is allowed during the tenant owner/admin setup session so the activated register can appear online immediately after the installer login and runtime sync. This does not authorize POS floor actions; those still require staff PIN and role permissions.

Device-code pairing is verified for POS, kiosk, KDS, customer display, and printer agent roles: the tenant owner/admin mints a signed enrollment claim, the device starts enrollment from that claim, polls as pending, the tenant owner/admin approves the user code, and the device receives a unique device id plus bootstrap payload.

If production requires `DEVICE_ENROLLMENT_START_SECRET`, direct tenant-id starts require `X-Device-Enrollment-Secret`. Signed claims minted from tenant admin avoid sharing that start secret with field devices; the verifier still supports `RMS_DEVICE_ENROLLMENT_START_SECRET` or `DEVICE_ENROLLMENT_START_SECRET` for fallback checks and never writes the secret value to reports.

## Device Access Map

Use tenant surface hostnames for devices. Do not run kiosk, KDS, display, POS, or signage through the public website host.

| Device | URL pattern | Auth boundary |
| --- | --- | --- |
| Main POS / Store Edge | `https://{tenant}.device.ellich.com/device` | Tenant admin login starts activation; POS actions use staff PIN/capability. |
| Additional POS | `https://{tenant}.pos.ellich.com/pos` | Device enrollment plus staff PIN. |
| Kiosk | `https://{tenant}.kiosk.ellich.com/kiosk` | Device/public tenant context, no employee login. |
| KDS | `https://{tenant}.kds.ellich.com/kds` | Kitchen station/device binding, no employee app login. |
| Customer display | `https://{tenant}.display.ellich.com/display` | Display device identity and POS stream token. |
| Digital signage | `https://{tenant}.menu.ellich.com/digital-menu` | Public screen token or published board, no staff login on TV. |
| Operating board | `https://{tenant}.admin.ellich.com/adm/pos/tasks` | Tenant manager/admin review session. |
| Printer agent | `https://{tenant}.device.ellich.com/device` plus USB Print Agent script when needed | Printer agent pairing; USB script only for USB-connected PCs. |

## Digital Signage Smart TV Setup

Digital signage is not a staff app and not a kiosk. Admin setup publishes a board and generates a TV boot link:

```text
https://{tenant}.menu.ellich.com/digital-menu?tv=1&remember=1&token={public_board_token}&screen={screen_id}
```

Brand guidance:

- Samsung Smart Signage/Tizen: use URL Launcher or Internet browser with the RMS boot link.
- LG webOS/webOS Signage: use browser, URL launcher, or managed signage shell with the RMS boot link.
- Sony BRAVIA/Android TV: use Chrome/TV browser or managed Android signage launcher.
- Fire TV: use Silk Browser for pilots; prefer commercial signage hardware for production.
- ChromeOS/Android/Windows signage player: use kiosk, dedicated-device, or startup-browser mode for the RMS boot link when native TV startup is unreliable.
- Roku/Vizio/Apple TV: use an external HDMI signage player when there is no reliable full browser URL launcher.

Production guidance:

- Prefer commercial Samsung/LG/Sony signage displays, managed Android TV, ChromeOS, Windows station, or a signage HDMI player for unattended menus.
- Consumer TV browsers and Fire TV/Silk are acceptable for pilots but must be reboot-tested before sign-off.
- Roku and Apple TV should not be treated as direct URL-launcher targets unless a native channel/app player exists; use an HDMI player for the RMS boot URL.

Each physical TV should have a unique `screen` id. Use `/digital-menu?reset=1` before reassigning a TV.

## Multi-Device Field Pilot Checklist

Customer field pilot is ready when the cloud verifier passes and the installer files are reachable. Physical production sign-off is separate and requires real installed devices.

The installer tab's `Multi-device field install plan` is the source of truth for live tenant URLs, minimum physical counts, setup actions, verification points, and auth boundaries during the pilot. Use `Download worksheet` from the same panel when the field team needs an offline CSV checklist; it pre-fills one row per required physical device with the live address, setup action, verification point, auth boundary, feedback endpoint, and export endpoint. Physical production sign-off only counts physical-device `WORKING` rows that include a valid `http://` or `https://` evidence URL.

Minimum physical sign-off counts:

| Surface | Minimum count | Required proof |
| --- | ---: | --- |
| Main POS / Store Edge | 1 | Installer launched, tenant admin login completed, runtime settings synced, secondary pairing available. |
| Additional POS terminals | 2 | Pairing completed, staff PIN accepted, payment/void/discount permissions checked. |
| Kiosk terminals | 2 | Device session opened, menu loaded, order handoff reached POS/KDS. |
| KDS screens | 2 | Station binding selected, tickets streamed, bump/recall worked. |
| Customer displays | 2 | Display paired, cart/total stream updated, idle recovery checked. |
| Digital signage screens | 2 | Token opened, board survived reload, TV/player reboot recovery checked. |
| Operating boards | 1 | Date filter checked, task/inventory review worked, table assignment visible. |
| Receipt/kitchen printers | 2 | Receipt print worked, kitchen print worked, USB/LAN recovery checked. |

Record every install result from tenant admin:

- `/adm/pos/hardware?section=installers`
- Download `Field pilot packet` for the store team before starting physical sign-off.
- Click `Download worksheet` before the first device install and keep the completed worksheet with photos and network notes.
- Field test feedback panel
- Click `Import worksheet` after the store team completes the CSV to save completed rows into tenant field feedback.
- Mark `Verified on physical device` only when the actual hardware was used.
- Include device label, location, app version, installer version, network mode, result, severity, count, summary, details, and a valid http/https evidence URL for photos/videos/receipts/network notes.
- Use `Export CSV` to download tenant-scoped evidence. The CSV includes surface-level sign-off summary rows and individual feedback rows for customer/support review, including `remaining_physical_count`, `invalid_evidence_count`, and `next_action` so open field work is visible without database access.

High or blocker feedback keeps physical production sign-off pending until resolved.
The screen shows a short recent feedback list for scanning, while the physical sign-off summary is calculated from up to the latest 500 tenant field feedback records so older device sign-offs are not lost when new notes are added.

### Physical Installer Smoke Evidence

Use these commands on the actual device being installed, not on a developer emulator or cloud browser:

```powershell
npm run station:smoke:windows
npm run station:smoke:android:device
```

`station:smoke:windows` performs a silent install, launches the Windows station app, uninstalls it, and writes a local evidence report under `artifacts/station-release/physical-windows/`.

`station:smoke:android:device` requires one USB-debugging Android device. It rejects emulators by default, installs the signed APK, launches Station, captures a screenshot/UI dump, records Android device metadata, and writes evidence under `artifacts/station-release/physical-android/`. Set `ELLICH_ANDROID_SERIAL` when more than one physical Android device is connected.

Both commands also write `field-feedback-draft.json`. The draft is ready to copy into tenant field feedback once `ELLICH_FIELD_EVIDENCE_URL` points at an uploaded `http://` or `https://` evidence bundle. Without that evidence URL, the local smoke can pass, but physical production sign-off must remain pending.

After uploading evidence, validate or submit the latest draft:

```powershell
npm run station:field:submit-draft -- --dry-run --evidence-url https://example.com/evidence/main-pos
$env:ELLICH_FIELD_EVIDENCE_URL="https://example.com/evidence/main-pos"
$env:ELLICH_FIELD_FEEDBACK_COOKIE="next-auth.session-token=..."
npm run station:field:submit-draft
```

Run `npm run station:physical:audit` after each install batch. It writes `physical-device-signoff-audit.json` and `physical-device-signoff-audit.md` into the final release folder with the tenant feedback summary, local Windows/Android evidence reports, connected Android device state, and the exact remaining surfaces.

When Android kiosk terminals or physical printers have already been verified in the store, generate a completed import worksheet for those successful rows:

```powershell
npm run station:physical:success-worksheet -- --kiosk-count 2 --printer-count 2 --evidence-url https://example.com/evidence/store-install
```

Import the generated CSV from the tenant admin installer page. Replace any `replace-with-evidence.example.com` placeholder with the real evidence URL before importing.

## Release Gate

Before field deployment, capture evidence for:

- tenant signup and operating-model conversion tests
- superadmin tenant management tests
- Windows installer install/uninstall smoke
- Android APK install smoke on emulator plus at least one physical Android device
- automated smoke reruns via `station:smoke:windows`, `station:smoke:android`, and `station:smoke:android:device`
- live device pairing approval from a trusted staff console
- offline order/sync recovery drill
- production signed APK/AAB generated from the release keystore
- `npm run station:new-tenant:verify` including new-tenant Main POS activation, tenant-generated multi-device field install plan, Main POS first-run heartbeat readiness, device-code pairing/approval/bootstrap for POS/kiosk/KDS/customer display/printer roles, multi-device fleet registration, owner/admin fleet `Run check`, first-launch heartbeat gating, and public token-based multi-screen digital signage checks
- `ELLICH_FIELD_TENANT_SLUG={tenant-slug} npm run station:field:verify`
- tenant admin field feedback showing physical sign-off for the multi-device checklist above
- public download access for the deployment runbook and field pilot packet

## Final Handoff Folder

- Final delivery artifacts are copied into `artifacts/station-release/final`
- The bundle includes stable file names for:
  - Windows installer
  - Android signed APK
  - Android signed AAB
  - deployment runbook
  - field pilot packet
- `release-bundle-manifest.json` records file size and SHA-256 for handoff verification
- `/downloads/station/manifest.json` is the public checksum manifest; tenant admins can open `Manifest / checksums` from `/adm/pos/hardware?section=installers` and compare full SHA-256 values before installing Windows or Android packages
- `release-gate-report.md` records the last automated sign-off run across build, smoke, and bundle checks
- `release-gate-production-report.md` records the production-signing gate separately
- `new-tenant-main-pos-readiness.md` records the latest production new-tenant Main POS and multi-device cloud verifier
- `field-device-access-readiness.md` records production download/surface reachability
- `release-readiness.json` summarizes customer field pilot readiness and physical production sign-off separately

