correctly processing enforcements
This commit is contained in:
@@ -11,15 +11,15 @@
|
|||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use attune_common::{
|
use attune_common::{
|
||||||
models::{Enforcement, Event, Rule},
|
models::{Enforcement, EnforcementStatus, Event, Rule},
|
||||||
mq::{
|
mq::{
|
||||||
Consumer, EnforcementCreatedPayload, ExecutionRequestedPayload, MessageEnvelope, Publisher,
|
Consumer, EnforcementCreatedPayload, ExecutionRequestedPayload, MessageEnvelope, Publisher,
|
||||||
},
|
},
|
||||||
repositories::{
|
repositories::{
|
||||||
event::{EnforcementRepository, EventRepository},
|
event::{EnforcementRepository, EventRepository, UpdateEnforcementInput},
|
||||||
execution::{CreateExecutionInput, ExecutionRepository},
|
execution::{CreateExecutionInput, ExecutionRepository},
|
||||||
rule::RuleRepository,
|
rule::RuleRepository,
|
||||||
Create, FindById,
|
Create, FindById, Update,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,11 +144,40 @@ impl EnforcementProcessor {
|
|||||||
&rule,
|
&rule,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// Update enforcement status to Processed after successful execution creation
|
||||||
|
EnforcementRepository::update(
|
||||||
|
pool,
|
||||||
|
enforcement_id,
|
||||||
|
UpdateEnforcementInput {
|
||||||
|
status: Some(EnforcementStatus::Processed),
|
||||||
|
payload: None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
debug!("Updated enforcement {} status to Processed", enforcement_id);
|
||||||
} else {
|
} else {
|
||||||
info!(
|
info!(
|
||||||
"Skipping execution creation for enforcement: {}",
|
"Skipping execution creation for enforcement: {}",
|
||||||
enforcement_id
|
enforcement_id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Update enforcement status to Disabled since it was not actionable
|
||||||
|
EnforcementRepository::update(
|
||||||
|
pool,
|
||||||
|
enforcement_id,
|
||||||
|
UpdateEnforcementInput {
|
||||||
|
status: Some(EnforcementStatus::Disabled),
|
||||||
|
payload: None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Updated enforcement {} status to Disabled (skipped)",
|
||||||
|
enforcement_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -215,7 +244,8 @@ impl EnforcementProcessor {
|
|||||||
);
|
);
|
||||||
bail!(
|
bail!(
|
||||||
"Rule {} references a deleted action (action_ref: {})",
|
"Rule {} references a deleted action (action_ref: {})",
|
||||||
rule.id, rule.action_ref
|
rule.id,
|
||||||
|
rule.action_ref
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const NOTIFICATION_CHANNELS: &[&str] = &[
|
|||||||
"inquiry_created",
|
"inquiry_created",
|
||||||
"inquiry_responded",
|
"inquiry_responded",
|
||||||
"enforcement_created",
|
"enforcement_created",
|
||||||
|
"enforcement_status_changed",
|
||||||
"event_created",
|
"event_created",
|
||||||
"workflow_execution_status_changed",
|
"workflow_execution_status_changed",
|
||||||
];
|
];
|
||||||
@@ -167,6 +168,8 @@ mod tests {
|
|||||||
fn test_notification_channels_defined() {
|
fn test_notification_channels_defined() {
|
||||||
assert!(!NOTIFICATION_CHANNELS.is_empty());
|
assert!(!NOTIFICATION_CHANNELS.is_empty());
|
||||||
assert!(NOTIFICATION_CHANNELS.contains(&"execution_status_changed"));
|
assert!(NOTIFICATION_CHANNELS.contains(&"execution_status_changed"));
|
||||||
|
assert!(NOTIFICATION_CHANNELS.contains(&"enforcement_created"));
|
||||||
|
assert!(NOTIFICATION_CHANNELS.contains(&"enforcement_status_changed"));
|
||||||
assert!(NOTIFICATION_CHANNELS.contains(&"inquiry_created"));
|
assert!(NOTIFICATION_CHANNELS.contains(&"inquiry_created"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,47 @@ CREATE TRIGGER enforcement_created_notify
|
|||||||
|
|
||||||
COMMENT ON FUNCTION notify_enforcement_created() IS 'Sends enforcement creation notifications via PostgreSQL LISTEN/NOTIFY';
|
COMMENT ON FUNCTION notify_enforcement_created() IS 'Sends enforcement creation notifications via PostgreSQL LISTEN/NOTIFY';
|
||||||
|
|
||||||
|
-- Function to notify on enforcement status changes
|
||||||
|
CREATE OR REPLACE FUNCTION notify_enforcement_status_changed()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
DECLARE
|
||||||
|
payload JSON;
|
||||||
|
BEGIN
|
||||||
|
-- Only notify on updates when status actually changed
|
||||||
|
IF TG_OP = 'UPDATE' AND OLD.status IS DISTINCT FROM NEW.status THEN
|
||||||
|
payload := json_build_object(
|
||||||
|
'entity_type', 'enforcement',
|
||||||
|
'entity_id', NEW.id,
|
||||||
|
'id', NEW.id,
|
||||||
|
'rule', NEW.rule,
|
||||||
|
'rule_ref', NEW.rule_ref,
|
||||||
|
'trigger_ref', NEW.trigger_ref,
|
||||||
|
'event', NEW.event,
|
||||||
|
'status', NEW.status,
|
||||||
|
'old_status', OLD.status,
|
||||||
|
'condition', NEW.condition,
|
||||||
|
'conditions', NEW.conditions,
|
||||||
|
'config', NEW.config,
|
||||||
|
'payload', NEW.payload,
|
||||||
|
'created', NEW.created,
|
||||||
|
'updated', NEW.updated
|
||||||
|
);
|
||||||
|
|
||||||
|
PERFORM pg_notify('enforcement_status_changed', payload::text);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- Trigger on enforcement table for status changes
|
||||||
|
CREATE TRIGGER enforcement_status_changed_notify
|
||||||
|
AFTER UPDATE ON enforcement
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION notify_enforcement_status_changed();
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION notify_enforcement_status_changed() IS 'Sends enforcement status change notifications via PostgreSQL LISTEN/NOTIFY';
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- INQUIRY NOTIFICATIONS
|
-- INQUIRY NOTIFICATIONS
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ export function useEnforcementStream(
|
|||||||
// Extract enforcement data from notification payload (flat structure)
|
// Extract enforcement data from notification payload (flat structure)
|
||||||
const enforcementData = notification.payload as any;
|
const enforcementData = notification.payload as any;
|
||||||
|
|
||||||
|
// Invalidate history queries so the EntityHistoryPanel picks up new records
|
||||||
|
// (e.g. status changes recorded by the enforcement_history trigger)
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["history", "enforcement", notification.entity_id],
|
||||||
|
});
|
||||||
|
|
||||||
// Update specific enforcement query if it exists
|
// Update specific enforcement query if it exists
|
||||||
queryClient.setQueryData(
|
queryClient.setQueryData(
|
||||||
["enforcements", notification.entity_id],
|
["enforcements", notification.entity_id],
|
||||||
|
|||||||
Reference in New Issue
Block a user