03 - Project Tour

A guided walk through the flutter_app/ folder structure. By the end of this page you'll know where every file lives and what it does.

Top-level Layout

flutter_app/Tree
flutter_app/
├── android/                # Native Android wrapper (Gradle, AndroidManifest)
├── ios/                    # Native iOS wrapper (Xcode, Info.plist, Podfile)
├── web/                    # Web entry (index.html, manifest.json, favicon)
├── windows/                # Windows desktop (optional target)
├── linux/                  # Linux desktop (optional target)
├── macos/                  # macOS desktop (optional target)
├── assets/
│   └── images/             # 41 Lottie/SVG/PNG assets (RISE logo, illustrations, icons)
├── lib/                    # ★ All Dart source code lives here
│   ├── config/
│   ├── models/
│   ├── services/
│   ├── screens/
│   ├── widgets/
│   ├── app.dart
│   └── main.dart
├── test/                   # Unit/widget tests (mostly empty, TBD)
├── pubspec.yaml            # Dependencies and asset registration
└── pubspec.lock            # Locked dependency versions
Focus on lib/

The android/, ios/, web/ folders are auto-generated platform wrappers. You rarely touch them. 99% of your work happens in lib/.

The lib/ Folder

flutter_app/lib/Tree
lib/
├── config/                         # Compile-time constants and config
│   ├── api_config.dart             # Base URL, routes, env flag, timeouts
│   ├── routes.dart                 # Named routes for all 16 stages
│   ├── theme.dart                  # MaterialApp theme (RISE colors, Inter font)
│   └── assets.dart                 # Static paths to Lottie/SVG/PNG assets
│
├── models/                         # Plain Dart classes with fromJson factories
│   ├── lead.dart                   # Lead (leadId, mobile, state)
│   ├── pan_result.dart             # PAN verification response
│   ├── bank_result.dart            # Bank verification response + isPreVerified
│   ├── otp_result.dart             # OTP verify response
│   ├── journey_status.dart         # Journey stage + progress
│   ├── nominee.dart                # Nominee data
│   └── api_response.dart           # Generic ApiResponse<T> wrapper
│
├── services/                       # Business logic / external interfaces
│   ├── api_service.dart            # ★ 60+ API methods, single file
│   ├── storage_service.dart        # Singleton SharedPreferences wrapper
│   └── analytics_service.dart      # Event tracking stub (debugPrint)
│
├── screens/                        # One file per stage screen
│   ├── stage0_arrival.dart         # Splash + session init + resume detection
│   ├── stage1_registration.dart    # Mobile + name + T&C
│   ├── stage2_otp.dart             # Mobile OTP verification
│   ├── stage3_email.dart           # Email (Google / KRA / Manual OTP)
│   ├── stage4_pan.dart             # PAN entry + NSDL verify
│   ├── stage5_digilocker.dart      # DigiLocker WebView + mock bypass
│   ├── stage6_bank.dart            # UPI RPD or manual or Decentro pre-verified
│   ├── stage7_liveness.dart        # Camera selfie + HyperVerge
│   ├── stage8_signature.dart       # Draw signature on canvas
│   ├── stage9_personal.dart        # Personal details + income + F&O + nominees
│   ├── stage10_income.dart         # Deprecated (redirects to stage 9)
│   ├── stage11_validation.dart     # Backend compliance validation (animated)
│   ├── stage12_document.dart       # AOF PDF generation
│   ├── stage13_esign.dart          # eMudhra/HyperVerge eSign WebView
│   ├── stage14_account.dart        # CBOS account creation
│   └── stage15_congrats.dart       # Success screen + Razorpay fund transfer
│
├── widgets/                        # Reusable widgets
│   ├── loading_overlay.dart        # Full-screen Lottie loader
│   ├── session_timer.dart          # 15-min inactivity timeout + warning
│   ├── back_button_handler.dart    # Intercepts device back button
│   ├── progress_bar.dart           # JourneyProgressBar (16-stage striped)
│   ├── striped_progress_painter.dart # CustomPainter for striped fill
│   ├── error_dialog.dart           # Error dialog + snackbar helpers
│   ├── otp_input.dart              # 4-digit OTP box input
│   └── consent_checkbox.dart       # Consent checkbox with rich text
│
├── app.dart                        # MaterialApp root (theme, routes)
└── main.dart                       # Entry point, orientation lock, storage init

The Five Sub-folders Explained

config/

Compile-time constants. Nothing here has state. All values are static. Read once at startup, never change.

FilePurposeJump to
api_config.dartAll backend endpoint paths as getters. Environment flag. Timeouts.09 - Config
routes.dartStatic route names (/, /otp, etc.) and stage → route map for resume logic.09 - Config
theme.dartMaterialApp ThemeData. RISE brand colors, Inter font, 8px button radius, AppBar style.09 - Config
assets.dartStatic path constants for Lottie JSONs, SVGs, PNGs.09 - Config

models/

Dart classes that mirror backend response shapes. Each has a fromJson factory. No methods beyond data access. Immutable where possible.

flutter_app/lib/models/api_response.dartDart
class ApiResponse<T> {
  final bool success;
  final String? message;
  final String? errorCode;
  final T? data;
  final String displayMessage;

  ApiResponse({
    required this.success,
    this.message,
    this.errorCode,
    this.data,
    required this.displayMessage,
  });

  static ApiResponse<T> ok<T>(T data, [String? msg]) => ...
  static ApiResponse<T> fail<T>(String msg, [String? code]) => ...
}

services/

Where the business logic and external interactions live. Three files only.

FilePurposeJump to
api_service.dart60+ methods, one per backend endpoint. Handles auth, headers, error handling, stage tracking.07 - ApiService
storage_service.dartSingleton. Wraps SharedPreferences. Stores leadId, sessionId, token, currentStage, last activity.07 - ApiService
analytics_service.dartStub. Currently just debugPrints events. Plug in Firebase/CleverTap later.07 - ApiService

screens/

One file per stage. Each file contains everything for that stage: the widget, local state, event handlers, API calls, validation, UI building. No BLoCs, no separate controllers.

Mental model

Each stage is self-contained. To understand Stage 6, open stage6_bank.dart - it's all there. No need to hunt across 5 files.

See 06 - Stage Walkthrough for a full trace of Stage 1.

widgets/

Reusable UI pieces. Five wrapper widgets handle cross-cutting concerns (loading, session timeout, back button, progress, error). No business logic.

See 08 - Widgets Reference for the full catalog.

pubspec.yaml - Dependencies

flutter_app/pubspec.yamlYAML
name: ekyc_app
description: MOSL EKYC 3.0 - Digital Account Opening Journey
version: 3.0.0+1

environment:
  sdk: '>=3.2.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.0                    # REST client used by ApiService
  shared_preferences: ^2.2.2      # Key-value storage (StorageService)
  path_provider: ^2.1.2           # File paths (for signature save)
  google_sign_in: ^6.1.6          # Stage 3 email Google OAuth
  file_picker: ^8.0.0             # Stage 9 income proof upload
  url_launcher: ^6.2.2            # Open external URLs (T&C, Razorpay redirect)
  webview_flutter: ^4.4.3         # Stage 5 DigiLocker, Stage 13 eSign
  permission_handler: ^11.1.0     # Camera/location permissions
  sms_autofill: ^2.3.0            # Stage 2 OTP auto-read
  signature: ^5.4.1               # Stage 8 signature canvas
  geolocator: ^11.0.0             # GPS for Stage 7 liveness
  razorpay_flutter: ^1.3.7        # Stage 15 mobile payment SDK
  image_picker: ^1.0.7            # Camera/gallery for selfie
  google_fonts: ^6.2.1            # Inter font from Google Fonts
  lottie: ^3.3.1                  # Lottie animations (loader, tick, congrats)
  flutter_svg: ^2.2.0             # SVG rendering (RISE logo, illustrations)

flutter:
  uses-material-design: true
  assets:
    - assets/images/              # Registers all 41 asset files

assets/images/

41 files. Copied from the old EkycDevProject app as part of the visual migration.

TypeCountExamples
Lottie animations (JSON)5ic_loader.json, ic_tick_animation.json, congratulation_animation.json, no_connection.json, riselogo.json
SVG illustrations12ic_rise_logo.svg, ic_register_illustration.svg, ic_pan_illustrator.svg, ic_selfieimage.svg, ...
PNG icons~21ic_tick_green.png, ic_calender.png, digilocker.png, ic_gpay.png, ...
WebP images3location.webp, location_on.webp, upi.webp

All assets are referenced via AppAssets constants in lib/config/assets.dart. Never hardcode a path string in a screen file - always use the constant.

Entry Points

flutter_app/lib/main.dartDart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'app.dart';
import 'services/storage_service.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Lock to portrait mode
  await SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);

  // Initialize singleton storage (async)
  await StorageService.getInstance();

  runApp(const EkycApp());
}

main.dart does three things: lock orientation, init storage, launch the root widget. The actual MaterialApp is in app.dart.