Spaces:
Running
Running
File size: 1,672 Bytes
557ee65 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | from typing import Optional, Dict, Any
from domain.runner_positioning import RunnerPositioning
from domain.training.weekly_snapshot import WeeklySnapshot
from domain.training.weekly_trend import WeeklyTrend
from application.positioning_service import PositioningEngine
class RunnerPositioningService:
"""
Application service for Runner Positioning.
Enforces architectural boundaries: no LLM, no persistence, no observability here.
"""
def generate(
self,
snapshot: WeeklySnapshot,
trend: WeeklyTrend,
goal_progress: Optional[Dict[str, Any]] = None
) -> RunnerPositioning:
"""
Aggregates domain data into a RunnerPositioning assessment.
"""
# Extract necessary values for deterministic logic
target_distance = None
if goal_progress:
# goal_service.compute_goal_progress returns a dict
# We assume it has a 'target_value' if applicable
target_distance = goal_progress.get("target_value")
# Call domain logic
engine = PositioningEngine()
training_phase = engine.detect_training_phase(snapshot, trend)
return RunnerPositioning.compute(
week_start=snapshot.week_start_date,
total_distance=snapshot.total_distance_km,
target_distance=target_distance,
consistency_score=snapshot.consistency_score,
pace_delta=trend.pace_delta_s_per_km,
hr_delta=trend.hr_delta,
distance_delta_pct=trend.distance_delta_pct,
comparison_available=trend.comparison_available,
training_phase=training_phase
)
|