Files
configcenter/internal/store/postgres/migrations/001_init.sql

135 lines
5.3 KiB
SQL

CREATE TABLE IF NOT EXISTS applications (
id BIGSERIAL PRIMARY KEY,
app_code VARCHAR(64) UNIQUE NOT NULL,
name VARCHAR(128) NOT NULL,
department VARCHAR(128) NOT NULL DEFAULT '',
owner VARCHAR(64) NOT NULL DEFAULT '',
description TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS environments (
id BIGSERIAL PRIMARY KEY,
env_code VARCHAR(32) UNIQUE NOT NULL,
name VARCHAR(64) NOT NULL,
sort_order INT NOT NULL DEFAULT 0,
description TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS namespaces (
id BIGSERIAL PRIMARY KEY,
app_id BIGINT NOT NULL REFERENCES applications(id) ON DELETE CASCADE,
name VARCHAR(64) NOT NULL,
format VARCHAR(16) NOT NULL DEFAULT 'properties',
description TEXT NOT NULL DEFAULT '',
UNIQUE(app_id, name),
CONSTRAINT namespaces_format_check CHECK (format IN ('properties', 'yaml', 'json', 'xml'))
);
CREATE TABLE IF NOT EXISTS config_items (
id BIGSERIAL PRIMARY KEY,
namespace_id BIGINT NOT NULL REFERENCES namespaces(id) ON DELETE CASCADE,
env_id BIGINT NOT NULL REFERENCES environments(id) ON DELETE CASCADE,
key VARCHAR(256) NOT NULL,
value TEXT NOT NULL,
released_value TEXT,
pending_delete BOOLEAN NOT NULL DEFAULT false,
comment TEXT NOT NULL DEFAULT '',
updated_by VARCHAR(64) NOT NULL DEFAULT 'admin',
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE(namespace_id, env_id, key)
);
CREATE TABLE IF NOT EXISTS releases (
id BIGSERIAL PRIMARY KEY,
namespace_id BIGINT NOT NULL REFERENCES namespaces(id) ON DELETE CASCADE,
env_id BIGINT NOT NULL REFERENCES environments(id) ON DELETE CASCADE,
version INT NOT NULL,
snapshot JSONB NOT NULL,
diff_added INT NOT NULL DEFAULT 0,
diff_modified INT NOT NULL DEFAULT 0,
diff_removed INT NOT NULL DEFAULT 0,
comment TEXT NOT NULL DEFAULT '',
operator VARCHAR(64) NOT NULL,
etcd_revision BIGINT,
status VARCHAR(16) NOT NULL DEFAULT 'pending',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE(namespace_id, env_id, version),
CONSTRAINT releases_status_check CHECK (status IN ('pending', 'applied', 'failed'))
);
CREATE TABLE IF NOT EXISTS release_outbox (
id BIGSERIAL PRIMARY KEY,
release_id BIGINT NOT NULL REFERENCES releases(id) ON DELETE CASCADE,
etcd_key VARCHAR(512) NOT NULL,
payload JSONB NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'pending',
retry_count INT NOT NULL DEFAULT 0,
last_error TEXT NOT NULL DEFAULT '',
next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT now(),
locked_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT outbox_status_check CHECK (status IN ('pending', 'processing', 'done', 'failed'))
);
CREATE INDEX IF NOT EXISTS release_outbox_poll_idx
ON release_outbox(status, next_attempt_at, id);
CREATE INDEX IF NOT EXISTS releases_scope_idx
ON releases(namespace_id, env_id, version DESC);
CREATE INDEX IF NOT EXISTS config_items_scope_idx
ON config_items(namespace_id, env_id, key);
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
username VARCHAR(64) UNIQUE NOT NULL,
password_hash VARCHAR(256) NOT NULL,
display_name VARCHAR(64) NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS roles (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(32) UNIQUE NOT NULL
);
CREATE TABLE IF NOT EXISTS user_app_roles (
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
app_id BIGINT NOT NULL REFERENCES applications(id) ON DELETE CASCADE,
role_id BIGINT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
PRIMARY KEY (user_id, app_id)
);
CREATE TABLE IF NOT EXISTS audit_logs (
id BIGSERIAL PRIMARY KEY,
actor VARCHAR(64) NOT NULL,
action VARCHAR(32) NOT NULL,
target_type VARCHAR(32) NOT NULL,
target_id BIGINT,
detail JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS audit_logs_created_idx ON audit_logs(created_at DESC);
CREATE TABLE IF NOT EXISTS gray_rules (
id BIGSERIAL PRIMARY KEY,
namespace_id BIGINT NOT NULL REFERENCES namespaces(id) ON DELETE CASCADE,
env_id BIGINT NOT NULL REFERENCES environments(id) ON DELETE CASCADE,
rule_type VARCHAR(16) NOT NULL,
rule_value JSONB NOT NULL,
overrides JSONB NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
INSERT INTO environments(env_code, name, sort_order, description) VALUES
('DEV', '开发环境', 1, '开发联调使用'),
('TEST', '测试环境', 2, 'QA 测试验证'),
('STAGING', '预发环境', 3, '上线前灰度验证'),
('PROD', '生产环境', 4, '线上正式环境')
ON CONFLICT (env_code) DO NOTHING;
INSERT INTO roles(name) VALUES ('admin'), ('app-owner'), ('viewer')
ON CONFLICT (name) DO NOTHING;