Sync the Fly App's waypoint routes through the API Server

Routes saved in the Fly App's mission library now sync to a new per-user
routes collection on the API Server, in the WaypointMissionSpec JSON
format. The library pulls on load and pushes on every save and delete,
merges last-writer-wins by updatedAt, keeps unacknowledged deletes as
tombstones, and keeps working offline. Each signed-in account has its
own copy on the device; routes saved while signed out go to the first
account that signs in.

The API Server gets list / get / upsert / delete route endpoints with a
PocketBase migration, and the Web App a read-only Routes view on the
dashboard (rebuilt dist).

Tested against a fake PocketBase and a fake server only; not yet tried
with a real sign-in on the tablet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 5.5 committed 2026-10-20 17:26:45 +02:00
1 parent e49f318a0e
commit 93f4a580e9
18 files changed
+1525 -43

No files matched your search

+8
View File
@@ -168,6 +168,14 @@ func (s *Server) Handler() http.Handler {
mux.HandleFunc("DELETE /api/documents/{id}", s.requireUser(s.handleDeleteDocument))
mux.HandleFunc("GET /api/documents/{id}/file", s.requireUser(s.handleDownloadDocument))
// Routes — saved waypoint missions, synced with the Fly App's mission
// library (last-writer-wins by the route's updatedAt; deletes tombstoned).
// Per-role scoping is enforced inside the handlers.
mux.HandleFunc("GET /api/routes", s.requireUser(s.handleListRoutes))
mux.HandleFunc("GET /api/routes/{id}", s.requireUser(s.handleGetRoute))
mux.HandleFunc("PUT /api/routes/{id}", s.requireUser(s.handlePutRoute))
mux.HandleFunc("DELETE /api/routes/{id}", s.requireUser(s.handleDeleteRoute))
// Device / dashboard API.
mux.HandleFunc("GET /api/devices", s.handleListDevices)
mux.HandleFunc("GET /api/devices/{id}/track", s.handleTrack)