This document outlines the technical architecture, technology stack, and implementation strategy for the The Paragliding App mobile application based on the functional requirements.
Flutter (Google’s UI Framework)
SQLite via sqflite package
SharedPreferences
Path Provider + Device File System
dependencies:
flutter_map: ^8.2.1 # Cross-platform map visualization
latlong2: ^0.9.1 # Coordinate handling
dependencies:
flutter_inappwebview: ^6.1.5 # WebView integration
name: the_paragliding_app
description: "A mobile app for logging paraglider, hang glider, and microlight flights"
dependencies:
flutter:
sdk: flutter
# Core dependencies for The Paragliding App
cupertino_icons: ^1.0.8 # iOS-style icons
async: ^2.11.0 # Async utilities including CancelableOperation
# Data Storage
sqflite: ^2.4.2 # Local SQLite database - platform architecture updates
sqflite_common_ffi: ^2.3.6 # SQLite for desktop platforms - latest stable version
shared_preferences: ^2.5.3 # Settings storage - new async APIs
# Mapping Solutions - OpenStreetMap instead of Google Maps
flutter_map: ^8.2.1 # Cross-platform map visualization with OpenStreetMap
latlong2: ^0.9.1 # Coordinate handling for flutter_map
# File Handling
file_picker: ^10.3.1 # IGC file import - minor improvements
receive_sharing_intent: ^1.8.1 # Handle IGC files shared from other apps
# Data Processing & IGC Parsing
xml: ^6.5.0 # XML/KML parsing for paragliding sites
intl: ^0.20.2 # Date/time formatting
timezone: ^0.10.1 # Timezone database and lookup
crypto: ^3.0.5 # SHA256 hashing for cache keys
# Visualization & Charts
fl_chart: ^1.0.0 # Charts for altitude/climb rate
# 3D Visualization - Cesium Integration
flutter_inappwebview: ^6.1.5 # WebView for 3D Cesium integration with CORS bypass
# Network & Connectivity
connectivity_plus: ^6.1.5 # Network connectivity detection - WASM support & fixes
url_launcher: ^6.3.2 # Open external URLs for OSM links
http: ^1.2.2 # HTTP client - pinned from "any" to stable
# State Management
provider: any # State management (flexible version)
# Utilities
path: ^1.8.0 # Database path utilities
path_provider: ^2.1.5 # App directory paths - bug fixes & stability
logger: ^2.6.1 # Structured logging framework
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
flutter_lints: ^6.0.0 # Latest lint rules
MVVM with Repository Pattern
┌─────────────────┐
│ UI Layer │ ← Flutter Widgets
├─────────────────┤
│ ViewModels │ ← Business Logic (Provider)
├─────────────────┤
│ Repositories │ ← Data Access Abstraction
├─────────────────┤
│ Data Sources │ ← SQLite, Files, Preferences
└─────────────────┘
lib/
├── main.dart
├── app.dart
├── core/
│ ├── constants/
│ ├── themes/
│ └── utils/
├── data/
│ ├── models/
│ │ ├── flight.dart
│ │ ├── site.dart
│ │ ├── wing.dart
│ │ └── settings.dart
│ ├── repositories/
│ │ ├── flight_repository.dart
│ │ ├── site_repository.dart
│ │ └── settings_repository.dart
│ └── datasources/
│ ├── local/
│ │ ├── database_helper.dart
│ │ └── preferences_helper.dart
│ └── parsers/
│ ├── igc_parser.dart
│ └── csv_parser.dart
├── domain/
│ ├── entities/
│ └── usecases/
├── presentation/
│ ├── screens/
│ │ ├── splash_screen.dart
│ │ ├── flight_list_screen.dart
│ │ ├── add_flight_screen.dart
│ │ ├── edit_flight_screen.dart
│ │ ├── flight_detail_screen.dart
│ │ ├── flight_track_3d_screen.dart
│ │ ├── igc_import_screen.dart
│ │ ├── statistics_screen.dart
│ │ ├── edit_site_screen.dart
│ │ ├── manage_sites_screen.dart
│ │ ├── wing_management_screen.dart
│ │ ├── edit_wing_screen.dart
│ │ ├── database_settings_screen.dart
│ │ └── about_screen.dart
│ ├── widgets/
│ │ ├── cesium_3d_map_inappwebview.dart
│ │ ├── flight_track_3d_widget.dart
│ │ └── common/
│ └── providers/
│ └── (using Provider pattern with ChangeNotifier)
└── services/
├── export_service.dart
├── import_service.dart
└── location_service.dart
-- Flights table
CREATE TABLE flights (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
launch_time TEXT NOT NULL,
landing_time TEXT NOT NULL,
duration INTEGER NOT NULL,
launch_site_id INTEGER,
landing_site_id INTEGER,
max_altitude REAL,
max_climb_rate REAL,
max_sink_rate REAL,
distance REAL,
wing_id INTEGER,
notes TEXT,
track_log_path TEXT,
source TEXT CHECK(source IN ('manual', 'igc', 'parajournal')),
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (launch_site_id) REFERENCES sites (id),
FOREIGN KEY (landing_site_id) REFERENCES sites (id),
FOREIGN KEY (wing_id) REFERENCES wings (id)
);
-- Sites table
CREATE TABLE sites (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
latitude REAL NOT NULL,
longitude REAL NOT NULL,
altitude REAL,
custom_name INTEGER DEFAULT 0,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
-- Wings table
CREATE TABLE wings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
manufacturer TEXT,
model TEXT,
size TEXT,
color TEXT,
purchase_date TEXT,
active INTEGER DEFAULT 1,
notes TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for performance
CREATE INDEX idx_flights_date ON flights(date);
CREATE INDEX idx_flights_launch_site ON flights(launch_site_id);
CREATE INDEX idx_flights_wing ON flights(wing_id);
UI & Maps
// Example: IGC Parser Test
test('parses IGC header correctly', () {
final parser = IgcParser();
final result = parser.parseHeader('HFDTE2501231');
expect(result.date, DateTime(2023, 01, 25));
});
// Example: Flight Entry Form Test
testWidgets('validates landing after launch', (tester) async {
await tester.pumpWidget(FlightEntryForm());
// Test implementation
});
# Development
flutter run
# Release build for Play Store
flutter build appbundle --release
# APK for direct installation
flutter build apk --release
App Signing
keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
Build Configuration (android/key.properties)
storePassword=<password>
keyPassword=<password>
keyAlias=upload
storeFile=../upload-keystore.jks
Permissions (android/app/src/main/AndroidManifest.xml)
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
2D Maps (flutter_map + OpenStreetMap)
Cache-Control: max-age=31536000 (12 months)3D Maps (Cesium + WebView)
max-age=31536000, immutable (12 months)Monitoring:
// Cache statistics in Database Settings
CacheUtils.getCurrentCacheCount() // Returns tile count
CacheUtils.getCurrentCacheSize() // Returns size in bytes
CacheUtils.formatBytes(size) // Human-readable format (KB/MB/GB)
Manual Management:
# Branching strategy
main # Production releases
develop # Development branch
feature/* # Feature branches
release/* # Release candidates
hotfix/* # Emergency fixes
# Install Flutter
git clone https://github.com/flutter/flutter.git
export PATH="$PATH:`pwd`/flutter/bin"
# Verify installation
flutter doctor
# Create project
flutter create the_paragliding_app --org com.theparaglidingapp
# Run on device
flutter run