mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
Introduce an operator-level ChatGPT-subscription (Codex) credential that the operator connects once and shares server-wide, plus a per-user switch to route AI egress through it. - Schema (migration 0235): three encrypted columns on AppSettings for the operator's central Codex access/refresh tokens and the ChatGPT-Account-ID claim, plus expiry/connected-at/status; a per-user useCentralCodex flag (default false). Register the new encrypted columns in the rotation registry and script. - Resolution: add the admin-codex chain type; append it to a user's resolved chain only when they opted in AND the operator connected it. Tokens refresh server-side against the singleton row (CAS-style), same primitives as the per-user Codex path. - Budget: bill an admin-codex primary against the operator cost cap, not the user plan — it drains the operator's account. - Consent: admin-codex is server-managed external egress, gated by the existing consent machinery (self-snapshot and document surfaces alike). No existing consent path is weakened. - Document order: rank admin-codex with the subscription tier (last), so the document class stays local-first. - UI: admin device-code connect/disconnect card (cookie-only admin routes) with honest copy on account pooling, shared rate limits, and training-by-default; a per-user opt-in switch shown only once the operator has connected it, off by default, behind a one-time honesty confirm. - i18n across all six locales; unit tests for the chain type, budget cap, consent gate, vision capability, and document order; a mocked e2e for both the admin connect surface and the per-user switch. The central credential's tokens are encrypted at rest and never returned to a non-admin API; the opt-in only takes effect once the operator has connected the shared account.
29 lines
1.5 KiB
SQL
29 lines
1.5 KiB
SQL
-- Operator-shared central Codex (ChatGPT subscription) OAuth + per-user opt-in.
|
|
--
|
|
-- The only operator-level AI credential so far has been an API key
|
|
-- (`app_settings.admin_ai_key_encrypted`). This adds an operator-level Codex
|
|
-- OAuth credential: the operator connects ONE signed-in ChatGPT account (the
|
|
-- same device-code flow the per-user `codex_*_encrypted` columns use) and shares
|
|
-- it server-wide. Each user opts in individually via `users.use_central_codex`.
|
|
--
|
|
-- All columns are additive and defaulted, so existing rows keep the current
|
|
-- behaviour (no central Codex, no user opted in) with no backfill. The three
|
|
-- token pieces are AES-256-GCM encrypted at rest, same crypto as every other
|
|
-- `*_encrypted` column, so the key-rotation script covers them.
|
|
--
|
|
-- Routing through the central Codex is external egress on a shared,
|
|
-- train-by-default consumer account bound by the operator's own rate limits.
|
|
-- It is consent-gated (server-managed provider) and billed against the operator
|
|
-- cost cap, never the user plan. OFF until the operator connects it.
|
|
|
|
ALTER TABLE "app_settings"
|
|
ADD COLUMN "admin_codex_access_token_encrypted" TEXT,
|
|
ADD COLUMN "admin_codex_refresh_token_encrypted" TEXT,
|
|
ADD COLUMN "admin_codex_account_id_encrypted" TEXT,
|
|
ADD COLUMN "admin_codex_token_expires_at" TIMESTAMP(3),
|
|
ADD COLUMN "admin_codex_connected_at" TIMESTAMP(3),
|
|
ADD COLUMN "admin_codex_connection_status" TEXT NOT NULL DEFAULT 'disconnected';
|
|
|
|
ALTER TABLE "users"
|
|
ADD COLUMN "use_central_codex" BOOLEAN NOT NULL DEFAULT false;
|