Spaces:
Running
Running
| from typing import Optional, Any | |
| from domain.training.weekly_snapshot import WeeklySnapshot | |
| from domain.training.weekly_trend import WeeklyTrend | |
| from domain.runner_positioning import RunnerPositioning, TrainingPhase | |
| from domain.training.training_recommendation import TrainingRecommendation | |
| from _app.presentation.ui_text import get_text | |
| class RecommendationService: | |
| """ | |
| Stateless service to generate training recommendations based on positioning. | |
| """ | |
| def generate( | |
| self, | |
| snapshot: WeeklySnapshot, | |
| trend: WeeklyTrend, | |
| positioning: Any, # Can be RunnerPositioning or WeeklyPositioning | |
| language: str = "en" | |
| ) -> TrainingRecommendation: | |
| """ | |
| Pure rule-based logic to map positioning to training focus and session types. | |
| """ | |
| # Mapping from positioning focus or status | |
| # Handle both Domain (RunnerPositioning) and Application (WeeklyPositioning) models | |
| if hasattr(positioning, "recommended_focus"): | |
| focus_val = positioning.recommended_focus | |
| else: | |
| # Fallback for WeeklyPositioning (Application Layer) | |
| status_map = { | |
| "CONSTRUCTIVE_ADAPTATION": "INTENSITY", | |
| "PRODUCTIVE_LOAD": "CONSISTENCY", | |
| "STRAIN": "RECOVERY", | |
| "PLATEAU": "MAINTENANCE" | |
| } | |
| focus_val = status_map.get(getattr(positioning, "status", ""), "MAINTENANCE") | |
| focus_key = focus_val.lower() | |
| # Initial recommendation mapping as per requirements: | |
| # Building Momentum (CONSTRUCTIVE_ADAPTATION) -> introduce_intensity / tempo_intervals | |
| # Maintaining Consistency (PRODUCTIVE_LOAD) -> build_endurance / long_run | |
| # Recovery (STRAIN) -> protect_recovery / easy_run | |
| # Default -> maintain_consistency | |
| mapping = { | |
| "RECOVERY": { | |
| "focus": "protect_recovery", | |
| "session_type": "easy_run", | |
| "confidence": 0.9 | |
| }, | |
| "CONSISTENCY": { | |
| "focus": "build_endurance", | |
| "session_type": "long_run", | |
| "confidence": 0.8 | |
| }, | |
| "INTENSITY": { | |
| "focus": "introduce_intensity", | |
| "session_type": "tempo_intervals", | |
| "confidence": 0.85 | |
| }, | |
| "MAINTENANCE": { | |
| "focus": "maintain_consistency", | |
| "session_type": "steady_run", | |
| "confidence": 0.75 | |
| } | |
| } | |
| rec_data = mapping.get(focus_val, { | |
| "focus": "maintain_consistency", | |
| "session_type": "steady_run", | |
| "confidence": 0.5 | |
| }) | |
| # Resolve localized description | |
| description = get_text(f"rec_desc_{rec_data['focus']}", language) | |
| return TrainingRecommendation( | |
| focus=get_text(f"rec_focus_{rec_data['focus']}", language), | |
| session_type=get_text(f"rec_session_{rec_data['session_type']}", language), | |
| description=description, | |
| confidence=rec_data["confidence"] | |
| ) | |