15 - Master Dev Help
A single lookup sheet: "I want to change X in the Flutter app — which file do I open?" Pick a category from the index below, scan the table, click through to the file or to the detailed page that explains the pattern.
This is a cheat-sheet, not a tutorial. Every row answers one question: where does this live? For the why and the how of a topic, click the "see also" link in each section to jump to the full guide.
Jump to
Entry Point & Routing
| I want to change… | Open this file | Notes |
|---|---|---|
| App bootstrap / MaterialApp / theme wiring | lib/main.dart lib/app.dart | main() runs platform init then pushes App as the root widget. |
| The route table (all stage screens) | lib/config/routes.dart | Single source of truth for route names and the stageRoutes map used by resume logic. |
| Initial screen after splash | lib/screens/stage0_arrival.dart | Handles fresh vs resume flow, calls getJourneyStatus() and navigates. |
| Deep-link handling | lib/app.dart (MaterialApp onGenerateRoute) | Named routes from routes.dart are matched here. |
Screens (one per stage)
Every eKYC stage is a single Stateful widget under lib/screens/stage<N>_<name>.dart. The pattern is: capture input → call api.* → navigate or show error. See 06 - Stage Walkthrough for an end-to-end trace.
| Stage | File | What happens here |
|---|---|---|
| 0 — Arrival / splash | lib/screens/stage0_arrival.dart | Device init, session resume logic, route picker. |
| 1 — Registration | lib/screens/stage1_registration.dart | Mobile, name, consents, signup call. |
| 2 — OTP verification | lib/screens/stage2_otp.dart | OTP input, resend, verifyOtp call. |
| 3 — Email verification | lib/screens/stage3_email.dart | Email input, email OTP. |
| 4 — PAN confirmation | lib/screens/stage4_pan.dart | PAN confirm / entry, KRA pre-fill. |
| 5 — Aadhaar via DigiLocker | lib/screens/stage5_digilocker.dart | DigiLocker webview / callback handling. |
| 6 — Bank verification | lib/screens/stage6_bank.dart | Account + IFSC, penny-drop SDK, result confirm. |
| 7 — Liveness + photo match | lib/screens/stage7_liveness.dart | Camera permission, liveness SDK, face-match result. |
| 8 — Signature | lib/screens/stage8_signature.dart | Signature pad, upload. |
| 9 — Personal details + nominees | lib/screens/stage9_personal.dart | Occupation, income, FATCA, nominee flow, income-proof upload. |
| 10 — Income proof (optional) | lib/screens/stage10_income.dart | Alternative income-proof path (OneMoney AA). |
| 11 — Final validation | lib/screens/stage11_validation.dart | Summary screen before document generation. |
| 12 — Document generation | lib/screens/stage12_document.dart | Polls AOF generation, shows status. |
| 13 — eSign | lib/screens/stage13_esign.dart | Launches eSign flow + handles callback. |
| 14 — Account creation | lib/screens/stage14_account.dart | Polls CBOS account creation status. |
| 15 — Congrats / activation | lib/screens/stage15_congrats.dart | Success state, payment CTA, downstream sync. |
Widgets (reusable)
All shared widgets live in lib/widgets/. See 08 - Widgets Reference for props and usage.
| Widget | File | Used for |
|---|---|---|
| LoadingOverlay | lib/widgets/loading_overlay.dart | Full-screen spinner over a screen during async calls. |
| SessionTimer | lib/widgets/session_timer.dart | Inactivity countdown + session-expired dialog. |
| BackButtonHandler | lib/widgets/back_button_handler.dart | Shows "Exit journey?" confirmation on Android back / swipe. |
| ProgressBar | lib/widgets/progress_bar.dart lib/widgets/striped_progress_painter.dart | Journey progress header (stage N of 15). |
| ErrorDialog | lib/widgets/error_dialog.dart | .show (returns Future), .showSuccess (void snackbar). |
| ConsentCheckbox | lib/widgets/consent_checkbox.dart | Legal text checkbox with link support. |
| OtpInput | lib/widgets/otp_input.dart | Autofill-aware OTP boxes. |
Services (API, storage, analytics)
Only three services exist — on purpose. All backend calls go through ApiService. See 07 - ApiService.
| Service | File | Responsibility |
|---|---|---|
| ApiService | lib/services/api_service.dart | Every HTTP call. Headers, JWT, _post / _get helpers, ApiResult<T> wrapper. If the backend is involved, it goes here. |
| StorageService | lib/services/storage_service.dart | SharedPreferences-backed persistence for leadId, JWT, resume state, device id. Singleton via getInstance(). |
| AnalyticsService | lib/services/analytics_service.dart | Event tracking wrapper (mostly no-op in dev, Clevertap-bound in prod). |
Models & data classes
All DTOs are plain Dart classes with fromJson factories under lib/models/. No code generation, no freezed — everything is hand-written so the Flutter build is simple. Grep for the class name when you need to update a backend-matching DTO.
Config, Theme & Assets
| I want to change… | Open this file | Notes |
|---|---|---|
| Backend base URL per environment | lib/config/api_config.dart | Set via --dart-define=ENV=dev|uat|prod. |
| Theme colors / fonts | lib/config/theme.dart | Single AppTheme with a Material 3 color scheme and Google Font Inter. |
| Route names | lib/config/routes.dart | Constants only; no registration logic. |
| Asset paths (Lottie, images, svg) | lib/config/assets.dart | One constant per asset so refactors are one-file changes. |
| Register a new asset | pubspec.yaml → flutter.assets | Then add a constant in lib/config/assets.dart. |
| Change the app name / bundle id / icon | android/app/build.gradle ios/Runner/Info.plist android/app/src/main/res/ ios/Runner/Assets.xcassets/ | Platform-specific. Don't forget to regenerate launcher icons if changing. |
State & data flow
No global state manager. Each screen is a StatefulWidget that owns its own local state. Cross-screen data goes through StorageService (persisted) or via the backend (source of truth). See 05 - Coding Patterns for the reasoning.
| Need… | Use… | Notes |
|---|---|---|
| Local screen state (form inputs, toggles) | setState in a StatefulWidget | No Bloc, no Provider, no Riverpod. |
| Data that survives app restart (leadId, JWT, resume) | StorageService | Async singleton via StorageService.getInstance(). |
| Cross-screen communication (current stage, user name) | Fetch from backend via ApiService → never pass via constructors across stages. | Keeps stage screens independently launchable (important for resume). |
| Error handling | ApiResult<T> returned from every ApiService call | Check .success and use .displayMessage or .errorCode. |
Platform-specific files
| Platform | Root folder | What lives there |
|---|---|---|
| Android | android/ | Gradle build files, AndroidManifest.xml, launcher icons, runtime permissions, Google Services config. |
| iOS | ios/ | Info.plist, Runner Xcode project, app icons, push entitlements. |
| Web | web/ | index.html, favicon, manifest. Used by flutter build web. |
| Windows / macOS / Linux | windows/ / macos/ / linux/ | Desktop shells; not part of the shipping product but kept buildable. |
Build, Run & Environments
| I want to… | Run this | Notes |
|---|---|---|
| Run on a connected device in dev | flutter run --dart-define=ENV=dev | Default flavour = dev. See 01 - Getting Started. |
| Run on web (Chrome) | flutter run -d chrome --dart-define=ENV=dev | Some native plugins stub out on web — see plugin docs. |
| Point at a different backend | --dart-define=API_BASE_URL=http://<host>:5000 | Set inside api_config.dart. |
| Build a release APK | flutter build apk --release --dart-define=ENV=prod | Signed with Play upload key in CI. |
| Build a release IPA | flutter build ipa --release --dart-define=ENV=prod | Requires Apple signing set up in Xcode. |
| Build web for staging | flutter build web --release --dart-define=ENV=uat | Drops output to build/web. |
| Refresh dependencies after pulling | flutter pub get | Or flutter clean && flutter pub get if things get weird. |
Debugging & Logging
| I want to… | Use this | Notes |
|---|---|---|
| See network requests live | DevTools → Network tab or debugPrint inside ApiService | Every request already logs the URL and status code in dev mode. |
| Inspect the widget tree | DevTools → Widget Inspector (Flutter) | Select an element on the device to jump to its source. |
| Debug layout issues | DevTools → Layout Explorer | Or add debugPaintSizeEnabled = true in main.dart. |
| Debug a specific screen in isolation | Push it directly from a dev-only button | Every stage screen can be launched standalone; data comes from the backend. |
| Set a breakpoint in VS Code / Android Studio | Click the gutter next to a line → run with debugger | Hot reload still works during a breakpoint. |
| Check what's stored locally | DevTools → StorageService getters in a watch expression | Keys: leadId, jwtToken, resumePage, currentStage, deviceId. |
See 10 - Debugging for the full guide.
Static Analysis (Sonar)
| I want to… | Run this | Notes |
|---|---|---|
| Run the analyzer | flutter analyze | Uses analysis_options.yaml (which includes very_good_analysis). |
| Auto-fix all safe issues | dart fix --apply | Big diff — review before committing. |
| Generate the HTML Sonar report | node scripts/to_sarif.js → sarif html | Full workflow: 14 - Sonar Analysis. |
| Run the bulk fixers | scripts/fix_unawaited.js scripts/fix_inference.js scripts/fix_with_opacity.js | Each script is self-documenting. Re-run flutter analyze --write=... before re-running a fixer. |
Common "Where do I add…"
| New thing | Add it here | Don't forget |
|---|---|---|
| A new stage screen | lib/screens/stage<N>_<name>.dart Register route in lib/config/routes.dart Add to stageRoutes map for resume logic | Update StageDefinitions in the backend constants in lockstep. |
| A new backend API call | lib/services/api_service.dart → new method returning Future<ApiResult<T>> | Reuse _post / _get; they handle auth + error envelope. |
| A new DTO / model | lib/models/<name>.dart | Plain Dart class with fromJson factory. No codegen. |
| A new shared widget | lib/widgets/<name>.dart | Follow the wrapper style of existing widgets; see 08 - Widgets Reference. |
| A new asset (Lottie, PNG, SVG) | assets/… + pubspec.yaml + lib/config/assets.dart | All three steps or it won't load. |
| A new color / font weight | lib/config/theme.dart | Keep everything in the theme — do not inline colors in screens. |
| A new environment (e.g. STAGE) | lib/config/api_config.dart README for CI / launcher scripts | Flutter flavours are optional — --dart-define is the primary switch. |
| A platform permission | android/app/src/main/AndroidManifest.xml ios/Runner/Info.plist | Both platforms. Runtime check in Dart via permission_handler. |
| A new push channel / deep link | android + iOS config + lib/app.dart onGenerateRoute | Test with adb shell am start -W -a android.intent.action.VIEW -d <url>. |
Open 03 - Project Tour for the folder-by-folder walkthrough, 06 - Stage Walkthrough for an end-to-end trace of Stage 1, or 11 - How-To Guides for task-oriented recipes.