bmc_hub/migrations/1001_alert_notes_system.sql

103 lines
4.3 KiB
MySQL
Raw Permalink Normal View History

-- Migration 1001: Alert Notes System
-- Description: Contextual popup/info system for customers and contacts
-- Date: 2026-02-17
-- Alert Notes main table
CREATE TABLE IF NOT EXISTS alert_notes (
id SERIAL PRIMARY KEY,
entity_type VARCHAR(20) NOT NULL CHECK (entity_type IN ('customer', 'contact')),
entity_id INTEGER NOT NULL,
title VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
severity VARCHAR(20) NOT NULL DEFAULT 'info' CHECK (severity IN ('info', 'warning', 'critical')),
requires_acknowledgement BOOLEAN DEFAULT TRUE,
active BOOLEAN DEFAULT TRUE,
created_by_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Alert Note Restrictions (who is allowed to handle the customer/contact)
-- Supports both group-based and user-based restrictions
CREATE TABLE IF NOT EXISTS alert_note_restrictions (
id SERIAL PRIMARY KEY,
alert_note_id INTEGER NOT NULL REFERENCES alert_notes(id) ON DELETE CASCADE,
restriction_type VARCHAR(20) NOT NULL CHECK (restriction_type IN ('group', 'user')),
restriction_id INTEGER NOT NULL,
-- restriction_id references either groups.id or users.user_id depending on restriction_type
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(alert_note_id, restriction_type, restriction_id)
);
-- Alert Note Acknowledgements (tracking who has seen and acknowledged alerts)
CREATE TABLE IF NOT EXISTS alert_note_acknowledgements (
id SERIAL PRIMARY KEY,
alert_note_id INTEGER NOT NULL REFERENCES alert_notes(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
acknowledged_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(alert_note_id, user_id)
);
-- Create indexes for performance
CREATE INDEX IF NOT EXISTS idx_alert_notes_entity ON alert_notes(entity_type, entity_id);
CREATE INDEX IF NOT EXISTS idx_alert_notes_active ON alert_notes(active) WHERE active = TRUE;
CREATE INDEX IF NOT EXISTS idx_alert_notes_severity ON alert_notes(severity);
CREATE INDEX IF NOT EXISTS idx_alert_notes_created_by ON alert_notes(created_by_user_id);
CREATE INDEX IF NOT EXISTS idx_alert_note_restrictions_alert ON alert_note_restrictions(alert_note_id);
CREATE INDEX IF NOT EXISTS idx_alert_note_acknowledgements_alert ON alert_note_acknowledgements(alert_note_id);
CREATE INDEX IF NOT EXISTS idx_alert_note_acknowledgements_user ON alert_note_acknowledgements(user_id);
-- Trigger to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_alert_notes_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_update_alert_notes_updated_at
BEFORE UPDATE ON alert_notes
FOR EACH ROW
EXECUTE FUNCTION update_alert_notes_updated_at();
-- Add alert_notes permissions
INSERT INTO permissions (code, description, category) VALUES
('alert_notes.view', 'View alert notes', 'alert_notes'),
('alert_notes.create', 'Create alert notes', 'alert_notes'),
('alert_notes.edit', 'Edit alert notes', 'alert_notes'),
('alert_notes.delete', 'Delete alert notes', 'alert_notes'),
('alert_notes.manage', 'Full management of alert notes', 'alert_notes')
ON CONFLICT (code) DO NOTHING;
-- Assign all alert_notes permissions to Administrators group
INSERT INTO group_permissions (group_id, permission_id)
SELECT g.id, p.id
FROM groups g
CROSS JOIN permissions p
WHERE g.name = 'Administrators' AND p.category = 'alert_notes'
ON CONFLICT DO NOTHING;
-- Assign create, edit permissions to Managers group
INSERT INTO group_permissions (group_id, permission_id)
SELECT g.id, p.id
FROM groups g
CROSS JOIN permissions p
WHERE g.name = 'Managers' AND p.code IN (
'alert_notes.view', 'alert_notes.create', 'alert_notes.edit'
)
ON CONFLICT DO NOTHING;
-- Assign view permission to all other groups (Technicians, Viewers)
INSERT INTO group_permissions (group_id, permission_id)
SELECT g.id, p.id
FROM groups g
CROSS JOIN permissions p
WHERE g.name IN ('Technicians', 'Viewers') AND p.code = 'alert_notes.view'
ON CONFLICT DO NOTHING;
-- Verify migration
SELECT 'Alert Notes system created successfully' AS status,
(SELECT COUNT(*) FROM alert_notes) AS alert_notes_count,
(SELECT COUNT(*) FROM permissions WHERE category = 'alert_notes') AS permissions_count;