-- =============================================
-- 智慧水务管理系统 - 报警规则引擎 + 报警管理中心 DDL
-- 版本: V2
-- =============================================

-- ==================== 报警规则定义 ====================
CREATE TABLE IF NOT EXISTS prod_alert_rule (
    id              BIGSERIAL PRIMARY KEY,
    rule_name       VARCHAR(100) NOT NULL,
    rule_code       VARCHAR(50) UNIQUE,
    description     TEXT,
    device_type     VARCHAR(30),
    metric_key      VARCHAR(50) NOT NULL,
    alert_level     VARCHAR(10) NOT NULL DEFAULT 'general',    -- general/important/urgent
    condition_expr  TEXT NOT NULL,                              -- JSON: {"op":"AND","conditions":[{"metric":"pressure","operator":">","threshold":0.8},...]}
    threshold_value DECIMAL(12,4),                              -- 简单阈值(向后兼容)
    debounce_sec    INT DEFAULT 300,
    notify_channels VARCHAR(200),                               -- 逗号分隔: sms,wechat,app,email
    notify_template VARCHAR(500),                               -- 通知模板
    enabled         SMALLINT DEFAULT 1,
    priority        INT DEFAULT 0,                              -- 规则优先级
    effective_start TIME,                                       -- 生效开始时间
    effective_end   TIME,                                       -- 生效结束时间
    created_by      BIGINT,
    updated_by      BIGINT,
    deleted         SMALLINT DEFAULT 0,
    created_time    TIMESTAMP DEFAULT NOW(),
    updated_time    TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE prod_alert_rule IS '报警规则定义表';
COMMENT ON COLUMN prod_alert_rule.alert_level IS '报警等级: general(一般)/important(重要)/urgent(紧急)';
COMMENT ON COLUMN prod_alert_rule.condition_expr IS '条件表达式JSON: 支持AND/OR组合条件';

-- ==================== 报警记录(全生命周期) ====================
CREATE TABLE IF NOT EXISTS prod_alert_record (
    id              BIGSERIAL PRIMARY KEY,
    rule_id         BIGINT REFERENCES prod_alert_rule(id),
    rule_name       VARCHAR(100),
    device_id       BIGINT,
    device_sn       VARCHAR(100),
    device_name     VARCHAR(200),
    area            VARCHAR(50),
    metric_key      VARCHAR(50) NOT NULL,
    metric_value    DECIMAL(12,4),
    threshold_value VARCHAR(50),
    alert_level     VARCHAR(10) NOT NULL DEFAULT 'general',
    title           VARCHAR(200),
    message         TEXT,
    -- 生命周期状态: 0=活跃 1=已确认 2=已派单 3=处理中 4=已处理 5=已归档
    status          INT DEFAULT 0,
    confirmed_by    BIGINT,
    confirmed_time  TIMESTAMP,
    dispatch_time   TIMESTAMP,
    assignee_id     BIGINT,
    assignee_name   VARCHAR(50),
    handler_id      BIGINT,
    handler_name    VARCHAR(50),
    handle_result   TEXT,
    handle_time     TIMESTAMP,
    archive_time    TIMESTAMP,
    archive_reason  VARCHAR(500),
    resolved_at     TIMESTAMP,
    created_time    TIMESTAMP DEFAULT NOW(),
    updated_time    TIMESTAMP DEFAULT NOW(),
    deleted         SMALLINT DEFAULT 0
);
COMMENT ON TABLE prod_alert_record IS '报警记录表(全生命周期)';
CREATE INDEX IF NOT EXISTS idx_alert_record_time ON prod_alert_record(created_time DESC);
CREATE INDEX IF NOT EXISTS idx_alert_record_device ON prod_alert_record(device_sn, created_time DESC);
CREATE INDEX IF NOT EXISTS idx_alert_record_status ON prod_alert_record(status);
CREATE INDEX IF NOT EXISTS idx_alert_record_level ON prod_alert_record(alert_level);
CREATE INDEX IF NOT EXISTS idx_alert_record_area ON prod_alert_record(area);

-- ==================== 报警通知记录 ====================
CREATE TABLE IF NOT EXISTS prod_alert_notification (
    id              BIGSERIAL PRIMARY KEY,
    alert_record_id BIGINT REFERENCES prod_alert_record(id),
    rule_id         BIGINT,
    channel         VARCHAR(30) NOT NULL,        -- sms/wechat/app/email
    recipient       VARCHAR(100) NOT NULL,       -- 接收人标识
    recipient_name  VARCHAR(50),
    title           VARCHAR(200),
    content         TEXT,
    status          INT DEFAULT 0,               -- 0=待发送 1=已发送 2=发送失败 3=已读
    send_time       TIMESTAMP,
    read_time       TIMESTAMP,
    retry_count     INT DEFAULT 0,
    error_msg       VARCHAR(500),
    created_time    TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE prod_alert_notification IS '报警通知记录表';
CREATE INDEX IF NOT EXISTS idx_alert_notif_record ON prod_alert_notification(alert_record_id);
CREATE INDEX IF NOT EXISTS idx_alert_notif_status ON prod_alert_notification(status);

-- ==================== 报警规则-设备关联(可选) ====================
CREATE TABLE IF NOT EXISTS prod_alert_rule_device (
    id              BIGSERIAL PRIMARY KEY,
    rule_id         BIGINT REFERENCES prod_alert_rule(id),
    device_id       BIGINT,
    device_sn       VARCHAR(100),
    area            VARCHAR(50),
    created_time    TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE prod_alert_rule_device IS '报警规则-设备/区域关联表';

-- ==================== 初始规则数据 ====================
INSERT INTO prod_alert_rule (rule_name, rule_code, metric_key, alert_level, condition_expr, threshold_value, debounce_sec, description, enabled) VALUES
('管网压力过高报警', 'RULE_PRESSURE_HIGH', 'pressure', 'urgent',
 '{"op":"AND","conditions":[{"metric":"pressure","operator":">","threshold":0.8}]}',
 0.8000, 300, '管网压力超过0.8MPa时触发紧急报警', 1),
('管网压力过低报警', 'RULE_PRESSURE_LOW', 'pressure', 'important',
 '{"op":"OR","conditions":[{"metric":"pressure","operator":"<","threshold":0.2}]}',
 0.2000, 300, '管网压力低于0.2MPa时触发重要报警', 1),
('水质浊度超标', 'RULE_TURBIDITY_HIGH', 'turbidity', 'urgent',
 '{"op":"AND","conditions":[{"metric":"turbidity","operator":">","threshold":1.0}]}',
 1.0000, 600, '水质浊度超过1.0NTU触发紧急报警', 1),
('余氯偏低报警', 'RULE_CHLORINE_LOW', 'residual_chlorine', 'general',
 '{"op":"AND","conditions":[{"metric":"residual_chlorine","operator":"<","threshold":0.1}]}',
 0.1000, 600, '余氯低于0.1mg/L触发一般报警', 1),
('流量异常波动', 'RULE_FLOW_ANOMALY', 'flow', 'important',
 '{"op":"OR","conditions":[{"metric":"flow","operator":">","threshold":100},{"metric":"flow","operator":"<","threshold":5}]}',
 NULL, 120, '流量异常偏高或偏低时触发报警', 1);
