52 lines
2.5 KiB
SQL
52 lines
2.5 KiB
SQL
-- Additive, private server-side model registry. No credentials or production imports in migration.
|
|
CREATE TABLE ai_model_providers (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
base_url TEXT NOT NULL,
|
|
enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
credential_source TEXT NOT NULL CHECK (credential_source IN ('environment','encrypted')),
|
|
secret_ciphertext TEXT,
|
|
secret_nonce TEXT,
|
|
secret_auth_tag TEXT,
|
|
legacy_binding BOOLEAN NOT NULL DEFAULT FALSE,
|
|
revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0),
|
|
synced_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT ai_model_credential_complete CHECK (
|
|
(credential_source = 'environment' AND secret_ciphertext IS NULL AND secret_nonce IS NULL AND secret_auth_tag IS NULL)
|
|
OR (credential_source = 'encrypted' AND secret_ciphertext IS NOT NULL AND secret_nonce IS NOT NULL AND secret_auth_tag IS NOT NULL)
|
|
)
|
|
);
|
|
CREATE UNIQUE INDEX ai_model_providers_legacy_binding_key ON ai_model_providers (legacy_binding) WHERE legacy_binding = TRUE;
|
|
CREATE TABLE ai_model_catalog (
|
|
id TEXT PRIMARY KEY,
|
|
provider_id TEXT NOT NULL REFERENCES ai_model_providers(id) ON DELETE RESTRICT,
|
|
model_id TEXT NOT NULL,
|
|
enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
stages TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[] CHECK (stages <@ ARRAY['analysis','copy','image']::TEXT[]),
|
|
present BOOLEAN NOT NULL DEFAULT TRUE,
|
|
compatibility TEXT NOT NULL DEFAULT 'unconfirmed' CHECK (compatibility IN ('confirmed','unconfirmed')),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT ai_model_enabled_compatible CHECK (NOT enabled OR (cardinality(stages)>0 AND compatibility='confirmed')),
|
|
CONSTRAINT ai_model_catalog_provider_model_key UNIQUE(provider_id,model_id)
|
|
);
|
|
CREATE TABLE ai_model_configuration (
|
|
id TEXT PRIMARY KEY CHECK (id = 'detail-generator'),
|
|
default_analysis TEXT REFERENCES ai_model_catalog(id) ON DELETE RESTRICT,
|
|
default_copy TEXT REFERENCES ai_model_catalog(id) ON DELETE RESTRICT,
|
|
default_image TEXT REFERENCES ai_model_catalog(id) ON DELETE RESTRICT,
|
|
revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
CREATE TABLE ai_model_audit (
|
|
id TEXT PRIMARY KEY,
|
|
actor_id TEXT NOT NULL,
|
|
action TEXT NOT NULL,
|
|
provider_id TEXT,
|
|
details JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
CREATE INDEX ai_model_audit_created_idx ON ai_model_audit(created_at);
|