Calitex
B2B Wholesale Distribution Platform

The complete
Calitex system
architecture

End-to-end order lifecycle management for wholesale distribution. From customer ordering through warehouse operations, last-mile delivery, to invoicing and accounting reconciliation.

17
Architecture Docs
97%
Production Ready
4
AI Agents
10K
Orders/Day Ceiling
Platform Overview

What Calitex Does

A B2B wholesale distribution platform serving business customers across the Netherlands. Manages the complete chain from product ordering to warehouse fulfillment and last-mile delivery with integrated invoicing.

User Roles Doc 01

📱

Customer

Mobile app. Browse products, place orders, select delivery dates, pay invoices, track deliveries.

📦

Order Picker

Web + mobile. Pick & pack orders with barcode scanning, manage loading lists, deliver goods.

Admin

Web panel. Manage stock, customers, products, regions, carriers. View-only on order status.

🔒

SuperAdmin

Full control. Manage admin accounts, reports, force-cancel orders, approve sensitive changes.

Core Capabilities Doc 01, 02

Payment Gating

Orders blocked if customer has unpaid invoices >30 days or exceeds credit limit. AI-enhanced risk scoring.

Cut-off Time Engine

Orders before 14:00 eligible for next-day delivery. After 14:00, earliest is day-after-tomorrow. Region-configurable.

Capacity Management

Weight and volume limits per delivery day per region. Pessimistic locks prevent overbooking.

Barcode Pick & Pack

Warehouse staff scan product barcodes during picking. System validates against order. Wrong product = immediate alert.

QR Delivery Tracking

QR codes on pallets. Driver scans to identify order and recipient. Signature capture for proof-of-delivery.

Accounting Sync

Invoices and payments sync to Exact Online. Event-driven with daily reconciliation. OAuth token lifecycle managed.

Calitex PVC Flooring
Premium PVC Flooring Distribution
Diamonds · Originals · Wood · Stone · Grande
System Interfaces

Application Interfaces

Three purpose-built applications serve different user roles. Customer orders via mobile, pickers operate in the warehouse, administrators manage the business through a web dashboard.

Calitex
🛒
Diamonds
Originals
Wood
Plinten
Eternity Visgraat Click
DM-304-HB · Diamonds · 5mm
€34.95/m²
Hope Plank Click
DM-306-PL · Diamonds · 5mm
€32.50/m²
Amazon Visgraat Click
OG-103-HB · Originals · 5mm
€29.90/m²
Slate Oak Visgraat Click
WD-204-HB · Wood · 5mm
€27.50/m²
🏠Shop
📦Orders
🚚Levering
📄Facturen
👤Account
Customer App
React Native (Expo) · iOS + Android
Pick & Pack
🖶
Order CAL-20260416-0042
Vloeren Discount Amsterdam
In Progress
Items (3 van 5 gepickt)
Eternity Visgraat Click
DM-304-HB · 24 dozen
24
Hope Plank Click
DM-306-PL · 18 dozen
18
MDF Plint Wit 14x100mm
MDF-W-14100 · 8 bundels
8
Sierra Plank Dry-Back
DBDM-308-PL · 12 dozen
12
Plakplint AC1515
AC1515 · 6 bundels
6
⚳ Scan Barcode
Picker / Driver App
React Native (Expo) · Barcode + QR
admin.calitex.nl/dashboard
Navigatie
📈 Dashboard
📦 Orders
📦 Voorraad
Vloeren
👥 Klanten
🚚 Bezorging
🌎 Regio's
📄 Facturen
👤 Gebruikers
Dashboard
Woensdag 16 april 2026 · 14:23
83
Orders vandaag
▲ 12% vs vorige week
€127K
Omzet vandaag
▲ 8% vs vorige week
96.2%
Bezorgsuccespercentage
▼ 1.1% vs vorige week
Order Pipeline Laatste 7 dagen
Recente Orders
OrderKlantBedragStatus
CAL-0416-0247Vloeren Discount Amsterdam€4,342.50Picking
CAL-0416-0246Woonwarenhuis Den Haag€2,189.00Confirmed
CAL-0416-0245Interieur Plus Rotterdam€8,750.80Delivery
CAL-0416-0244FloorPro Eindhoven€1,894.30Confirmed
Admin Dashboard
React + Vite + TanStack · Web Application
End-to-End Flow

Order Lifecycle

The complete journey from customer order to invoice completion. Every step is transactionally protected with defined failure recovery paths.

🛒
Browse &
Order
Customer App
💳
Payment
Validation
AI + Rules
📅
Delivery
Scheduling
Cut-off + Capacity
Order
Confirmed
Atomic TX
📦
Pick &
Pack
Barcode Scan
🚚
Loading &
QR Codes
Driver Assigned
🚲
Out for
Delivery
Customer Notified
Delivered
Signature
📄
Invoice &
Accounting
Exact Sync

Transaction Boundary Doc 12

Order confirmation is a single atomic database transaction that reserves delivery capacity (FOR UPDATE lock on capacity slot), reserves inventory (FOR UPDATE lock on products, sorted by ID to prevent deadlocks), creates the order, and creates the delivery record. If any step fails, everything rolls back. Async side effects (email, stock sync) run after commit via BullMQ.

Architecture Explorer

System Architecture

Modular monolith deployed on AWS. Clean module boundaries with defined data ownership. Every module communicates through explicit service calls (transactional) or BullMQ queues (async).

Frontend
Customer App React Native
Picker App React Native
Admin Panel React + Vite
API
REST + OpenAPI
JWT Auth
Rate Limiting
Idempotency
AI Layer
Order Decision
Delivery Planning
Exception Resolution
Input Parsing
Services
Orders
Inventory
Deliveries
Payments
Invoices
Customers
Products
Regions
Carriers
Data
PostgreSQL 16
Prisma ORM
Redis 7
BullMQ Queues
S3 Storage
Integrations
Stripe
Exact Online
External Webshops
SES Email
Firebase Push
Infra
ECS Fargate
RDS Multi-AZ
ElastiCache
CloudFront CDN
ALB
Route 53

Why Modular Monolith Doc 02

Team of 4-6 engineers. All domains tightly coupled in business logic. Single deployment unit for simpler CI/CD, debugging, and on-call. Clear module boundaries allow future service extraction.

Why Not Microservices

Distributed transactions across services for "validate payment + check capacity + confirm order" adds unnecessary complexity. No independent scaling needs at this volume.

Workflow Deep Dives

Critical Workflows

Step-by-step operational flows with failure handling at each stage.

🛒 Order Creation Flow Doc 03, 12

Phase 1 — Pre-validation (read-only, outside transaction)

Validate customer exists and is active. Load product details. AI OrderDecisionAgent evaluates risk (if applicable). Payment validation checks overdue invoices and credit limit. Cut-off time engine calculates earliest delivery date. Capacity engine verifies availability.

Phase 2 — Atomic reservation (single DB transaction)

SELECT FOR UPDATE on delivery_capacity_slots. SELECT FOR UPDATE on products (sorted by ID). Insert inventory transactions. Create order with status CONFIRMED. Create delivery record. Generate order number via PostgreSQL SEQUENCE.

Phase 3 — Async side effects (after commit)

BullMQ: order confirmation email, push notification, webshop stock sync. For critical events (invoice, Exact sync): transactional outbox pattern ensures delivery even if process crashes after commit.

If payment required: Order created with PENDING_PAYMENT status. Stripe PaymentIntent created with orderId in metadata. Webhook processes payment and advances to CONFIRMED. Cleanup job cancels stale PENDING_PAYMENT orders after 30 minutes.

📦 Pick & Pack Flow Doc 03

Trigger: Daily scheduled job at 16:00 CET generates pick lists for tomorrow's deliveries.

Picker opens app, selects order from pick list. System transitions order to IN_PROGRESS (customer can no longer cancel). Picker scans each product barcode. System validates barcode matches expected product and checks quantity. Wrong barcode = immediate audio/visual alert.

All items picked → status PICKED. Picker confirms physical packing → status PACKED. If product not in stock: picker marks item SHORT. Admin decides: ship partial or hold.

Concurrency protection: Optimistic locking (version column) on pick list items prevents two pickers from picking the same item.

🚚 Loading & Delivery Flow Doc 03

Loading: Aggregate all PACKED orders for a region + delivery date. Generate loading list. Assign driver. Generate QR codes for each order/pallet (contains order ID, customer name, address). Print QR stickers. Confirm loading → status LOADED.

Delivery: Driver opens app, sees delivery list ordered by route. Starts route → all orders status OUT_FOR_DELIVERY. Customers notified via push. At each stop: driver scans QR code on pallet. System shows order details + recipient. Driver delivers goods. Customer signs on device. Signature stored in S3 with GPS coordinates and timestamp. Confirm → status DELIVERED.

Failure: Customer absent → DELIVERY_FAILED. Admin can reschedule (returns to CONFIRMED for re-pick) or cancel. App works offline with sync-on-reconnect.

📄 Invoice & Payment Flow Doc 03, 15

Invoice generation is a resumable multi-step process triggered by order delivery. Step 1: Create invoice record. Step 2: Generate PDF, upload to S3. Step 3: Email to customer. Step 4: Advance order to COMPLETED. Step 5: Enqueue Exact sync via outbox. Each step checks if previous step completed — safe to retry.

Payment application: Customer selects invoices to pay, or enters amount (applied to oldest first via FIFO). Stripe PaymentIntent created. On webhook success: amount split across invoices. SELECT FOR UPDATE on invoice rows prevents double-application. Webhook handler always fetches current PaymentIntent state from Stripe API (handles out-of-order delivery).

Calitex Interior
From Order to Delivery
Complete Warehouse · Logistics · Invoicing
State Machines

Order State Machine

Strict state transitions enforced via optimistic locking. Every transition logged in audit trail.

PENDING_PAYMENT
CONFIRMED
IN_PROGRESS
PICKED
PACKED
LOADED
OUT_FOR_DELIVERY
DELIVERED
COMPLETED
CANCELLED
DELIVERY_FAILED

Cancellation Rules Doc 04

Allowed PENDING_PAYMENT, CONFIRMED
Blocked IN_PROGRESS through COMPLETED
Override SuperAdmin can force-cancel IN_PROGRESS through PACKED

Invoice States

DRAFT
SENT
PARTIALLY_PAID
PAID

Delivery States

PENDING
LOADED
IN_TRANSIT
DELIVERED
Data Model

Core Entities

PostgreSQL 16 with Prisma ORM. Strong relational integrity for financial data. ACID transactions protect all state changes.

Customer
id
company_name
credit_limit
region_id
is_active
Order
id, order_number
customer_id
status, version
delivery_date
total_amount
OrderItem
id
order_id
product_id
quantity, unit_price
picked_quantity
Product
id, sku, barcode
name, unit_price
weight_kg, volume_cm3
stock_quantity
Delivery
id
order_id, region_id
driver_id
status, qr_code
signature_url
Invoice
id, invoice_number
order_id, customer_id
total_amount, paid_amount
status, due_date
exact_sync_status
Payment
id
invoice_id
amount, method
reference
Region
id, code
name
delivery_days
capacity limits
CapacitySlot
region_id + date
max_weight/volume
reserved_weight/vol
FOR UPDATE lock

Inventory Truth Doc 11

Source of truth: inventory_transactions ledger (append-only). products.stock_quantity is a cached counter, recalculated in the same transaction. Daily reconciliation verifies consistency. CHECK constraint prevents negative stock.

Outbox Pattern Doc 15

Critical async events (invoice generation, Exact sync) written to outbox_events table inside the DB transaction. Poller reads every 5 seconds and enqueues to BullMQ. Survives process crashes after commit.

Production Hardening

Concurrency & Data Integrity

Every race condition identified, analyzed, and fixed with specific locking strategies. No vague "optimistic locking" — every lock type is chosen and justified.

🔒
Pessimistic Locking
Inventory & Capacity Reservation Doc 11, 12
SELECT FOR UPDATE on product rows (sorted by ID) and capacity slot rows. Inside single DB transaction with 10s timeout. Prevents overselling and overbooking. Lock ordering (capacity → products) prevents deadlocks.
🔄
Optimistic Locking
Order State Transitions Doc 11
Version column on orders table. UPDATE WHERE version = X. Prevents two pickers from starting the same order. ConcurrentModificationError on conflict — client retries.
🔑
Idempotency
API + Webhooks + Consumers Doc 12, 13
Client-sent Idempotency-Key header on all POST endpoints (Redis cache 24h). Stripe event ID dedup in processed_webhook_events table. Consumer state-check pattern: verify current state before acting.
📨
Transactional Outbox
Critical Async Event Delivery Doc 15
Invoice generation and Exact sync events written to outbox_events table inside the DB transaction. Poller enqueues to BullMQ. Solves dual-write problem: DB commit + Redis enqueue can't both succeed atomically.
🛡
Circuit Breakers
External Integration Resilience Doc 16
opossum circuit breakers on Stripe, Exact Online, webshop sync, and SES. 50% error threshold trips circuit. 30s reset timeout. Graceful degradation: orders proceed without payment if customer is pre-approved.
Deadlock Prevention
Global Lock Ordering Doc 15
All FOR UPDATE locks acquired in deterministic order: capacity_slots first, then products sorted by ID, then invoices sorted by ID. Prevents A→B / B→A deadlock cycles between concurrent transactions.
Operations & Reliability

Running in Production

Structured logging, business + technical metrics, actionable alerts with runbooks, zero-downtime deployments.

📈

Monitoring

CloudWatch + Grafana. Business metrics (orders/hour, delivery success rate, overdue invoices) and technical metrics (API latency, DB connections, queue depth).

🔔

Alerting

P1: API error spike, DB pool exhaustion, payment webhook DLQ, pick lists not generated. P2: invoice stuck, Exact failing, capacity near full. P3: latency, queue backlog.

📖

Runbooks

Step-by-step recovery guides: payment webhook failure, stuck invoices, capacity overbooking, Exact sync failure. What system does, what human does.

🛠

CI/CD

GitHub Actions. PR: lint + type-check + unit tests (parallel) → integration tests → staging deploy. Main: manual approval gate → ECS rolling update (zero-downtime).

🗃

Migration Safety

Every migration backward-compatible. Add nullable columns, CREATE INDEX CONCURRENTLY, dual-write for renames. SET lock_timeout = 5s. Never break running code.

📑

Structured Logging

JSON format. Every entry: timestamp, requestId, userId, module, level. Correlation IDs flow from API through BullMQ workers via AsyncLocalStorage.

SLA Targets Doc 16

99.9%
Order API Uptime
~43 min downtime/month
99.5%
Picker/Driver API
~3.6h downtime/month
2h
Invoice SLA
Generated within 2h of delivery
Calitex Product
Built for Resilience
Production Hardened · Chaos Tested · 97% Ready
Failure Modes

What Breaks & How We Recover

Every critical failure scenario analyzed with specific recovery design. Chaos testing plan validates all scenarios before launch.

Critical
Transaction Deadlock
Two orders lock products in different order
Global lock ordering
Critical
Inventory Oversell
Concurrent orders claim same stock
FOR UPDATE + CHECK(>=0)
Critical
Payment Lost
Stripe charged but no order created
PENDING_PAYMENT state
High
Worker Crash Mid-Job
Invoice generation dies mid-PDF
BullMQ stall detection
High
Redis Data Loss
ElastiCache failover loses ~1s of jobs
Outbox pattern + reconciliation
High
Webhook Out-of-Order
Stripe sends failed after succeeded
Fetch PI state from API
Medium
Connection Pool Exhaustion
Lock contention starves connection pool
Pool=25, tx timeout=10s
Medium
Stripe Partial Outage
50% of Stripe calls failing
Circuit breaker (opossum)
AI-First Extension

AI Decision Layer

An advisory AI layer that sits on top of the deterministic backbone. AI suggests. The system decides. Transactions remain atomic. The system works without AI.

Frontend Applications
Customer App, Picker App, Admin Panel
API Layer
REST + Auth + Validation + Rate Limiting
✨ AI Decision Layer (Claude API)
Advisory only. Validated outputs. Deterministic fallback. <2s latency budget.
Service Layer + Transactions
Business logic, state machine, DB transactions (unchanged)
Data + Queue + Integrations
PostgreSQL, Redis, BullMQ, Stripe, Exact

AI Agents Doc 17

OrderDecisionAgent
sync <2s
Risk scoring, payment flexibility, anomaly detection. Falls back to deterministic rules if confidence <0.7.
DeliveryPlanningAgent
async batch
Capacity prediction, date optimization, route sequencing. Pre-computed daily, cached 6 hours.
ExceptionResolutionAgent
async event
Failed delivery, stock shortage, partial fulfillment. Auto-resolves at confidence ≥0.85, otherwise creates admin task.
InputParsingAgent
sync <2s
Parse email/chat orders into structured data. Phase 2. Always requires customer confirmation before order creation.

Three-Layer Guardrails

Layer 1: Zod schema validation on every AI output.
Layer 2: Business rule post-check (hard rules always win).
Layer 3: Confidence gate (below threshold = deterministic fallback).

Feedback Loop

Every AI decision logged with input, output, confidence, and whether it was accepted or overridden. Outcomes tracked (did customer pay on time? did delivery succeed?). Monthly prompt refinement based on override patterns.

Source Basis

Documentation Provenance

This presentation synthesizes 17 architecture documents produced through four review rounds. Each section traces to its source material.

📄 System Design & Workflows
Doc 01: System Overview Doc 02: Architecture Design Doc 03: Critical Workflows Doc 04: State Machine Doc 08: Tech Stack
🗃 Data & API
Doc 09: Database Schema (Prisma) Doc 10: API Endpoints Doc 05: Gaps & Assumptions
🔒 Production Hardening
Doc 11: Critical Issues (12 flaws found) Doc 12: Architecture & Data Fixes Doc 15: Deep Failure Modes (10 second-order failures)
🛠 Operations & Security
Doc 06: Scaling & Reliability Doc 07: Security Doc 13: Operations, CI/CD, API Hardening Doc 14: Launch Checklist
✨ Final Review & AI Extension
Doc 16: CTO Sign-off (97%) Doc 17: AI Decision Layer
97 out of 100
Production Readiness Score
Remaining: pen test execution, load test execution, multi-region DR plan