# aviavinash24/orderflow architecture

> Architecture diagram of the GitHub repository aviavinash24/orderflow, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/aviavinash24/orderflow
- Repository: https://github.com/aviavinash24/orderflow

## Overview

#### Purpose and Entry Points
OrderFlow is a concurrency-safe e-commerce order backend with a React/Vite client. It reserves stock, transitions orders through payment/cancel/expiry states, applies payment webhooks idempotently, and reliably publishes side effects via an outbox.

- API process and lifespan: `app/main.py`
- RQ worker process: `app/worker.py`
- Browser entry/UI root: `frontend/src/main.jsx`, `frontend/src/App.jsx`

#### HTTP and Authentication Boundary
FastAPI routers are the business-logic boundary; handlers use explicit async PostgreSQL transactions rather than an ORM. JWT authentication protects order operations, while simulated payment webhooks are unauthenticated. Redis enforces a fixed-window per-user order creation limit.

- Routing: `app/routers/auth.py`, `app/routers/orders.py`, `app/routers/webhooks.py`
- Security/dependencies/rate limiting: `app/core/security.py`, `app/core/deps.py`, `app/core/rate_limit.py`
- API DTOs: `app/schemas/orders.py`, `app/schemas/webhooks.py`

#### Ordering and Inventory Reservation
`POST /orders` is the central correctness path. Within one transaction it sorts requested items by product ID to establish lock order, conditionally decrements available inventory and increments reserved inventory, creates a `placed` order with an expiry, and persists line-item price snapshots. Insufficient stock aborts the full transaction.

Cancellation locks the order, permits only `placed`/`paid`, changes it to `cancelled`, and returns reserved inventory to available.

- Order flows: `app/routers/orders.py`
- Inventory/order schema: `migrations/0004_create_inventory.sql`, `migrations/0005_create_orders.sql`, `migrations/0006_create_order_items.sql`

#### Payment and Transactional Outbox
Payment webhooks lock the referenced order and record each gateway event. A unique gateway event ID makes duplicate delivery idempotent. A successful event changes only a currently `placed` order to `paid`; in that same transaction it creates an `order.paid` outbox event. The webhook always responds successfully to avoid retry storms, including duplicates or unknown orders.

- Webhook state transition: `app/routers/webhooks.py`
- Payment/outbox persistence: `migrations/0007_create_payment_events.sql`, `migrations/0008_create_outbox_events.sql`

#### Background State Reconciliation
The API lifespan owns the reservation-expiry loop. It claims expired unpaid `placed` orders using row locking with `SKIP LOCKED`, marks them `expired`, and releases their reservations. This enables concurrent pollers without duplicate work.

A separate RQ worker polls/enqueues and drains pending outbox rows, claims batches with `SKIP LOCKED`, handles events, and marks them processed. Database outbox state is the durability boundary; Redis is a broker/wake-up mechanism, not the system of record.

- Expiry job: `app/jobs/expire_reservations.py`, `app/main.py`
- Outbox processing: `app/jobs/outbox.py`, `app/worker.py`

#### Persistence and Infrastructure
PostgreSQL 16 is authoritative for users, catalog, inventory counters, orders, payment events, and outbox events; access is raw SQL through `asyncpg`. Ordered migrations establish constraints and indexes supporting correctness and polling. Redis 7 supports rate limits and RQ. Docker Compose runs API, worker, database, and Redis.

- DB/config boundary: `app/core/db.py`, `app/core/config.py`
- Migration execution and base schema: `scripts/run_migrations.py`, `migrations/0001_enable_uuid.sql`
- Service topology: `docker-compose.yml`, `Dockerfile`

#### Frontend Client
The Vite React SPA manages auth state and cart state locally, calls the API through a shared client, and exposes product, cart, order, and authentication pages. It is a consumer of the API rather than a source of business-state correctness.

- API/auth/cart clients: `frontend/src/api.js`, `frontend/src/auth.jsx`, `frontend/src/cart.jsx`
- Primary pages: `frontend/src/pages/ProductsPage.jsx`, `frontend/src/pages/CartPage.jsx`, `frontend/src/pages/OrderPage.jsx`

Main entry points: [`app/main.py`](https://github.com/aviavinash24/orderflow/blob/main/app/main.py) (FastAPI app), [`docker-compose.yml`](https://github.com/aviavinash24/orderflow/blob/main/docker-compose.yml) (Docker Compose), [`app/core/db.py`](https://github.com/aviavinash24/orderflow/blob/main/app/core/db.py) (PostgreSQL 16), [`app/routers/orders.py`](https://github.com/aviavinash24/orderflow/blob/main/app/routers/orders.py) (Order routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["React client"]
  node_spa["Vite React SPA<br/>browser client<br/>[main.jsx]"]
  node_client_api["API client<br/>frontend client<br/>[api.js]"]
end

subgraph group_api["API process"]
  node_api_process["FastAPI app<br/>API process<br/>[main.py]"]
  node_auth_routes["Auth routes<br/>router<br/>[auth.py]"]
  node_order_routes["Order routes<br/>transactional router<br/>[orders.py]"]
  node_webhook_routes["Payment webhooks<br/>idempotent router<br/>[webhooks.py]"]
  node_auth_rate_limit["JWT and order limits<br/>security dependencies<br/>[security.py]"]
end

subgraph group_background["Background processing"]
  node_expiry_job["Reservation expiry<br/>reconciliation job"]
  node_rq_worker["RQ worker<br/>worker process<br/>[worker.py]"]
  node_outbox_job["Outbox processor<br/>background job<br/>[outbox.py]"]
end

subgraph group_data["Data and infrastructure"]
  node_postgres[("PostgreSQL 16<br/>authoritative database<br/>[db.py]")]
  node_inventory_orders["Inventory and orders<br/>relational state"]
  node_payment_outbox["Payment events and outbox<br/>relational state"]
  node_redis["Redis 7<br/>rate-limit and RQ broker"]
  node_migrations["Ordered migrations<br/>schema migration runner<br/>[run_migrations.py]"]
  node_compose["Docker Compose<br/>service topology<br/>[docker-compose.yml]"]
end

node_spa -->|"uses"| node_client_api
node_client_api -->|"HTTP"| node_api_process
node_api_process -->|"serves"| node_auth_routes
node_api_process -->|"serves"| node_order_routes
node_api_process -->|"serves"| node_webhook_routes
node_order_routes -->|"authenticates and limits"| node_auth_rate_limit
node_auth_rate_limit -->|"fixed-window counters"| node_redis
node_order_routes -->|"reserve, place, cancel"| node_inventory_orders
node_webhook_routes -->|"idempotent paid event"| node_payment_outbox
node_inventory_orders -->|"stored in"| node_postgres
node_payment_outbox -->|"stored in"| node_postgres
node_api_process -->|"runs in lifespan"| node_expiry_job
node_expiry_job -->|"SKIP LOCKED expiry"| node_inventory_orders
node_rq_worker -->|"runs"| node_outbox_job
node_outbox_job -->|"claims and processes"| node_payment_outbox
node_rq_worker -->|"RQ broker"| node_redis
node_migrations -->|"creates schema"| node_postgres
node_compose -.->|"runs"| node_api_process
node_compose -.->|"runs"| node_rq_worker
node_compose -.->|"runs"| node_postgres
node_compose -.->|"runs"| node_redis

click node_spa "https://github.com/aviavinash24/orderflow/blob/main/frontend/src/main.jsx"
click node_client_api "https://github.com/aviavinash24/orderflow/blob/main/frontend/src/api.js"
click node_api_process "https://github.com/aviavinash24/orderflow/blob/main/app/main.py"
click node_auth_routes "https://github.com/aviavinash24/orderflow/blob/main/app/routers/auth.py"
click node_order_routes "https://github.com/aviavinash24/orderflow/blob/main/app/routers/orders.py"
click node_webhook_routes "https://github.com/aviavinash24/orderflow/blob/main/app/routers/webhooks.py"
click node_auth_rate_limit "https://github.com/aviavinash24/orderflow/blob/main/app/core/security.py"
click node_expiry_job "https://github.com/aviavinash24/orderflow/blob/main/app/jobs/expire_reservations.py"
click node_rq_worker "https://github.com/aviavinash24/orderflow/blob/main/app/worker.py"
click node_outbox_job "https://github.com/aviavinash24/orderflow/blob/main/app/jobs/outbox.py"
click node_postgres "https://github.com/aviavinash24/orderflow/blob/main/app/core/db.py"
click node_inventory_orders "https://github.com/aviavinash24/orderflow/blob/main/migrations/0005_create_orders.sql"
click node_payment_outbox "https://github.com/aviavinash24/orderflow/blob/main/migrations/0007_create_payment_events.sql"
click node_migrations "https://github.com/aviavinash24/orderflow/blob/main/scripts/run_migrations.py"
click node_compose "https://github.com/aviavinash24/orderflow/blob/main/docker-compose.yml"

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_spa,node_client_api toneBlue
class node_api_process,node_auth_routes,node_order_routes,node_webhook_routes,node_auth_rate_limit toneAmber
class node_expiry_job,node_rq_worker,node_outbox_job toneMint
class node_postgres,node_inventory_orders,node_payment_outbox,node_redis,node_migrations,node_compose toneRose
```

## Components

### React client

- [Vite React SPA](https://github.com/aviavinash24/orderflow/blob/main/frontend/src/main.jsx): browser client · Local auth and cart state; consumes the API. · `frontend/src/main.jsx`
- [API client](https://github.com/aviavinash24/orderflow/blob/main/frontend/src/api.js): frontend client · `frontend/src/api.js`

### API process

- [FastAPI app](https://github.com/aviavinash24/orderflow/blob/main/app/main.py): API process · Owns HTTP serving and the reservation-expiry lifecycle. · `app/main.py`
- [Auth routes](https://github.com/aviavinash24/orderflow/blob/main/app/routers/auth.py): router · `app/routers/auth.py`
- [Order routes](https://github.com/aviavinash24/orderflow/blob/main/app/routers/orders.py): transactional router · Creates, cancels, and reads orders in explicit async SQL transactions. · `app/routers/orders.py`
- [Payment webhooks](https://github.com/aviavinash24/orderflow/blob/main/app/routers/webhooks.py): idempotent router · Records gateway events and transitions placed orders to paid. · `app/routers/webhooks.py`
- [JWT and order limits](https://github.com/aviavinash24/orderflow/blob/main/app/core/security.py): security dependencies · Authenticates order users and applies fixed-window creation limits. · `app/core/security.py`

### Background processing

- [Reservation expiry](https://github.com/aviavinash24/orderflow/blob/main/app/jobs/expire_reservations.py): reconciliation job · Claims expired placed orders, expires them, and releases stock. · `app/jobs/expire_reservations.py`
- [RQ worker](https://github.com/aviavinash24/orderflow/blob/main/app/worker.py): worker process · `app/worker.py`
- [Outbox processor](https://github.com/aviavinash24/orderflow/blob/main/app/jobs/outbox.py): background job · Claims pending events, handles them, and marks them processed. · `app/jobs/outbox.py`

### Data and infrastructure

- [PostgreSQL 16](https://github.com/aviavinash24/orderflow/blob/main/app/core/db.py): authoritative database · System of record for catalog, inventory, orders, payment events, and outbox state. · `app/core/db.py`
- [Inventory and orders](https://github.com/aviavinash24/orderflow/blob/main/migrations/0005_create_orders.sql): relational state · Available/reserved counters, order state, expiry, and price snapshots. · `migrations/0005_create_orders.sql`
- [Payment events and outbox](https://github.com/aviavinash24/orderflow/blob/main/migrations/0007_create_payment_events.sql): relational state · Unique gateway events and durable side-effect events. · `migrations/0007_create_payment_events.sql`
- **Redis 7**: rate-limit and RQ broker · Broker and wake-up mechanism, not durable outbox state.
- [Ordered migrations](https://github.com/aviavinash24/orderflow/blob/main/scripts/run_migrations.py): schema migration runner · Establishes database constraints and polling indexes. · `scripts/run_migrations.py`
- [Docker Compose](https://github.com/aviavinash24/orderflow/blob/main/docker-compose.yml): service topology · Runs API, worker, PostgreSQL, and Redis. · `docker-compose.yml`

## Connections

- Vite React SPA → API client: uses
- API client → FastAPI app: HTTP
- FastAPI app → Auth routes: serves
- FastAPI app → Order routes: serves
- FastAPI app → Payment webhooks: serves
- Order routes → JWT and order limits: authenticates and limits
- JWT and order limits → Redis 7: fixed-window counters
- Order routes → Inventory and orders: reserve, place, cancel · Locks rows, reserves stock, and rolls back insufficient-stock requests.
- Payment webhooks → Payment events and outbox: idempotent paid event · Records gateway delivery and creates order.paid atomically.
- Inventory and orders → PostgreSQL 16: stored in
- Payment events and outbox → PostgreSQL 16: stored in
- FastAPI app → Reservation expiry: runs in lifespan
- Reservation expiry → Inventory and orders: SKIP LOCKED expiry
- RQ worker → Outbox processor: runs
- Outbox processor → Payment events and outbox: claims and processes · Uses SKIP LOCKED batches and marks completed events.
- RQ worker → Redis 7: RQ broker
- Ordered migrations → PostgreSQL 16: creates schema
- Docker Compose → FastAPI app: runs
- Docker Compose → RQ worker: runs
- Docker Compose → PostgreSQL 16: runs
- Docker Compose → Redis 7: runs
