Case study

Dyshez

Food delivery

A full-stack food delivery app with a Supabase backend (real-time orders on Postgres) and a custom rewards & loyalty system. Live on both the App Store and Google Play.

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. 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. 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. 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. 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. 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

Dyshez screenshot 1Dyshez screenshot 2Dyshez screenshot 3Dyshez screenshot 4Dyshez screenshot 5

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)