Distribution App Development

Build custom app solutions with Scrums.com's expert development team. With an NPS (Net Promoter Score) of 82, Scrums.com crafts cost-effective, custom applications that drive results.

Companies building third-party logistics platforms, wholesale distribution systems, and B2B fulfilment operations need engineering teams who understand the specific data architecture challenges of multi-warehouse inventory, order wave planning, carrier rate management, and the route optimisation logic that determines whether last-mile delivery is profitable. Scrums.com provides dedicated software engineering teams for distribution app development, deploying production-ready systems with append-only goods receipt ledgers, configurable pick-pack-ship workflows, carrier integration adapters, and the proof-of-delivery infrastructure that closes the fulfilment loop.

Warehouse Management, Inbound Receiving, and Putaway Architecture

Distribution platforms manage the full inbound flow from purchase order through goods receipt to putaway, and each step must be traceable as the basis for inventory accuracy.

Inbound receiving uses an append-only goods_receipt_events table: purchase_order_id, supplier_id, received_at, receiving_dock_id, and line items capturing variant_id, expected_quantity, received_quantity, and condition (ACCEPTABLE | DAMAGED | REJECTED). Discrepancies between expected and received quantities write discrepancy_records linked to the goods receipt. The inventory ledger is updated only after receipt confirmation: a RECEIVED event writes inventory_transactions rows for accepted quantities; DAMAGED quantities write to a separate quarantine_inventory table pending quality disposition.

Putaway management assigns received stock to storage locations based on a putaway_rules config table: rules specify preferred zones by product category, whether to consolidate with existing stock of the same SKU, and maximum pallet height per zone. A putaway_tasks table assigns work to warehouse operatives: variant_id, from_location (receiving dock), to_location (storage bin), quantity, status (PENDING | IN_PROGRESS | COMPLETED | EXCEPTION), and completed_at. Task completion writes the inventory_transactions row that moves stock from receiving to the bin location: inventory is not considered in storage until the putaway task reaches COMPLETED.

The warehouse_locations table models the physical structure: warehouse_id, zone_id, aisle, bay, level, bin, location_type (BULK | PICK_FACE | STAGING | RECEIVING_DOCK | DISPATCH_DOCK), and capacity constraints. Location capacity is enforced by checking current occupancy (aggregated from inventory_transactions) against the configured limit before any new putaway_tasks row is written.

Order Fulfilment, Pick-Pack-Ship Workflow, and Carrier Integration

Distribution order fulfilment connects inbound customer orders to the physical pick, pack, and ship workflow inside the warehouse, with inventory reservations ensuring no two fulfilment waves conflict over the same stock.

Outbound orders arrive through an order_intake_events table (from EDI, API, or manual entry) and are normalised into an orders table with a state machine: RECEIVED / ALLOCATED / WAVE_ASSIGNED / PICKING / PICKED / PACKING / PACKED / DISPATCHED / DELIVERED | CANCELLED | RETURNED. Each transition writes to order_status_events. Inventory allocation uses SELECT...FOR UPDATE to lock the relevant warehouse_inventory rows and write allocation_records linking order lines to specific bins and lot numbers. Allocation holds against quantity_reserved; inventory does not leave the warehouse_inventory table until dispatch.

Wave planning groups orders into fulfilment waves based on configurable criteria: cut-off time, carrier collection window, order priority tier, and shared pick paths to minimise operative travel. A wave_plans table records wave_id, planned order IDs, warehouse_id, target_dispatch_at, and status (PLANNED | RELEASING | IN_PROGRESS | COMPLETE). Releasing a wave generates pick_tasks rows sequenced by bin location to minimise walking distance. Task sequencing is driven by a pick_sequence_config table rather than hard-coded aisle order.

Carrier integration uses a carrier_adapter layer that normalises FedEx, UPS, DHL, Royal Mail, and customer-specific parcel contracts into a rate_quotes schema. Rate shopping compares carrier responses at label generation time and selects the cheapest option meeting the required service level. Carrier API calls write carrier_api_events rows for every request and response. Label generation writes a shipment_labels row; tracking number assignment writes to shipment_tracking_numbers. Both are immutable after creation.

Distribution apps like these are built and delivered by dedicated engineering teams through our mobile app development service.

Route Optimisation, Last-Mile Delivery, and Proof of Delivery

Last-mile delivery planning uses OR-Tools VRPTW (Vehicle Routing Problem with Time Windows) to compute optimal stop sequences across the delivery fleet. Input parameters (vehicle capacities, driver shift start and end times, customer delivery windows, and depot location) are read from configuration tables rather than hard-coded, allowing operations managers to adjust fleet and schedule parameters without engineering involvement. Solved route sequences are written to a route_assignments table as a point-in-time snapshot; when a replan is triggered by a new order or vehicle unavailability, a new snapshot row is inserted and the previous sequence is retained for audit.

Dynamic re-routing updates routes mid-shift when delivery failures, traffic events, or customer cancellations change the optimal sequence. A route_events append-only table records REPLAN_TRIGGERED, STOP_ADDED, STOP_REMOVED, and SEQUENCE_CHANGED events with the reason code and operator reference. The active route sequence for any vehicle is always derived from the latest route_assignments row: the route_events table provides the audit trail of why the sequence changed but is never the source of truth for what the driver should execute next.

Driver mobile apps communicate with the backend via a delivery_events API: ARRIVED_AT_STOP, DELIVERY_ATTEMPTED, DELIVERED, FAILED_DELIVERY (with a reason code: NOT_AT_HOME | ACCESS_DENIED | REFUSED | DAMAGED), and RETURNED_TO_DEPOT. Each event is appended to a delivery_status_events table. Proof of delivery (POD) captures signature_image_url, recipient_name, photo_url, and geolocation at the moment of the DELIVERED event. POD records are immutable after creation; a separate pod_disputes table handles customer disputes without modifying the original POD.

Failed delivery management follows a configurable re-attempt policy stored in a delivery_attempt_config table: maximum attempts per order, re-attempt interval, and escalation action (RETURN_TO_DEPOT | HOLD_AT_LOCKER | NOTIFY_CUSTOMER). After the maximum attempts are exhausted, a return_to_depot_events row is created and the order transitions to a FAILED terminal state: the inventory is returned to the warehouse_inventory ledger via a RETURN inventory_transaction.

Multi-Warehouse Operations, Inter-Depot Transfers, and Distribution Analytics

Multi-warehouse distribution platforms must route orders to the optimal fulfilment location without creating inventory inconsistencies between sites. Order routing uses a fulfilment_routing_config table that defines rules by priority: route to the warehouse closest to the delivery address with available stock; if out-of-stock at the closest site, route to the next preferred warehouse. Routing decisions are logged in order_routing_events rows (the decision, the rule that triggered it, and the warehouse assigned), creating an auditable record of why each order was routed where it was.

Inter-depot transfers move stock between warehouse locations without passing through a customer order. A transfer is modelled as two inventory_transaction rows: a TRANSFER_OUT from the source location and a TRANSFER_IN at the destination, linked by a transfer_id. Both rows are written atomically within a database transaction so that stock is never simultaneously absent from both locations. Transfer state is tracked in a transfer_requests table (REQUESTED / APPROVED / IN_TRANSIT / RECEIVED | CANCELLED) with each transition appended to transfer_events. Transit inventory (stock that has left the source but not yet reached the destination) is held in a TRANSFER_IN_TRANSIT transaction type that does not contribute to available inventory at either location until the TRANSFER_IN event is confirmed.

Distribution analytics materialised views aggregate from the append-only ledger without querying transactional tables directly. Standard views include throughput_by_warehouse_by_day (orders received, picked, packed, dispatched, delivered), carrier_performance_by_lane (on-time delivery rate, average transit days, failed delivery rate per carrier and route), inventory_turn_by_sku, and return_rate_by_product_category. Because these views are recomputable from source rows, correcting a source event and refreshing the view regenerates accurate performance metrics without manual data patching.

SLA monitoring uses a sla_configs table keyed by customer account and order priority tier, defining maximum pick time, pack time, carrier collection deadline, and delivery window. A sla_breach_events table records any breach: order_id, the SLA metric that breached, the configured threshold, the actual value, and detected_at. SLA breach events are immutable; they are never deleted even if the underlying delivery is subsequently resolved, preserving the evidence required for customer penalty calculations and carrier performance reviews.

Frequently Asked Questions

How does inventory allocation prevent two fulfilment waves from claiming the same stock?

When an order is allocated to a wave, the platform uses SELECT...FOR UPDATE to lock the relevant warehouse_inventory rows before writing allocation_records. The locked row's quantity_reserved is incremented atomically, reducing the quantity_available visible to any concurrent allocation attempt. Allocations are held until dispatch; if an order is cancelled, the allocation_record is reversed and quantity_reserved decreases, making the stock available again. Two waves running concurrently queue behind the lock rather than both claiming the same reserved quantity.

How is carrier rate selection recorded for audit purposes?

Every carrier API request and response is logged as an immutable carrier_api_events row: the carrier, the service level requested, the quoted rate, and the timestamp. When a label is generated, the selected carrier, rate, and the carrier_api_event that produced the quote are referenced on the shipment_labels row. This creates a complete audit trail showing which rates were offered, which was selected, and what the decision criteria were: accessible for any shipment at any point after dispatch.

How does re-routing update a driver's sequence mid-shift without losing the original plan?

The active route sequence is always the latest route_assignments row for a given vehicle. When a replan is triggered, a new route_assignments row is inserted with the updated sequence; the previous row is retained. The route_events table records REPLAN_TRIGGERED with the reason code, so the full history of every sequence change is visible. The driver's app reads the latest route_assignments row; the previous plan is never overwritten and remains accessible for audit.

How does the platform handle transit inventory during inter-depot transfers?

An inter-depot transfer writes two inventory_transaction rows atomically: TRANSFER_OUT from the source location and a TRANSFER_IN_TRANSIT record that does not add to available inventory at the destination. When the receiving warehouse confirms receipt, the TRANSFER_IN_TRANSIT is superseded by a TRANSFER_IN row that makes the stock available at the destination. At no point is the stock double-counted: it is either at the source (before TRANSFER_OUT) or in transit (between the two events), but never at both simultaneously.

How long does it take to deploy a distribution platform with Scrums.com?

Scrums.com deploys dedicated engineering teams within 21 days. The team works within your existing warehouse infrastructure, integrates with your carrier contracts and WMS via adapter layers, and delivers core receiving, fulfilment, and route planning functionality in the first sprint. Scope and timeline are agreed before engagement begins.

Want to Know if Scrums.com is a Good Fit for Your Business?

Get in touch and let us answer all your questions.

Book a Demo

Don't Just Take Our Word for It

Hear from some of our amazing customers who are building with Scrums.com Teams.

"Scrums.com has been a long-term partner of OneCart. You have a great understanding of our business, our culture and have helped us find some real tech rockstars. Our Scrums.com team members are high-impact, hard working, always available, and fun to have around. Thanks a million!"
CTO, OneCart
On-demand marketplace connecting users and top retailers
"The Scrums.com Team is always ready to take my call and assist me with my unique challenges. No problem is to big or small. Great partner, securing strong talent to support our teams."
CIO, Network
Leading digital payments provider
"Finding great developers through Scrums.com is easier than explaining to my mom what I do for a living. Over the past couple of years, their top-tier devs and QAs have plugged seamlessly into Payfast by Network, turbo-charging our sprints without a hitch."
Engineering Manager, PayFast by Network
A secure digital payment processor for online businesses
"Our project was incredibly successful thanks to the guidance and professionalism of the Scrums.com teams. We were supported throughout the robust and purpose-driven process, and clear channels for open communication were established. The Scrums.com team often pre-empted and identified solutions and enhancements to our project, going over and above to make it a success."
CX Expert, Volkswagen Financial Services
Handles insurance, fleet and leasing
"The Scrums.com teams are extremely professional and a pleasure to work with. Open communication channels and commitment to deliver against deadlines ensures successful delivery against requirements. Their willingness to go beyond what is required and technical expertise resulted in a world class product that we are extremely proud to take to market."
Product Manager, BankservAfrica
Africa's largest clearing house
“Scrums.com Team Subscriptions allow us to easily move between tiers and as our needs have evolved, it has been incredibly convenient to adjust the subscription to meet our demands. This flexibility has been a game-changer for our business. Over and above this, one of their key strengths is the amazing team members who have brought passion and creativity to our project, with enthusiasm and commitment. They have been a joy to work with and I look forward to the continued partnership.”
CEO & Co-Founder, Ikue
World's first CDP for telcos
“Since partnering with Scrums.com in 2022, our experience has been nothing short of transformative. From day one, Scrums.com hasn't just been a service provider; they've become an integral part of our team. Despite the physical distance, their presence feels as close and accessible as if they were located in the office next door. This sense of proximity is not just geographical but extends deeply into how they have seamlessly integrated with our company's culture and identity.”
SOS Team, Skole
Helping 60k kids learn, every day
"Scrums.com joined Shout-It-Now on our mission to empower young women in South Africa to reduce the rates of HIV, GBV and unwanted pregnancy. By developing iSHOUT!, an app exclusively for young women, and Chomi, a multilingual GBV chatbot, they have contributed to the critical task of getting information & support to those who need it most. Scrums.com continues to be our collaborative partner on the vital journey."
CX Expert, iShout
Empowering the youth of tomorrow
"Scrums.com has been Aesara Partner's tech provider for the past few years; and with the development support provided by the Scrums.com team, our various platforms have evolved. Throughout the developing journey, Scrums.com has been able to provide us with a team to match our needs for that point in time."
Founder, Aesara Partners
A global transformation practice

Find Related App Types

Transport app

Shipment tracker app

GPS Tracking App

Telecoms app

Privacy Protection app

Banking App