A Flutter e-commerce application showcasing offline-first architecture, multi-locale support, and clean state management — backed by Supabase.
- Offline-first — Browse, add to cart, and place orders without a connection. Changes sync automatically when back online.
- Multi-locale — English, French, and Arabic (RTL) with full i18n support.
- Authentication — Supabase email/password login, registration, and session restore.
- Product catalog — Search, filter, bookmarks, and recently viewed.
- Cart & orders — Full checkout flow with order history.
- Realtime notifications — Live updates via Supabase Realtime.
- Profile & avatar — Profile sync and avatar upload to Supabase Storage.
- Light / dark theme — Persisted user preference.
| Concern | Library |
|---|---|
| Backend | Supabase (Postgres, Auth, Storage, Realtime) |
| State management | Riverpod 2.x |
| Navigation | GoRouter |
| Local database | Drift (SQLite) |
| HTTP client (offline queue) | Dio |
| Connectivity | connectivity_plus |
| Localization | Flutter gen-l10n |
The app uses a repository pattern with an offline-first data flow:
UI → Provider → Repository → Local DB (fast)
↘ Supabase (when online, if cache stale)
Write operations that happen offline are queued in a PendingOperations table and replayed against the Supabase REST API when connectivity is restored, with exponential backoff retry logic.
lib/
├── config/ # Theme, colors, constants, supabase_config.dart
├── data/
│ ├── local/ # Drift tables and local data sources
│ └── remote/ # Supabase data sources + Dio client (offline queue)
├── models/ # Data models
├── navigation/ # GoRouter configuration (auth redirect)
├── providers/ # Riverpod providers
├── repositories/ # Offline-first repository implementations
├── screens/ # UI screens
├── services/ # ConnectivityService, SyncManager, OfflineQueueService
├── utils/ # Validators, helpers
└── widgets/ # Reusable UI components
Create a project at supabase.com, then run the SQL from docs/supabase/PLAN.md (tables, RLS policies, storage bucket, Realtime). Copy your Project URL and anon key from Settings → API.
cp scripts/dart_define.sh.example scripts/dart_define.sh
# Edit scripts/dart_define.sh and fill in SUPABASE_URL and SUPABASE_ANON_KEYscripts/dart_define.sh is gitignored and must never be committed.
# Install dependencies
flutter pub get
# Generate Drift database code and mocks
dart run build_runner build --delete-conflicting-outputs
# Generate localization files
flutter gen-l10n
# Run the app (credentials injected at build time)
bash scripts/run_app.sh
# Or target a specific device
bash scripts/run_app.sh -d <device_id>GitHub Actions runs on every push to main / develop and every pull request to main:
- analyze-and-test —
flutter analyze+flutter test --coverage - build-apk — release APK artifact (main branch only)
Add SUPABASE_URL and SUPABASE_ANON_KEY as repository secrets in GitHub (Settings → Secrets → Actions) before the first CI run.
This project is also a structured testing reference for the Flutter community. Every test file, comment, and decision is explained — not just the what, but the why. If you're writing Flutter tests for the first time or looking for a real-world example to learn from, start with the guides below.
| Guide | What you learn |
|---|---|
| Philosophy | The strategy behind the entire test suite — why fakes over mocks, why keys matter, how the pyramid applies |
| 00 — App Refactoring | Every change made to app code for testability, and why each change was necessary |
| 01 — Models | Unit testing pure Dart — AAA pattern, computed properties, JSON round-trips |
| 02 — Providers | Testing Riverpod state — ProviderContainer, fakes, async state, error handling |
| 03 — Widgets | Testing UI components — pumpApp, key-based finding, interaction testing |
| 04 — Screens | Testing full screens — navigation, loading/error/empty states, form submission |
| 05 — Integration | Testing user flows across multiple screens |
| 06 — Golden | Visual regression testing — themes, locales, RTL |
| 07 — Async & Mocking | pumpAndSettle vs pump, awaiting provider state, when to use Mockito |
flutter test test/unit/ # Models and providers
flutter test test/widget/ # Component and screen tests
flutter test test/integration/ # User flow tests
flutter test test/golden/ # Visual regression (macOS only)
flutter test --coverage # With coverage reportTranslations live in lib/l10n/. After adding keys to app_en.arb, run:
flutter gen-l10nSupported locales: en_US, fr_FR, ar_TN.