4. Solution strategy¶
Last reviewed: 2026-11-03
The few decisions that shape everything else.
| Strategy | Why | Goal | Where |
|---|---|---|---|
| Watch records offline and uploads SLTB segments when a connection is there; the server stores them as 5 s track files | Never lose a track on deck | Q2 | track-sync, ADR 017 |
| Nothing leaves the watch before consent on the watch | Privacy by design | Q1 | ADR 006 |
| One spec per product is the source of truth; ports follow it | Several platforms, one behaviour | Q5 | specs/README, parity |
| One Rails app serves website, logbook, watch API and admin, server-rendered with Hotwire | Small team, no front-end build | Q7 | specs/server |
| Own map tiles, depth and places instead of paid map services | Cost and control | Q7 | ADR 004, 005, 013 |
| Heavy jobs on a separate worker VM, by priority | Keep the website fast | Q6, Q7 | ADR 011 |
| Every record id from a request goes through an access scope | Users see only their own and shared data | Q3 | ADR 015 |
| Engine detection is a suggestion the skipper corrects | Algorithms are not perfect | Q4 | ADR 009 |
| Infrastructure as code (OpenTofu), deploys only through CI | Repeatable, no hand-made changes | Q3, Q7 | infra |
Two more strategies that serve the goals: map lines are stored simplified and the trip page reads them, not the points (Q6, ADR 007); all derived values are recomputed from the stored points, never patched (Q4, Q2). Goals: section 10.
Technology decisions¶
| Decision | Reason | Where |
|---|---|---|
| Each watch platform is built with its own toolchain: Monkey C (Connect IQ 3+), Kotlin with Compose for Wear OS, Swift later; one spec for all | Watch apps must be native; the behaviour is shared through the spec, not through code | AGENTS.md §1, specs/watchapp |
| A compact binary format (SLTB) in JSON with base64 | A Connect IQ app can neither read back its own FIT file nor send raw binary | track-sync § Purpose |
| Ruby on Rails with server-rendered ERB, Hotwire and importmap, no build step, no CSS framework | Small team, few moving parts | specs/server |
| PostgreSQL with PostGIS | Places and geometry for the OSM data, one database for everything | DEPLOYMENT § Postgres, ADR 013 |
| Solid Queue with its own database | Jobs run on the worker VM with the same image and secrets | ADR 011 |
| Passkeys and magic links, no passwords | Nothing to leak or reset | auth |
| Kamal to Oracle Cloud VMs, SSH through Cloudflare Tunnels, tiles from R2 behind a Worker | Low cost, no open SSH port, own map tiles | DEPLOYMENT.md, ADR 004 |
Organisational approach¶
- One repository for all products; the specs are the single source of truth for behaviour and are edited with the code (specs/README).
- Decisions are ADRs, append-only (ADR template).
- Every agent and subagent follows one Definition of Done, enforced by hooks and gates (AGENTS.md §0).
- Deploys only from the GitHub deploy job on
main; store releases only from tags the owner creates (AGENTS.md §4).