Gauteng Wellbeing Mapper - API Reference
Overview
This document provides detailed information about the Gauteng Wellbeing Mapper codebase APIs, including class methods, database schemas, encryption services, and integration points. This reference is intended for developers working on the codebase for the Planet4Health project case study on mental wellbeing in environmental & climate context.
The app supports research participation with end-to-end encryption for secure data transmission to research servers in Gauteng, South Africa.
Research Participation APIs
ParticipationSettings
Manages user participation preferences and research site configuration.
class ParticipationSettings {
final bool isResearchParticipant;
final String? participantCode; // Site-specific participant identifier
final String? researchSite; // 'gauteng'
final DateTime createdAt;
// Factory constructors
factory ParticipationSettings.privateUser()
factory ParticipationSettings.researchParticipant(String participantCode, String researchSite)
// JSON serialization
Map<String, dynamic> toJson()
factory ParticipationSettings.fromJson(Map<String, dynamic> json)
}
ConsentResponse
Handles informed consent for research participation with detailed consent tracking.
class ConsentResponse {
final String participantUuid; // Anonymous UUID identifier
final bool informedConsent;
final bool dataProcessing;
final bool locationData;
final bool surveyData;
final bool dataRetention;
final bool dataSharing;
final bool voluntaryParticipation;
final DateTime consentedAt;
final String participantSignature;
// Validation
bool hasGivenValidConsent()
// JSON serialization
Map<String, dynamic> toJson()
factory ConsentResponse.fromJson(Map<String, dynamic> json)
}
Encryption & Data Upload APIs
DataUploadService
Core service for encrypting and uploading research data to secure servers.
class DataUploadService {
// Configuration
static const Map<String, ServerConfig> _serverConfigs = {
'barcelona': ServerConfig(...),
'gauteng': ServerConfig(...)
};
// Main upload method
static Future<UploadResult> uploadParticipantData({
required String researchSite,
required List<InitialSurveyResponse> initialSurveys,
required List<RecurringSurveyResponse> recurringSurveys,
required List<LocationTrack> locationTracks,
required String participantUuid,
})
// Encryption
static Future<EncryptionResult> encryptData(Map<String, dynamic> data, String researchSite)
// Upload scheduling
static Future<bool> shouldUploadData(String researchSite)
static Future<void> markUploadCompleted(String researchSite, String uploadId)
// Location data management
static Future<List<LocationTrack>> getRecentLocationTracks()
}
ServerConfig
Configuration for research site servers with embedded public keys.
class ServerConfig {
final String baseUrl; // HTTPS server URL
final String uploadEndpoint; // API endpoint path
final String publicKey; // RSA-4096 public key (PEM format)
}
EncryptionResult
Result of data encryption operations.
class EncryptionResult {
final bool success;
final String? encryptedData; // Base64 encoded: rsa_key|aes_data
final Map<String, dynamic>? encryptionMetadata;
final String? error;
}
UploadResult
Result of data upload operations to research servers.
class UploadResult {
final bool success;
final String? uploadId; // UUID for tracking uploads
final String? error;
final DateTime? uploadedAt;
}
LocationTrack
Location tracking data structure for research uploads.
class LocationTrack {
final double latitude;
final double longitude;
final double? accuracy; // Accuracy in meters
final DateTime timestamp;
final bool synced; // Upload synchronization status
Map<String, dynamic> toJson()
factory LocationTrack.fromJson(Map<String, dynamic> json)
}
Survey System APIs
Enhanced Survey Models
Survey models now support site-specific questions and research site tracking.
InitialSurveyResponse
class InitialSurveyResponse {
final String id;
final String participantUuid;
final String? researchSite; // NEW: Site-specific surveys
final int wellbeingScore;
final int stressLevel;
final String mood;
final List<String> activities;
final String? ethnicity; // Site-specific options
final String? buildingType; // Site-specific options
final DateTime submittedAt;
Map<String, dynamic> toJson()
factory InitialSurveyResponse.fromJson(Map<String, dynamic> json)
}
RecurringSurveyResponse
class RecurringSurveyResponse {
final String id;
final String participantUuid;
final String? researchSite; // NEW: Site-specific surveys
final int wellbeingScore;
final int stressLevel;
final String mood;
final String? suburb; // Gauteng-specific
final String? generalHealth; // Gauteng-specific
final DateTime submittedAt;
Map<String, dynamic> toJson()
factory RecurringSurveyResponse.fromJson(Map<String, dynamic> json)
}
Database APIs
SurveyDatabase
Enhanced database class with location tracking and encryption support.
class SurveyDatabase {
// Survey operations
Future<int> insertInitialSurvey(InitialSurveyResponse survey)
Future<List<InitialSurveyResponse>> getInitialSurveys()
Future<int> insertRecurringSurvey(RecurringSurveyResponse survey)
Future<List<RecurringSurveyResponse>> getRecurringSurveys()
// Consent operations
Future<int> insertConsent(ConsentResponse consent)
Future<ConsentResponse?> getConsent()
// Location tracking (NEW)
Future<int> insertLocationTrack(Map<String, dynamic> locationData)
Future<List<LocationTrack>> getLocationTracksSince(DateTime since)
Future<List<LocationTrack>> getAllLocationTracks()
Future<void> markLocationTracksAsSynced(List<String> trackIds)
// Utility methods
Future<DateTime?> getLastRecurringSurveyDate()
Future<int> getRecurringSurveyCount()
Future<List<Map<String, dynamic>>> getPendingSyncItems()
}
Database Schema
location_tracks table (NEW)
CREATE TABLE location_tracks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
latitude REAL NOT NULL,
longitude REAL NOT NULL,
accuracy REAL,
timestamp TEXT NOT NULL,
synced INTEGER DEFAULT 0,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
Enhanced survey tables
initial_surveys
: Addedresearch_site
columnrecurring_surveys
: Addedresearch_site
,suburb
,general_health
columnsconsent_responses
: Complete consent tracking with all required fields
UI Components APIs
DataUploadScreen
User interface for managing research data uploads.
class DataUploadScreen extends StatefulWidget {
// Main screen for upload management
// Shows upload status, data summary, and privacy information
// Handles encrypted data transmission to research servers
}
class _DataUploadScreenState extends State<DataUploadScreen> {
// State management
bool _isLoading;
String? _participantUuid;
String? _researchSite;
DateTime? _lastUpload;
bool _canUpload;
// Core methods
Future<void> _loadParticipantInfo()
Future<void> _uploadData()
// UI builders
Widget _buildParticipantInfo()
Widget _buildUploadStatus()
Widget _buildDataSummary()
Widget _buildUploadButton()
Widget _buildPrivacyNote()
}
ParticipationSelectionScreen
Enhanced three-way participation selection interface.
class ParticipationSelectionScreen extends StatefulWidget {
// Supports three modes:
// 1. Private usage (no data sharing)
// 2. Barcelona research participation
// 3. Gauteng research participation
}
class _ParticipationSelectionScreenState extends State<ParticipationSelectionScreen> {
String _selectedMode; // 'private', 'gauteng'
TextEditingController _participantCodeController;
// Site-specific UI rendering
Widget _buildParticipationOption(String mode)
Widget _buildParticipantCodeInput(String site)
// Navigation to consent forms
void _proceedToConsent(String site, String participantCode)
}
ConsentFormScreen
Dynamic consent form generation based on research site.
class ConsentFormScreen extends StatefulWidget {
final String participantCode;
final String researchSite; // 'barcelona' or 'gauteng'
}
class _ConsentFormScreenState extends State<ConsentFormScreen> {
// Site-specific content generation
String _getConsentTitle()
String _getConsentContent()
String _getLocationConsentText()
// Consent processing
Future<void> _submitConsent()
ConsentResponse _buildConsentResponse()
}
Encryption Technical Specifications
Hybrid Encryption Process
- AES-256-GCM Encryption:
- Generate random 256-bit AES key
- Generate random 96-bit IV
- Encrypt JSON payload with AES-256-GCM
- Produces:
encrypted_data + auth_tag
- RSA-4096-OAEP Key Encryption:
- Encrypt AES key with research site’s RSA public key
- Use OAEP padding with SHA-256
- Produces:
encrypted_aes_key
- Final Payload:
- Format:
base64(encrypted_aes_key)|base64(encrypted_data+auth_tag)
- Metadata:
{"algorithm": "RSA-OAEP-AES-256-GCM", "iv": "base64_iv", ...}
- Format:
Server-Side Decryption
// Node.js decryption example
function decryptUpload(encryptedPayload, encryptionMetadata, privateKey) {
const [encryptedAESKeyB64, encryptedDataB64] = encryptedPayload.split('|');
// Decrypt AES key with RSA private key
const aesKey = crypto.privateDecrypt({
key: privateKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256'
}, Buffer.from(encryptedAESKeyB64, 'base64'));
// Decrypt data with AES-256-GCM
const iv = Buffer.from(encryptionMetadata.iv, 'base64');
const encryptedData = Buffer.from(encryptedDataB64, 'base64');
const authTag = encryptedData.slice(-16);
const ciphertext = encryptedData.slice(0, -16);
const decipher = crypto.createDecipherGCM('aes-256-gcm', aesKey);
decipher.setIV(iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(ciphertext, null, 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
REST API Specifications
Upload Endpoint
POST /api/v1/participant-data
Request Headers:
Content-Type: application/json
User-Agent: WellbeingMapper/1.0
Request Body:
{
"uploadId": "uuid-v4",
"participantUuid": "uuid-v4",
"researchSite": "gauteng",
"encryptedData": "base64-encoded-payload",
"encryptionMetadata": {
"algorithm": "RSA-OAEP-AES-256-GCM",
"keySize": 4096,
"iv": "base64-iv",
"timestamp": "ISO-8601-timestamp"
},
"dataPeriod": {
"start": "ISO-8601-timestamp",
"end": "ISO-8601-timestamp"
}
}
Response:
{
"success": true,
"uploadId": "uuid-v4",
"receivedAt": "ISO-8601-timestamp",
"message": "Data uploaded successfully"
}
Decrypted Data Structure
After server-side decryption, the payload contains:
{
"participantUuid": "uuid-v4",
"researchSite": "gauteng",
"uploadTimestamp": "ISO-8601-timestamp",
"surveys": [
{
"type": "initial" | "recurring",
"submittedAt": "ISO-8601-timestamp",
"responses": {
"wellbeingScore": 1-10,
"stressLevel": 1-10,
"mood": "string",
"suburb": "string", // Gauteng only
"generalHealth": "string", // Gauteng only
"ethnicity": "string", // Site-specific options
"buildingType": "string" // Site-specific options
}
}
],
"locationTracks": [
{
"timestamp": "ISO-8601-timestamp",
"latitude": -90.0 to 90.0,
"longitude": -180.0 to 180.0,
"accuracy": 0.0-1000.0
}
]
}
Core Classes API
CustomLocation
Primary class for handling location data with geocoded information.
class CustomLocation {
// Properties
String _uuid; // Unique identifier
String _timestamp; // ISO 8601 timestamp
double _latitude; // Decimal degrees
double _longitude; // Decimal degrees
String _locality; // City/locality name
String _subAdministrativeArea; // State/region
String _street; // Street address
String _isoCountryCode; // ISO country code
String _activity; // Movement activity type
num _speed; // Speed in m/s
num _speedAccuracy; // Speed accuracy
num _altitude; // Altitude in meters
num _altitudeAccuracy; // Altitude accuracy
}
Static Methods
// Create CustomLocation from background geolocation data
static Future<CustomLocation> createCustomLocation(var recordedLocation)
// Reverse geocoding helper
static Future<Placemark?> getLocationData(double lat, double long)
Instance Methods
// Getters
String getUUID()
String getTimestamp()
double getLatitude()
double getLongitude()
String getLocality()
String getSubAdministrativeArea()
String getStreet()
String getISOCountryCode()
String getActivity()
num getSpeed()
num getSpeedAcc()
num getAltitude()
num getAltitudeAcc()
// Setters
void setUUID(String uuid)
void setTimestamp(String timestamp)
void setLatitude(double latitude)
void setLongitude(double longitude)
void setLocality(String locality)
void setSubAdministrativeArea(String subAdminArea)
void setStreet(String street)
void setISOCountry(String isoCountryCode)
void setActivity(String activity)
void setSpeed(num speed, num speedAccuracy)
void setAltitude(num altitude, num altitudeAccuracy)
// Utility Methods
DateTime timestampToDateTime(String timestamp)
String getFormattedTimestamp()
String getFormattedInformation(BuildContext context)
Future<void> deleteThisLocation()
CustomLocationsManager
Static class for managing collections of CustomLocation objects.
class CustomLocationsManager {
static List<CustomLocation> customLocations = [];
}
Static Methods
// Retrieve recent locations from background geolocation storage
static Future<List<CustomLocation>> getLocations(int maxElements)
// Remove all stored locations
static Future<void> removeAllCustomLocations()
Project
Core class representing research projects.
class Project {
// Properties
int id; // Unique project ID
String name; // Project display name
String summary; // Project description
String? webUrl; // Survey/project URL
String? projectScreen; // Internal screen route
String imageUrl; // Project banner image
int locationSharingMethod; // Data sharing method (0-3)
String surveyElementCode; // Form element identifier
}
Methods
// Navigate to project participation
void participate(BuildContext context, String locationHistoryJSON)
// String representation
String toString()
ShareLocation
Simplified location data structure for sharing.
class ShareLocation {
// Properties
String timestamp; // ISO 8601 timestamp
double latitude; // Decimal degrees latitude
double longitude; // Decimal degrees longitude
double accuracy; // Location accuracy in meters
String userUUID; // Anonymous user identifier
// Constructor
ShareLocation(this.timestamp, this.latitude, this.longitude,
this.accuracy, this.userUUID);
// JSON serialization
Map<String, dynamic> toJson()
}
DataSharingConsent
Manages user consent preferences for research data sharing with granular location control.
class DataSharingConsent {
// Properties
String id; // Unique consent record ID
LocationSharingOption locationSharingOption; // User's sharing preference
DateTime decisionTimestamp; // When consent was given
String participantUuid; // Anonymous participant identifier
List<String>? customLocationIds; // Selected location cluster IDs for partial sharing
String? reasonForPartialSharing; // Optional reason for partial selection
// Constructor
DataSharingConsent({
required this.id,
required this.locationSharingOption,
required this.decisionTimestamp,
required this.participantUuid,
this.customLocationIds,
this.reasonForPartialSharing,
});
// JSON serialization
Map<String, dynamic> toJson()
factory DataSharingConsent.fromJson(Map<String, dynamic> json)
}
LocationSharingOption
Enumeration of data sharing options for research participants.
enum LocationSharingOption {
fullData, // Upload complete 2-week geolocation history
partialData, // Upload selected/filtered location data
surveyOnly, // Upload only survey responses, no location data
}
DataUploadSummary
Preview information shown to users before data sharing consent.
class DataUploadSummary {
// Properties
int surveyResponseCount; // Number of survey responses to upload
int locationTrackCount; // Number of location records to upload
DateTime oldestLocationDate; // Date range of location data
DateTime newestLocationDate;
double locationAccuracyStats; // Average location accuracy
List<LocationCluster> locationClusters; // Grouped locations for privacy preview
// Constructor
DataUploadSummary({
required this.surveyResponseCount,
required this.locationTrackCount,
required this.oldestLocationDate,
required this.newestLocationDate,
required this.locationAccuracyStats,
required this.locationClusters,
});
}
LocationCluster
Grouped location data for privacy-conscious display and selection.
class LocationCluster {
// Properties
String areaName; // General area name (e.g., "Johannesburg CBD")
int trackCount; // Number of location records in cluster
double centerLatitude; // Cluster center coordinates
double centerLongitude;
DateTime firstVisit; // Time range of visits to this area
DateTime lastVisit;
// Constructor
LocationCluster({
required this.areaName,
required this.trackCount,
required this.centerLatitude,
required this.centerLongitude,
required this.firstVisit,
required this.lastVisit,
});
}
Data Sharing Services
ConsentAwareDataUploadService
Enhanced upload service that respects user data sharing preferences.
class ConsentAwareDataUploadService {
// Core upload method with consent dialog
static Future<void> uploadWithConsent({
required BuildContext context,
required String participantUuid,
required String researchSite,
required VoidCallback onSuccess,
required Function(String) onError,
});
// Get upload summary for preview
static Future<Map<String, dynamic>> getUploadSummary({
required String participantUuid,
required LocationSharingOption sharingOption,
});
}
DataSharingConsentDialog
Interactive dialog for collecting user consent with data preview.
class DataSharingConsentDialog extends StatefulWidget {
// Constructor
DataSharingConsentDialog({
Key? key,
required this.participantUuid,
required this.onUploadProceed,
required this.onUploadCancelled,
});
// Callbacks
final String participantUuid;
final VoidCallback onUploadProceed;
final VoidCallback onUploadCancelled;
}
Database Schema Updates
data_sharing_consent Table
Stores user consent preferences and location cluster selections.
CREATE TABLE data_sharing_consent (
id TEXT PRIMARY KEY,
participant_uuid TEXT NOT NULL,
location_sharing_option INTEGER NOT NULL,
decision_timestamp TEXT NOT NULL,
custom_location_ids TEXT, -- JSON array of selected cluster IDs
reason_for_partial_sharing TEXT
);
UI Components
DataSharingPreferencesScreen
Management interface for ongoing consent preferences.
class DataSharingPreferencesScreen extends StatefulWidget {
// Features:
// - View current consent settings
// - Update preferences anytime
// - See consent history
// - Privacy information and explanations
}
Database APIs
UnPushedLocationsDatabase
Manages failed location uploads for retry mechanisms.
class UnPushedLocationsDatabase {
static final UnPushedLocationsDatabase instance = UnPushedLocationsDatabase._init();
static Database? _database;
}
Core Methods
// Database operations
Future<Database> get database
Future<LocationToPush> createRecord(LocationToPush location)
Future<LocationToPush> readLocation(int id)
Future<List<LocationToPush>> readAllRecords()
Future<int> deleteRecord(String userUUID)
Future<int> getAmountOfRows()
Future close()
Database Schema
CREATE TABLE unpushedLocations(
"_id" INTEGER PRIMARY KEY AUTOINCREMENT,
"user_UUID" STRING,
"user_code" STRING,
"app_version" STRING,
"os" STRING,
"type_of_data" STRING,
"message" STRING,
"lon" DOUBLE,
"lat" DOUBLE,
"unix_time" STRING,
"speed" STRING,
"activity" STRING,
"altitude" STRING
)
UI Component APIs
HomeView
Main application screen managing location tracking and navigation.
class HomeView extends StatefulWidget {
HomeView(this.appName);
final String appName;
}
class HomeViewState extends State<HomeView>
with TickerProviderStateMixin<HomeView>, WidgetsBindingObserver {
// State variables
late bool _enabled; // Location tracking enabled state
late String appName; // Application title
}
Key Methods
// Lifecycle
void initState()
void didChangeAppLifecycleState(AppLifecycleState state)
// Background geolocation setup
void initPlatformState()
void _configureBackgroundGeolocation(user_uuid, sample_id)
void _configureBackgroundFetch()
// User interactions
void _onClickEnable(enabled)
void _onClickGetCurrentPosition()
// Event handlers
void _onLocation(bg.Location location)
void _onLocationError(bg.LocationError error)
void _onMotionChange(bg.Location location)
void _onProviderChange(bg.ProviderChangeEvent event)
void _onHttp(bg.HttpEvent event)
void _onConnectivityChange(bg.ConnectivityChangeEvent event)
void _onHeartbeat(bg.HeartbeatEvent event)
void _onGeofence(bg.GeofenceEvent event)
void _onSchedule(bg.State state)
void _onEnabledChange(bool enabled)
void _onNotificationAction(String action)
void _onPowerSaveChange(bool enabled)
// Project management
void fetchProjects()
// Build method
Widget build(BuildContext context)
MapView
Interactive map component displaying location history.
class MapView extends StatefulWidget {}
class MapViewState extends State<MapView>
with AutomaticKeepAliveClientMixin<MapView> {
// Map components
List<CircleMarker> _currentPosition = [];
List<LatLng> _polyline = [];
List<CircleMarker> _locations = [];
List<CircleMarker> _stopLocations = [];
List<Polyline> _motionChangePolylines = [];
List<CircleMarker> _stationaryMarker = [];
LatLng _center = new LatLng(51.5, -0.09);
late MapController _mapController;
late MapOptions _mapOptions;
}
Key Methods
// Lifecycle
void initState()
bool get wantKeepAlive
// Event handlers
void _onLocation(bg.Location location)
void _onMotionChange(bg.Location location)
void _onEnabledChange(bool enabled)
void _onPositionChanged(MapPosition pos, bool hasGesture)
// Display methods
void _displayStoredLocations()
void _updateCurrentPositionMarker(LatLng ll)
// Map element builders
Polyline _buildMotionChangePolyline(bg.Location from, bg.Location to)
CircleMarker _buildStopCircleMarker(bg.Location location)
// Build method
Widget build(BuildContext context)
ProjectDetail
Detailed view for individual research projects.
class ProjectDetail extends StatefulWidget {
final int projectID;
ProjectDetail(this.projectID);
}
class _ProjectDetailState extends State<ProjectDetail> {
Project? project;
bool endButtonPressed = false;
int dropdownValue = 7;
String statusToSet = "ongoing";
String surveyType = "starting";
DateTime? startTime;
}
Key Methods
// Lifecycle
void initState()
void loadData()
// Data management
Future<Map<String, dynamic>> checkProjectStatus()
Future<String> getLocationsToShare(int maxDays)
// Navigation
Future<void> _navigationToProject(BuildContext context)
// UI builders
Widget build(BuildContext context)
Widget _renderBody(BuildContext context, Project project)
Widget _renderHeader()
Widget _renderConsentForm()
Widget _renderBottomSpacer()
Global Data and State Management
GlobalData
Application-wide state container.
class GlobalData {
static String userUUID = ""; // Unique user identifier
static bool user_active_projects = false; // Has active projects
static bool user_available_projects = false; // Has available projects
}
GlobalRouteData
Navigation state management.
class GlobalRouteData {
static String? user_route = "brown"; // Current route identifier
}
GlobalProjectData
Project-specific state management.
class GlobalProjectData {
static int? active_project_number; // Current active project ID
static String active_project_status = ""; // Project status
static String generatedUrl = ""; // Generated survey URL
}
Background Processing APIs
Background Geolocation Events
// Main headless task handler
void backgroundGeolocationHeadlessTask(bg.HeadlessEvent headlessEvent)
// Supported events:
// - bg.Event.TERMINATE: App termination
// - bg.Event.HEARTBEAT: Periodic heartbeat
// - bg.Event.LOCATION: New location
// - bg.Event.MOTIONCHANGE: Movement state change
// - bg.Event.GEOFENCE: Geofence entry/exit
// - bg.Event.GEOFENCESCHANGE: Geofence configuration change
// - bg.Event.SCHEDULE: Schedule state change
// - bg.Event.ACTIVITYCHANGE: Activity type change
// - bg.Event.HTTP: HTTP response
// - bg.Event.POWERSAVECHANGE: Power save mode change
// - bg.Event.CONNECTIVITYCHANGE: Network connectivity change
// - bg.Event.ENABLEDCHANGE: Service enabled state change
// - bg.Event.AUTHORIZATION: Permission authorization change
Background Fetch
// Background fetch handler
void backgroundFetchHeadlessTask(String taskId)
// Configuration
BackgroundFetchConfig(
minimumFetchInterval: 15, // Minimum interval in minutes
startOnBoot: true, // Start on device boot
stopOnTerminate: false, // Continue after app termination
enableHeadless: true, // Enable headless execution
requiresStorageNotLow: false, // Storage requirements
requiresBatteryNotLow: false, // Battery requirements
requiresCharging: false, // Charging requirements
requiresDeviceIdle: false, // Device idle requirements
requiredNetworkType: NetworkType.NONE // Network requirements
)
Utility APIs
Environment Configuration
class ENV {
static final String TRACKER_HOST; // Server host URL
static final String DEFAULT_SAMPLE_ID; // Default sample identifier
}
Authentication
class TransistorAuth {
// Register device with server
static Future<bool> register()
// Handle authentication errors
static Future<void> registerErrorHandler()
}
Dialog Utilities
class Dialog {
// Get sound ID for notifications
static int getSoundId(String soundName)
}
Navigation and Routing
RouteGenerator
Application navigation management.
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings)
}
Supported Routes
// Available routes:
'/' // HomeView (main screen)
'/participate_in_a_project' // Available projects list
'/active_projects' // Active projects list
'/locations_history' // Location history list
'/report_an_issue' // Issue reporting form
'/navigation_to_webview' // Project survey webview
'/new_project' // Project creation/QR scan
'/tiger_in_car' // Specific project screen
'/tiger_in_car_finish' // Project completion screen
Data Models
LocationToPush
Model for queued location uploads.
class LocationToPush {
// Properties
final int? id;
final String userUUID;
final String userCode;
final String appVersion;
final String operativeSystem;
final String typeOfData;
final String message;
final double longitude;
final double latitude;
final String unixTime;
final num speed;
final String activity;
final String altitude;
// Methods
LocationToPush copy({...}) // Create copy with optional changes
Map<String, Object?> toJson() // Convert to JSON
static LocationToPush fromJson(Map<String, Object?> json) // Create from JSON
}
Contact
Contact form data model.
class Contact {
// Properties
final int? id;
final String name;
final String email;
final String phone;
final String message;
final String timestamp;
// Methods
Contact copy({...}) // Create copy with optional changes
Map<String, Object?> toJson() // Convert to JSON
static Contact fromJson(Map<String, Object?> json) // Create from JSON
}
Error Handling
Common Error Types
// Location errors
class LocationError {
int code; // Error code
String message; // Error description
}
// Database errors
class DatabaseException extends Exception {
String message;
DatabaseException(this.message);
}
// Network errors
class NetworkException extends Exception {
String message;
int? statusCode;
NetworkException(this.message, [this.statusCode]);
}
Error Handling Patterns
// Try-catch with graceful degradation
try {
await riskyOperation();
} catch (error) {
print('Operation failed: $error');
await fallbackOperation();
}
// Future error handling
riskyAsyncOperation()
.then((result) => handleSuccess(result))
.catchError((error) => handleError(error));
// Database error handling
Future<void> safeDatabaseOperation() async {
try {
await database.transaction((txn) async {
// Database operations
});
} on DatabaseException catch (e) {
print('Database error: ${e.message}');
// Handle database-specific errors
} catch (e) {
print('Unexpected error: $e');
// Handle unexpected errors
}
}
This API reference provides comprehensive coverage of the Wellbeing Mapper codebase. For implementation examples and usage patterns, refer to the Developer Guide and Architecture documentation.