A robust, test-driven Flutter MVVM application for managing IPSC match stages, shooters, and scoring with scale factors. Modern UI, persistent storage, Unicode PDF export, and advanced test coverage.
- Match Setup: Configure stages (1-30) and scoring shoots (1-32)
- Shooter Management: Add shooters with unique names and scale factors (0.100–2.000)
- Stage Input: Record scores with mobile-friendly numeric input, validation, and error feedback
- New: results can be marked with a Status ("Completed", "DNF", "DQ"). When a result is not "Completed" numeric inputs are disabled and submitted values are zeroed by the ViewModel. An RO remark field is available for match officials to record notes.
- Results: Calculate and display hit factors, adjusted hit factors, and rank shooters
- Stage Result Table:
- Rotated (vertical) header labels for all columns to maximize mobile readability
- Fixed column widths (in characters): Name: 10, Raw HF: 5, Scaled HF: 5, Time: 5, A: 2, C: 2, D: 2, Misses: 2, No Shoots: 2, Procedure Errors: 2
- Vertical rules (dividers) between columns for improved alignment and readability on mobile
- Export: Export all stage results to PDF (Unicode support, including Traditional Chinese; uses bundled font for cross-platform reliability)
- Persistence: All data is auto-saved and restored using SharedPreferences
- Note: The persisted schema was recently extended (schema v2) to include
statusandroRemarkonStageResult.PersistenceServiceimplements a migration path that upgrades older data to the new schema on app startup.
- Note: The persisted schema was recently extended (schema v2) to include
- Clear All Data: One-tap clear with confirmation
- Modern UI: Card-based, mobile-optimized, visually appealing
- MVVM Pattern:
- Views: UI only (
lib/views/) - ViewModels: Business logic (
lib/viewmodel/) - Models: Data structures (
lib/models/) - Services: Persistence (
lib/services/)
- Views: UI only (
- State Management: Provider
- Persistence:
- Uses
shared_preferencesfor local storage - Data schema is versioned and backward compatible
- Schema version stored as
dataSchemaVersionin SharedPreferences - Any schema change requires version bump, migration logic, and integration test
- See
data_schema_history.mdanddocs/data_schema_versioning.md
- Schema version stored as
- Uses
- Run app:
flutter run - Add dependency:
flutter pub add <package> - Test:
flutter test- New/Updated tests: migration tests (schema v2), widget tests for DNF/DQ + RO remark behavior, and additional stability improvements to StageInput widget tests.
- Hot Reload: Supported
- Schema changes:
- Increment schema version in
PersistenceServicefor breaking changes - Add migration logic and integration tests
- Update
data_schema_history.mdanddocs/data_schema_versioning.md
- Increment schema version in
- All features are covered by widget and logic tests (test-driven development)
- Migration logic is covered by integration tests simulating older schema data being loaded and verified.
- Stage Result table tests verify:
- All columns and headers are present and rotated
- All columns are visible and correct on mobile-sized screens
- Vertical rules are present between columns in both header and data rows
- Migration logic is covered by integration tests in
test/persistence_test.dart
- All core features are covered by unit, widget, and integration tests in
test/ - ViewModel logic is tested (e.g.,
test/viewmodel_main_menu_test.dart,test/viewmodel_match_setup_test.dart) - Persistence logic is tested (e.g.,
test/services_test.dart) - Widget navigation and UI are tested (e.g.,
test/widget_test.dart) - PDF export is tested for Unicode (Traditional Chinese) using
pdftotextfor robust extraction - All TODOs for tests have been implemented and committed
flutter test --coverageTo collect merged VM+Chrome coverage and generate an HTML report locally run:
chmod +x ./scripts/collect_coverage.sh
./scripts/collect_coverage.shNotes:
- The script tries
flutter test -d chrome --coveragefirst (some Flutter versions write lcov that way). - If that fails it falls back to
--platform chromeand finally attempts a VM-service based collection (requiresdartanddart pub global activate coverage). - On CI, ensure Chrome is installed and
CHROME_EXECUTABLEis set or Chrome is on PATH.
Recent CI notes
- The GitHub workflows were hardened after CI troubleshooting: the Flutter installer action is invoked with
channel: 'stable', the job now printsflutter --versionto logs for easier debugging, andactions/cacheis used to cache~/.pub-cache. An earliernpm cistep that caused failures was removed.
- The PDF export test requires
pdftotext(from poppler-utils) to be installed for Unicode extraction verification. - On macOS:
brew install poppler
- Follow MVVM and Provider patterns
- Write or update tests for all new features and bug fixes
- Keep the codebase warning- and lint-free (
flutter analyze) - Document all schema changes and migrations
- Data schema history:
data_schema_history.md - Schema versioning and migration:
docs/data_schema_versioning.md - Developer/contributor instructions:
.github/copilot-instructions.md - Unicode PDF export and font bundling: see
.github/copilot-instructions.md