# OrderService — In-Process Outbox with Scheduled Delivery

**Location:** [`samples/outbox-inapp/OrderService.InAppOutboxScheduling/`](https://github.com/deveel/hermodr/tree/main/samples/outbox-inapp/OrderService.InAppOutboxScheduling)\
**Framework:** ASP.NET Core 9 Minimal API\
**Transport:** RabbitMQ — `Hermodr.Publisher.RabbitMq`\
**Pattern:** Transactional Outbox with delayed transport delivery

***

## Overview

This sample demonstrates a specific semantic: the domain event already occurred, but its **broker delivery** is deferred.

The API creates an `Order` immediately and publishes `OrderCreated` through the outbox using `OutboxPublishOptions.ScheduleDeliveryAt`. The outbox row is persisted immediately, and the in-process relay waits until the scheduled UTC timestamp before forwarding the event to RabbitMQ.

```
POST /orders
    -> OrderCreated recorded now
    -> DbOutboxMessage persisted now
    -> relay forwards later when ScheduleDeliveryAt is due
```

***

## What it shows

### 1. Delivery scheduling via Outbox

Business code maps request input to outbox publish options:

```csharp
var publishOptions = request.ScheduleEventDeliveryAt is { } scheduleDeliveryAt
    ? new OutboxPublishOptions { ScheduleDeliveryAt = scheduleDeliveryAt }
    : null;

await _publisher.PublishAsync(new OrderCreated
{
    OrderId = order.Id,
    CustomerId = order.CustomerId,
    TotalAmount = order.TotalAmount,
    CreatedAt = order.CreatedAt,
    Items = /* ... */
}, publishOptions, ct);
```

### 2. Immediate persistence, delayed forwarding

The outbox stores the event row immediately, setting `NextRetryAt` to the scheduled delivery time. The relay then treats the row as ineligible until it becomes due.

### 3. Inspectable outbox state

The sample exposes:

```
GET /outbox/messages
```

so you can observe `Pending`, `NextRetryAt`, and later `Delivered` without opening SQLite manually.

***

## Running the sample

```bash
cd samples/outbox-inapp/OrderService.InAppOutboxScheduling

docker compose up -d

dotnet run --project OrderService.InAppOutboxScheduling.csproj
```

Generate a timestamp a few seconds in the future:

```bash
SCHEDULE_AT=$(python3 - <<'PY'
from datetime import datetime, timezone, timedelta
print((datetime.now(timezone.utc) + timedelta(seconds=20)).isoformat().replace('+00:00', 'Z'))
PY
)
```

Create a scheduled-delivery order event:

```bash
curl -s -X POST http://localhost:5000/orders \
  -H "Content-Type: application/json" \
  -d "{
    \"customerId\": \"cust-42\",
    \"scheduleEventDeliveryAt\": \"$SCHEDULE_AT\",
    \"items\": [
      { \"productId\": \"sku-001\", \"productName\": \"Widget\", \"quantity\": 2, \"unitPrice\": 9.99 }
    ]
  }" | jq
```

Inspect the outbox immediately:

```bash
curl -s http://localhost:5000/outbox/messages | jq
```

Wait until due time, then inspect again:

```bash
sleep 25
curl -s http://localhost:5000/outbox/messages | jq
```

***

## Why this sample exists

This sample is intentionally different from “future domain events”. It models:

* event occurred now
* outbox record exists now
* transport delivery happens later

That keeps the event semantics intact while still supporting infrastructure-level delayed fan-out.

***

## Related docs

* [Transactional Outbox](/publisher-channels/outbox.md)
* [RabbitMQ Publisher](/publisher-channels/rabbitmq.md)
* [Samples overview](/samples/samples.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hermodr.deveel.org/samples/outbox-inapp-scheduled-delivery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
