Shipment Delay Auto-Mitigation
Publisher: User Data Function | Consumer: Activator, Eventhouse
Business context
A logistics company manages thousands of shipments per day across multiple carriers and routes. When a delay is detected, the standard response requires a human to identify the affected order, assess available inventory and alternate routes, notify the customer, and log the incident — a process that can take hours and routinely results in SLA breaches.
A User Data Function receives a delay signal from the supply chain system, retrieves order, inventory, route, and SLA context from Fabric, calls an AI model to generate a mitigation plan, and publishes a Supply.Chain.ShipmentDelayed Business Event. Three independent Activator rules act on the event: one reroutes the shipment, one reallocates inventory, and one notifies the customer. Eventhouse stores the full delay record for SLA reporting and route performance analysis.
The problem without Business Events: The User Data Function would need to call the routing system, the inventory system, the customer notification API, and the audit store directly. Adding a new mitigation action — escalating to a carrier account manager, for example — requires modifying the function code and redeploying.
The solution with Business Events: The function publishes one delay event carrying the full mitigation context. Each action is an independent Activator rule. A new mitigation step is a new subscription, not a code change.
Architecture
flowchart LR
subgraph External
SC[Supply Chain\nSystems]
end
subgraph Fabric
UDF[User Data Function\nDelay mitigator]
FA[(Fabric Data + AI\nOrders, inventory, routes,\nSLA rules, AI model)]
BE([Business Event\n'Supply.Chain.ShipmentDelayed'])
end
subgraph Consumers
ACT1{Activator\nReroute rule}
ACT2{Activator\nReallocate rule}
ACT3{Activator\nNotify rule}
EH[(Eventhouse\nSLA analytics)]
end
SC -->|Delay webhook| UDF
FA -.->|context + mitigation plan| UDF
UDF -->|Publish event| BE
BE --> ACT1
BE --> ACT2
BE --> ACT3
BE --> EH
ACT1 --> ROUTE[Reroute\nshipment]
ACT2 --> INV[Reallocate\ninventory]
ACT3 --> CUST[Notify\ncustomer]
Step 1: Create the Business Event
- Go to Real-Time Hub → Business Events → Create.
- Create or select an Event Schema Set. Use
SupplyChainas the schema set name. You will need this name when connecting the Event Schema Set to the User Data Function through the connection manager. - Name the event
Supply.Chain.ShipmentDelayed. -
In the schema editor, paste the following JSON:
{ 'type': 'record', 'name': 'Supply.Chain.ShipmentDelayed', 'fields': [ { 'name': 'shipment_id', 'type': 'string', 'doc': "Unique identifier of the delayed shipment" }, { 'name': 'order_id', 'type': 'string', 'doc': "Identifier of the order associated with this shipment" }, { 'name': 'route_id', 'type': 'string', 'doc': "Identifier of the current shipping route" }, { 'name': 'carrier_id', 'type': 'string', 'doc': "Identifier of the carrier responsible for the shipment" }, { 'name': 'delay_minutes', 'type': 'int', 'doc': "Estimated delay in minutes relative to the original SLA" }, { 'name': 'sla_breach', 'type': 'boolean', 'doc': "True if the delay results in an SLA breach" }, { 'name': 'detected_at', 'type': 'string', 'doc': "ISO 8601 timestamp of when the delay was detected" } ] } -
Confirm that Analyze in Eventhouse is enabled. Create a new Eventhouse or select an existing one. This creates a dedicated KQL table named
Supply.Chain.ShipmentDelayedautomatically. - Select Create.
Step 2: Publisher - User Data Function
The User Data Function receives a delay signal, enriches it with Fabric data and AI context, and publishes the Business Event.
Create the User Data Function
- In your Fabric workspace, select + New item and create a User Data Function named
PublishShipmentDelayedEvent. - Inside the UDF item, select New function.
Connect to the schema set
- In the Home ribbon, select Manage connections.
- Select + Add connection, search for
SupplyChain, and select Connect. - Note the alias (
SupplyChainby default). Close the pane.
Function code
import fabric.functions as fn
from datetime import datetime, timezone
import logging
udf = fn.UserDataFunctions()
@udf.connection(argName='businessEventsClient', alias='SupplyChain')
@udf.function()
def publish_shipment_delayed_event(
businessEventsClient: fn.FabricBusinessEventsClient,
shipment_id: str,
order_id: str,
route_id: str,
carrier_id: str,
delay_minutes: int,
sla_breach: bool
) -> str:
logging.info("publish_shipment_delayed_event invoked.")
event_data = {
'shipment_id': shipment_id,
'order_id': order_id,
'route_id': route_id,
'carrier_id': carrier_id,
'delay_minutes': delay_minutes,
'sla_breach': sla_breach,
'detected_at': datetime.now(timezone.utc).isoformat(),
}
businessEventsClient.PublishEvent(
type='Supply.Chain.ShipmentDelayed',
event_data=event_data,
data_version='v1'
)
return f"Event 'Supply.Chain.ShipmentDelayed' published for shipment {shipment_id}"
For full details on publishing Business Events from User Data Functions, see the User Data Function publisher documentation.
Step 3: Consumers
Consumer 1 - Activator: Reroute shipment
- In Real-Time Hub, locate
Supply.Chain.ShipmentDelayed. - Select Set alert and name the rule
Delay - Reroute Shipment. - Set Condition to
On each event. Add filter:sla_breach == true. - In Action, configure the Power Automate flow or webhook that calls the routing system to switch the shipment to an alternate route. Add
shipment_id,route_id, anddelay_minutesas context fields. - Select Save.
Consumer 2 - Activator: Reallocate inventory
- Locate
Supply.Chain.ShipmentDelayedand select Set alert. - Name the rule
Delay - Reallocate Inventory. Add filter:delay_minutes > 240. - In Action, configure the flow that triggers an inventory reallocation from the nearest fulfillment center. Add
order_idandshipment_idas context fields. - Select Save.
Consumer 3 - Activator: Notify customer
- Locate
Supply.Chain.ShipmentDelayedand select Set alert. - Name the rule
Delay - Notify Customer. - Set Condition to
On each event(notify for all delays, not only SLA breaches). - In Action, configure the email or SMS notification flow. Add
order_id,delay_minutes, andsla_breachas context fields. - Select Save.
Consumer 4 - Eventhouse: SLA analytics
Every delay event is ingested automatically. Use the following queries to monitor route performance and SLA impact.
Delays by route — last 7 days:
['Supply.Chain.ShipmentDelayed']
| where ingestion_time() > ago(7d)
| summarize DelayCount = count(), AvgDelay = avg(delay_minutes) by route_id
| order by DelayCount desc
SLA breach rate by carrier:
['Supply.Chain.ShipmentDelayed']
| where ingestion_time() > ago(30d)
| summarize
Total = count(),
Breaches = countif(sla_breach == true)
by carrier_id
| extend BreachRate = round(todouble(Breaches) / Total * 100, 1)
| order by BreachRate desc
Delay trend over the last 30 days:
['Supply.Chain.ShipmentDelayed']
| where ingestion_time() > ago(30d)
| summarize
Delays = count(),
AvgDelayMins = avg(delay_minutes),
SLABreaches = countif(sla_breach == true)
by bin(ingestion_time(), 1d)
| order by ingestion_time() asc
Step 4: End-to-end test
Invoke publish_shipment_delayed_event with the following test values:
| Parameter | Value |
|---|---|
shipment_id |
shp-77412 |
order_id |
ord-55200 |
route_id |
route-mx-la |
carrier_id |
carrier-004 |
delay_minutes |
300 |
sla_breach |
true |
Then confirm the event arrived in Eventhouse:
['Supply.Chain.ShipmentDelayed']
| where shipment_id == "shp-77412"
| project shipment_id, route_id, delay_minutes, sla_breach, detected_at
| take 1
If the row is present and all three Activator rules fire, your end-to-end setup is working.
What happens next
With delay events flowing, logistics, customer experience, and finance teams can build on the same signal independently.
flowchart LR
BE([Business Event\n'Supply.Chain.ShipmentDelayed']) --> ACT[Activator]
BE --> EH[(Eventhouse)]
ACT --> ROUTE[Reroute shipment]
ACT --> INV[Reallocate inventory]
ACT --> CUST[Customer notification]
ACT --> ESC[Carrier escalation]
EH --> KQL[SLA analytics]
EH --> RTD[Real-Time Dashboard\ndelay heatmap by route]
| Extension | What it enables |
|---|---|
| Reroute shipment | Activator switches to alternate route for SLA breaches |
| Reallocate inventory | Activator triggers fulfillment center reallocation for long delays |
| Customer notification | Proactive delay communication via email or SMS |
| Carrier escalation | New Activator rule that notifies the carrier account manager for repeat breaches |
| SLA analytics | Route and carrier performance history for contract reviews |
| Delay heatmap | Real-Time Dashboard showing delay density by route and time window |