Skip to main content

minco_interaction/
activity.rs

1use minco_plugin_audit::{AuditEvent, AuditService};
2use minco_plugin_events::{DomainEvent, EventServices, OutboxRecord};
3use minco_plugin_notifications::{Notification, NotificationService};
4use serde::{Deserialize, Serialize};
5
6/// Stable public warning emitted by the explicitly post-commit recorder.
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub struct PostCommitActivityWarning {
9    pub code: String,
10    pub detail: String,
11}
12
13/// Compatibility helper for best-effort work after an operational commit.
14///
15/// This helper does not provide transactional audit durability. An adapter may
16/// claim that only when it atomically commits the mutation and local audit or
17/// outbox intent in its own store transaction.
18#[derive(Debug, Clone)]
19pub struct PostCommitActivityRecorder {
20    pub audit: AuditService,
21    pub events: EventServices,
22    pub notifications: NotificationService,
23}
24
25impl PostCommitActivityRecorder {
26    pub async fn record(
27        &self,
28        audit: AuditEvent,
29        event: DomainEvent,
30        notification: Option<Notification>,
31    ) -> Vec<PostCommitActivityWarning> {
32        let mut warnings = Vec::new();
33        if self.audit.append(audit).await.is_err() {
34            warnings.push(warning(
35                "interaction_post_commit_audit_failed",
36                "The operation completed, but its external audit record was not appended.",
37            ));
38        }
39        if self
40            .events
41            .outbox
42            .enqueue(OutboxRecord::pending(event))
43            .await
44            .is_err()
45        {
46            warnings.push(warning(
47                "interaction_post_commit_event_failed",
48                "The operation completed, but its external event was not queued.",
49            ));
50        }
51        if let Some(notification) = notification
52            && self.notifications.send(notification).await.is_err()
53        {
54            warnings.push(warning(
55                "interaction_post_commit_notification_failed",
56                "The operation completed, but its notification was not sent.",
57            ));
58        }
59        warnings
60    }
61}
62
63fn warning(code: &str, detail: &str) -> PostCommitActivityWarning {
64    PostCommitActivityWarning {
65        code: code.into(),
66        detail: detail.into(),
67    }
68}