Workout Processor
The workout processor handles parsing, validation, and aggregation of workout data from various sources.
Functions
processWorkout
Transform raw workout data into a normalized format.
typescript
import { processWorkout } from '@running-days/business-logic';
const workout = processWorkout({
name: "Running",
start: "2024-01-15T08:00:00Z",
end: "2024-01-15T08:35:00Z",
duration: 2100,
distance: 5000,
energyBurned: 350
});Returns:
typescript
{
id: "wkt_abc123...",
date: "2024-01-15",
year: 2024,
startTime: "2024-01-15T08:00:00Z",
endTime: "2024-01-15T08:35:00Z",
durationSeconds: 2100,
distanceMeters: 5000,
avgPaceSecondsPerKm: 420, // 7:00/km
energyBurnedKcal: 350,
source: "healthkit"
}isRunningWorkout
Check if a workout qualifies as a running workout.
typescript
import { isRunningWorkout } from '@running-days/business-logic';
isRunningWorkout({ name: "Running" }); // true
isRunningWorkout({ name: "Outdoor Run" }); // true
isRunningWorkout({ name: "Walking" }); // false
isRunningWorkout({ name: "Cycling" }); // falseRecognized running types:
- Running
- Outdoor Run
- Indoor Run
- Treadmill
- Trail Run
filterRunningWorkouts
Filter an array to only running workouts.
typescript
import { filterRunningWorkouts } from '@running-days/business-logic';
const runs = filterRunningWorkouts(allWorkouts);aggregateDailyStats
Aggregate multiple workouts into daily statistics.
typescript
import { aggregateDailyStats } from '@running-days/business-logic';
const dailyStats = aggregateDailyStats(workouts, "2024-01-15");Returns:
typescript
{
date: "2024-01-15",
year: 2024,
runCount: 2,
totalDistanceMeters: 12000,
totalDurationSeconds: 4200,
longestRunMeters: 7000,
fastestPaceSecondsPerKm: 390,
avgPaceSecondsPerKm: 420
}mergeDailyStats
Merge two daily stats records (for incremental sync).
typescript
import { mergeDailyStats } from '@running-days/business-logic';
const merged = mergeDailyStats(existingStats, newStats);calculatePaceSecondsPerKm
Calculate pace from distance and duration.
typescript
import { calculatePaceSecondsPerKm } from '@running-days/business-logic';
const pace = calculatePaceSecondsPerKm(5000, 1800);
// Returns: 360 (6:00/km)generateWorkoutId
Generate a deterministic ID for deduplication.
typescript
import { generateWorkoutId } from '@running-days/business-logic';
const id = generateWorkoutId(startTime, endTime, distance);The ID is based on start time, end time, and distance to detect duplicates.
Date Handling
All date operations use explicit parsing to avoid timezone issues:
typescript
import { extractDateFromISO, extractYearFromISO } from '@running-days/business-logic';
extractDateFromISO("2024-01-15T08:00:00Z"); // "2024-01-15"
extractYearFromISO("2024-01-15T08:00:00Z"); // 2024These functions parse dates from the ISO string directly, avoiding new Date() timezone interpretation.