Files
platform/src/databases/officer_db/src/schema.ts
T
pastilhasandClaude Opus 5 52f209c69f caldav leaves the platform
calendar and contacts are a plugin now — plugins/caldav, its own repository like
every other one. a fresh machine runs five processes instead of seven and gets a
calendar by installing one plugin, which is the whole point: the platform stops
carrying a python calendar server for people who may not want one.

what left: the radicale sidecar, four routers, the panel apps, the
dav_app_passwords table, the two screens, the two dock tiles, the permission
registry entry, the settings section, and radicale from every package list.

three platform things had to change first, each committed on its own:
6b5c87da a plugin can be more than one screen; e0df28ff a first-party plugin can
claim a reserved root path. this commit adds the third, `personal` on a plugin
permission — a member granted READ must still mint and revoke their own app
password, because that password is how their own phone reaches their own
calendar. those rows are theirs and nobody else's.

two fixes the work surfaced rather than caused. the dock pinned mountPrefix, so
a multi-screen plugin pinned a tile pointing at /caldav — a route no plugin
serves. and the OPTIONS carve-out was a literal list of four DAV paths; it asks
the claim registry now, so it follows whoever owns the route.

/calendar stays in DEFAULT_DOCK_PATHS. it is installed by default and a fresh
dock that silently dropped it would read as a downgrade.

docs:check earned its keep twice here: it caught spotlight still offering
/settings/integrations/dav-app-passwords after the section was deleted, and the
permission count going 22 -> 21. neither is greppable and both were already wrong
when it ran.

verified against alpha, which is still on the pre-extraction code: /.well-known/
caldav 301s, /dav/ answers 401 with the same WWW-Authenticate realm byte for
byte, /api/caldav/passwords 401s, and OPTIONS reaches the DAV router rather than
being answered as a CORS preflight. installed here end to end — schema applied,
sidecar started, two tiles with their own artwork behind one permission.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
2026-08-27 04:54:42 +00:00

71 lines
5.0 KiB
TypeScript

// What `db:push` creates.
//
// This barrel is drizzle-kit's view of the schema — `drizzle.config.ts` points `schema` straight at
// this file. It is NOT the runtime's view: every query imports its table object from the schema file
// directly and calls `db.select().from(table)`, and nothing uses drizzle's relational API (`db.query.X`),
// which is the only thing the `schema` passed to `drizzle()` in db.ts is for.
//
// So a commented line here removes a table from the DATABASE without removing a line of code. That is
// deliberate and it is what makes the split below possible.
//
// ── Core, and plugins ──
//
// A fresh install creates the core tables only. Everything under "plugins" belongs to a sidecar a
// baseline install does not run.
//
// A plugin's tables are NOT among them any more: a plugin owns its schema at
// `plugins/<name>/db/schema.ts`, and installing it regenerates `plugin-schemas.gen.ts` (imported at the
// bottom of this file) and runs `db:push`. Offscale was the first out, on 2026-08-15.
//
// The commented lines below are kept rather than deleted. They record what each remaining sidecar's
// tables are called and which file defines them — which is exactly what each one needs when its turn to
// be extracted comes.
// ── Core ─────────────────────────────────────────────────────────────────────────────────────────
export * from './auth/schema'; // users, passkeys, passkey_challenges, token_blacklist
export * from './permissions/schema'; // role_permissions — what each ROLE may reach
export * from './api-keys/schema'; // api_keys
export * from './user-data/schema'; // user_settings, user_state, user_integrations, dock_configs
export * from './dashboards/schema'; // dashboards, screens, dashboard_defaults
export * from './server/schema'; // server_config (SMTP lives here), server_integrations
export * from './pipeline-jobs/schema'; // pipeline_jobs
export * from './chat-events/schema'; // chat_session_events
export * from './chat-session-models/schema'; // chat_session_models
export * from './chat-notification-prefs/schema'; // chat_notification_prefs
export * from './ai-provider-usage/schema'; // ai_provider_usage — last usage reading per AI account
export * from './anthropic-accounts/schema'; // anthropic_accounts — switchable OAuth credentials
export * from './theme-favorites/schema'; // theme_favorites — starred themes, per account
export * from './command-hq/schema'; // command_hq_categories, command_hq_sessions, command_hq_tags, command_hq_session_tags
export * from './sendoff/schema'; // sendoff_devices, sendoff_senders
export * from './roles/schema'; // roles
export * from './agent-panels/schema'; // agent_panels
// Core because the tailnet is the perimeter — a security model resting on it cannot treat administering
// The app store itself, and the credentials it stores for what it installs. `app-store/effects.ts`
// reads service_connections, so this is core however few plugins are installed.
export * from './app-store/schema'; // sidecar_installs
export * from './plugins/schema'; // plugin_installs — core: the plugin system is the platform's own
export * from './service-connections/schema'; // service_connections
export * from './notify/schema'; // push_devices — core since 2026-08-19, see docs/push-notifications.md
export * from './nudges/schema'; // nudges — the Nudger schedule
// ── Plugins — nothing here ───────────────────────────────────────────────────────────────────────
//
// `dav_app_passwords` was the last entry and it left with caldav on 2026-08-27. A plugin's tables are
// generated into `drizzle-schema.ts` from the plugin's own `db/schema.ts` when it is installed, which is
// what this hand-maintained line was standing in for while caldav was core.
// ── Plugin tables are NOT here ───────────────────────────────────────────────────────────────────
//
// They live in `drizzle-schema.ts`, which re-exports this file and adds the generated barrel. That file
// is drizzle-kit's entry; this one is the runtime's, and the split exists because the barrel names plugin
// directories that may not be on this machine. Importing it here put a file that is ALLOWED to be wrong
// into the module graph of the process that must always start — and on 2026-08-16 it stopped a server
// booting after a pull deleted `plugins/`. See `drizzle-schema.ts`.
//
// The barrel still follows DIRECTORIES rather than installs: push drops what it cannot see, so tracking
// installs would delete a plugin's tables on uninstall. Following the directory means uninstall keeps
// every row and only deleting a plugin's source can lose data.