- Active tab (ALL/UNREAD): Light text on dark background instead of white-on-white
- Unread notifications: Cyan-tinted semi-transparent background for visibility
- Actor names: Light color (#e8e8f0) for proper contrast in dark mode
- Hover states: Dark purple background (#301550) instead of white
- Notification icons: Semi-transparent backgrounds with bright neon colors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
ActivityControllerIntegrationTest was failing because the helper method
createTestActivity() didn't set the source_file_format field, which
became required after migration V15.
Added sourceFileFormat("FIT") to the Activity builder in the test helper.
Test Results:
- ✅ 128 tests passing
- ✅ 0 failures
- ✅ 0 errors
- 4 tests skipped (expected)
All integration tests now pass with Docker/Testcontainers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Integration tests using Testcontainers require Docker. This profile allows
running unit tests in CI/CD environments or local setups without Docker.
Usage:
mvn test -P skip-integration-tests
Results:
- 97 unit tests pass
- 18 integration tests skipped (require Docker)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit adds comprehensive GPX file support alongside existing FIT file support, enabling users to import activities from Strava, Komoot, and other GPS apps.
## Key Features
### Core Components
- **GpxParser**: Full GPX 1.1 parsing with Garmin TrackPointExtension support
- **GpxFileValidator**: Validation for GPX file format and structure
- **ActivityFileService**: Unified service with automatic format detection (FIT/GPX)
- **ParsedActivityData**: Common data structure for both FIT and GPX files
### GPX Parsing Capabilities
- GPS track point extraction (latitude, longitude, elevation, timestamp)
- Garmin extension data (heart rate, cadence, temperature)
- Activity type detection from GPX metadata
- Distance calculation using Haversine formula
- Elevation gain/loss calculation
- Speed calculation from consecutive GPS points
- Speed smoothing to remove GPS artifacts
- Timezone detection from GPS coordinates
- Moving time vs. stopped time analysis
### Database Changes
- Migration V15: Renamed raw_fit_file → raw_activity_file
- Added source_file_format column (FIT/GPX) with constraint
- Index on source_file_format for performance
- Updated Activity entity with new fields
### Controller & UI Updates
- ActivityController: Now handles both FIT and GPX uploads
- Upload form: Updated to accept .fit and .gpx files
- Help text: Clarified both formats are supported
### Testing
- GpxParserIntegrationTest: 9 comprehensive tests with real GPX file
- Tests cover: parsing, validation, heart rate extraction, distance calculation,
elevation metrics, speed calculation, chronological ordering, smoothing
- Fixed TrainingLoadServiceTest date issue (testDate outside 30-day window)
- All 97 unit tests passing (integration tests require Docker)
### Technical Details
- Supports GPX 1.0 and 1.1 specifications
- Handles multiple track segments
- Processes Garmin TrackPointExtension v1 and v2
- Same track simplification as FIT (Douglas-Peucker algorithm)
- Consistent JSONB storage format for track points
- Compatible with existing analytics, heatmaps, and image generation
## Testing Summary
- ✅ 9/9 GpxParserIntegrationTest tests passing
- ✅ 4/4 FitParserIntegrationTest tests passing
- ✅ 14/14 FitFileServiceTest tests passing
- ✅ 97/97 total unit tests passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>