Add motivational training challenges and shared club goals
This commit is contained in:
@@ -476,11 +476,14 @@ Owns:
|
||||
- daily summaries, controlled-lap streak, and recent personal-best gain
|
||||
- signed personal pace and consistency trends from the latest 30 laps versus the preceding 30, with a minimum of 10 laps in each window
|
||||
- derived automatic achievements for sessions, lap totals, training days, controlled streaks, and a completed five-minute result
|
||||
- derived optional daily missions for lap volume, controlled consecutive laps, and a completed five-minute stint
|
||||
- derived positive highlights for current activity, personal-best gain, pace, consistency, and endurance
|
||||
- active 30-minute pace buckets using a trimmed average and omitting empty clock periods
|
||||
- persisted class-specific setup markers and 30-minute before/after comparisons
|
||||
- extended stint analysis with normal pace, best 10-lap race pace, mistake count, consistency, and start/end change
|
||||
- rule-based practice recommendation selection
|
||||
- automatic and custom milestone progress calculation
|
||||
- shared club-goal progress from a persisted ledger baseline
|
||||
|
||||
Rules:
|
||||
- only passings with a matching `driverId` are included
|
||||
@@ -495,6 +498,8 @@ Rules:
|
||||
- consistency trend is `previous spread - current spread`, so a positive value means a smaller recent spread
|
||||
- trend fields remain neutral until both comparison windows contain at least 10 valid laps
|
||||
- achievements are derived on read and are not persisted; custom reward goals remain persisted in `state.training.goals`
|
||||
- daily missions and positive highlights are derived on read, reset by local calendar day, and remain isolated to the selected class
|
||||
- the shared club goal is persisted, but its progress is derived from `ledger.length - clubGoal.baselineLaps`
|
||||
- every save replaces ledger rows only for session IDs that still exist in `resultsBySession`
|
||||
- ledger rows for a deleted session are retained and become historical records
|
||||
- `sourceKey` deduplicates repeated saves of the same session passing
|
||||
@@ -519,13 +524,16 @@ Owns:
|
||||
- mobile-responsive training markup
|
||||
- compact live-practice card and primary personal-profile action for the selected driver
|
||||
- personal trend and achievement cards that never combine classes
|
||||
- positive-credit and optional daily-challenge cards based on the selected driver's own development
|
||||
- recent club progress feed ordered by latest activity, without position numbers or cross-driver performance scoring
|
||||
- shared club-goal create, celebrate, replace, and delete actions in the overview
|
||||
- collapsed Extra statistics with pace heatmap, setup-marker actions, weekday pace, featured stints, and an expandable full stint table
|
||||
|
||||
Mutations:
|
||||
- replaces or appends entries in `state.training.goals`
|
||||
- creates, rotates, enables, or disables entries in `state.training.shares`
|
||||
- creates and removes entries in `state.training.markers`
|
||||
- replaces or clears `state.training.clubGoal`
|
||||
- always calls injected `saveState()` before rerender
|
||||
|
||||
Route behavior:
|
||||
@@ -1767,7 +1775,8 @@ This bucket is the most dynamic part of state and is mutated heavily during live
|
||||
goals: TrainingGoal[],
|
||||
ledger: TrainingLap[],
|
||||
shares: TrainingShare[],
|
||||
markers: TrainingMarker[]
|
||||
markers: TrainingMarker[],
|
||||
clubGoal: TrainingClubGoal | null
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1797,6 +1806,22 @@ This bucket is the most dynamic part of state and is mutated heavily during live
|
||||
}
|
||||
```
|
||||
|
||||
`TrainingClubGoal`:
|
||||
|
||||
```js
|
||||
{
|
||||
id: string,
|
||||
title: string,
|
||||
reward: string,
|
||||
targetLaps: number,
|
||||
baselineLaps: number, // ledger length when this club challenge starts
|
||||
createdAt: string,
|
||||
celebratedAt: string // empty until the reached goal is acknowledged
|
||||
}
|
||||
```
|
||||
|
||||
Club-goal progress is intentionally aggregate-only. Creating a replacement goal captures the current ledger length as a new baseline; historical laps remain available for personal statistics but do not advance the new shared target.
|
||||
|
||||
Share rules:
|
||||
- no share exists until an admin explicitly enables the selected personal profile
|
||||
- only one normalized share entry is retained per personal profile
|
||||
@@ -1856,6 +1881,7 @@ Migration behavior:
|
||||
- the next `saveState()` imports valid registered-driver laps from all current session results
|
||||
- invalid laps, anonymous transponders, and laps at or below `500 ms` are excluded
|
||||
- older state without `training.markers` normalizes to an empty marker list
|
||||
- older state without `training.clubGoal` normalizes to `null`
|
||||
|
||||
## 15.9 `Settings`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user