Part of billmallard/pyEfis#181 (FP9). Phase 2 - a design pass now, built only after Bill has flown the first cut and approved the design. Depends on FP4 (billmallard/pyEfis#183) for the route JSON schema. Spec: makerplane/briefs/flight_plan_plan.md section 3.7, Appendix B.
Problem
Routes saved on the device live as mp-route/1 JSON files under ~/makerplane/pyefis/flightplans/routes/. The configurator already knows the device (devices with device_token_hash, pairing via pyefis-data pair <CODE>, configurator/migrations/0001_init.sql:36-48, src/index.ts:204-244) and has an append-only, one-active, project-scoped versioning pattern (aircraft_profiles, 0002_aircraft_profiles.sql:6-16). But the device channel is pull-only (GET /device/config is the only device-authenticated read; there is no device write endpoint), config installs run on boot only (pyefis-config-pull.service), and nothing stores routes or user waypoints in D1.
Design pass to deliver (a doc, docs/route_sync.md, PR'd for Bill; no code until approved)
- D1:
routes(project_id, slug, version, json, active, created_at) modelled on aircraft_profiles (append-only versions, one active per slug), and user_waypoints(project_id, version, json, active, created_at); migrations 0003_routes.sql.
- Pull:
GET /device/routes (bearer device token, ETag over the set) returning the active version of every route for the device's project plus the user waypoints; config_pull writes them as <userdir>/routes/managed_<slug>.json and merges cloud user waypoints into a managed section of user_waypoints.json, under the same backup/rollback discipline as screens (config_pull.py:232-253, 564-626) - but no pyEfis restart is needed for routes (the instrument re-reads the catalog on page open). Decide whether routes pull on boot only (today's rule, no in-flight restarts) or also on a timer (safe, since nothing restarts).
- Push:
POST /device/routes (the first device-authenticated write in the Worker; token scope and rate limit to specify) uploading device-authored routes and device-created user waypoints. Namespacing: cloud-authored routes are managed_* and read-only on the device; device-authored routes upload under their own slugs and appear in the web UI in a "from device" section. With disjoint namespaces no merge policy is needed; say so explicitly, and say what happens on re-pairing to a different project.
- Web UI: a Routes page per project: list, create/edit against the
mp-route/1 schema with ident lookup from the editor's navdata (which source the Worker uses for idents is a decision: the same packs via R2, or a small ident index built by CI), invert/copy/delete, activate a version. Waypoint entry reuses the FastFind rule so the two editors feel the same.
- Security: the device token is long-lived, plaintext on the device, no scopes (
config.py:59, index.ts:212); the doc must state what a leaked token can now write (routes only) and whether a per-endpoint scope or a rotation path is needed before the write endpoint ships. Reference docs/device_deployment.md:24-30 on authenticity vs authorization.
- Environments: dev/qa/prod per
docs/environments.md (separate D1 per env).
Definition of done
docs/route_sync.md with the six sections above, each ending in a decision list for Bill; D1 DDL and endpoint contracts written out; a sequence diagram of pull, push and re-pair. No code.
- Cross-link from
docs/system_designer.md once that doc is recovered from design/system-designer (it is cited from configurator/CLAUDE.md:6 but absent on dev/qa/main - flag this in the PR).
Repo: makerplane-data, branch from dev. Owner: AVIONICS-DATA. Size: L (spec: M).
Part of billmallard/pyEfis#181 (FP9). Phase 2 - a design pass now, built only after Bill has flown the first cut and approved the design. Depends on FP4 (billmallard/pyEfis#183) for the route JSON schema. Spec:
makerplane/briefs/flight_plan_plan.mdsection 3.7, Appendix B.Problem
Routes saved on the device live as
mp-route/1JSON files under~/makerplane/pyefis/flightplans/routes/. The configurator already knows the device (deviceswithdevice_token_hash, pairing viapyefis-data pair <CODE>,configurator/migrations/0001_init.sql:36-48,src/index.ts:204-244) and has an append-only, one-active, project-scoped versioning pattern (aircraft_profiles,0002_aircraft_profiles.sql:6-16). But the device channel is pull-only (GET /device/configis the only device-authenticated read; there is no device write endpoint), config installs run on boot only (pyefis-config-pull.service), and nothing stores routes or user waypoints in D1.Design pass to deliver (a doc,
docs/route_sync.md, PR'd for Bill; no code until approved)routes(project_id, slug, version, json, active, created_at)modelled onaircraft_profiles(append-only versions, one active per slug), anduser_waypoints(project_id, version, json, active, created_at); migrations0003_routes.sql.GET /device/routes(bearer device token, ETag over the set) returning the active version of every route for the device's project plus the user waypoints;config_pullwrites them as<userdir>/routes/managed_<slug>.jsonand merges cloud user waypoints into amanagedsection ofuser_waypoints.json, under the same backup/rollback discipline as screens (config_pull.py:232-253, 564-626) - but no pyEfis restart is needed for routes (the instrument re-reads the catalog on page open). Decide whether routes pull on boot only (today's rule, no in-flight restarts) or also on a timer (safe, since nothing restarts).POST /device/routes(the first device-authenticated write in the Worker; token scope and rate limit to specify) uploading device-authored routes and device-created user waypoints. Namespacing: cloud-authored routes aremanaged_*and read-only on the device; device-authored routes upload under their own slugs and appear in the web UI in a "from device" section. With disjoint namespaces no merge policy is needed; say so explicitly, and say what happens on re-pairing to a different project.mp-route/1schema with ident lookup from the editor's navdata (which source the Worker uses for idents is a decision: the same packs via R2, or a small ident index built by CI), invert/copy/delete, activate a version. Waypoint entry reuses the FastFind rule so the two editors feel the same.config.py:59,index.ts:212); the doc must state what a leaked token can now write (routes only) and whether a per-endpoint scope or a rotation path is needed before the write endpoint ships. Referencedocs/device_deployment.md:24-30on authenticity vs authorization.docs/environments.md(separate D1 per env).Definition of done
docs/route_sync.mdwith the six sections above, each ending in a decision list for Bill; D1 DDL and endpoint contracts written out; a sequence diagram of pull, push and re-pair. No code.docs/system_designer.mdonce that doc is recovered fromdesign/system-designer(it is cited fromconfigurator/CLAUDE.md:6but absent ondev/qa/main- flag this in the PR).Repo: makerplane-data, branch from
dev. Owner: AVIONICS-DATA. Size: L (spec: M).