Discovery & data model
Offline-operation audit, per-store inventory model, customer journey for parents in the US and EU, GDPR and CCPA scoping, App Store and Google Play submission planning.
Case study · Retail · E-commerce
How we shipped a native Swift + Kotlin marketplace for an offline children's-goods chain — a frictionless signup, a smart catalog with flexible search, a two-tap checkout, an admin panel for the business team, and a two-way inventory sync that keeps online and offline stock aligned without manual work, all under US and EU audience expectations and GDPR + CCPA framing.
The Malish team came to us with a successful offline chain of children's-goods stores and a clear digital ambition: bring the assortment online without forcing parents to travel to a store with kids in tow, and reach demand beyond the walking radius of each location. The constraint was not aspirational; it was operational. The offline inventory operation works, the store staff knows the catalog, and the chain's competitive advantage is the assortment curation that earned its reputation. The digital surface had to extend that operation, not replace it — and could not introduce a stock-misalignment incident that breaks customer trust in either direction. The buyer profile spans US and EU consumer-retail patterns for similar chains expanding online: parents who research on the phone in the evening, expect predictable inventory accuracy, and re-purchase on a sub-30-second flow when the product is already known. SaaS marketplace platforms were eliminated because their vendor-defined inventory rules and integration constraints fight the chain's own assortment logic. A Flutter MVP was considered and de-prioritized because retail polish — system-native haptics, predictable accessibility, idiomatic platform behavior — is exactly where a children's-goods buyer notices the difference, and the trust premium on this category does not survive an uncanny-valley UI. The result is a native Swift iOS client, a native Kotlin Android client, a Symfony backend with a React admin panel, ElasticSearch-powered catalog, two-way inventory sync with the offline stores, and integrated delivery — all positioned for audiences across the US and EU under GDPR and CCPA expectations from launch.
A snapshot of what the Malish build delivered across native iOS, native Android, the Symfony admin, and the multi-store inventory sync in its first production cycle.

The platform decision dominates every other architectural choice on a retail marketplace where buyer trust is the product. We chose native Swift on iOS and Kotlin on Android over Flutter and SaaS marketplace platforms because the trade-offs line up cleanly with the chain's competitive advantage. Native Swift and Kotlin deliver the platform-idiomatic feel a retail buyer notices in the first three taps — accurate haptic feedback, system-native navigation, predictable accessibility, and a tap-to-purchase flow that feels indistinguishable from the buyer's other commerce apps. Flutter is a legitimate alternative when the brand explicitly accepts a slight uncanny-valley UI and prioritizes single-codebase velocity over retail polish; for a children's-goods chain whose trust premium does not survive that trade-off, native wins.
SaaS marketplace platforms were eliminated because their vendor-defined inventory rules and integration constraints fight the chain's own assortment logic and the multi-store stock alignment the operation already runs. A Shopify-plus-custom-mobile-wrapper option was considered and de-prioritized because the lock-in surface compounds — payment provider, theme, inventory model, app-extension limits — and the chain's competitive moat is exactly the curation that a templated marketplace flattens. The whole stack — Swift, Kotlin, Symfony, React admin, ElasticSearch, PostgreSQL, Redis — is open and citable end-to-end, with no proprietary platform that locks the ops team into a single vendor.
| Dimension | Native (Malish) | Flutter | SaaS marketplace platform |
|---|---|---|---|
| Native polish | Platform-idiomatic — haptics, navigation, accessibility | Close, but uncanny-valley risk on retail | Vendor-defined; varies by template |
| Inventory-sync flexibility | First-party Symfony connector per store | First-party — same Symfony backend | Vendor connector; limited extension |
| Multi-store fit | Per-store availability in catalog | Possible; same backend | Vendor's multi-store model — opinionated |
| Marketplace SaaS lock-in | None — fully owned stack | None — fully owned stack | High — payment, theme, inventory |
| Time to launch | 14–22 weeks for MVP | 10–18 weeks — single codebase | 4–10 weeks — template-defined |
| App Store / Play Store fit | First-class native binaries | Acceptable; review patterns known | Vendor's app — branded shell |
| Compliance fit (US & EU) | First-party — GDPR + CCPA designed in | First-party — same posture | Vendor-controlled — varies by region |
Platform references: Apple Swift documentation, Kotlin documentation, Symfony documentation.

The iOS client is built in Swift with a UIKit-plus-SwiftUI hybrid for the screens where SwiftUI's velocity helps and UIKit's predictability matters. The entire user-facing surface is structured around a smart catalog with ElasticSearch-backed flexible search — by brand, category, age range, size, store, and free-text terms parents actually use — and a two-tap checkout that collapses the returning-buyer flow to its smallest credible surface. One tap confirms the cart with the default delivery address and stored payment method; the second tap places the order with a final review step. Apple Pay and stored cards pre-populate the payment surface; address autocomplete pre-populates delivery.
The signup is frictionless by design — a parent with a toddler on their hip has no patience for a multi-screen onboarding. Store selection on first launch is location-aware with a manual override; subsequent launches default to the last-selected store. Push notifications for promotions, order status, and pickup-ready signals run on Apple Push Notification service with explicit consent on first authorization. The iOS surface is delivered as part of our mobile app development practice and shares its design system with the Android client through a shared design-tokens spec rather than a shared codebase.

The Android client is written in Kotlin with Jetpack Compose for the UI layer and the same ElasticSearch-backed catalog the iOS client consumes. The catalog computes per-store availability rather than a single chain-wide number, so a buyer who picks up in store sees stock for that store, and a delivery buyer sees stock from the nearest fulfilling store. The multi-store fit was the dominant design constraint — a children's-goods chain whose stores carry overlapping but not identical assortments cannot survive a single chain-wide stock number that lies to the buyer in either direction.
Behind the catalog, the order workflow engine on the Symfony backend handles state transitions — placed, picked, ready, dispatched, delivered — with webhook events to the offline stores' staff terminals and push notifications to the buyer. Google Play Billing handles any in-app purchases; the delivery-provider API integration carries the courier handoff so the chain does not coordinate couriers by hand. The same engineering team carries iOS and Android in lockstep as part of our iOS and Android engineering practice, and the React admin panel — a separate but co-designed surface — sits inside the same Symfony deployment for the ops team.

Malish's privacy posture was an architecture decision before it was a banner. Personal data on the mobile clients is limited to what is necessary for checkout, delivery, and re-purchase; the data model encodes retention windows per entity so a delivered-order record purges on a schedule rather than accumulating indefinitely. Children's data is intentionally not collected — the buyer is the parent, the catalog is for children's goods, but the app does not solicit child-identifying information beyond a generic age-range filter on the catalog.
The two-way inventory sync is the operational backbone. Each offline store has a typed connector that emits webhook updates on stock changes — sales, restocks, manual corrections — and the Symfony backend ingests, reconciles, and propagates to the mobile catalog. The reconciliation log is exposed in the React admin panel so an operator can debug a discrepancy in minutes rather than reconcile two systems by hand. Access logs are structured and rotated; every catalog change, every order state transition, and every consent decision is recorded with an immutable audit trail. The posture is built to align with GDPR obligations for users in the European Union and CCPA / CPRA obligations for users in California and the broader United States.
Compliance posture: GDPR-aligned · ISO 27001 ready · SOC 2 Type II in progress · HIPAA-capable · CCPA-acknowledged.
A five-phase build that took Malish from an offline-only retail chain to a native iOS + Android marketplace with a multi-store inventory sync and integrated delivery.
Offline-operation audit, per-store inventory model, customer journey for parents in the US and EU, GDPR and CCPA scoping, App Store and Google Play submission planning.
Symfony skeleton, typed REST API, ElasticSearch catalog, per-store availability model, order workflow engine, Redis cache, two-way inventory sync skeleton.
Swift iOS client and Kotlin Android client built in lockstep, smart catalog UX, two-tap checkout, push notifications, Apple Pay and Google Play Billing integration.
React admin panel with role-based access, order dashboard, delivery-provider API integration, reconciliation log, audit-ready hardening, third-party readiness scaffolding.
App Store + Google Play submission across US and EU storefronts, offline-store rollout of the inventory connectors, ops-team onboarding, analytics dashboards.
Malish's order workflow is the part of the build that compounds operationally. The Symfony backend hosts a workflow engine that drives orders through placed, picked, ready, dispatched, and delivered states with explicit transition guards and webhook fan-out to the offline stores' staff terminals and the buyer's push channel. The delivery-provider API integration carries the courier handoff: when an order enters the "ready" state, the backend requests a courier from the integrated provider, hands off the address payload, and listens for status updates that propagate back to the buyer in near real time. Cash-on-delivery and card-on-delivery flows are supported alongside in-app payment for the buyer profiles where that choice still matters. The React admin panel wraps the workflow with a role-based access model — store associate, store manager, central ops, finance — and an audit trail that survives team turnover. Flexible product and category management lets the business team add a brand, a category, an age range, or a seasonal collection without a developer in the loop; the same admin surface carries promotional campaigns, banner scheduling, and the CRM-style buyer view the ops team uses for repeat-purchase outreach. Adding a new store to the chain is a one-page configuration change against the same admin panel: a row, an inventory connector, a delivery-zone polygon, and the store appears in the multi-store catalog without a deploy.
Malish launched on Apple App Store and Google Play with storefronts active across the United States and the European Union for retail chains expanding online. The same architecture serves a multi-store children's-goods chain in California, New York, Texas, Florida, or Washington in the US, and in the Netherlands, Germany, France, Ireland, or Sweden in the EU, without per-region forks of the codebase. Consent flows are region-aware at the client layer: buyers from the EU and EEA receive a GDPR-style granular consent screen with separate toggles for any optional product analytics; buyers from California receive a CCPA-style "Do Not Sell or Share My Personal Information" disclosure in the same flow. Data-handling practices are aligned with GDPR for European users and with the US state-privacy patchwork — CCPA / CPRA (California), VCDPA (Virginia), CPA (Colorado), CTDPA (Connecticut), UCPA (Utah), TDPSA (Texas), and Oregon CPA. Because the data model minimizes personal data by design and explicitly does not solicit child-identifying information, regional compliance reduces to honest disclosure and a clean consent flow rather than per-jurisdiction data segregation.
Infrastructure rolled out across EU and US regions in parallel — Netherlands, Germany, France, Sweden, and Ireland for EU coverage; US East and US West for North America — so the apps serve both markets with low latency from launch. Both the App Store age rating and the Google Play content rating were calibrated for the children's-goods retail feature set, and the in-app privacy policy was drafted to document the architecture above, citing GDPR obligations and California CCPA obligations directly. The engineering team behind the build sits across CET and runs a CET workday with East-Coast US overlap (9 AM–1 PM ET) for stand-ups, store-review choreography, and incident response — the timezone that lets a US-based retail operator and an EU engineering team share four hours of live overlap every day. The marketplace serves US & EU audiences as one unified surface.
The active custom software development roadmap for Malish includes a loyalty subsystem with per-store tiering and a parent-facing rewards wallet, a store-locator surface with real-time hours and pickup-window booking, an expanded delivery-zone model for cross-store fulfillment, and a wholesale tier for B2B customers in the US and EU childcare segment. A web companion surface is scoped as a phase-two extension — sharing the Symfony backend and the design-tokens spec with the native clients — to capture desktop research traffic without forcing parents off mobile. Infrastructure plans include further reconciliation-log automation, an internal stock-misalignment alerting harness, and a future independent readiness assessment scaffolded into the cloud & DevOps roadmap.
If you are planning a native iOS + Android marketplace, a multi-store retail chain going online, or any consumer-retail product where the inventory sync and the platform polish both have to land together for audiences in the US and EU, we have shipped this stack end-to-end and can compress the build timeline meaningfully. The engineering team behind it sits inside YuSMP Group. We work fixed-price for well-scoped MVPs and on dedicated development teams for ongoing delivery, with a CET workday and a guaranteed East-Coast US overlap (9 AM–1 PM ET) window for stand-ups, demos, and incident response.
A native iOS plus Android local marketplace with a Symfony backend, ElasticSearch catalog, two-tap checkout, and a basic admin panel typically costs $140k–$310k for an MVP. Adding two-way inventory sync with the offline stores, delivery-service integration, role-based admin access, ElasticSearch-powered flexible search, and a hardened CRM-grade admin console brings a full-featured product to $360k–$680k. The dominant cost drivers are the inventory sync layer, the multi-store catalog logic, and the App Store and Google Play submission and review choreography.
Native Swift on iOS and Kotlin on Android deliver the platform-idiomatic feel a retail buyer notices in the first three taps — accurate haptic feedback, system-native navigation, predictable accessibility. Flutter is a legitimate alternative when the brand explicitly accepts a slight uncanny-valley UI and prioritizes single-codebase velocity. SaaS marketplace platforms lock the brand into vendor-defined inventory rules and integration constraints — fatal for a chain whose competitive advantage is the offline store network and its own assortment. For Malish, native won on retail polish and integration flexibility.
A defensible two-way inventory sync is an architecture decision. Each offline store has a typed connector that emits webhook updates on stock changes; the Symfony backend ingests, reconciles, and propagates to the mobile catalog. The catalog computes per-store availability rather than a single chain-wide number, so a buyer who picks up in store sees stock for that store. The admin panel exposes the reconciliation log so an operator can debug a discrepancy in minutes rather than reconcile two systems by hand.
A two-tap checkout flow collapses the buyer's decisions into the smallest credible surface: one tap confirms the cart with the default delivery address and stored payment method; a second tap places the order with a final review step. Stored cards, Apple Pay, and Google Play Billing pre-populate the payment surface; address autocomplete pre-populates the delivery surface; and a substitution toggle lets the buyer pre-authorize a swap for an out-of-stock item. The flow is the gold standard for repeat-purchase retail apps.
A focused MVP with native Swift and Kotlin clients, a Symfony backend, ElasticSearch search, a two-tap checkout, and basic admin tooling typically takes 14–22 weeks. Adding two-way inventory sync with the offline stores, delivery-service integration, role-based admin access, an analytics dashboard, and a loyalty subsystem adds 8–14 weeks. The audit-ready hardening pass — App Store and Google Play submission, KYC handoff for payments, third-party readiness review — should be budgeted at 3–5 weeks of dedicated work.
Related cases
Customer app, picker app, admin panel for a regional grocery chain — designed-from-scratch logistics.
View case → Retail · FloristryDiscovery for a flower delivery app pair — stock-aware catalog, three-step checkout, florist inventory.
View case → Automotive · E-commerceAuto-parts marketplace plus seller CRM — VIN search, multi-location inventory.
View case →