///|
/// A stable report model suitable for a CLI or service adapter.
pub(all) struct MonitoringReport {
transaction_summary : TransactionSummary
alert_count : Int
high_risk_count : Int
cases : Int
invalid_records : Int
}
///|
pub fn build_report(
rules : Array[Rule],
transactions : Array[Transaction],
) -> MonitoringReport {
let alerts = evaluate(rules, transactions)
let cases = group_cases(alerts)
let scores = aggregate_scores(alerts)
let mut high = 0
for score in scores {
if score.total >= 70 {
high += 1
}
}
{
transaction_summary: summarize(transactions),
alert_count: alerts.length(),
high_risk_count: high,
cases: cases.length(),
invalid_records: validate_batch(transactions).length(),
}
}
///|
pub fn report_is_consistent(report : MonitoringReport) -> Bool {
report.alert_count >= 0 &&
report.high_risk_count >= 0 &&
report.cases >= 0 &&
report.invalid_records >= 0 &&
report.high_risk_count <= report.alert_count
}
///|
pub fn risk_band_name(severity : AlertSeverity) -> String {
match severity {
Info => "info"
Low => "low"
Medium => "medium"
High => "high"
Critical => "critical"
}
}
///|
pub fn status_name(status : AlertStatus) -> String {
match status {
Open => "open"
Triaged => "triaged"
Escalated => "escalated"
Resolved => "resolved"
Dismissed => "dismissed"
}
}
///|
pub fn summarize_alerts(alerts : Array[Alert]) -> Array[String] {
let result : Array[String] = []
for alert in alerts {
result.push(
"rule=\{alert.rule_id};transaction=\{alert.transaction_id};status=\{status_name(alert.status)}",
)
}
result
}