wip: insurance booking phases 1 and 2

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent 411166ffba
commit 241785b428
8 changed files with 1109 additions and 4 deletions
@@ -0,0 +1,402 @@
# Insurance Booking System Implementation Plan
## Overview
This document outlines the complete implementation plan for making travel insurances bookable per participant in the MyEP Next Booking system. The implementation includes sophisticated criteria matching, automatic re-selection when participant prices change, and comprehensive form integration.
## Current System Status
### ✅ Already Implemented
- **Insurance XML Parsing**: `InsuranceParser` and `InsuranceLoader` classes
- **Insurance Model**: Complete with price ranges, age constraints, dates, family flags
- **Family Status Logic**: `BookingCreateDto::isFamilyBooking()` method
- **Individual Pricing**: `BookingPriceCalculatorService::calculateIndividualParticipantPrice()` method
- **Field Handler Architecture**: Existing pattern for dynamic form fields
- **HTMX Integration**: Real-time form updates infrastructure
### ❌ Missing Implementation
- Insurance subtype parsing and type resolution system
- Participant insurance field and selection logic
- Insurance matching service with criteria validation
- Auto-reselection when participant price changes
- Form integration and field handlers
- Frontend templates and UX
## Key Technical Discoveries
### Insurance XML Structure Analysis
- **Individual Insurances**: Have `unterart` (subtype) attribute (RRV, PAK, OHN)
- **Insurance Packages**: No subtype but contain individual insurances
- **Family Detection**: Use `familienversicherung` boolean attribute (not label parsing)
- **Package Type Resolution**: Analyze contained insurances to determine dominant type
### Age Calculation Requirement
- **Critical**: Use travel start date for age calculation, not current date
- Insurance eligibility based on participant's age at time of travel
## Implementation Phases
### Phase 1: Insurance Type System
**Goal**: Add type resolution capability to distinguish insurance types
#### 1.1 Extend Insurance Model
- [ ] Add `subType` property to `Insurance` model (from XML `unterart`)
- [ ] Add computed `type` property (resolved via service)
- [ ] Update serialization groups if needed
#### 1.2 Update Insurance Parser
- [ ] Modify `InsuranceParser::parseInsuranceNode()` to parse `unterart` attribute
- [ ] Add subtype to individual insurance parsing
- [ ] Ensure package parsing maintains existing functionality
#### 1.3 Create Insurance Type Resolver
- [ ] Create `InsuranceTypeResolver` service
- [ ] Implement type resolution for individual insurances
- [ ] Implement package type resolution via contained insurance analysis
- [ ] Define type constants: `TRAVEL_CANCELLATION`, `TRAVEL_PROTECTION`, etc.
- [ ] Handle family variants using `familyInsurance` boolean
```php
// Type Constants
const TRAVEL_CANCELLATION = 'TRAVEL_CANCELLATION';
const TRAVEL_CANCELLATION_FAMILY = 'TRAVEL_CANCELLATION_FAMILY';
const TRAVEL_PROTECTION = 'TRAVEL_PROTECTION';
const TRAVEL_PROTECTION_FAMILY = 'TRAVEL_PROTECTION_FAMILY';
```
#### 1.4 Testing
- [ ] Create `InsuranceTypeResolverTest`
- [ ] Test individual insurance type resolution
- [ ] Test package type resolution
- [ ] Test family variant detection
- [ ] Verify existing insurance parsing still works
### Phase 2: Enhanced Age Calculation
**Goal**: Support age calculation at specific dates (travel start date)
#### 2.1 Update ParticipantDto
- [ ] Add `getAgeAtDate(\DateTimeImmutable $referenceDate): ?int` method
- [ ] Keep existing `getAge(): ?int` for backward compatibility
- [ ] Ensure proper null handling for missing birth dates
#### 2.2 Testing
- [ ] Add tests for `getAgeAtDate()` method
- [ ] Test edge cases (leap years, same day, etc.)
- [ ] Verify existing age calculation still works
### Phase 3: Insurance Matching Service
**Goal**: Implement comprehensive insurance matching with all criteria
#### 3.1 Create Insurance Matching Service
- [ ] Create `InsuranceMatchingService` class
- [ ] Implement `getMatchingInsurances()` method with all criteria:
- Age at travel date validation
- Price range validation
- Booking date validation
- Travel date validation
- Family insurance validation
- [ ] Implement `getMatchingInsurancesByType()` for auto-reselection
- [ ] Add "No Insurance" option handling
#### 3.2 Auto-Reselection Logic
- [ ] Implement `handlePriceChange()` method
- [ ] Find matching insurance of same type when price changes
- [ ] Maintain coverage when possible, fallback to null
- [ ] Log auto-reselection events for debugging
#### 3.3 Service Registration
- [ ] Register service in `services.yaml`
- [ ] Configure dependencies (InsuranceLoader, InsuranceTypeResolver)
#### 3.4 Testing
- [ ] Create comprehensive `InsuranceMatchingServiceTest`
- [ ] Test all matching criteria combinations
- [ ] Test auto-reselection scenarios
- [ ] Test edge cases and boundary conditions
### Phase 4: Participant DTO Enhancement
**Goal**: Add insurance property and integrate with pricing
#### 4.1 Extend ParticipantDto
- [ ] Add `?Insurance $insurance = null` property
- [ ] Add validation groups if needed
- [ ] Ensure proper serialization/deserialization
#### 4.2 Update Price Calculation
- [ ] Modify `BookingPriceCalculatorService::calculateParticipantServiceTotal()`
- [ ] Include insurance price in participant total
- [ ] Update `calculateIndividualParticipantPrice()` to include insurance
- [ ] Update `calculateAllParticipantIndividualPrices()` accordingly
#### 4.3 Testing
- [ ] Update `BookingPriceCalculatorServiceTest`
- [ ] Test price calculation with insurance
- [ ] Test pricing without insurance
- [ ] Verify individual participant pricing includes insurance
### Phase 5: Form Field Handler
**Goal**: Create form field handler for insurance selection
#### 5.1 Create Insurance Field Handler
- [ ] Create `ParticipantInsuranceFieldHandler` extending `AbstractParticipantFieldHandler`
- [ ] Implement field processing logic
- [ ] Handle insurance selection validation
- [ ] Implement auto-reselection on price changes
- [ ] Clear insurance if criteria no longer match
#### 5.2 Field Dependencies
- [ ] Define dependencies: `dateOfBirth` (for age calculation)
- [ ] Handle field visibility based on available insurances
- [ ] Implement proper error handling
#### 5.3 Service Registration
- [ ] Register handler in `services.yaml` with proper tags
- [ ] Set appropriate priority in relation to other handlers
#### 5.4 Testing
- [ ] Create `ParticipantInsuranceFieldHandlerTest`
- [ ] Test field processing
- [ ] Test auto-reselection scenarios
- [ ] Test validation logic
### Phase 6: Form Integration
**Goal**: Add insurance field to participant form
#### 6.1 Update Form Type
- [ ] Modify `BookingCreateParticipantType`
- [ ] Add insurance choice field
- [ ] Configure field type and options
- [ ] Add HTMX trigger attributes
#### 6.2 Field Options Provider
- [ ] Add insurance field to `ParticipantFieldOptionsProvider`
- [ ] Generate "No Insurance" option
- [ ] Generate valid insurance options per participant
- [ ] Use `InsuranceMatchingService` for filtering
- [ ] Format options with price and type information
#### 6.3 Field State Provider Integration
- [ ] Update `CreateFieldStateProvider` if needed
- [ ] Handle field visibility conditions
- [ ] Register field state conditions
#### 6.4 Testing
- [ ] Test form field rendering
- [ ] Test field options generation
- [ ] Test HTMX integration
### Phase 7: Controller Integration
**Goal**: Update controllers to handle insurance data
#### 7.1 Update Step 2 Controller
- [ ] Ensure insurance data is included in template variables
- [ ] Handle insurance-related HTMX updates
- [ ] Update participant price calculations to include insurance
#### 7.2 Error Handling
- [ ] Add proper error handling for insurance validation
- [ ] Handle insurance matching failures gracefully
- [ ] Provide user-friendly error messages
#### 7.3 Testing
- [ ] Test controller responses include insurance data
- [ ] Test HTMX updates work correctly
- [ ] Test error scenarios
### Phase 8: Frontend Templates
**Goal**: Add insurance field to templates and display pricing
#### 8.1 Template Updates
- [ ] Add insurance field to `create_step_2.html.twig`
- [ ] Position field appropriately in participant sections
- [ ] Add proper labeling and help text
- [ ] Configure HTMX attributes for real-time updates
#### 8.2 Pricing Display
- [ ] Update participant headers to show insurance pricing
- [ ] Include insurance in individual participant price display
- [ ] Update booking summary to include insurance totals
#### 8.3 UX Enhancements
- [ ] Show criteria-based availability information
- [ ] Display auto-reselection notifications
- [ ] Add loading states for HTMX updates
### Phase 9: Advanced Features
**Goal**: Implement applicant control and bulk operations
#### 9.1 Applicant Insurance Control
- [ ] Add special UI for first participant (applicant)
- [ ] Implement bulk insurance selection
- [ ] Respect individual criteria while allowing bulk operations
- [ ] Add override capabilities with proper validation
#### 9.2 Real-time Price Integration
- [ ] Monitor price changes via HTMX
- [ ] Trigger auto-reselection when participant price changes
- [ ] Provide visual feedback for automatic changes
- [ ] Update pricing summary dynamically
#### 9.3 Enhanced UX
- [ ] Add insurance type grouping in selection
- [ ] Implement insurance comparison features
- [ ] Add detailed insurance information display
- [ ] Improve mobile responsiveness
### Phase 10: Testing & Quality Assurance
**Goal**: Comprehensive testing and code quality
#### 10.1 Integration Testing
- [ ] Create end-to-end insurance booking tests
- [ ] Test complete booking flow with insurances
- [ ] Test auto-reselection scenarios
- [ ] Test applicant control features
#### 10.2 Performance Testing
- [ ] Test insurance matching performance with large datasets
- [ ] Optimize insurance filtering algorithms
- [ ] Test HTMX update performance
#### 10.3 Code Quality
- [ ] Run PHP CS Fixer on all new files
- [ ] Ensure PSR-12 compliance
- [ ] Add proper PHPDoc documentation
- [ ] Review and optimize service dependencies
#### 10.4 User Acceptance Testing
- [ ] Test with real insurance data
- [ ] Validate business logic with stakeholders
- [ ] Test edge cases and error scenarios
- [ ] Gather user feedback on UX
## Technical Architecture
### New Classes Overview
```
src/Service/
├── InsuranceTypeResolver.php # Type resolution for insurances and packages
├── InsuranceMatchingService.php # Criteria-based insurance matching
└── Insurance/
├── Criteria/
│ ├── AgeCriterion.php # Age-based matching
│ ├── PriceCriterion.php # Price range matching
│ ├── DateCriterion.php # Date validation
│ └── FamilyCriterion.php # Family insurance validation
└── Matcher/
└── InsuranceMatcher.php # Core matching logic
src/Form/Service/
├── ParticipantInsuranceFieldHandler.php # Form field processing
└── Insurance/
└── InsuranceFieldOptionsProvider.php # Field options generation
tests/Service/
├── InsuranceTypeResolverTest.php
├── InsuranceMatchingServiceTest.php
└── Insurance/
└── Criteria/
├── AgeCriterionTest.php
├── PriceCriterionTest.php
├── DateCriterionTest.php
└── FamilyCriterionTest.php
tests/Form/Service/
└── ParticipantInsuranceFieldHandlerTest.php
```
### Database Changes
- **None required** - All insurance data loaded from XML
### Configuration Changes
- Service registrations in `services.yaml`
- Field handler tags and priorities
- Form field configurations
## Implementation Guidelines
### Code Standards
- Follow PSR-12 coding standards
- Use `declare(strict_types=1)` on all files
- Apply Symfony coding standards via php-cs-fixer
- Use English for all variable and constant names
- Follow existing architectural patterns
### Testing Standards
- Minimum 90% code coverage for new classes
- Unit tests for all service methods
- Integration tests for form processing
- End-to-end tests for complete booking flow
- Performance tests for matching algorithms
### Documentation Standards
- PHPDoc for all public methods
- Business logic documentation in comments
- Update CLAUDE.md with new features
- Create user documentation for insurance features
## Risk Mitigation
### Technical Risks
1. **Performance**: Large insurance datasets could slow matching
- **Mitigation**: Implement caching and optimize algorithms
2. **Complexity**: Auto-reselection logic could introduce bugs
- **Mitigation**: Comprehensive testing and logging
3. **Data Integrity**: Price changes could cause inconsistent states
- **Mitigation**: Atomic operations and validation
### Business Risks
1. **Incorrect Matching**: Wrong insurance eligibility could cause issues
- **Mitigation**: Thorough testing with real data and stakeholder validation
2. **User Confusion**: Complex insurance options could confuse users
- **Mitigation**: Clear UX design and comprehensive help text
## Success Criteria
### Functional Requirements
- ✅ Participants can select appropriate insurances based on all criteria
- ✅ Auto-reselection works when participant price changes
- ✅ Applicant can manage insurances for all participants
- ✅ Real-time pricing updates include insurance costs
- ✅ Form validation prevents invalid insurance selections
### Performance Requirements
- ✅ Insurance matching completes within 100ms for typical datasets
- ✅ HTMX updates complete within 500ms
- ✅ Page load times remain under 2 seconds
### Quality Requirements
- ✅ 90%+ code coverage for new functionality
- ✅ Zero critical bugs in production
- ✅ PSR-12 compliance for all new code
- ✅ Comprehensive documentation
## Future Enhancements
### Phase 11+ (Future)
- Insurance comparison tools
- Advanced filtering and search
- Insurance recommendation engine
- Historical insurance selection analytics
- Multi-language insurance descriptions
- PDF insurance documentation generation
## Dependencies
### External Dependencies
- Insurance XML data must be available and properly formatted
- BusProNet API integration for insurance booking
- Travel data must include proper date information
### Internal Dependencies
- Existing individual pricing calculation system
- Field handler architecture
- HTMX integration infrastructure
- Family status determination logic
---
**Document Version**: 1.0
**Last Updated**: 2025-09-26
**Author**: Claude Code Implementation Plan
**Status**: Ready for Implementation