A small helpdesk system: an office Pixel running a patched GrapheneOS Dialer answers technician calls, records both call legs as separate channels, and a Ruby backend transcribes them through Whisper and files an AI summary against the caller. Squashed to a single commit for sharing. No credentials are included; secrets live outside the repo in /etc/helpdesk/env on the server or a gitignored .claude/env.local locally. See .claude/env.local.example for the shape. Start at README.md, then docs/architecture.md.
2.4 KiB
2.4 KiB
components/backend
The deployed Helpdesk service: one Ruby process serving the operator console, the operator API, and
the phone's device API. WEBrick and the standard library; the PostgreSQL store adds the pg and
sequel gems, the JSON-file store needs nothing.
Run
ruby server.rb # JSON store, dev mode, http://127.0.0.1:4000
HELPDESK_DATABASE_URL=postgres://localhost/helpdesk_dev ruby server.rb # PostgreSQL store
make serve and make sim wrap the common combinations.
Test
make test # the offline suite - no network, no database
ruby db/parity_check.rb # JSON vs PostgreSQL behave identically (needs HELPDESK_TEST_DATABASE_URL)
ruby sim/simulator.rb # drives a running server over HTTP with real device auth
The offline suite is fast and covers the domain (147 assertions), the reverse-command channel (37), the resolutions ledger (28), the summariser (31), the pipeline (20), reporting (16), the context maintainer (9), and the wiki RAG (18).
What's here
server.rb HTTP layer: routes, device auth (authed?), operator auth (operator_authed?)
lib/helpdesk/domain.rb the Store seam + the Service: call state machine, people, reconcile
lib/helpdesk/pg_store.rb PostgreSQL backend (write-through cache over Sequel)
lib/helpdesk/ledger.rb deterministic per-caller resolutions ledger
lib/helpdesk/business_hours.rb Mon-Fri 08-16 Europe/Prague incl. CZ holidays
lib/helpdesk/reporting.rb KPI/billing rollups from the event stream
db/migrate/001_init.sql the schema - source of truth for the data model
db/parity_check.rb scripted JSON-vs-PG diff
db/import_json.rb one-shot JSON-snapshot -> PostgreSQL importer
pipeline.rb audio -> transcript -> summary sequencing
summariser.rb per-call Czech summary + action items (OpenRouter)
context_maintainer.rb the per-caller AI dossier (OpenRouter)
wiki/ wiki grounding: client, embedder, cosine index, build script
public/console.html the whole operator console, one file
sim/simulator.rb stands in for the phone; the fastest way to see a full call
seed.rb demo data for dev mode
Each file's header says what it is and how it fits; the architecture and the device wire contract are
in docs/architecture.md and docs/device-api.md.