2026-01-06 22:59:58 +08:00

178 lines
7.5 KiB
Markdown

# Implementation Plan: Yearly Statistics Display Logic
## Overview
This implementation plan modifies the `GetYearlyStatisticsByMonthAsync` method to support a rolling 15-month display window that adapts based on the current month. The implementation adds two new helper methods and refactors the main method logic.
## Tasks
- [x] 1. Create helper method for calculating display window
- Implement `CalculateDisplayWindow` method that takes current year and month as parameters
- Calculate start month/year by subtracting 3 months from current (handle year boundary)
- Calculate end month/year by adding 11 months to current (handle year boundary)
- Return tuple of (startYear, startMonth, endYear, endMonth)
- Add unit tests for various current months (January, March, September, October, December)
- _Requirements: 1.1, 1.2, 1.3, 1.4, 5.1, 6.1, 7.1, 8.1, 9.1, 10.1_
- [ ]* 1.1 Write unit tests for CalculateDisplayWindow
- Test January: should return (previousYear, 10, currentYear, 11)
- Test March: should return (previousYear, 12, currentYear, 2)
- Test September: should return (currentYear, 6, currentYear + 1, 8)
- Test October: should return (currentYear, 7, currentYear + 1, 9)
- Test December: should return (currentYear, 9, currentYear + 1, 11)
- _Requirements: 1.2, 1.3, 1.4, 5.1, 6.1, 7.1, 8.1, 9.1_
- [x] 2. Create helper method for zero statistics
- Implement `CreateZeroStatistics` method that takes year and month as parameters
- Create SecondaryCircuitInspectionStatisticsOutput with all counts set to 0
- Set StatisticsStartTime to first day of month
- Set StatisticsEndTime to last millisecond of month
- Initialize empty StatisticsByModule list
- _Requirements: 4.1, 4.3, 4.4_
- [ ]* 2.1 Write unit test for CreateZeroStatistics
- Verify all count fields are 0
- Verify StatisticsStartTime is correct
- Verify StatisticsEndTime is correct
- Verify StatisticsByModule is empty
- _Requirements: 4.1, 4.3, 4.4_
- [x] 3. Refactor GetYearlyStatisticsByMonthAsync main logic
- [x] 3.1 Update method to use current date instead of year parameter
- Get current DateTime.Now
- Extract currentYear and currentMonth
- Log that year parameter is ignored for rolling window
- _Requirements: 10.1, 12.5_
- [x] 3.2 Calculate display window using helper method
- Call CalculateDisplayWindow(currentYear, currentMonth)
- Store returned startYear, startMonth, endYear, endMonth
- _Requirements: 1.1, 5.1, 6.1, 7.1, 8.1, 9.1, 10.1_
- [x] 3.3 Implement month iteration logic
- Create loop to iterate from (startYear, startMonth) to (endYear, endMonth)
- Handle year boundary crossing in loop
- For each month, determine if it's historical, predicted, or zero
- _Requirements: 10.2, 11.3, 12.4_
- [x] 3.4 Implement historical data retrieval
- For months <= currentMonth (accounting for year), call GetStatisticsAsync
- Use dateRange format "yyyy-MM"
- Add to historicalMonthlyStats list for prediction
- Mark as IsPredicted = false
- _Requirements: 1.5, 2.1, 2.2, 2.3_
- [x] 3.5 Implement predicted data generation
- For months currentMonth + 1 to currentMonth + 3, use prediction algorithm
- Call PredictMonthlyStatisticsWithModuleDetails once with 3 months
- Handle year boundary for prediction start month
- Mark as IsPredicted = true
- _Requirements: 3.1, 3.2, 3.3, 3.4_
- [x] 3.6 Implement zero data generation
- For months beyond currentMonth + 3, call CreateZeroStatistics
- Mark as IsPredicted = false
- _Requirements: 4.1, 4.3, 4.4_
- [x] 3.7 Handle September special case
- When currentMonth == 9, adjust display window to Jan-Dec of current year only
- Ensure only 12 months are returned
- _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5_
- [x] 3.8 Add error handling for individual month failures
- Wrap each month's data retrieval in try-catch
- On failure, use CreateZeroStatistics instead of failing entire request
- Log warning for failed months
- _Requirements: 11.4_
- [ ] 4. Checkpoint - Ensure all tests pass
- Run all unit tests
- Verify no compilation errors
- Ask the user if questions arise
- [ ]* 5. Write property-based tests
- [ ]* 5.1 Write property test for three historical months
- **Property 1: Three Historical Months Preceding Current**
- **Validates: Requirements 1.1, 1.5**
- Generate random current months (April-December)
- Verify 3 preceding months are in window with actual data
- Verify IsPredicted = false for historical months
- [ ]* 5.2 Write property test for current month inclusion
- **Property 2: Current Month Inclusion and Marking**
- **Validates: Requirements 2.1, 2.2, 2.3**
- Generate random current months
- Verify current month is in window
- Verify IsPredicted = false
- Verify data is not zero
- [ ]* 5.3 Write property test for predicted months
- **Property 3: Three Predicted Months Following Current**
- **Validates: Requirements 3.1, 3.2, 3.3, 3.4**
- Generate random current months
- Verify next 3 months are in window
- Verify IsPredicted = true
- Verify year boundary handling
- [ ]* 5.4 Write property test for zero data range
- **Property 4: Zero Data Beyond Prediction Range**
- **Validates: Requirements 4.1, 4.3, 4.4**
- Generate random current months
- Verify months beyond current + 3 have all zeros
- Verify IsPredicted = false
- Verify empty StatisticsByModule
- [ ]* 5.5 Write property test for display window size
- **Property 5: Display Window Size**
- **Validates: Requirements 10.2, 12.2**
- Generate random current months
- Verify 15 months for all except September
- Verify 12 months for September
- [ ]* 5.6 Write property test for chronological sequence
- **Property 6: Chronological Month Sequence**
- **Validates: Requirements 11.3, 12.4**
- Generate random current months
- Verify each month is exactly 1 month after previous
- Verify year increments correctly at boundaries
- [ ]* 5.7 Write property test for month and year validity
- **Property 7: Month and Year Value Validity**
- **Validates: Requirements 11.1, 11.2**
- Generate random current months
- Verify all month values are 1-12
- Verify all year values are valid (>= 1900, <= 9999)
- [ ]* 5.8 Write property test for output year property
- **Property 8: Output Year Property**
- **Validates: Requirements 12.5**
- Generate random current months
- Verify output.Year equals current year
- [ ]* 6. Write integration tests
- Test with real GetStatisticsAsync calls (using test database or mocks)
- Test with real prediction algorithm
- Test end-to-end flow for various current months
- _Requirements: All_
- [x] 7. Update logging
- Add log statement when year parameter is ignored
- Add log statements for display window calculation
- Add log statements for each month type (historical/predicted/zero)
- _Requirements: All_
- [ ] 8. Final checkpoint - Ensure all tests pass
- Run all unit tests
- Run all property-based tests (minimum 100 iterations each)
- Run integration tests
- Verify no compilation errors
- Ask the user if questions arise
## Notes
- Tasks marked with `*` are optional and can be skipped for faster MVP
- Each task references specific requirements for traceability
- Property tests should run minimum 100 iterations
- The year parameter is validated but not used in the new logic (for backward compatibility)
- September is a special case that returns only 12 months instead of 15