# Event-Driven Architecture Design: [Solution or domain landscape name]

> Solution-level design for an event-driven architecture that spans
> many producers, consumers and event APIs: business events and domains,
> event types and their semantics, broker topology and clusters, topic
> and channel naming, partitioning, the event catalogue, envelope and
> schema registry with compatibility modes, delivery, ordering and
> idempotency, the transactional outbox and change data capture,
> retention and replay, security and access control, observability and
> lineage, governance and capacity. Contracts follow the AsyncAPI
> Specification 3.1.0 and the CloudEvents 1.0.2 envelope; pattern names
> follow Enterprise Integration Patterns. Replace every `[bracketed]`
> value and every row marked *Example*.

<!--
Guidance: How to use this template
- Use this document for the shared rules and the shared infrastructure
  of an event-driven landscape. Each producing domain still writes an
  Event API Specification (`architecture/event-api-specification`) for
  its own channels and messages; this design sets the rules those
  specifications must follow.
- Settle event semantics (section 3), naming (section 5), schema
  compatibility (section 7) and delivery guarantees (section 8) before
  the first production topic. They are the hardest things to change once
  consumers depend on them.
- Broker internals are covered in System Design: Message Queue
  (`system-design/design-message-queue`); CDC mechanics in System
  Design: CDC Pipeline (`system-design/design-cdc-pipeline`); event
  sourcing inside one service in Event Sourcing and CQRS Design
  (`architecture/event-sourcing-cqrs`). Reference them instead of
  repeating them.
- Worked examples use a retailer with order, payment, fulfilment, stock
  and customer domains on a partitioned log broker.
-->

## Document control

<!-- Guidance: Identify the landscape this design governs and the broker estate it covers. A change of broker technology, envelope or compatibility default is a new major version. -->

| Field | Value |
|---|---|
| Document ID | [EDA-001] |
| Landscape or programme | [Name] |
| Broker estate | [Product and clusters covered] |
| Version | [0.1] |
| Status | [Draft / In review / Approved / Superseded] |
| Owner | [@eda-lead] |
| Approvers/reviewers | [@chief-architect], [@platform-lead], [@security-architect], [@data-governance-lead] |
| Classification | [Internal / Confidential] |
| Last updated | YYYY-MM-DD |
| Related documents | [Integration strategy], [Event API specifications], [Event storming summary] |

### Approvals

| Role | Name | Decision | Date |
|---|---|---|---|
| Chief architect | [@name] | [Approve / Approve with conditions / Reject] | YYYY-MM-DD |
| Platform owner | [@name] | [Decision] | YYYY-MM-DD |
| Security | [@name] | [Decision] | YYYY-MM-DD |
| Data governance | [@name] | [Decision] | YYYY-MM-DD |

### Revision history

| Version | Date | Author | Change summary |
|---|---|---|---|
| 0.1 | YYYY-MM-DD | [@name] | First draft |
| 1.0 | YYYY-MM-DD | [@name] | *Example:* Approved; CloudEvents envelope and BACKWARD_TRANSITIVE default adopted |
| 1.1 | YYYY-MM-DD | [@name] | *Example:* Added a second region with topic mirroring |

## Contents

<!-- Guidance: Keep this list aligned with the headings. -->

1. [Scope, drivers and context](#1-scope-drivers-and-context)
2. [Business events and domains](#2-business-events-and-domains)
3. [Event types and semantics](#3-event-types-and-semantics)
4. [Broker topology](#4-broker-topology)
5. [Topic and channel design](#5-topic-and-channel-design)
6. [Event catalogue](#6-event-catalogue)
7. [Envelope and schema governance](#7-envelope-and-schema-governance)
8. [Delivery, ordering and idempotency](#8-delivery-ordering-and-idempotency)
9. [Publishing from systems of record](#9-publishing-from-systems-of-record)
10. [Retention, replay and archive](#10-retention-replay-and-archive)
11. [Security and access control](#11-security-and-access-control)
12. [Observability and lineage](#12-observability-and-lineage)
13. [Capacity and service levels](#13-capacity-and-service-levels)
14. [Governance and lifecycle](#14-governance-and-lifecycle)
15. [Risks and decisions](#15-risks-and-decisions)
16. [Glossary and references](#16-glossary-and-references)

## 1. Scope, drivers and context

<!-- Guidance: State why the landscape is event-driven and what is not. Questions: which business outcomes need events rather than calls? Which systems are in scope? Pitfall: adopting events for everything, including interactions that need an immediate answer. -->

### 1.1 Drivers

| ID | Driver | Why events |
|---|---|---|
| EDR-001 *(Example)* | Stock must be visible to every channel within seconds | One stock change fans out to many consumers without the WMS knowing them |
| EDR-002 *(Example)* | Order processing must survive downstream outages | Consumers catch up from the log after recovery |
| EDR-003 *(Example)* | New consumers (fraud, analytics, loyalty) are added every quarter | Subscribing does not require a change to the producer |
| [EDR-NNN] | [Driver] | [Why events] |

### 1.2 Scope

| In scope | Out of scope |
|---|---|
| *Example:* Business events between order, payment, fulfilment, stock and customer domains | Request and response APIs (see API Design Guidelines, `architecture/api-design-guidelines`) |
| *Example:* Change events from the ERP and the WMS | Streaming analytics jobs (see Streaming Solution Design, `architecture/streaming-solution-design`) |
| *Example:* Outbound partner webhooks fed from internal events | Webhook delivery platform internals (`system-design/design-webhook-delivery`) |
| [Item] | [Item] |

### 1.3 Context

The context view shows producers, the broker estate and the main consumers for the worked example.

```mermaid
flowchart LR
  subgraph Producers
    ORD[Order service]
    PAY[Payment service]
    WMS[WMS via CDC]
    ERP[ERP via outbox relay]
  end
  subgraph Broker[Event broker cluster]
    T1[(order events)]
    T2[(payment events)]
    T3[(stock events)]
    REG[Schema registry]
  end
  subgraph Consumers
    FUL[Fulfilment]
    NOT[Notifications]
    ANA[Data platform]
    WH[Partner webhooks]
  end
  ORD --> T1
  PAY --> T2
  WMS --> T3
  ERP --> T3
  T1 --> FUL
  T1 --> NOT
  T2 --> FUL
  T3 --> ANA
  T1 --> WH
  ORD -. schema check .-> REG
```

## 2. Business events and domains

<!-- Guidance: Start from the business, not from tables. Run an event storming workshop and record it in Event Storming Summary (`architecture/event-storming-summary`). Each event belongs to exactly one owning domain. Pitfall: events named after database operations, such as OrderRowUpdated. -->

| Domain | Owning team | Key business events | System of record |
|---|---|---|---|
| Order *(Example)* | @team-order | OrderPlaced, OrderCancelled, OrderCompleted | Order service |
| Payment *(Example)* | @team-payment | PaymentAuthorised, PaymentCaptured, RefundIssued | Payment service |
| Fulfilment *(Example)* | @team-fulfilment | ShipmentDispatched, ShipmentDelivered | WMS |
| Stock *(Example)* | @team-stock | StockLevelChanged, StockReserved | WMS and ERP |
| Customer *(Example)* | @team-customer | CustomerRegistered, CustomerConsentChanged | CRM |
| [Domain] | [@team] | [Events] | [System] |

Rules for business events:

- Name each event as a past-tense fact in the language of the domain.
- One owning domain per event type; only the owner publishes it.
- An event describes what happened, not what a consumer should do.
- Publish an event only after the change it describes is committed.

## 3. Event types and semantics

<!-- Guidance: Agree what kinds of messages flow on the broker and what each promises. Mixing kinds on one channel confuses consumers. Pitfall: commands disguised as events, which hide coupling. -->

| Kind | Meaning | Payload | Consumers | Example |
|---|---|---|---|---|
| Event notification | Something happened; fetch details if needed | Identifiers and minimal facts | Many, unknown to producer | *Example:* OrderPlaced with order ID and total |
| Event-carried state transfer | Something happened and here is the new state | Full or partial entity state | Many; can build local read models | *Example:* StockLevelChanged with SKU, location, quantity |
| Domain event (internal) | Fact inside one bounded context | Domain model, may change often | Same domain only | *Example:* Internal pricing rule applied |
| Integration event (public) | Fact published across domain boundaries | Stable public contract | Other domains | *Example:* PaymentCaptured |
| Command | Request to one receiver to do something | Instruction and parameters | One known receiver | *Example:* ReserveStock on a queue |
| Change event (CDC) | Row-level change in a database | Before and after images | Same domain or translation step | *Example:* inventory table update |

Rules:

| ID | Rule |
|---|---|
| EVR-001 *(Example)* | Only integration events and commands cross domain boundaries; domain events and raw change events stay inside the owning domain |
| EVR-002 *(Example)* | Commands use point-to-point channels with exactly one consumer group; events use publish-subscribe channels |
| EVR-003 *(Example)* | Prefer event-carried state transfer for entities that consumers cache; prefer notification for large or sensitive entities |
| EVR-004 *(Example)* | Never put a reply expectation inside an event; use a request and reply pattern with correlation IDs if a reply is needed |
| [EVR-NNN] | [Rule] |

## 4. Broker topology

<!-- Guidance: Decide how many clusters, where they run and how they connect. Questions: what fails together? What data must stay in a region? Pitfall: one shared cluster for production, test and analytics workloads. -->

| Cluster | Purpose | Region and zones | Tenancy | Replication |
|---|---|---|---|---|
| prod-core *(Example)* | Business events and commands | [Region 1], three zones | Shared by domains, quotas per domain | Replication factor 3, minimum in-sync replicas 2 |
| prod-cdc *(Example)* | Raw change events and connectors | [Region 1], three zones | Platform team only | Replication factor 3 |
| prod-dr *(Example)* | Disaster recovery copy of prod-core | [Region 2] | Read only until failover | Asynchronous topic mirroring |
| nonprod *(Example)* | Development and test | [Region 1] | Shared | Replication factor 3, shorter retention |
| [Cluster] | [Purpose] | [Region] | [Tenancy] | [Replication] |

```mermaid
flowchart LR
  subgraph R1[Region 1]
    CORE[prod-core]
    CDC[prod-cdc]
  end
  subgraph R2[Region 2]
    DR[prod-dr]
  end
  CDC -- translated business events --> CORE
  CORE -- mirroring, async --> DR
  CORE -- connector --> LAKE[Data platform]
```

Decisions to record: managed service or self-run, cross-region model
(active and passive, or active and active with per-region topics),
expected recovery point (mirroring lag) and recovery time, and how
consumer offsets are translated on failover. Link the tiering to
Resilience Tiering and HA/DR Design (`architecture/resilience-tiering-ha-dr-design`).

## 5. Topic and channel design

<!-- Guidance: Fix the naming convention, the partitioning key and the number of partitions. Partition keys decide ordering; partition counts are hard to change for keyed topics. Pitfall: one topic per consumer, which turns publish-subscribe back into point-to-point. -->

### 5.1 Naming convention

Pattern: `[env].[domain].[event-family].[kind].v[major]`

| Part | Values | Example |
|---|---|---|
| env | prod, stg, dev | prod |
| domain | Owning domain from section 2 | order |
| event-family | Aggregate or entity | order |
| kind | event, cmd, cdc | event |
| major | Major contract version | 1 |

*Example:* `prod.order.order.event.v1`, `prod.stock.reservation.cmd.v1`,
`prod.fulfilment.shipment.event.v2`.

Dead-letter topics append `.dlq.[consumer-group]` to the source topic
name, so each consuming group owns its own dead-letter topic, for example
`prod.order.order.event.v1.dlq.fulfilment`. Retry topics follow the same
rule with `.retry.[consumer-group]`.

### 5.2 Topic granularity

| Option | When to use |
|---|---|
| One topic per event type | Consumers want only one type; types have different retention or security |
| One topic per entity with several event types | Consumers need all changes of an entity in order (the default here) |
| One topic per domain | Very small domains; rarely recommended |

### 5.3 Partitioning

| Topic | Partition key | Ordering guarantee | Partitions | Reason |
|---|---|---|---|---|
| prod.order.order.event.v1 *(Example)* | orderId | All events of one order in order | 24 | Peak 6,000 events per second, consumers process 500 per second per partition, so 12 needed, doubled for growth |
| prod.stock.level.event.v2 *(Example)* | sku + locationId | Per SKU and location | 48 | High fan-in from stores |
| prod.customer.customer.event.v1 *(Example)* | customerId | Per customer | 12 | Low volume |
| [Topic] | [Key] | [Guarantee] | [Count] | [Reason] |

## 6. Event catalogue

<!-- Guidance: Keep one catalogue of every published event type, generated from AsyncAPI documents where possible. It is the event view of the integration catalogue in the Integration Strategy (`architecture/integration-strategy`). Pitfall: a wiki page that drifts from the registry. -->

| Event ID | Type (CloudEvents `type`) | Topic | Owner | Schema subject | Version | Classification | Consumers |
|---|---|---|---|---|---|---|---|
| EVT-001 *(Example)* | com.example.order.placed.v1 | prod.order.order.event.v1 | @team-order | order.OrderPlaced | 1.3.0 | Internal | Fulfilment, Notifications, Data platform |
| EVT-002 *(Example)* | com.example.payment.captured.v1 | prod.payment.payment.event.v1 | @team-payment | payment.PaymentCaptured | 1.1.0 | Confidential | Fulfilment, Finance |
| EVT-003 *(Example)* | com.example.stock.level-changed.v2 | prod.stock.level.event.v2 | @team-stock | stock.StockLevelChanged | 2.0.0 | Internal | Web, Mobile, Marketplaces |
| [EVT-NNN] | [type] | [topic] | [@team] | [subject] | [x.y.z] | [Class] | [Consumers] |

Each entry links to the producing domain's AsyncAPI 3.1.0 document and
its Event API Specification. The catalogue is published in the developer
portal next to HTTP APIs.

## 7. Envelope and schema governance

<!-- Guidance: Fix one envelope for all events and one default compatibility mode for the schema registry. Questions: which serialisation format? Which compatibility mode, and who may override it? Pitfall: NONE compatibility in production, which lets a producer break every consumer. -->

### 7.1 Envelope

All events use the CloudEvents 1.0.2 envelope. In the structured mode
the attributes travel in the payload; in the binary mode, preferred on
the broker, they travel as message headers (prefixed `ce_` on Kafka).

| Attribute | Rule in this landscape |
|---|---|
| specversion | Always `1.0` |
| id | UUID generated by the producer; unique per source; used for deduplication |
| source | URI of the producing service, for example `/order-service/prod` |
| type | Reverse-domain name from the catalogue ending in the major contract version, which matches the topic major, for example `com.example.order.placed.v1` |
| time | Time of the business fact in UTC, RFC 3339 format |
| subject | Entity identifier, for example the order ID |
| datacontenttype | `application/avro`, `application/protobuf` or `application/json` |
| dataschema | URI of the payload schema in the schema registry |
| Extension: traceparent | W3C Trace Context value for end-to-end tracing (CloudEvents distributed tracing extension) |
| Extension: partitionkey | Value used as the partition key (CloudEvents partitioning extension) |

### 7.2 Serialisation and registry

| Decision | Choice | Reason |
|---|---|---|
| Serialisation format *(Example)* | Avro for internal events, JSON Schema for partner-facing events | Compact, strong evolution rules; JSON for external readability |
| Registry *(Example)* | One schema registry per environment | Producers and consumers fetch schemas at runtime |
| Subject naming *(Example)* | `[domain].[EventName]` | Several event types per topic |
| Default compatibility *(Example)* | BACKWARD_TRANSITIVE | New schema readable by consumers of all previous versions |
| Override *(Example)* | FULL_TRANSITIVE for events consumed by partners | Both old and new consumers keep working whatever upgrades first |

### 7.3 Compatibility modes

| Mode | What it guarantees | Upgrade order |
|---|---|---|
| BACKWARD | Consumers using the new schema can read data written with the previous one | Upgrade consumers first |
| BACKWARD_TRANSITIVE | As BACKWARD, checked against all earlier versions | Upgrade consumers first |
| FORWARD | Consumers using the previous schema can read data written with the new one | Upgrade producers first |
| FORWARD_TRANSITIVE | As FORWARD, against all earlier versions | Upgrade producers first |
| FULL and FULL_TRANSITIVE | Both directions, against the previous or all earlier versions | Either order |
| NONE | No check | Not allowed in production |

Mode names are those used by widely deployed schema registries; check
the documentation of the registry you run. Breaking changes need a new
major version, a new topic (`.v2`), a period of dual publishing and a
deprecation notice following API Deprecation Policy (`architecture/api-deprecation-policy`).

## 8. Delivery, ordering and idempotency

<!-- Guidance: State the guarantees the platform gives and what consumers must do in return. Exactly-once processing end to end is rare; plan for at-least-once delivery and idempotent consumers. Pitfall: assuming the broker removes duplicates that come from producer retries or consumer restarts. -->

| Concern | Platform guarantee | Producer obligation | Consumer obligation |
|---|---|---|---|
| Delivery | At-least-once for all business events | Wait for acknowledgement from all in-sync replicas; enable idempotent producer where supported | Commit offsets only after processing |
| Ordering | Per partition only | Use the partition key from section 5.3 | Process one key at a time; do not reorder in thread pools |
| Duplicates | Possible after retries and rebalances | Stable `id` across retries | Idempotent Receiver: store processed IDs or use upserts by version |
| Poison messages | Dead Letter Channel per consumer | Validate against schema before publishing | Retry with backoff [3] times, then move to the consumer's `.dlq.[consumer-group]` topic with error headers |
| Late or out-of-order events | Not prevented across partitions | Include entity version or sequence | Ignore events older than the stored version |

```mermaid
sequenceDiagram
  participant P as Producer
  participant B as Broker
  participant C as Consumer
  participant S as Consumer store
  P->>B: publish event id=E1, key=O-42
  B-->>P: ack after replication
  B->>C: deliver E1
  C->>S: check processed id E1
  S-->>C: not seen
  C->>S: apply change and record E1 in one transaction
  C->>B: commit offset
  B->>C: redeliver E1 after rebalance
  C->>S: check processed id E1
  S-->>C: already processed
  C->>B: commit offset, no side effect
```

## 9. Publishing from systems of record

<!-- Guidance: Decide how each producer gets events onto the broker without losing or inventing events. Questions: can the application write to an outbox table? Is log-based CDC available and licensed for the database? Pitfall: dual writes (database commit, then publish) that lose events when the second step fails. -->

| Technique | How it works | Use when | Watch for |
|---|---|---|---|
| Transactional outbox with polling publisher | Business change and outbox row written in one transaction; a relay polls the outbox and publishes | Application code can be changed; moderate volume | Polling delay, outbox cleanup |
| Transactional outbox with log tailing | As above, but the relay reads the outbox through CDC on the database log | Higher volume, low latency | CDC tooling must be operated |
| Log-based CDC of business tables | Connector reads the database log and emits change events | Packaged or legacy application that cannot be changed | Exposes internal schema; translate to business events before publishing across domains |
| Native events from the application | Packaged application publishes its own events | SaaS or ERP with an event feature | Vendor schema; map to the catalogue type |
| Direct publish after commit (dual write) | Application commits, then publishes | Not allowed for business events | Lost or phantom events on failure |

| Producer | Technique | Translation step | Owner |
|---|---|---|---|
| Order service *(Example)* | Outbox with log tailing | None, outbox holds the integration event | @team-order |
| WMS *(Example)* | Log-based CDC | Stream processor maps inventory rows to StockLevelChanged | @team-stock |
| ERP *(Example)* | Native business events | Adapter maps ERP events to catalogue types | @team-erp |
| [Producer] | [Technique] | [Translation] | [@owner] |

## 10. Retention, replay and archive

<!-- Guidance: Decide how long events stay on the broker, how consumers replay them and where they go after. Retention is also a privacy decision. Pitfall: infinite retention of personal data with no erasure path. -->

| Topic class | Retention on broker | Cleanup policy | Archive | Replay method |
|---|---|---|---|---|
| Business events *(Example)* | 7 days | Delete | Object storage for 13 months, partitioned by date | Reset consumer group offset by time, or reload from archive |
| Entity state topics *(Example)* | Unlimited | Compact by key | Not needed | New consumers read from the beginning |
| Commands *(Example)* | 3 days | Delete | None | Not replayed; producers resend |
| CDC raw *(Example)* | 3 days | Delete | None | Re-snapshot from source |
| Dead letter *(Example)* | 14 days | Delete | Ticket attached | Replay tool after fix |
| [Class] | [Retention] | [Policy] | [Archive] | [Method] |

Replay rules: replays use a dedicated consumer group or a flag in the
event headers so that side effects (emails, payments) are not repeated;
every replay is logged with requester, range and reason. For personal
data, prefer notification events with identifiers, or crypto-shredding
(per-subject keys deleted on erasure), and record the approach in the
DPIA (`compliance/dpia`).

## 11. Security and access control

<!-- Guidance: Apply least privilege per client and per topic. Link to Security Architecture (`security/security-architecture`). Pitfall: one shared superuser credential used by all connectors. -->

| Control | Rule |
|---|---|
| Authentication | Each producer and consumer has its own identity (mutual TLS certificate or OAuth 2.0 client credentials), issued by the platform |
| Authorisation | Access control lists per topic: write for the owning domain only, read per approved consumer, granted through a request in the catalogue |
| Encryption in transit | TLS on every client and inter-broker connection |
| Encryption at rest | Broker storage encrypted with platform-managed or customer-managed keys |
| Payload protection | Field-level encryption or tokenisation for card and special-category fields; keys held outside the broker |
| Schema registry | Write access for CI pipelines only; humans read |
| Admin | Topic creation only through infrastructure as code with review |
| Audit | Admin actions, ACL changes and replays logged and retained [13 months] |

## 12. Observability and lineage

<!-- Guidance: Make every event traceable from producer to every consumer. Use Observability Specification (`ops/observability-spec`) for signal details. Pitfall: monitoring broker health but not consumer lag, which is what users feel. -->

| Signal | Measure | Alert threshold *(Example)* |
|---|---|---|
| Consumer lag | Messages or seconds behind the head, per consumer group and partition | Above 60 seconds for 5 minutes on tier 1 consumers |
| End-to-end latency | Event `time` to consumer completion, 95th percentile | Above 5 seconds for stock events |
| Dead letter arrivals | Count per consumer | Any arrival on tier 1 |
| Producer errors | Failed publishes and retries | Above 1 % for 5 minutes |
| Under-replicated partitions | Count | Any for more than 5 minutes |
| Schema rejections | Failed registrations in CI and at runtime | Any in production |
| Outbox backlog | Unpublished outbox rows | Older than 2 minutes |

Lineage: the catalogue records producer, topic and consumer groups for
every event type; trace context in the envelope links spans across
hops; the data platform records which datasets are built from which
topics.

## 13. Capacity and service levels

<!-- Guidance: Size the clusters from expected volumes and set service levels per tier. Recompute when volumes change. Pitfall: sizing for averages when peaks drive partition counts and storage. -->

| Input | Value *(Example)* |
|---|---|
| Average event rate, all topics | 1,500 events per second |
| Peak event rate | 6,000 events per second |
| Average event size including envelope | 1 KB |
| Retention for business events | 7 days |
| Replication factor | 3 |

*Example* calculation: 1,500 events per second x 1 KB x 86,400 seconds
= 129.6 GB per day; x 7 days = 907.2 GB; x 3 replicas = about 2.7 TB of
broker storage, plus [30 %] headroom = about 3.5 TB. Peak ingress is
6,000 x 1 KB = 6 MB per second before replication.

| Tier | Example topics | Availability | End-to-end latency, 95th percentile | Recovery point | Recovery time |
|---|---|---|---|---|---|
| Tier 1 *(Example)* | Order, payment, stock | 99.95 % | 2 seconds | Mirroring lag below 30 seconds | 30 minutes |
| Tier 2 *(Example)* | Customer, notifications | 99.9 % | 30 seconds | 5 minutes | 4 hours |
| Tier 3 *(Example)* | Analytics feeds | 99.5 % | 15 minutes | 1 hour | 24 hours |

## 14. Governance and lifecycle

<!-- Guidance: Decide who approves new event types, topics and breaking changes, and how events are retired. Use the RACI below and the architecture governance process. Pitfall: governance so heavy that teams bypass the broker with point-to-point calls. -->

| Activity | EDA lead | Platform team | Producing domain | Consuming domain | Security | Data governance |
|---|---|---|---|---|---|---|
| Event naming and envelope rules | A, R | C | C | I | I | C |
| New event type and schema | C | I | A, R | C | C | C |
| Topic provisioning and quotas | I | A, R | R | I | C | I |
| Consumer access request | I | R | A | R | C | C |
| Breaking change and deprecation | C | I | A, R | C | I | I |
| Retention and privacy rules | C | R | C | I | C | A |

Lifecycle: Proposed, Designed (schema and AsyncAPI reviewed), Published
(registered in the catalogue), Deprecated (successor published,
consumers notified, sunset date set), Retired (topic deleted after
archive). A review checklist for every new event type:

- [ ] Named as a past-tense business fact owned by one domain
- [ ] CloudEvents attributes filled as in section 7.1
- [ ] Schema registered with the default compatibility mode or an approved override
- [ ] Partition key chosen and ordering need stated
- [ ] Classification set and personal data fields marked
- [ ] Publishing technique from section 9 named; no dual write
- [ ] AsyncAPI 3.1.0 document committed and linked from the catalogue
- [ ] Consumer dead letter handling and alerts defined

## 15. Risks and decisions

<!-- Guidance: Record the main design risks and the decisions with their ADR references in the Architecture Decision Log (`architecture/architecture-decision-log`). -->

| ID | Type | Description | Response | Owner |
|---|---|---|---|---|
| RSK-001 *(Example)* | Risk | Hot partition on popular SKUs during promotions | Composite key with location; monitor partition skew | @team-stock |
| RSK-002 *(Example)* | Risk | Consumers depend on CDC row formats | EVR-001 enforced in review; translation step owned by producer | @eda-lead |
| RSK-003 *(Example)* | Risk | Failover loses events within the mirroring lag | Producers can replay from the outbox for the last [1 hour] | @platform-lead |
| DEC-001 *(Example)* | Decision | CloudEvents binary mode on the broker | ADR-EDA-001 | @eda-lead |
| DEC-002 *(Example)* | Decision | BACKWARD_TRANSITIVE as default compatibility | ADR-EDA-002 | @eda-lead |
| [ID] | [Type] | [Description] | [Response] | [@owner] |

## 16. Glossary and references

<!-- Guidance: Define terms consumers and producers must share, and list sources with the date you checked them. -->

### 16.1 Glossary

| Term | Meaning |
|---|---|
| Event | Immutable record of a business fact that already happened |
| Command | Message asking one receiver to perform an action |
| Topic or channel | Named stream on the broker that carries messages |
| Partition | Ordered subset of a topic; ordering holds only inside it |
| Consumer group | Set of consumer instances that share the work of reading a topic |
| Consumer lag | Distance between the newest message and the consumer's position |
| Compaction | Cleanup that keeps only the latest message per key |
| Outbox | Table written in the business transaction and published by a relay |
| Crypto-shredding | Making data unreadable by deleting the key that encrypted it |

### 16.2 References

| Reference | Version or date checked | Use |
|---|---|---|
| AsyncAPI Specification, asyncapi.com | 3.1.0, released January 2026 | Channel, operation and message contracts |
| CloudEvents specification, CNCF, github.com/cloudevents/spec | 1.0.2 | Envelope attributes in section 7.1 |
| Enterprise Integration Patterns, Hohpe and Woolf, enterpriseintegrationpatterns.com | Site checked YYYY-MM-DD | Pattern names |
| Transactional outbox, polling publisher and transaction log tailing, microservices.io | Checked YYYY-MM-DD | Section 9 |
| Schema evolution and compatibility, schema registry documentation of your product | Checked YYYY-MM-DD | Section 7.3 mode names |
| W3C Trace Context, w3.org/TR/trace-context | Level 1 Recommendation (Level 2 in progress), checked YYYY-MM-DD | traceparent extension |
| [Internal standard] | [Version] | [Use] |

## Standard and licence note

Based on public specifications: the AsyncAPI Specification 3.1.0 and the
CloudEvents specification 1.0.2, both published under the Apache License
2.0. Pattern names (Publish-Subscribe Channel, Dead Letter Channel,
Idempotent Receiver and others) come from Enterprise Integration
Patterns by Gregor Hohpe and Bobby Woolf and are used by name with
attribution; the outbox and log tailing techniques are described in
original words with credit to microservices.io. Schema compatibility
mode names follow common schema registry usage; product names are
trademarks of their owners and this template is not affiliated with or
endorsed by any vendor. This template is original text written for this
collection. Check the current official version of every specification
before use. Template licence: MIT.
