UXDL Docs

Event-Driven Architecture

Pub/sub patterns, queue topology, and idempotency guarantees.

Event topology

plaintext
Producer (API) → Redis Queue → Consumer (Worker) → Side effects

              Dead letter queue (failed after max retries)

Event envelope

Every event follows a standard shape:

json
{
  "id": "evt_01HZ...",
  "type": "user.created",
  "timestamp": "2026-05-24T18:00:00Z",
  "source": "backend-api",
  "data": {
    "userId": "usr_123",
    "email": "user@company.com"
  }
}

Idempotency

Consumers must handle duplicate delivery:

typescript
async function handleUserCreated(event: Event) {
  const existing = await db.processedEvent.findUnique({
    where: { eventId: event.id },
  });
  if (existing) return; // Already processed
 
  await db.$transaction([
    db.processedEvent.create({ data: { eventId: event.id } }),
    // ... side effects
  ]);
}

Naming conventions

PatternExample
Entity actionuser.created, order.paid
System eventdeployment.completed
Integrationstripe.payment_intent.succeeded