# Helpdesk A phone helpdesk for field technicians. A technician calls a stationary GrapheneOS Pixel in the office; before the operator picks up, the caller's card pops up on the operator's screen. The call is recorded, transcribed, and summarised, and filed against the caller as an event. Operators work in a web console; the phone talks to the backend over its own signed channel. The backend is one Ruby process: WEBrick and the standard library, plus the pg and sequel gems when it runs on PostgreSQL. In production it runs on `moje.al.army` - operators reach the console over mutual TLS on 443, the phone posts to its own TLS door on 8443. ## Run it locally Ruby 3.2+ and nothing else. The default mode stores everything in a JSON file, so there is no database to set up: ``` ruby components/backend/server.rb ``` That starts the console and the device API on http://127.0.0.1:4000 in dev mode: operator auth off, a few demo contacts seeded. Open http://127.0.0.1:4000 for the console. To run on PostgreSQL instead, point `HELPDESK_DATABASE_URL` at a database and the backend switches stores: ``` createdb helpdesk_dev psql helpdesk_dev -f components/backend/db/migrate/001_init.sql HELPDESK_DATABASE_URL=postgres://localhost/helpdesk_dev ruby components/backend/server.rb ``` Tests run from `components/backend`: `make test`, or any file directly (`ruby test/test_domain.rb`). To watch a whole call go through without a phone, start the server and run `ruby sim/simulator.rb`. ## Layout - `components/backend` - the deployed service: operator console, operator API, device API, storage, the AI pipeline. Start reading at `server.rb`. - `components/backend/lib/helpdesk` - the domain core: `domain.rb` (the Store seam and the Service, including the call state machine), `pg_store.rb` (PostgreSQL), `ledger.rb` (the resolutions ledger), `business_hours.rb`, `reporting.rb`. - `components/backend/wiki` - wiki grounding for summaries: GraphQL client, embedder, cosine index, build script. - `components/transcription-worker` - recording to speaker-tagged transcript: `remote_transcriber.rb` (hosted Whisper, what production uses) and `transcriber.rb` (local WhisperX fallback). - `components/dialer-patch` - the GrapheneOS Dialer patch: a Java overlay plus nine source patches. Built only on the build box (see `docs/runbooks/`), never in CI. - `components/sepolicy-patch` - one SELinux patch so the patched Dialer can read its `*.helpdesk.*` config properties. - `deploy/` - reference copies of the production config: systemd units, nginx vhosts, the deploy and backup scripts. - `ci/` - the end-to-end script the pipeline runs. - `docs/` - the human docs, listed below. - `resources/` - fetch scripts for the (huge, git-ignored) GrapheneOS sources, and the local Whisper CLI the fallback transcriber drives. ## Docs - `docs/architecture.md` - how the pieces fit: the two auth planes, a call's path through the system, storage, the AI subsystem. - `docs/operations.md` - the production server: deploy, roll back, logs, backups, secrets, CI. - `docs/device-api.md` - the wire contract between the phone and the backend. - `docs/phone-connectivity.md` - how the patched Dialer finds, authenticates to, and talks to the backend, with troubleshooting. - `docs/onboarding.md` - accounts, certificates, SSH, first run. - `docs/runbooks/` - building and flashing the Pixel: `graphene-build.md`, `pixel10a-flash-manual.md`, `windows-wsl2-build.md`. Plus `cert-renewal.md`, for the vmin certificates, which do not renew themselves.