PROJECT LEAD DEVELOPER Updated July 2026

Oodlestack: B2B E-commerce

Reduced network overhead by 40% by moving demand-aggregation logic into Postgres, and closed a savings-calculation bug worth roughly ₹7,130 per typical order.

Tech Stack
FlutterDartRiverpodSupabasePostgreSQLGoogle OR-ToolsFreezed

Architecture

Frontend

  • Riverpod + Flutter Hooks
  • Freezed Immutable Models
  • Material Design 3
  • JS Interop for Google Maps

Backend

  • Business logic in Postgres RPCs/triggers, not Edge Functions
  • Row-level locking for concurrent order reservation
  • Row-Level Security for multi-tenant data access
  • OR-Tools CP-SAT solver for buyer/seller allocation

Challenges & Solutions

Problem

Buyers were being evaluated against sellers they individually couldn't meet the minimum order quantity for, producing false-negative savings calculations worth roughly ₹7,130 per typical order.

Solution

Rewrote the allocation logic alongside a broader optimizer rebuild — caching tier costs, parallelizing candidate generation, and vectorizing with NumPy — landing a 1.4-3.8x speedup at the same time the correctness bug was fixed.

Problem

Passing a default district value as a plain string to a Postgres RPC caused Postgrest to fail resolving between overloaded function signatures (error PGRST203), breaking order creation for that path.

Solution

Resolved the default case to a real UUID before calling the RPC, removing the ambiguity that caused Postgrest's signature resolution to fail.

Problem

Re-running the allocation optimizer for the same product/district/date created duplicate order allocations because nothing prevented the same run from being processed twice.

Solution

Added an idempotency guard with a status flip (pending to aggregated) so orders can't be re-ingested, backed by a database uniqueness constraint — and a migration to deduplicate 53 rows that had already been created by the bug.

Problem

A simulation flag meant to speed up constraint solving (`use_mip_polish=False`) was silently skipping enforcement of minimum-order-quantity and pack-size-divisibility constraints, meaning 'passing' simulation runs weren't actually valid.

Solution

Fixed the flag so constraints are properly enforced, and added thread-pool-level parallelism across pools to recover the lost performance — a 480-pool simulation run dropped to about 0.8 seconds.

Key Achievements

Full Provider to Riverpod migration

1.4-3.8x optimizer speedup via caching and vectorization

Row-level locking preventing concurrent over-reservation

480-pool simulation solved in ~0.8s

Deep Dive

Reimagining B2B Demand Aggregation

Oodlestack is designed to solve the complexity of group buying. It’s not just an e-commerce app; it’s a coordination engine that aggregates demand from multiple buyers to unlock wholesale pricing tiers, using an operations-research allocation engine underneath rather than simple first-come-first-served logic.

It’s also a second iteration: the group-buying model started as CureCollective, my 2024 healthcare pooling prototype. Oodlestack rebuilds that idea with the hard parts done properly — constraint solving, concurrency safety, and settlement integrity.

The challenge was building a system that felt like a native mobile app but lived on the web, with correctness-critical allocation logic that has to hold up under concurrent orders.


The Architecture: Business Logic Lives in Postgres

I migrated the entire codebase from Provider to Riverpod, adopting HookConsumerWidget to combine Riverpod’s global state with Flutter Hooks’ local lifecycle management, and Freezed for immutable models throughout — a deliberate, documented choice to keep state changes predictable as the feature set grows.

The more consequential architectural decision was where business logic lives: demand aggregation, seller matching, and settlement calculations run as Postgres functions and triggers rather than JavaScript Edge Functions, so data processing happens where the data already is instead of round-tripping to a separate compute layer. Seller matching itself is a weighted scoring function (pricing 40%, distance 30% via Haversine, rating 20%, stock 10%) implemented directly in SQL.


The Engineering: Correctness Under Concurrency

The hardest bugs in this system weren’t UI bugs — they were race conditions and constraint-enforcement gaps in the allocation engine (see Challenges & Solutions below). The fixes converged on the same pattern: explicit row-level locking (SELECT ... FOR UPDATE, and FOR UPDATE SKIP LOCKED for the credit ledger) to stop concurrent requests from over-reserving inventory or double-applying rewards, plus database-level uniqueness constraints so an idempotency bug can’t resurface silently even if the application-level guard is ever bypassed.

On the mobile side, Flutter Web can’t natively bridge to the Google Places Autocomplete session-token API, so location search calls into plain JavaScript functions defined on the host page via dart:js_util, with a conditional-import stub keeping the same code path working unmodified on mobile.


Impact & Features

Today, Oodlestack provides a coordinated experience for both community organizers and business buyers: a calendar-based view of buying cycles that dynamically prices based on aggregated volume, a mobile-first UI built for field use, and an allocation engine — Google OR-Tools’ CP-SAT solver — that runs the actual buyer/seller/tier matching as a constraint-satisfaction problem rather than a greedy heuristic.