Overview of the PilotVault multi-service project: brand/design pointer, architecture diagram, surfaces table, PocketBase auth/org data model, run order (incl. Docker), telemetry lifecycle, and plugin system, with links to the per-surface READMEs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
117 lines
5.8 KiB
Markdown
117 lines
5.8 KiB
Markdown
# 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
|