135 lines
5.3 KiB
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;
|