# shadowjac/outbox-pattern-poc architecture

> Architecture diagram of the GitHub repository shadowjac/outbox-pattern-poc, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/shadowjac/outbox-pattern-poc
- Repository: https://github.com/shadowjac/outbox-pattern-poc

## Overview

OutboxPoc is a .NET order API and background event-delivery PoC. A client submits or lists orders; order creation stores the order and its serialized event together, then a polling processor publishes pending events and marks them processed. A Kafka consumer logs received events. PostgreSQL, Kafka, and Aspire orchestration are documented capabilities; source excerpts show the API and consumer wiring, but not all runtime configuration details. The publisher implementations are distinct; the excerpts do not establish which registration is ultimately selected at runtime.

Main entry points: [`src/OutboxPoc.Api/Program.cs`](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Program.cs) (API startup), [`src/OutboxPoc.Api/Infrastructure/AppDbContext.cs`](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Infrastructure/AppDbContext.cs) (EF data context), [`src/OutboxPoc.AppHost/AppHost.cs`](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.AppHost/AppHost.cs) (Aspire AppHost), [`src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs`](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs) (Order endpoints)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_order_api["Order API"]
  node_order_endpoints["Order endpoints<br/>[OrderEndpoints.cs]"]
  node_order["Order model<br/>[Order.cs]"]
  node_db_context["EF data context<br/>[AppDbContext.cs]"]
end

subgraph group_outbox_delivery["Outbox Delivery"]
  node_outbox_message["Outbox message<br/>[OutboxMessage.cs]"]
  node_processor["Outbox processor<br/>[OutboxProcessor.cs]"]
  node_publisher_interface["Publisher interface"]
  node_kafka_publisher["Kafka publisher"]
  node_log_publisher["Log publisher"]
end

subgraph group_event_consumption["Event Consumer"]
  node_consumer_worker["Consumer worker<br/>[Worker.cs]"]
end

subgraph group_runtime_services["Runtime Services"]
  node_postgres[("PostgreSQL")]
  node_kafka["Kafka orders topic"]
  node_api_host["API startup<br/>[Program.cs]"]
  node_consumer_host["Consumer startup<br/>[Program.cs]"]
  node_app_host["Aspire AppHost<br/>[AppHost.cs]"]
  node_service_defaults["Service defaults<br/>[Extensions.cs]"]
end

node_client(("HTTP client"))

node_client -->|"sends HTTP"| node_order_endpoints
node_order_endpoints -->|"saves and lists"| node_db_context
node_order_endpoints -->|"creates"| node_order
node_order_endpoints -->|"records event"| node_outbox_message
node_db_context -->|"maps entity"| node_order
node_db_context -->|"maps entity"| node_outbox_message
node_db_context -->|"persists data"| node_postgres
node_processor -->|"loads and marks"| node_db_context
node_processor -->|"publishes through"| node_publisher_interface
node_publisher_interface -->|"accepts message"| node_outbox_message
node_kafka_publisher -->|"implements"| node_publisher_interface
node_log_publisher -->|"implements"| node_publisher_interface
node_kafka_publisher -->|"produces events"| node_kafka
node_consumer_host -->|"registers worker"| node_consumer_worker
node_consumer_worker -->|"consumes events"| node_kafka
node_api_host -->|"configures database"| node_db_context
node_api_host -->|"registers processor"| node_processor
node_api_host -->|"registers publisher"| node_kafka_publisher
node_api_host -->|"registers publisher"| node_log_publisher
node_api_host -->|"adds defaults"| node_service_defaults
node_consumer_host -->|"adds defaults"| node_service_defaults
node_app_host -->|"orchestrates"| node_api_host
node_app_host -->|"orchestrates"| node_consumer_host
node_app_host -->|"starts resource"| node_postgres
node_app_host -->|"starts resource"| node_kafka

click node_order_endpoints "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs"
click node_order "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Domain/Order.cs"
click node_outbox_message "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Domain/OutboxMessage.cs"
click node_db_context "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Infrastructure/AppDbContext.cs"
click node_processor "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/OutboxProcessor.cs"
click node_publisher_interface "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/IMessagePublisher.cs"
click node_kafka_publisher "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/KafkaMessagePublisher.cs"
click node_log_publisher "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/LogMessagePublisher.cs"
click node_consumer_worker "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Consumer/Worker.cs"
click node_api_host "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Program.cs"
click node_consumer_host "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Consumer/Program.cs"
click node_app_host "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.AppHost/AppHost.cs"
click node_service_defaults "https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.ServiceDefaults/Extensions.cs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_order_endpoints,node_order,node_db_context,node_client toneBlue
class node_outbox_message,node_processor,node_publisher_interface,node_kafka_publisher,node_log_publisher toneAmber
class node_consumer_worker toneMint
class node_postgres,node_kafka,node_api_host,node_consumer_host,node_app_host,node_service_defaults toneRose
```

## Components

### Order API

- [Order endpoints](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs): `src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs`
- [Order model](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Domain/Order.cs): `src/OutboxPoc.Api/Domain/Order.cs`
- [EF data context](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Infrastructure/AppDbContext.cs): `src/OutboxPoc.Api/Infrastructure/AppDbContext.cs`

### Outbox Delivery

- [Outbox message](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Domain/OutboxMessage.cs): `src/OutboxPoc.Api/Domain/OutboxMessage.cs`
- [Outbox processor](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/OutboxProcessor.cs): `src/OutboxPoc.Api/Outbox/OutboxProcessor.cs`
- [Publisher interface](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/IMessagePublisher.cs): `src/OutboxPoc.Api/Outbox/IMessagePublisher.cs`
- [Kafka publisher](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/KafkaMessagePublisher.cs): `src/OutboxPoc.Api/Outbox/KafkaMessagePublisher.cs`
- [Log publisher](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Outbox/LogMessagePublisher.cs): `src/OutboxPoc.Api/Outbox/LogMessagePublisher.cs`

### Event Consumer

- [Consumer worker](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Consumer/Worker.cs): `src/OutboxPoc.Consumer/Worker.cs`

### Runtime Services

- **PostgreSQL**
- **Kafka orders topic**
- [API startup](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Api/Program.cs): `src/OutboxPoc.Api/Program.cs`
- [Consumer startup](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.Consumer/Program.cs): `src/OutboxPoc.Consumer/Program.cs`
- [Aspire AppHost](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.AppHost/AppHost.cs): `src/OutboxPoc.AppHost/AppHost.cs`
- [Service defaults](https://github.com/shadowjac/outbox-pattern-poc/blob/main/src/OutboxPoc.ServiceDefaults/Extensions.cs): `src/OutboxPoc.ServiceDefaults/Extensions.cs`

### Other components

- **HTTP client**

## Connections

- HTTP client → Order endpoints: sends HTTP (evidence: `README.md`)
- Order endpoints → EF data context: saves and lists (evidence: `src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs`)
- Order endpoints → Order model: creates (evidence: `src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs`)
- Order endpoints → Outbox message: records event (evidence: `src/OutboxPoc.Api/Endpoints/OrderEndpoints.cs`)
- EF data context → Order model: maps entity (evidence: `src/OutboxPoc.Api/Infrastructure/AppDbContext.cs`)
- EF data context → Outbox message: maps entity (evidence: `src/OutboxPoc.Api/Infrastructure/AppDbContext.cs`)
- EF data context → PostgreSQL: persists data (evidence: `README.md`)
- Outbox processor → EF data context: loads and marks (evidence: `src/OutboxPoc.Api/Outbox/OutboxProcessor.cs`)
- Outbox processor → Publisher interface: publishes through (evidence: `src/OutboxPoc.Api/Outbox/OutboxProcessor.cs`)
- Publisher interface → Outbox message: accepts message (evidence: `src/OutboxPoc.Api/Outbox/IMessagePublisher.cs`)
- Kafka publisher → Publisher interface: implements (evidence: `src/OutboxPoc.Api/Outbox/KafkaMessagePublisher.cs`)
- Log publisher → Publisher interface: implements (evidence: `src/OutboxPoc.Api/Outbox/LogMessagePublisher.cs`)
- Kafka publisher → Kafka orders topic: produces events (evidence: `src/OutboxPoc.Api/Outbox/KafkaMessagePublisher.cs`)
- Consumer startup → Consumer worker: registers worker (evidence: `src/OutboxPoc.Consumer/Program.cs`)
- Consumer worker → Kafka orders topic: consumes events (evidence: `README.md`)
- API startup → EF data context: configures database (evidence: `src/OutboxPoc.Api/Program.cs`)
- API startup → Outbox processor: registers processor (evidence: `src/OutboxPoc.Api/Program.cs`)
- API startup → Kafka publisher: registers publisher (evidence: `src/OutboxPoc.Api/Program.cs`)
- API startup → Log publisher: registers publisher (evidence: `src/OutboxPoc.Api/Program.cs`)
- API startup → Service defaults: adds defaults (evidence: `src/OutboxPoc.Api/Program.cs`)
- Consumer startup → Service defaults: adds defaults (evidence: `src/OutboxPoc.Consumer/Program.cs`)
- Aspire AppHost → API startup: orchestrates (evidence: `README.md`)
- Aspire AppHost → Consumer startup: orchestrates (evidence: `README.md`)
- Aspire AppHost → PostgreSQL: starts resource (evidence: `README.md`)
- Aspire AppHost → Kafka orders topic: starts resource (evidence: `README.md`)
