Gauteng Wellbeing Mapper - Architecture Overview

System Architecture Overview

Gauteng Wellbeing Mapper follows a layered architecture pattern designed for maintainability, testability, and scalability. The application is built using Flutter and implements a clean separation of concerns to support mental wellbeing mapping in environmental & climate context as part of the Planet4Health research project.

The architecture includes research participation with end-to-end encryption for secure data transmission to research servers in Gauteng, South Africa.

Architectural Layers

1. Presentation Layer (ui/)

The presentation layer handles all user interface components and user interactions.

Key Components:

Responsibilities:

2. Business Logic Layer (models/, services/)

This layer contains the application’s business rules and data processing logic.

Key Components:

Responsibilities:

3. Data Layer (db/ and models/)

The data layer manages all data persistence and retrieval operations.

Key Components:

Responsibilities:

4. Platform Layer (util/ and platform services)

This layer handles platform-specific functionality and external service integration.

Key Components:

Responsibilities:

Security & Encryption Architecture

Hybrid Encryption System

The app implements a sophisticated encryption system for secure research data transmission:

Local Data → AES-256-GCM → RSA-4096-OAEP → Base64 → HTTPS → Research Server
     ↓              ↓              ↓           ↓         ↓
Survey Responses   Fast Encryption  Key Security  Transit   Secure Storage
Location Tracks    Large Data      Public Key    Format    Private Key Only
Demographics       Performance     Exchange      Network   Decryption

Encryption Components:

Security Features:

Research Architecture

App Configuration:
├── Gauteng Research Site
│   ├── Public Key (embedded in app)
│   ├── Server: gauteng-research.domain.com
│   └── Site-specific surveys and consent
└── Private Mode
    └── No data transmission (local only)

Component Interaction Diagram

graph TB
    subgraph "Presentation Layer"
        A[ParticipationSelectionScreen]
        B[ConsentFormScreen]
        C[DataUploadScreen]
        D[HomeView]
        E[MapView]
        F[SurveyScreens]
    end
    
    subgraph "Business Logic Layer"
        G[DataUploadService]
        H[ConsentModels]
        I[SurveyModels]
        J[RouteGenerator]
        K[CustomLocation]
        L[LocationManager]
    end
    
    subgraph "Data Layer"
        K[SurveyDatabase]
        L[UnpushedLocationsDB]
        M[SharedPreferences]
        N[FileStorage]
    end
    
    subgraph "Platform Layer"
        P[BackgroundGeolocation]
        Q[Authentication]
        R[WebServices]
        S[Environment]
    end
    
    A --> F
    A --> I
    B --> G
    C --> G
    D --> H
    D --> J
    E --> H
    
    F --> K
    G --> L
    G --> M
    H --> K
    I --> P
    J --> K
    
    G --> P
    H --> R
    I --> Q
    J --> R
    
    K --> N
    L --> N
    M --> O

Data Flow Architecture

Location Tracking Flow

sequenceDiagram
    participant U as User
    participant HV as HomeView
    participant BG as BackgroundGeolocation
    participant CL as CustomLocation
    participant DB as Database
    participant MV as MapView
    
    U->>HV: Enable Tracking
    HV->>BG: Start Location Service
    BG->>BG: Background Monitoring
    BG->>CL: Location Event
    CL->>CL: Process Location Data
    CL->>DB: Store Location
    CL->>MV: Update Map Display
    MV->>U: Visual Update

App Mode Selection Flow

sequenceDiagram
    participant U as User
    participant MS as ModeSelection
    participant Config as AppConfig
    participant Prefs as SharedPreferences
    participant WV as WebView
    
    U->>MS: Select App Mode
    MS->>U: Display Mode Options
    U->>MS: Choose Research Mode
    MS->>WV: Show Consent Form
    WV->>U: Display Consent
    U->>WV: Accept Consent
    WV->>Config: Update Mode Configuration
    Config->>Prefs: Save Mode Settings
    Prefs->>MS: Confirm Update
    MS->>U: Mode Activated

Core Classes and Their Relationships

1. Location Management Classes

// Core location data structure
class CustomLocation {
    String _uuid;
    String _timestamp;
    double _latitude;
    double _longitude;
    String _locality;
    String _activity;
    // ... other properties
    
    static Future<CustomLocation> createCustomLocation(var recordedLocation);
    Future<void> deleteThisLocation();
    String getFormattedTimestamp();
}

// Location collection management
class CustomLocationsManager {
    static Future<List<CustomLocation>> getLocations(int maxElements);
    static Future<void> storeLocation(CustomLocation location);
    static Future<void> removeAllCustomLocations();
}

// Simplified location for sharing
class ShareLocation {
    String timestamp;
    double latitude;
    double longitude;
    double accuracy;
    String userUUID;
}

2. Project Management Classes

// Base project structure
class Project {
    int id;
    String name;
    String summary;
    String? webUrl;
    String? projectScreen;
    String imageUrl;
    int locationSharingMethod;
    String surveyElementCode;
    
    void participate(BuildContext context, String locationHistoryJSON);
}

3. Database Architecture

erDiagram
    CustomLocation {
        string uuid PK
        string timestamp
        double latitude
        double longitude
        string locality
        string activity
        double speed
        double altitude
    }
    
    Project {
        int projectNumber PK
        int projectId
        string projectName
        string description
        string externalLink
        string internalLink
        string imageLocation
        string duration
        string startDate
        string endDate
        string status
        int locationSharingMethod
        string surveyElementCode
    }
    
    Contact {
        int id PK
        string name
        string email
        string phone
        string message
        string timestamp
    }
    
    UnpushedLocation {
        int id PK
        string userUUID
        string userCode
        string appVersion
        string operativeSystem
        string typeOfData
        string message
        double longitude
        double latitude
        string unixTime
        string speed
        string activity
        string altitude
    }

Background Processing Architecture

Headless Tasks

Wellbeing Mapper implements sophisticated background processing to ensure location tracking continues even when the app is terminated.

// Main headless task handler
void backgroundGeolocationHeadlessTask(bg.HeadlessEvent headlessEvent) async {
    switch (headlessEvent.name) {
        case bg.Event.LOCATION:
            // Process new location data
            bg.Location location = headlessEvent.event;
            await processLocationInBackground(location);
            break;
        case bg.Event.MOTIONCHANGE:
            // Handle movement state changes
            break;
        case bg.Event.GEOFENCE:
            // Handle geofence events
            break;
        // ... other event types
    }
}

// Background fetch for periodic tasks
void backgroundFetchHeadlessTask(String taskId) async {
    // Retry failed uploads
    // Perform maintenance tasks
    // Update project status
    BackgroundFetch.finish(taskId);
}

State Management Pattern

graph LR
    A[User Action] --> B[State Change]
    B --> C[Business Logic]
    C --> D[Data Update]
    D --> E[UI Refresh]
    E --> F[User Feedback]
    
    subgraph "Global State"
        G[GlobalData]
        H[SharedPreferences]
        I[Database State]
    end
    
    C --> G
    C --> H
    C --> I

Security Architecture

Data Protection

Authentication Flow

sequenceDiagram
    participant A as App
    participant P as Preferences
    participant S as Server
    participant U as UUID Generator
    
    A->>P: Check User UUID
    alt UUID exists
        P->>A: Return UUID
    else UUID missing
        A->>U: Generate New UUID
        U->>A: Return UUID
        A->>P: Store UUID
    end
    
    A->>S: Register with UUID
    S->>A: Return Auth Token
    A->>P: Store Auth Token

Error Handling Architecture

Error Handling Strategy

  1. Graceful Degradation: App continues functioning with reduced capabilities
  2. Retry Mechanisms: Automatic retry for network failures
  3. Local Fallbacks: Store data locally when remote services fail
  4. User Feedback: Clear error messages and recovery options

Error Flow

graph TD
    A[Operation Attempt] --> B{Success?}
    B -->|Yes| C[Continue Normal Flow]
    B -->|No| D[Log Error]
    D --> E[Determine Error Type]
    E --> F{Recoverable?}
    F -->|Yes| G[Apply Recovery Strategy]
    F -->|No| H[Graceful Degradation]
    G --> I[Retry Operation]
    I --> B
    H --> J[Notify User]
    J --> K[Continue with Reduced Function]

Performance Considerations

Location Tracking Optimization

Database Optimization

Testing Architecture

Testing Strategy

  1. Unit Tests: Individual class and method testing
  2. Widget Tests: UI component testing
  3. Integration Tests: End-to-end workflow testing
  4. Platform Tests: Native functionality testing

Test Organization

test/
├── unit/
│   ├── models/
│   ├── services/
│   └── utils/
├── widget/
│   ├── ui/
│   └── components/
└── integration_test/
    ├── location_tracking_test.dart
    ├── project_participation_test.dart
    └── app_test.dart

Deployment Architecture

Build Configuration

Platform-Specific Considerations

Future Architecture Considerations

Scalability

Technology Evolution