Paramotor flight recorder
- STEERING.md — project direction and values
- PLAN.md — current status and next steps
- docs/INSETS.md — safe-area / notch handling (the
--ion-safe-area-*model + a verified per-page inset matrix)
Most development happens in a plain browser against a mock recording engine (append ?mock-speed=120 to time-compress simulated flights).
Maps work with zero configuration, on either backend. Apple MapKit JS is the default and gives both street and satellite; MapLibre is the fallback, with street view from OpenFreeMap. Both are switchable under Settings → Map Provider.
Satellite on the MapLibre backend is the one thing that needs a key, because it comes from MapTiler: get a free one at maptiler.com and paste it under Settings → Map Provider → MapTiler key. There is deliberately no built-in key and no build-time environment variable — first-party map costs are zero by construction, so a key is always the pilot's own.
pnpm install
pnpm dev # browser ring with mock engine
pnpm test # unit tests
pnpm e2e # Playwright e2e, including reload kill drills
pnpm build # typecheck + production buildSync is developed against a real CouchDB, with no Apple developer account, no StoreKit and no Mac — only the credential is faked:
docker compose -f dev/couchdb/docker-compose.yml up -d
pnpm devThen Settings → Subscription → Use my own server:
| Server | http://localhost:5984 |
|---|---|
| Database | dev-db |
| Username | dev-user |
| Password | dev-pw |
That account is provisioned on demand, with the real validate_doc_update that
is the paywall. A second browser profile is a second device. For a lapsed
(read-only) account, ask for one:
curl -XPOST localhost:5173/v1/session -H 'content-type: application/json' \
-d '{"fake":true,"account":"lapsed","entitled":false}' # -> lapsed-db/-user/-pwSettings → Subscription → Use my own server. Wingover talks to CouchDB directly and never to anything else, so CouchDB has to allow the app's origin — a stock install ships with CORS off, and without this the app cannot reach your server at all:
[chttpd]
enable_cors = true
[cors]
credentials = true
; the origin you serve Wingover from; tauri://localhost is the iOS app
origins = https://wingover.app, tauri://localhost
headers = accept, authorization, content-type, origin, referer
methods = GET, PUT, POST, HEAD, DELETEYou need a database and a user who can read and write it. Nothing else — no design documents, no schema. Wingover puts flights in whatever database you name, and a lapsed subscription is somebody else's problem on a server you own.
