-- Kundencenter-Lizenzierung (Meilenstein #113-#117): eigenes Lizenzsystem-Konto (licensing.flessinglabs.com), -- nicht zu verwechseln mit dem bestehenden "licensing"-Connector (der verwaltet KUNDEN-Lizenzen, die das -- Kundencenter weiterverkauft). Dies hier ist die Lizenz der Kundencenter-Installation selbst. CREATE TABLE license_state ( id TINYINT PRIMARY KEY DEFAULT 1, license_key_enc TEXT NULL, -- verschlüsselt (wie andere Secrets), vom Betreiber selbst eingetragen instance_id CHAR(36) NOT NULL, -- einmal erzeugt, bleibt stabil (zählt sonst als neues Gerät) -- zuletzt erfolgreich geprüfter (und signaturgeprüfter) Entitlement-Snapshot valid BOOLEAN NULL, message VARCHAR(300) NULL, plan VARCHAR(100) NULL, modules_json JSON NULL, expires_at DATETIME NULL, user_limit INT NULL, customer_limit INT NULL, entitlement_version INT NULL, is_trial BOOLEAN NOT NULL DEFAULT FALSE, addons_json JSON NULL, server_time DATETIME NULL, checked_at DATETIME(3) NULL, -- Zeitpunkt der letzten ERFOLGREICHEN Online-Prüfung (Basis fürs Offline-Fenster) last_attempt_at DATETIME(3) NULL, last_error VARCHAR(500) NULL, updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) ); INSERT INTO license_state (id, instance_id) VALUES (1, UUID()); -- Öffentliche Signaturschlüssel (GET /license/signing-keys), lokal zwischengespeichert statt bei jeder Prüfung -- abgerufen - sonst könnte ein kompromittierter/vorgetäuschter Server zu einer gefälschten Antwort auch gleich -- einen passenden Schlüssel mitliefern. Werden nur ergänzt, nie anhand der Liste selbst gelöscht. CREATE TABLE license_signing_keys ( kid VARCHAR(100) PRIMARY KEY, alg VARCHAR(20) NOT NULL, n_hex TEXT NOT NULL, e_hex VARCHAR(20) NOT NULL, status VARCHAR(20) NOT NULL, fetched_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) );