-- Create users table CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username VARCHAR(255) UNIQUE NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, role VARCHAR(50) NOT NULL CHECK (role IN ('admin', 'editor', 'analyst', 'viewer')), is_active BOOLEAN DEFAULT true, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); -- Create index on username and email for faster lookups CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_role ON users(role); -- Create alert_rules table CREATE TABLE IF NOT EXISTS alert_rules ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, group_name VARCHAR(255) NOT NULL, type VARCHAR(50) NOT NULL CHECK (type IN ('alert', 'record')), expression TEXT NOT NULL, duration VARCHAR(50), labels JSONB DEFAULT '{}', annotations JSONB DEFAULT '{}', severity VARCHAR(50), enabled BOOLEAN DEFAULT true, yaml_content TEXT NOT NULL, created_by UUID REFERENCES users(id) ON DELETE SET NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); -- Create indexes for alert_rules CREATE INDEX idx_alert_rules_group_name ON alert_rules(group_name); CREATE INDEX idx_alert_rules_enabled ON alert_rules(enabled); CREATE INDEX idx_alert_rules_created_by ON alert_rules(created_by); -- Create patterns table CREATE TABLE IF NOT EXISTS patterns ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, type VARCHAR(50) NOT NULL CHECK (type IN ('regex', 'ml')), description TEXT, config JSONB NOT NULL, severity VARCHAR(50), tags TEXT[], enabled BOOLEAN DEFAULT true, created_by UUID REFERENCES users(id) ON DELETE SET NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); -- Create indexes for patterns CREATE INDEX idx_patterns_type ON patterns(type); CREATE INDEX idx_patterns_enabled ON patterns(enabled); CREATE INDEX idx_patterns_created_by ON patterns(created_by); -- Create reports table CREATE TABLE IF NOT EXISTS reports ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, config JSONB NOT NULL, created_by UUID REFERENCES users(id) ON DELETE SET NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); -- Create index for reports CREATE INDEX idx_reports_created_by ON reports(created_by); -- Create audit_logs table for tracking sensitive operations CREATE TABLE IF NOT EXISTS audit_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE SET NULL, action VARCHAR(255) NOT NULL, resource_type VARCHAR(100), resource_id UUID, details JSONB, ip_address INET, user_agent TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); -- Create indexes for audit_logs CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id); CREATE INDEX idx_audit_logs_action ON audit_logs(action); CREATE INDEX idx_audit_logs_created_at ON audit_logs(created_at); -- Create function to update updated_at timestamp CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ language 'plpgsql'; -- Create triggers for updated_at CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); CREATE TRIGGER update_alert_rules_updated_at BEFORE UPDATE ON alert_rules FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); CREATE TRIGGER update_patterns_updated_at BEFORE UPDATE ON patterns FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); CREATE TRIGGER update_reports_updated_at BEFORE UPDATE ON reports FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- Insert default admin user (password: admin123 - CHANGE IN PRODUCTION!) -- Password hash is bcrypt hash of "admin123" INSERT INTO users (username, email, password_hash, role) VALUES ( 'admin', 'admin@example.com', '$2a$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5lW.HKCFcVpSK', 'admin' ) ON CONFLICT (username) DO NOTHING; -- Insert sample viewer user (password: viewer123) INSERT INTO users (username, email, password_hash, role) VALUES ( 'viewer', 'viewer@example.com', '$2a$12$3pYKzLw9z1FqN8QdKxI.J.nVZY5TqJxM7Y.qQHkZKZhzJ8qQnPZ8W', 'viewer' ) ON CONFLICT (username) DO NOTHING;