Appearance
Business Owner Mobile App
The Business Owner mobile app (BoMobileApp) is the mobile companion for tenant administrators. It allows business owners to manage their subscription, monitor ERP activity, and approve requests from anywhere.
Overview
| Property | Value |
|---|---|
| Directory | BoMobileApp/ |
| Platform | Android, iOS |
| Backend | BusinessOwners.Apis |
| Keycloak realm | businessowner |
| Offline support | No (requires internet) |
| Auth flow | Keycloak OIDC / PKCE |
Features
Tenant Management
- View and edit company profile (name, logo, contact details)
- Manage branches and locations
- View active subscription plan and renewal date
- Activate / deactivate ERP modules per tenant
Overview Dashboards
- Key performance indicators (KPIs) at a glance
- Revenue summaries (pulled from AppsPortal via BusinessOwners public API)
- User activity feed
- System health and service status
Approvals
- Pending approval inbox — purchase orders, leave requests, payment approvals
- One-tap approve / reject with optional comment
- Push notification integration — receive alerts for new pending items
User Management
- Invite new users to the tenant
- Assign roles and permissions
- View active sessions
Notifications
- In-app notification centre
- Push notification subscription management
Backend Integration
The app communicates exclusively with BusinessOwners.Apis via the Gateway. The MobileAPIClients package provides auto-generated Dart clients.
BoMobileApp → Gateway.API (/bo-apis/*) → BusinessOwners.ApisFor dashboard KPIs that require ERP data, BusinessOwners.Apis fetches data internally via IAccountingPublicApi, ISalesPublicApi, etc. — the mobile app does not call ERP services directly.
Project Structure
BoMobileApp/
├── lib/
│ ├── core/
│ │ ├── config/ # Environment, app constants
│ │ ├── di/ # Dependency injection setup
│ │ └── navigation/ # Route definitions
│ ├── data/
│ │ ├── api/ # API client wrappers
│ │ ├── local/ # Secure storage, preferences
│ │ └── repositories/ # Repository implementations
│ ├── domain/
│ │ ├── entities/ # Business entities
│ │ └── use_cases/ # Business logic
│ ├── presentation/
│ │ ├── auth/ # Login, Keycloak callback
│ │ ├── dashboard/ # Home dashboard
│ │ ├── tenants/ # Tenant management
│ │ ├── approvals/ # Approval inbox
│ │ ├── users/ # User management
│ │ └── notifications/ # Notification centre
│ └── main.dart
├── android/
├── ios/
├── melos.yaml
└── pubspec.yamlShared Libraries Used
| Library | Usage in BoMobileApp |
|---|---|
MobileDesignSystem | All UI components — buttons, cards, typography, colour palette |
MobileAPIClients | Auto-generated Dart clients for BusinessOwners.Apis endpoints |
MobileSharedComp | Auth helpers, storage utilities, base screen classes |
Setup & Running
bash
cd BoMobileApp
# First-time setup
melos run init
# Install / update dependencies
melos run get
# Run in debug mode (select device first)
melos run run
# Build Android APK
melos run build-apk
# Run tests
melos run testAuthentication Flow
Tokens are stored in Flutter Secure Storage (iOS Keychain / Android Keystore). They are never stored in plain SharedPreferences.
Push Notifications
The app uses Firebase Cloud Messaging (FCM) for Android and APNs for iOS, routed through the Notification.Apis microservice.
| Step | Description |
|---|---|
| 1 | App registers FCM/APNs token on first launch |
| 2 | Token stored in Notification.Apis (linked to user ID) |
| 3 | When a new approval is created, BusinessOwners.Apis calls INotificationPublicApi |
| 4 | Notification.Apis dispatches push to device via FCM/APNs |
Environment Configuration
dart
// Build-time environment variables
const apiBaseUrl = String.fromEnvironment('API_BASE_URL');
const keycloakUrl = String.fromEnvironment('KEYCLOAK_URL');| Environment | API Base URL | Keycloak URL |
|---|---|---|
| dev | https://gateway.microtec-test.com | https://keycloak.microtec-test.com |
| stage | https://gateway.microtecstage.com | https://keycloak.microtecstage.com |
| production | https://gateway.onlinemicrotec.com.sa | https://keycloak.onlinemicrotec.com.sa |
Build for a specific environment:
bash
flutter build apk \
--dart-define=API_BASE_URL=https://gateway.onlinemicrotec.com.sa \
--dart-define=KEYCLOAK_URL=https://keycloak.onlinemicrotec.com.saTroubleshooting
Login fails / redirect loop
- Verify
keycloakUrland that thebusinessownerrealm exists. - Ensure the Keycloak client
mobile-apphas the app's redirect URI registered (e.g.,com.microtec.bo://callback). - Check secure storage is not corrupted — clear the app data and retry.
API calls return 401
- Check the access token is not expired (
melos run runlogs include token expiry). - Verify the
Bearerheader is being sent. - Confirm the user has the correct role in the
businessownerrealm.
Melos bootstrap fails
bash
# Clean and retry
flutter clean
melos run init