The problem
Why it needed building
Most food apps are built around restaurants. Dyshez is built around dishes: people search for a specific dish, see real photos and videos from other diners, vote on the best version and follow people whose taste they trust. The app then grew into a platform with restaurant rewards, bookable live promos and direct ordering. That meant one app combining social discovery, maps, loyalty, bookings, payments and ordering, with heavy media on weak mobile networks, location-first content, loyalty points users can trust, and frequent releases without regressions.
My role
What I owned
- Shipped every production release from v1.23 to v1.40 on iOS and Android (Sep 2024 – today)
- Dish-first search and a clustered map explorer with Typesense and flutter_map
- Social feed with in-app camera, cropping, video trimming and resumable video uploads
- Restaurant rewards program with real-time updates over Supabase Realtime
- Promos Live booking with Stripe payments, and Dyshez Direct in-app ordering
- Release pipeline with Codemagic and Shorebird, plus Sentry, PostHog and Clarity monitoring
The approach
Key decisions
- 1
A hybrid architecture that scales
The app grew to about 775 Dart files and 160k lines of code. It is split into app, core, data, features and shared layers, with 19 feature modules. Dependencies point one way (features → data → core), and UI code never calls Supabase or Dio directly; it always goes through one of 31 repositories.
- 2
GetX with per-route bindings
GetX handles state, dependency injection and routing. Each route has its own binding, so controllers are released when a screen closes. A very large Supabase service file was split into domain-specific services and repositories.
- 3
Dish-first discovery
Typesense gives instant, typo-tolerant search over dishes and restaurants, with debounced queries to limit backend load. A flutter_map explorer with marker clustering, a live location marker and compass heading keeps dense areas readable, and "list by votes" rankings let the community pick the best dish in each category.
- 4
Rewards, promos and ordering
Restaurants run first-visit, base and milestone reward programs, with staff-authorised redemption, a points breakdown and QR visit logging. Promos Live takes users from a time-limited deal to reservation, Stripe payment and confirmation. Dyshez Direct adds multiple carts, scheduled orders, map-picked delivery addresses, order tracking and separate ratings for order, delivery and restaurant.
- 5
Platform features
Email OTP, Google and Apple sign-in; push notifications and an in-app notification center; deep links to dishes, restaurants and profiles; referrals; multi-language support generated from one JSON source; in-app update prompts and a maintenance mode. Dev, beta and production flavors keep configuration separate, and secrets come from Doppler instead of the code.
The product
Screens
Swipe to see more · tap a screen to open it full size
Challenges
The hard parts
Large videos on mobile networks
Uploads used to fail and restart from zero. Videos now upload over the TUS protocol to Cloudflare Stream using signed URLs, so an upload resumes after a network drop.
Maps with hundreds of pins
Restaurants, promos and rewards all depend on location. Marker clustering and debounced map-search queries keep the map responsive in dense areas.
Loyalty state users can trust
Supabase Realtime subscriptions on the rewards, milestone and notification tables update the UI the moment a milestone is reached, with retry logic and careful cleanup so subscriptions do not go stale or leak.
Fast fixes without waiting on store review
Shorebird ships Dart-only hotfixes over the air, while Codemagic builds signed store releases per branch. Sentry, PostHog and Microsoft Clarity make crashes and stuck users visible.
Staying on current platforms
The app moved to Flutter 3.44 and Android target API 36, migrating the packages that broke along the way.
Consistency across a large team
About 10 mobile developers have worked on the app. A written architecture guide, a release log and AI-agent rules that scaffold features in the house style keep the code consistent.
Results
What it achieved
- Shipped every production release from v1.23 to v1.40 (Android build 40 → 94)
- 1,600+ of the project’s 3,800+ commits, the most of any contributor, despite joining a year in
- Grew a social food-sharing MVP into a platform with loyalty, bookings, payments and direct ordering
- Kept a ~160k-line codebase on current tooling: Flutter 3.44 and Android 16 (API 36)




