Running Days Docs
GitHub

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" });     // false

Recognized 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"); // 2024

These functions parse dates from the ISO string directly, avoiding new Date() timezone interpretation.