Files
tajniak81andClaude Opus 4.8 afc6952eda Initial commit: PilotVault multi-service project
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>
2026-07-13 11:43:33 +02:00

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.