From 06bdf836578a910630c7f49f4c79232f0329ef8d Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Fri, 19 Jun 2026 17:01:22 +0200 Subject: [PATCH] kpi --- api/src/analytics/analytics.service.ts | 31 ++++++++++++++------------ 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/api/src/analytics/analytics.service.ts b/api/src/analytics/analytics.service.ts index 271cd51..020844e 100644 --- a/api/src/analytics/analytics.service.ts +++ b/api/src/analytics/analytics.service.ts @@ -568,7 +568,7 @@ export class AnalyticsService { acuteChronicRatio: number | null, ): RunningKpiDashboard['recovery'] { const sortedLoads = [...activityLoads] - .filter((load) => load.activity.startDate) + .filter((load) => load.activity.startDate !== null && load.activity.startDate !== undefined) .sort( (left, right) => (right.activity.startDate?.getTime() ?? 0) - @@ -1351,7 +1351,9 @@ export class AnalyticsService { acuteChronicRatio: number | null, now: Date, ): RunningInjuryRisk | null { - const sortedRuns = [...runs].sort((a, b) => (a.startDate?.getTime() ?? 0) - (b.startDate?.getTime() ?? 0)); + const sortedRuns = [...runs] + .filter((run) => run.startDate !== null && run.startDate !== undefined) + .sort((a, b) => (a.startDate?.getTime() ?? 0) - (b.startDate?.getTime() ?? 0)); const lastRun = sortedRuns.length > 0 ? sortedRuns[sortedRuns.length - 1] : null; const daysSinceLastRun = lastRun?.startDate ? this.daysBetween(lastRun.startDate, now) : null; @@ -1359,8 +1361,8 @@ export class AnalyticsService { const loadFactor = acuteChronicRatio !== null ? Math.min(acuteChronicRatio * 10, 100) : 50; // Faktor 2: Intensität - Anteil harter Läufe in den letzten 14 Tagen - const recentRuns = runs.filter((run) => run.startDate && this.daysBetween(run.startDate, now) <= 14); - const hardRuns = activityLoads.filter((al) => al.zone === 'hard' && al.activity.startDate && this.daysBetween(al.activity.startDate, now) <= 14); + const recentRuns = runs.filter((run) => run.startDate !== null && run.startDate !== undefined && this.daysBetween(run.startDate, now) <= 14); + const hardRuns = activityLoads.filter((al) => al.zone === 'hard' && al.activity.startDate !== null && al.activity.startDate !== undefined && this.daysBetween(al.activity.startDate, now) <= 14); const intensityFactor = recentRuns.length > 0 ? Math.round((hardRuns.length / recentRuns.length) * 100) : 0; // Faktor 3: Erholung (je mehr Tage seit letztem Lauf, desto besser) @@ -1394,7 +1396,9 @@ export class AnalyticsService { acuteChronicRatio: number | null, now: Date, ): RunningReadinessScore | null { - const sortedRuns = [...runs].sort((a, b) => (a.startDate?.getTime() ?? 0) - (b.startDate?.getTime() ?? 0)); + const sortedRuns = [...runs] + .filter((run) => run.startDate !== null && run.startDate !== undefined) + .sort((a, b) => (a.startDate?.getTime() ?? 0) - (b.startDate?.getTime() ?? 0)); const lastRun = sortedRuns.length > 0 ? sortedRuns[sortedRuns.length - 1] : null; const daysSinceLastRun = lastRun?.startDate ? this.daysBetween(lastRun.startDate, now) : null; @@ -1487,19 +1491,18 @@ export class AnalyticsService { } const sortedRuns = [...runs] - .filter((run) => run.startDate) - .sort((a, b) => (a.startDate?.getTime() ?? 0) - (b.startDate?.getTime() ?? 0)); + .filter((run) => run.startDate !== null && run.startDate !== undefined) + .sort((a, b) => (a.startDate!.getTime() ?? 0) - (b.startDate!.getTime() ?? 0)); - const lastRunDate = sortedRuns[sortedRuns.length - 1].startDate; - if (!lastRunDate) { + if (sortedRuns.length === 0) { return 0; } + const lastRunDate = sortedRuns[sortedRuns.length - 1].startDate!; + let streak = 1; for (let i = sortedRuns.length - 2; i >= 0; i--) { - const currentRunDate = sortedRuns[i].startDate; - if (!currentRunDate) continue; - + const currentRunDate = sortedRuns[i].startDate!; const daysDiff = this.daysBetween(currentRunDate, lastRunDate); if (daysDiff === 1) { streak++; @@ -1522,8 +1525,8 @@ export class AnalyticsService { const fourWeeksAgo = this.addDays(now, -28); const eightWeeksAgo = this.addDays(now, -56); - const recentLoads = activityLoads.filter((al) => al.activity.startDate && al.activity.startDate >= fourWeeksAgo); - const previousLoads = activityLoads.filter((al) => al.activity.startDate && al.activity.startDate >= eightWeeksAgo && al.activity.startDate < fourWeeksAgo); + const recentLoads = activityLoads.filter((al) => al.activity.startDate !== null && al.activity.startDate !== undefined && al.activity.startDate >= fourWeeksAgo); + const previousLoads = activityLoads.filter((al) => al.activity.startDate !== null && al.activity.startDate !== undefined && al.activity.startDate >= eightWeeksAgo && al.activity.startDate < fourWeeksAgo); const recentTSS = recentLoads.reduce((sum, load) => sum + load.load, 0); const previousTSS = previousLoads.reduce((sum, load) => sum + load.load, 0);