Back to Projects
Private

AVDAN

Multi-Sided Marketplace & Logistics Platform — Web + Mobile

Key Technical Highlights

Modular-monolith FastAPI backend (one module per business domain) under an enforced 'no service imports another service's internals' rule, deliberately seamed for future service extraction

17-state, event-sourced order lifecycle (purchase → vendor accept → hub QA → delivery → escrow release) with an append-only audit trail as the single write path

Real-time GPS tracking correct across multiple horizontally-scaled API instances via cache + pub/sub fan-out, so a WebSocket on a different server instance still gets live rider updates

Extracted a shared React Native package (tokens, UI primitives, API client, auth) out of two near-duplicate mobile apps before a third was built, verified by diffing compiled bundles

Found, root-caused, and fixed a live object-storage exposure serving confidential inspection images publicly — closed with a path-scoped WAF rule, verified across all four access patterns

The Case Study

Overview

AVDAN is a multi-sided marketplace and logistics platform — customer, vendor, rider, hub-QA, admin, and support roles — built on a modular FastAPI backend serving eight clients (five Next.js web apps and three React Native/Expo mobile apps) sharing a common design system and generated API types. Built by a small team; the work described here reflects majority ownership (roughly 69% of commits) rather than solo work.

Architecture

The backend is a modular monolith — one module per business domain (auth, orders, payment, dispatch, tracking, notification, vendor, QA, dispute, admin) — under an enforced rule that no service imports another service's internals, deliberately seaming the two highest-write-volume domains (tracking, notifications) for extraction into standalone services later without a restructuring project. Orders move through a 17-state lifecycle (purchase → vendor accept → hub QA → last-mile delivery → escrow release, with branch paths for rejection, QA failure, and dispute) with role-gated transitions and an append-only, event-sourced audit trail as the single write path for order status.

Payments & Money Handling

A Strategy-pattern payment-provider interface (charge / verify / transfer / refund / webhook-verify) means a second provider can be added later with zero changes to order or escrow logic — provider-specific ledger fields live in a JSONB column specifically so a new provider never forces a schema migration. Money is stored as integer minor units everywhere, and order-line items snapshot product name, price, and image at purchase time so a later catalogue edit can never rewrite what an already-placed order shows a customer.

Real-Time at Scale

Rider GPS updates stay correct across multiple horizontally-scaled API instances: location writes go to both a live cache and a day-partitioned, auto-purged time-series table, then fan out over pub/sub — so a WebSocket connection held by a different server instance than the one that received the update still delivers it live, with ETA recomputation gated on a minimum-movement threshold to avoid noise-driven churn.

"Code Exists" Is Not "Feature Works"

A dedicated reconciliation pass — opened specifically because an earlier status tracker had marked phases complete based on code existing rather than the feature having been run — found that the entire escrow/payout mechanism had never actually fired in production-shaped testing: nothing transitioned a delivered order into the payout-pending state the payout worker polled for, so every delivered order sat completed-but-unpaid with no vendor ever paid. Traced by walking the full order lifecycle live, then fixed with an automatic, same-request state transition triggered by the rider's own delivery confirmation.

Security

A live object-storage exposure — a CDN hostname bound to an entire private bucket, serving confidential QA-inspection images publicly and bypassing the API's own authorization checks entirely — was found, root-caused, fixed with a path-scoped edge WAF rule, and verified across all four relevant access patterns before being considered closed.