Context & Problem
A supply-chain business moving produce from farms through collection centers to distribution centers ran its operations on backend-managed documents — purchase orders, deliveries, sales orders, invoices, receipts, and route trip sheets. Field and operations staff needed to raise and view those documents where the work happens rather than at a back-office terminal, which meant a mobile client over the business's existing backend and its established entity model.
The backend already defined the business: over twenty entity types covering the chain from farm to distribution center. The mobile app's job was to expose that model faithfully to field staff — browsing inventory and routes, raising purchase orders, recording deliveries and receipts, creating sales orders and invoices, and filing trip sheets — without redefining any of it. That made the integration surface the core engineering problem: many endpoints, one consistent way to call them, and sessions that survive a full field day without re-authentication.
Design Constraints
- legacyThe app had to conform to an existing supply-chain backend and its entity model — over twenty endpoint domains, none of them negotiable.
- platformOne React Native codebase had to serve both iOS and Android field devices.
- teamLong field days meant sessions had to renew silently — bouncing a user to login mid trip-sheet was not acceptable.
Architecture Overview
Built a React Native app (iOS and Android) whose center of gravity is its API layer: one module per backend entity — auth, farms, collection centers, distribution centers, inventory, items, categories, customers, routes, units of measure, purchase orders and their deliveries, sales orders, invoices, receipts, reports, and trip sheets — all funneled through shared typed GET/POST gateways and a single config. Authentication is JWT with a dedicated refresh-token module for silent session renewal. Navigation pairs a native stack (splash, login) with a drawer of workflow hubs — dashboard, purchase, sale, invoice, receipt, and trip — plus form screens for creating items and sales orders. The UI uses material-style text fields, progress indicators, and popup menus, with connectivity awareness for field conditions.
Key Engineering Decisions
Outcomes & Lessons Learned
API Modules
Per-entity integration modules covering the backend's full supply-chain model
Field Workflows
Dashboard, purchase, sale, invoice, receipt, and trip-sheet workflows in one app
Platforms
Single React Native codebase serving both field platforms
Retrospective
- Hand-mirroring a large backend costs forever: with 20+ hand-written entity modules, every backend contract change meant editing a module by hand. At this integration scale, a generated client from an API specification would have repaid its setup cost many times over.
- Partial TypeScript adoption protects less than it appears to: the API layer was typed but the screens consuming it stayed JavaScript, so type safety ended exactly at the boundary where the data got used. Typing the edges of a codebase without its consumers leaves the riskiest seam unchecked.
