Files
Containr/app/backend/migrations_goose/20260922000000_app_settings.sql
T
Tomas DvorakandDevin c16b32f56a feat: owner accounts and in-app platform settings
- First registered account becomes admin (users.is_admin, backfilled
  to earliest account); better-auth mirror path does the same
- Public registration closes after bootstrap; admin can reopen it via
  GET/PUT /api/v1/settings (admin-gated) or SIGNUP_ENABLED env
- In-app settings override env vars; secrets stored in app_settings,
  token values never returned by the API
- Saving a Cloudflare Tunnel token pulls and runs a managed
  cloudflared sidecar on the backend's networks; clearing removes it;
  startup restores it from saved settings
- group_add DOCKER_GID grants the non-root backend user Docker socket
  access; install.sh probes the in-container socket gid
- Settings page gains an owner-only Platform section (registration
  toggle, tunnel token, link to Cloudflare dashboard); sign-up page
  stays reachable while registration is open
- OpenAPI spec + generated types updated; manual user creation now
  requires admin

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 18:05:22 +02:00

25 lines
939 B
SQL

-- +goose Up
-- In-app platform settings. Values here override environment variables;
-- secrets (e.g. Cloudflare tunnel token) are flagged and masked in API reads.
CREATE TABLE IF NOT EXISTS public.app_settings (
key character varying(255) PRIMARY KEY,
value text NOT NULL DEFAULT '',
is_secret boolean NOT NULL DEFAULT false,
updated_at timestamp with time zone NOT NULL DEFAULT now()
);
ALTER TABLE public.users ADD COLUMN IF NOT EXISTS is_admin boolean NOT NULL DEFAULT false;
-- The first registered user owns the platform. Backfill existing installs:
-- the earliest account becomes admin when no admin is set.
UPDATE public.users
SET is_admin = true
WHERE id = (
SELECT id FROM public.users ORDER BY created_at ASC, id ASC LIMIT 1
)
AND NOT EXISTS (SELECT 1 FROM public.users WHERE is_admin);
-- +goose Down
ALTER TABLE public.users DROP COLUMN IF EXISTS is_admin;
DROP TABLE IF EXISTS public.app_settings;