# PilotVault A platform for **drone operations management** — remote control, live telemetry, intelligent flight scheduling, route management, and third-party integration — built on top of the **DJI Mobile SDK V4**. Brand + design system live in [`Design/PilotVault Project logo/`](Design/PilotVault%20Project%20logo/) — **Vault Navy `#0F1E3D`** with a single **Signal Blue `#3D7BF0`** accent, Space Grotesk (structure/display) · Space Mono (data, serials, timestamps, eyebrows), and the **Vector** mark of two offset chevrons (flight, lift, parallax). All UI surfaces implement it with a persisted light/dark toggle (`data-*-theme` attribute); the Fly App follows the system theme. Multiple surfaces sit in front of a shared PocketBase. **The API Server is the only component that talks to PocketBase** — the Web App and Fly App talk only to the API Server, which is the single gateway. Live device/telemetry state is held in memory by the API Server and fanned out over WebSockets. ``` ┌────────────┐ ┌──────────────────┐ ┌──────────────┐ │ Web App │──/bff─►│ │ │ │ │ (Vue/Go) │ │ API Server │──auth─►│ PocketBase │ ├────────────┤ │ (Go) │ │ 10.2.1.10: │ │ Fly App │──/ws──►│ in-mem devices │ │ 8026 │ │ (Flutter) │ └──────────────────┘ └──────────────┘ └────────────┘ ``` ## Surfaces | Folder | Stack | Port | Status | |---|---|---|---| | [`API Server/`](API%20Server/) | Go (+ embedded Vue 3 / Tailwind panel) | `:8080` | ✅ Built & verified — gateway, panel, plugin system | | [`Web App/`](Web%20App/) | Go BFF + Vue 3 + Tailwind | `:8090` | ✅ Built & verified — control panel | | [`Fly App/`](Fly%20App/) | Flutter (Android) + Kotlin DJI MSDK V4 bridge | — | ✅ Built & run on a real device; live telemetry uplink | | [`Adobe Plugin/`](Adobe%20Plugin/) | — | — | 🚧 Placeholder | | [`Phone App/`](Phone%20App/) | — | — | 🚧 Placeholder | | [`Docker/`](Docker/) · [`Docker AIO/`](Docker%20AIO/) | Docker Compose | `:8080` `:8090` `:8026` | ✅ Combined stack + single all-in-one container | ## Data model (PocketBase) PocketBase provides **auth + persistence only**; device and telemetry state are in-memory in the API Server. Schema + seed ship as idempotent migrations in [`API Server/pocketbase/pb_migrations/`](API%20Server/pocketbase/pb_migrations/). - `users` — auth, plus `role` (`superadmin | admin | user`), `organization` relation (nullable), and a `preferences` JSON blob. - `organizations` — tenant grouping for users. **Roles:** `superadmin` = global (all orgs/users); `admin` = scoped to its own org (manages that org's users, cannot cross orgs); `user` = no management. Org-scoping is enforced in the API Server (`internal/api/users.go`, `orgs.go`). User/org management requires a PocketBase **superuser service account** in `API Server/.env` (`POCKETBASE_ADMIN_EMAIL/PASSWORD`, gitignored); without it, `/api/users` and `/api/orgs` return `503`. ## Run order 1. **PocketBase** — reachable at `http://10.2.1.10:8026` (override with `POCKETBASE_URL`). 2. **API Server** (`:8080`): ```powershell cd "API Server" Copy-Item .env.example .env # set POCKETBASE_URL and POCKETBASE_ADMIN_* cd panel; npm install; npm run build; cd .. # build the embedded panel ./scripts/Run-ApiServer.ps1 ``` The embedded, superadmin-only panel is at http://localhost:8080/ (live health, PocketBase connection settings, and the plugins manager). 3. **Web App** (`:8090`): ```powershell cd "Web App/web"; npm install; npm run build; cd ../server ./Run-WebApp.ps1 ``` Open http://localhost:8090 and sign in. 4. **Fly App** — see [`Fly App/README.md`](Fly%20App/README.md) (install Flutter + JDK, set your DJI App Key in `android/gradle.properties`, `flutter run` on a connected Android device — the DJI SDK does not run on emulators). ### Docker - [`Docker/`](Docker/) — combined stack (API Server + Web App) on a shared network: `cd Docker; docker compose up --build`. - [`Docker AIO/`](Docker%20AIO/) — PocketBase + API Server + Web App in **one** container: `cd "Docker AIO"; docker compose up --build`. ## Telemetry lifecycle The Fly App connects on `GET /ws/device?id={id}` and streams typed events — `registration`, `connection`, `battery`, `telemetry` (altitude, lat/lng, velocity, GPS sats, flight mode…). The API Server merges each into a per-device `DeviceState`, appends `latitude`/`longitude` to the device's GPS track, and fans every update out to connected dashboards on `/ws/ui` as `{type:"update", device, event}`. ## Plugins The API Server integrates third-party services through a uniform **plugin** contract (`internal/plugins`), managed by a superadmin from the panel. Two kinds share one interface: - **Built-in** — Go connectors compiled into the server (reference example: **OpenSky Network** live ADS-B flight data). Adding a new one needs a rebuild. - **External** — a remote HTTP service **registered at runtime, no rebuild**; answers `GET /health`, `GET /manifest`, `POST /invoke`. Enable-state and per-plugin config persist to a gitignored `plugins.json`. See [`API Server/internal/plugins/README.md`](API%20Server/internal/plugins/README.md) for the developer guide. ## Per-surface docs - [API Server README](API%20Server/README.md) — full endpoint reference, panel, plugins - [Web App README](Web%20App/README.md) — BFF proxy, dev/build - [Fly App README](Fly%20App/README.md) — Flutter + DJI MSDK V4 native bridge