c091ad7aed
Stand up an internal ops-api service with operator account, auth, and audit log subsystems backed by a dedicated migrations_ops migration set. Wire Makefile targets and the migrate Dockerfile stage so the new schema ships alongside the existing tenant + monitoring databases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
1.5 KiB
SQL
49 lines
1.5 KiB
SQL
CREATE SCHEMA IF NOT EXISTS ops;
|
|
|
|
CREATE TABLE ops.operator_accounts (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
username VARCHAR(64) NOT NULL,
|
|
email VARCHAR(255),
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
display_name VARCHAR(100) NOT NULL,
|
|
role VARCHAR(32) NOT NULL DEFAULT 'admin',
|
|
status VARCHAR(20) NOT NULL DEFAULT 'active',
|
|
last_login_at TIMESTAMPTZ,
|
|
created_by BIGINT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE UNIQUE INDEX uk_ops_operator_username
|
|
ON ops.operator_accounts(username)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
CREATE UNIQUE INDEX uk_ops_operator_email
|
|
ON ops.operator_accounts(email)
|
|
WHERE email IS NOT NULL AND deleted_at IS NULL;
|
|
|
|
CREATE TABLE ops.audit_logs (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
operator_id BIGINT,
|
|
operator_name VARCHAR(100),
|
|
action VARCHAR(64) NOT NULL,
|
|
target_type VARCHAR(64),
|
|
target_id VARCHAR(128),
|
|
metadata JSONB,
|
|
ip VARCHAR(64),
|
|
user_agent TEXT,
|
|
request_id VARCHAR(64),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_ops_audit_created_at
|
|
ON ops.audit_logs(created_at DESC);
|
|
|
|
CREATE INDEX idx_ops_audit_operator
|
|
ON ops.audit_logs(operator_id, created_at DESC)
|
|
WHERE operator_id IS NOT NULL;
|
|
|
|
CREATE INDEX idx_ops_audit_action
|
|
ON ops.audit_logs(action, created_at DESC);
|