Give the superadmin Plugins panel the same OpenSky "Default bounding
box" experience as the Web App: a grouped preset dropdown (World /
Continents / Countries) plus a Custom option for manual
lamin,lomin,lamax,lomax entry.
Introduce a "bbox" config-field type (rendering hint only; unknown
types still degrade to a text input) and mark the OpenSky bbox field
with it. Values that match a preset render as the region name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
startPluginEdit pre-filled any empty field with its descriptor default,
treating an explicitly cleared field (stored "") the same as one never set
(undefined). So a saved-blank OpenSky bounding box reappeared as the
default 50.5,3.2,53.7,7.3 on reopen (and would be re-persisted on save).
Only inject a default when the field has never been stored (undefined), so
intentional blanks stay blank.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a refresh-interval control to the Map settings popover: Auto (follows
the OpenSky plan) or a fixed 15/30/60/120s. The states endpoint now
resolves a recommended interval from the resolved plan (anonymous 60s,
standard 30s, contributor 15s) and returns it alongside the aircraft, so
"Auto" tracks the plan's credit budget and update rate. Polling reschedules
live when the effective interval changes; the map caption reflects it. New
airTrafficInterval preference (default 'auto', persisted + synced).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add GET /api/integrations/opensky/states: resolves the caller's OpenSky
cascade and returns trimmed aircraft state vectors (icao24, callsign,
country, lat/lng, heading, velocity, altitude, onGround) for their bbox.
Reuses the settings gates (global master / org / personal opt-in) and is
backed by a new Manager.InvokeWith that runs the plugin's states.bbox
action on a transient instance. Proxied through the Web App BFF.
DeviceMap now overlays these as rotatable plane markers (accent when
airborne, grey on ground) with tooltips; Dashboard polls every 30s while
Overview is visible and shows an aircraft count badge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds an inline preview for stored document files alongside download.
- API Server: GET /api/documents/{id}/file honours ?inline=1, serving an
inline Content-Disposition so the browser renders the file instead of
forcing a download (default stays attachment).
- Web App: BFF forwards the inline flag; documentPreviewUrl() helper; an eye
icon; and a preview modal (Teleported to body) that picks a viewer from the
file extension — images -> <img>, PDFs/text -> <iframe>, else a
download-instead fallback. Closes on backdrop click or Escape.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduces a `documents` collection and full-stack UI for tracking pilot
certificates, aircraft registrations, insurance, airspace authorisations,
contracts, and other paperwork.
- Migration 1720300800_add_documents.js (also provisioned live on remote PB):
doc_type/owner/expiry/status/access_tier + file blob, a self-referential
`replaces` version chain, audit fields, and a partial index on expiry_date.
- API Server (documents.go): role-scoped CRUD, server-computed expiry
assessment, ?expiring=N query, versioning (replaces -> version+1, old row
auto-archived), and streamed blob download. admin.go gains multipart upload,
file tokens, and protected-file streaming.
- Web App: BFF passthrough (multipart create + streamed download), api.js
client fns, and Documents.vue wired into the Documents nav slot.
Blobs live in PocketBase file storage for now; only that backend swaps when
S3-compatible object storage lands.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reorder the Status card meta() detail so HTTP status and URL come
first and the latency (ms) reads last, e.g. "HTTP 200 · <url> · 12ms".
Rebuild the embedded panel assets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The superadmin panel had backend CRUD for users/orgs (internal/api/users.go,
orgs.go) but no UI. Add two tabs to panel/src/App.vue:
- Users: create form (email/password/role/org), list with role + org badges,
inline editor (email/role/org/verified/password reset), and delete. Self-role
change and self-delete are suppressed to mirror the server-side guards.
- Organizations: create, inline rename, and delete, with client-derived member
counts; delete is disabled while an org still has members.
PocketBase validation errors are unwrapped into a readable line via a shared
apiError() helper. Rebuilds the embedded panel bundle (dist).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Model Denmark's Dronebekendtgørelsen § 5 (on top of EU 2019/947) across all
three tiers: schema, API Server, and Web App.
Schema (migration 1720300700_add_logbook.js): two collections — `drones`
(classification inputs: mtom, is_toy, autologs, c_class, operator no.) and
`flights` (§5 minimum content + category/purpose/logging-path + operational
maturity + a retention_until computed as operation_date + 5y). Locked API
rules; access flows through the service account like users/orgs.
API Server (logbook.go, logbook_export.go): /api/drones and /api/flights CRUD
with per-role scoping in Go (user→own, admin→org, superadmin→all), plus
GET /api/logbook/export (CSV — the "readable electronic format" for
Trafikstyrelsen / pending police disclosure). Compliance is computed
server-side per flight: exemption (toy / club-area / <250 g hobby), effective
logging path, and red flags (autologs-without-FDR, specific-category-without-
authorisation, missing §5 fields, past retention). Manual-path saves missing a
§5 field are blocked (422).
Web App: BFF proxies (export preserves the CSV Content-Type/Disposition),
api.js client fns, and a Logbook.vue view (Flights/Drones tabs, inline forms,
compliance badges + expandable detail, Export CSV) wired into Dashboard.vue,
replacing the placeholder. Includes the rebuilt embedded dist bundle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add API Server (Go/PocketBase), Web App (Go BFF + Vue), Fly App
(Flutter/DJI MSDK), Adobe Plugin, and Docker/Docker AIO deployment
configs. Design assets and build artifacts are gitignored.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>