diff --git a/CHANGELOG.md b/CHANGELOG.md index 6269cd9..e0e7cb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Cluster-Migration fuer Proxmox-Verbindungen mit `encrypted_token bytea` angelegt. - Projekte-und-Quotas-Migration mit Defaults und Constraints angelegt. - Kern-Tabellen-Migration fuer `profiles`, `tenants` und `memberships` angelegt. - `golang-migrate`-Setup mit Baseline-Migration und Make-Targets fuer Up/Down/Version angelegt. diff --git a/TODO.md b/TODO.md index 9b61866..24d409e 100644 --- a/TODO.md +++ b/TODO.md @@ -44,6 +44,11 @@ Arbeitsliste auf Basis von `proxmox-console-entwicklungsplan.md`. Die Entwurfsda - [x] Projekte referenzieren eindeutig einen Tenant - [x] Quotas referenzieren 1:1 ein Projekt und erhalten Defaults - [x] Quota-Checks fuer nicht-negative Werte gesetzt +- [x] E2-T04: Clusters-Tabelle fuer verschluesselte Credentials + - [x] Migration fuer `clusters` angelegt + - [x] `encrypted_token` als `bytea` ohne Klartext-Token-Spalte angelegt + - [x] `token_id`, `api_endpoint`, `tls_fingerprint`, Status und Zeitstempel angelegt + - [x] Checks und Indizes fuer Endpoint/Status gesetzt ## MVP-Backlog @@ -85,3 +90,4 @@ Arbeitsliste auf Basis von `proxmox-console-entwicklungsplan.md`. Die Entwurfsda - 2026-06-10: `golang-migrate`-Setup mit Baseline-Migration angelegt; lokaler Up/Down-Lauf gegen Supabase verifiziert. - 2026-06-10: Kern-Tabellen-Migration `0002_core_identity` angelegt und lokal gegen Supabase verifiziert. - 2026-06-10: Projekte-und-Quotas-Migration `0003_projects_and_quotas` angelegt und lokal gegen Supabase verifiziert. +- 2026-06-10: Cluster-Migration `0004_clusters` angelegt und lokal gegen Supabase verifiziert. diff --git a/migrations/0004_clusters.down.sql b/migrations/0004_clusters.down.sql new file mode 100644 index 0000000..7f331a1 --- /dev/null +++ b/migrations/0004_clusters.down.sql @@ -0,0 +1,4 @@ +DROP INDEX IF EXISTS public.clusters_status_idx; +DROP INDEX IF EXISTS public.clusters_api_endpoint_key; +DROP TABLE IF EXISTS public.clusters; +DROP TYPE IF EXISTS public.cluster_status; diff --git a/migrations/0004_clusters.up.sql b/migrations/0004_clusters.up.sql new file mode 100644 index 0000000..654b107 --- /dev/null +++ b/migrations/0004_clusters.up.sql @@ -0,0 +1,20 @@ +CREATE TYPE public.cluster_status AS ENUM ('active', 'disabled', 'error'); + +CREATE TABLE public.clusters ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + name text NOT NULL, + api_endpoint text NOT NULL, + tls_fingerprint text, + encrypted_token bytea NOT NULL, + token_id text NOT NULL, + status public.cluster_status NOT NULL DEFAULT 'active', + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + CONSTRAINT clusters_name_not_blank_check CHECK (btrim(name) <> ''), + CONSTRAINT clusters_api_endpoint_not_blank_check CHECK (btrim(api_endpoint) <> ''), + CONSTRAINT clusters_token_id_not_blank_check CHECK (btrim(token_id) <> ''), + CONSTRAINT clusters_api_endpoint_protocol_check CHECK (api_endpoint ~ '^https://') +); + +CREATE UNIQUE INDEX clusters_api_endpoint_key ON public.clusters (api_endpoint); +CREATE INDEX clusters_status_idx ON public.clusters (status);