Skip to content

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).