Skip to main content

backbone_integrations/application/service/
integrations_events.rs

1//! Integrations domain events (hand-authored, user-owned) — the processing surface.
2//!
3//! Tenancy (ADR-0029): the payloads keep their `company_id` field as the legacy
4//! tenancy twin. The module's own tables carry no company column — the composing
5//! service's tenancy decorator owns org scoping — but the event payloads route
6//! through the module's outbox (whose rows keep a tenant column for the
7//! cross-tenant relay) and onto consumers that may still be company-fenced.
8
9use serde::{Deserialize, Serialize};
10use uuid::Uuid;
11
12/// An inbound event was mapped to an internal record.
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
14pub struct IntegrationEventMapped {
15    pub event_id: Uuid,
16    /// Legacy tenancy twin (ADR-0029) — see the module docs above.
17    pub company_id: Uuid,
18    pub connector_id: Uuid,
19    pub event_type: String,
20    pub external_id: String,
21    pub internal_ref_type: String,
22    pub internal_ref_id: Uuid,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
26#[serde(tag = "type")]
27pub enum IntegrationEvent {
28    IntegrationEventMapped(IntegrationEventMapped),
29    IntegrationEventFailed { event_id: Uuid, /// Legacy tenancy twin (ADR-0029) — see the module docs above.
30                             company_id: Uuid, connector_id: Uuid, external_id: String, reason: String },
31    IntegrationEventIgnored { event_id: Uuid, /// Legacy tenancy twin (ADR-0029) — see the module docs above.
32                              company_id: Uuid, connector_id: Uuid, external_id: String, reason: String },
33}
34
35pub trait IntegrationEventSink: Send + Sync {
36    fn publish(&self, event: &IntegrationEvent);
37}
38
39#[derive(Debug, Default, Clone)]
40pub struct LoggingSink;
41
42impl IntegrationEventSink for LoggingSink {
43    fn publish(&self, event: &IntegrationEvent) {
44        tracing::info!(?event, "integration event");
45    }
46}