Reliable webhook processing service that implements Idempotency, Strict Ordering by Entity, and Audit Logging. Built to demonstrate correctness in handling distributed events.
Portfolio Note: This project prioritizes architectural correctness, clean code, and transparency in trade-offs. It serves as a reference implementation for securely handling asynchronous event processing patterns.
flowchart TD
In([Webhook Request]) --> Validate{Valid Payload?}
Validate -- No --> R400[400 Bad Request]
Validate -- Yes --> Idem{Idempotency Check}
Idem -- Duplicate & Processed --> R409[409 Conflict]
Idem -- Duplicate & Failed --> Retry[Retry: Reset & Accept]
Idem -- New Event --> Accept[202 Accepted]
Retry --> Queue
Accept --> Queue
Queue --> Lock{Acquire Mutex}
Lock --> Process[Sequential Processing]
Process -- Success --> DB_OK[(DB: PROCESSED + Audit)]
Process -- Error --> DB_FAIL[(DB: FAILED + Audit)]
Prevents “double spending” or duplicate side effects when providers send the same event multiple times.
event_id.Ensures that OrderCreated is always processed before OrderPaid.
customer_id.All decisions—whether accepted, ignored, processed, or rejected—are permanently logged.
cp .env.example .env
docker-compose up -d
npm install
npm run db:migrate
npm run dev
# Swagger Docs at http://localhost:3000/api-docs
This architecture makes explicit trade-offs for simplicity and consistency in a single-node environment.
| Constraint | Implication | Production Solution (Scale) |
|---|---|---|
| In-Memory Locks | Scaling to multiple instances breaks ordering guarantees. | Redis Lock (Redlock) or Kafka Partitioning (keyed messages). |
| No Dead Letter Queue | Failed events remain FAILED in the database. |
Separate DLQ table + Retry mechanism. |
| Synchronous DB Writes | Higher latency on accepting requests. | Decouple ingestion (SQS/RabbitMQ) from storage. |
Gérson Resplandes
Backend Engineer focused on Distributed Systems and Reliability.