Skip to content

Mobile Developer Onboarding — Day 1

A practical guide to becoming productive on the Microtec ERP mobile apps.

Prerequisites: Complete the Day 1 Checklist for general access
Stack: Flutter, Dart, Melos, Git submodules


Mobile Apps Overview

Microtec has three Flutter mobile applications:

AppDirectoryDescriptionAudience
Business OwnerBoMobileApp/Tenant management and dashboardsBusiness owners
ERP MobileERPMobileApps/ERP modules (HR, Inventory, Sales)ERP users
Van SalesVanSalesMobileApp/Field sales and deliverySales representatives

All three apps share packages via Git submodules:

SubmodulePurpose
MobileDesignSystem/Shared UI components, design tokens, themes
MobileAPIClients/Auto-generated Dart API clients (from OpenAPI spec)
MobileSharedComp/Shared business logic, utilities, base classes

Step 1 — Install Flutter

The platform targets Flutter stable channel. Always use the version pinned in .flutter-version or pubspec.yaml at the repo root.

macOS

bash
# Install Flutter via FVM (Flutter Version Manager) — recommended
dart pub global activate fvm

# Install and use the project's Flutter version
fvm install
fvm use

# Verify
fvm flutter --version
# Expected: Flutter 3.x.x (stable channel)

Verify Dart SDK

Dart comes bundled with Flutter — no separate install needed.

bash
fvm dart --version
# Expected: Dart SDK version 3.x.x

Install Xcode (macOS — for iOS builds)

bash
xcode-select --install
sudo xcodebuild -license accept

# Install iOS simulator
xcrun simctl list devices

Install Android Studio and SDK

  1. Download from developer.android.com/studio
  2. Open Android Studio → SDK Manager → Install:
    • Android SDK Platform 34 (API level 34)
    • Android SDK Build-Tools 34.0.0
    • Android Emulator
bash
# Accept licenses
flutter doctor --android-licenses

# Verify setup
flutter doctor
# All required items should show ✓ or ✓ (with notes for optional items)

Step 2 — Install Melos

All three apps use Melos — a tool for managing multi-package Dart/Flutter workspaces. Melos runs scripts defined in melos.yaml and handles dependency resolution across packages.

bash
# Install Melos globally
dart pub global activate melos

# Verify
melos --version   # Minimum: 3.0.0

Why Melos?

Each Flutter app contains multiple Dart packages (feature packages, shared packages, API clients). Melos runs pub get on all packages in the correct order, resolves cross-package dependencies, and provides workspace-level scripts like melos run test that run tests across all packages simultaneously.


Step 3 — Clone with Submodules

The mobile repos use Git submodules for shared packages. You must initialise submodules after cloning:

bash
# Clone your target app — ALWAYS use --recurse-submodules
git clone --recurse-submodules \
  https://dev.azure.com/microtec/Microtec/_git/BoMobileApp
cd BoMobileApp

# If you already cloned without --recurse-submodules:
git submodule update --init --recursive

Update submodules after a git pull

bash
# After pulling changes, always sync submodules
git pull --recurse-submodules

# Or manually:
git pull
git submodule update --recursive

Submodule divergence

If you see submodule directories that appear empty (no files inside), run git submodule update --init --recursive. This is the most common Day-1 issue for mobile developers.


Step 4 — First-Time Workspace Setup

bash
cd BoMobileApp    # or ERPMobileApps / VanSalesMobileApp

# Step 4a: Bootstrap the workspace (links submodule packages to the workspace)
melos run init

# What 'init' does:
# 1. Runs pub get on all packages in dependency order
# 2. Generates code (Freezed, Riverpod, etc.) via build_runner
# 3. Generates API clients from OpenAPI specs in MobileAPIClients/

# Step 4b: Get dependencies (run after every git pull)
melos run get

Expected output after melos run init:

melos run init
   └─ Running script...

   ✓ MobileDesignSystem — pub get
   ✓ MobileSharedComp — pub get
   ✓ MobileAPIClients — pub get
   ✓ BoMobileApp — pub get
   ✓ MobileDesignSystem — build_runner build
   ✓ MobileAPIClients — openapi-generator
   ✓ BoMobileApp — build_runner build
   
   SUCCESS: All packages bootstrapped

Step 5 — Run the App

bash
# List available devices
flutter devices

# Run on connected device or simulator
melos run run

# Or run directly on a specific device
flutter run -d <device-id>

# Run with hot reload in debug mode
flutter run --debug

Environment Configuration

The apps use environment-specific configuration. The development config is pre-selected for local runs:

bash
# Run against the dev API (default)
melos run run

# Run against stage API
melos run run -- --dart-define=ENV=stage

Environment files are in lib/config/:

FileAPI Base URL
config_dev.darthttps://gateway.microtec-test.com
config_stage.darthttps://gateway.microtecstage.com
config_prod.darthttps://gateway.onlinemicrotec.com.sa

Step 6 — Run Tests

bash
# Run all tests across all packages
melos run test

# Run tests in a specific package
cd MobileSharedComp
flutter test

# Run a single test file
flutter test test/auth/auth_repository_test.dart

# Run with coverage
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html

Target: 80% code coverage (enforced in CI for new code).


Common Melos Commands

CommandDescription
melos run initFirst-time setup: pub get + code generation
melos run getRun pub get across all packages
melos run buildRun build_runner build across all packages
melos run runRun the app in debug mode
melos run testRun all tests
melos run build-apkBuild Android APK (release)
melos run build-ipaBuild iOS IPA (release)
melos run lintRun flutter analyze across all packages
melos run formatRun dart format across all packages

Project Structure (BoMobileApp example)

BoMobileApp/
├── melos.yaml                  ← Workspace config; defines all scripts
├── pubspec.yaml                ← Root pubspec; app entry point
├── lib/
│   ├── main.dart               ← Entry point
│   ├── config/                 ← Environment configs
│   ├── features/               ← Feature packages (one folder per feature)
│   │   ├── auth/
│   │   ├── dashboard/
│   │   └── tenant-management/
│   └── shared/                 ← App-level shared widgets
├── MobileDesignSystem/         ← Git submodule: shared UI
├── MobileAPIClients/           ← Git submodule: generated API clients
├── MobileSharedComp/           ← Git submodule: shared business logic
└── test/

Feature folder structure

features/dashboard/
├── lib/
│   ├── dashboard_page.dart     ← Page widget
│   ├── dashboard_controller.dart ← Riverpod controller
│   ├── dashboard_repository.dart ← Data access
│   └── models/                 ← Freezed models
└── test/
    └── dashboard_controller_test.dart

State Management

All three apps use Riverpod for state management. Key patterns:

dart
// Provider definition
@riverpod
class DashboardController extends _$DashboardController {
  @override
  Future<DashboardData> build() async {
    return ref.read(dashboardRepositoryProvider).getDashboardData();
  }
}

// Consuming in a widget
class DashboardPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncData = ref.watch(dashboardControllerProvider);
    return asyncData.when(
      data: (data) => DashboardContent(data: data),
      loading: () => const CircularProgressIndicator(),
      error: (e, st) => ErrorWidget(e.toString()),
    );
  }
}

API Client Generation

API clients in MobileAPIClients/ are generated from OpenAPI specs. When the backend API changes:

bash
# Regenerate all API clients
melos run generate-clients

# Or regenerate a specific client
cd MobileAPIClients
dart run openapi-generator \
  --spec ../../api-specs/hr-api.yaml \
  --output lib/hr/

TIP

You do not normally need to run this manually. The pipeline regenerates clients when the backend API spec changes. If you see type errors in the API clients after pulling, run melos run get && melos run build.


Troubleshooting

SymptomLikely CauseFix
melos: command not foundMelos not on PATHAdd ~/.pub-cache/bin to your PATH
Submodule directories are empty--recurse-submodules not usedgit submodule update --init --recursive
pub get fails with version conflictSubmodule out of dategit submodule update --recursive --remote
Build fails: build_runner output missingCode generation not runmelos run build
iOS build fails: signing errorXcode signing not configuredOpen ios/Runner.xcworkspace in Xcode → set team
Android emulator not foundAVD not createdAndroid Studio → Device Manager → Create Device
flutter doctor shows issuesSDK paths wrongRun flutter config --android-sdk <path>
API calls fail locallyWrong environment configCheck lib/config/ — confirm dev URL is active

Internal Documentation — Microtec Platform Team