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>
80 lines
3.8 KiB
Markdown
80 lines
3.8 KiB
Markdown
# PocketBase — PilotVault schema
|
|
|
|
PilotVault adds an `organizations` collection and three fields to the `users`
|
|
auth collection:
|
|
|
|
- **`preferences`** (JSON) — each user's settings blob. Written with the user's
|
|
own token, so PocketBase's default owner-only update rule
|
|
(`@request.auth.id = id`) is all the authorization needed.
|
|
- **`role`** (select: `superadmin` | `admin` | `user`) — the user-rights level.
|
|
A **superadmin** spans every organization; an **admin** is scoped to their own
|
|
organization (may manage its users *and* admins, but not superadmins); a
|
|
**user** has no management rights. Missing/empty is treated as `user`.
|
|
- **`organization`** (relation → `organizations`, maxSelect 1, optional) — which
|
|
org the user belongs to. Nullable: a user may belong to **no** organization.
|
|
|
|
The **`organizations`** collection is a plain base collection with a unique
|
|
`name`. It is reached only through the API Server's superuser service account
|
|
(its API rules stay locked to superusers), the same way user management works.
|
|
|
|
## User + org management requires a service account
|
|
|
|
Listing/creating/deleting users and organizations is done by the API Server
|
|
using a **superuser service account** (`POCKETBASE_ADMIN_EMAIL` /
|
|
`POCKETBASE_ADMIN_PASSWORD`), but only *after* verifying the caller's own token
|
|
resolves to a manager role (`admin` for user management, `superadmin` for org
|
|
management). This is the single place the server uses elevated PocketBase
|
|
credentials; without the env vars, the `/api/users` and `/api/orgs` endpoints
|
|
return 503 and the rest is unaffected.
|
|
|
|
Preferences never need the service account — they use the caller's own token.
|
|
|
|
## Add the schema
|
|
|
|
Pick **one** of the following.
|
|
|
|
### Option A — migration (recommended)
|
|
|
|
Copy the migration files into your PocketBase deployment's `pb_migrations/`
|
|
directory and restart PocketBase (migrations run automatically on boot; they
|
|
target the PocketBase v0.22+/v0.23 JS migration API). They are idempotent, so
|
|
they are safe even if the schema was already provisioned live:
|
|
|
|
- [`pb_migrations/1720300000_add_users_preferences.js`](pb_migrations/1720300000_add_users_preferences.js)
|
|
- [`pb_migrations/1720300100_add_users_role.js`](pb_migrations/1720300100_add_users_role.js)
|
|
- [`pb_migrations/1720300200_add_organizations.js`](pb_migrations/1720300200_add_organizations.js)
|
|
- [`pb_migrations/1720300300_add_users_organization.js`](pb_migrations/1720300300_add_users_organization.js)
|
|
- [`pb_migrations/1720300400_extend_users_role_superadmin.js`](pb_migrations/1720300400_extend_users_role_superadmin.js)
|
|
- [`pb_migrations/1720300500_seed_orgs_and_users.js`](pb_migrations/1720300500_seed_orgs_and_users.js) — seeds the PilotVault org + baseline accounts
|
|
|
|
### Option B — Admin UI (any version)
|
|
|
|
1. Open the PocketBase Admin UI → **Collections → New collection** `organizations`
|
|
(base); add a **text** field **`name`** (required) with a unique index.
|
|
2. **Collections → `users` → New field.** Add **JSON** field **`preferences`**,
|
|
not required, max size ~5 MB.
|
|
3. Add **Select** field **`role`**, values `superadmin`, `admin`, `user`, max select 1.
|
|
4. Add **Relation** field **`organization`** → `organizations`, max select 1, not
|
|
required, cascade delete off.
|
|
5. Save.
|
|
|
|
## Verify
|
|
|
|
With a normal user token you should be able to round-trip the field:
|
|
|
|
```bash
|
|
# 1) log in (PocketBase directly, or via the API Server /api/auth/login)
|
|
TOKEN=... # the "token" from the auth response
|
|
|
|
# 2) save
|
|
curl -X PATCH "$PB_URL/api/collections/users/records/$USER_ID" \
|
|
-H "Authorization: $TOKEN" -H "Content-Type: application/json" \
|
|
-d '{"preferences":{"fontSize":"lg","themeMode":"dark"}}'
|
|
|
|
# 3) read back
|
|
curl "$PB_URL/api/collections/users/auth-refresh" -X POST -H "Authorization: $TOKEN"
|
|
```
|
|
|
|
In the app the round-trip is: browser → `GET/PUT /bff/preferences` → API Server
|
|
`GET/PUT /api/preferences` → PocketBase user record.
|