Fix Team Race duplicate-membership bug and two related team-roster gaps
Reported by the user: creating a team, adding the wrong driver, then moving that driver to another team by ticking them on the new team's edit form left the driver on both teams at once. Root cause: there was never a "move" action - the edit form only ever added a driver to the team being saved, never removed them from wherever they already were. Live laps from a driver on two teams were then silently credited to only the first-matching team, with no clear error. reassignTeamMembers (event_race_logic.js) now strips a driver/car being saved onto one team out of every other team in the same event, and the team checkbox list shows which team a driver is already on before you move them. Also fixed two related gaps found while investigating, at the user's request to fix everything: getTeamDriverPool had regressed to ignoring the event's class/participant scoping entirely (showing every driver in the club), and deleting a driver or car left them behind in team rosters forever. Added a duplicate_team_members Race Day preflight check as defense in depth for any already-corrupted saved state. Verified with new unit tests for reassignTeamMembers, getTeamDriverPool and the new preflight check, plus a new permanent browser test reproducing the user's exact reported scenario end to end. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
19
ROADMAP.md
19
ROADMAP.md
@@ -189,6 +189,25 @@ Fixed 2026-09-09, reported while exporting an old race from the new Results arch
|
||||
|
||||
Verified 2026-09-09: a new integration test (`tests/server_persistence.integration.test.js`) exports a PDF with a Swedish title and a table row containing å/ä/ö/Å/Ä/Ö, asserts the font declares WinAnsiEncoding, asserts the correct single-byte WinAnsi sequence is present in the raw PDF bytes, and explicitly asserts the old UTF-8 byte sequence is *not* present - confirmed this test genuinely fails against the pre-fix code (not a tautology) by re-running it with the fix reverted.
|
||||
|
||||
## Team Race roster duplicate-membership bug
|
||||
|
||||
Reported 2026-09-10 by the user: creating a team, adding a driver to it by mistake, then "moving" that driver to a different team by ticking them on the new team's edit form left the driver on *both* teams at once. Investigated before fixing, per the user's own account of the exact steps that triggered it.
|
||||
|
||||
Root cause: there was never a "move driver to another team" action - the only way to reassign someone was to tick their checkbox on the *new* team's edit form (`event_manager_controller.js`'s `teamForm`/`teamEditForm` submit handlers). That handler only ever wrote the team being saved; it never checked whether the driver/car was already listed on a different team, so ticking them there added them without ever removing them from wherever they already were. Consequence found while investigating: `findEventTeamForPassing` (`event_race_logic.js`) resolves a team by the *first* array match, so a driver on two teams had every one of their live laps silently credited to only one of them - the other team got nothing, with no error surfaced anywhere except a misleading "duplicate transponders" preflight warning (and only when the driver actually had a transponder set).
|
||||
|
||||
Two related bugs surfaced in the same code while investigating, at the user's request to fix everything found:
|
||||
- `getTeamDriverPool` (`event_race_logic.js`) had been reduced, in an earlier change, to unconditionally return every driver in the club regardless of the event's class or configured participants - the class/participant-scoped filtering (with a documented fallback to "show everyone" only when the scoped list is empty) existed in an earlier version of this function and had been silently dropped.
|
||||
- Deleting a driver or car (`core_views.js`) cleaned up session assignments but never removed them from any team's roster, so a deleted driver/car stayed a permanent "member" of whichever teams they'd been added to, inflating team member counts forever.
|
||||
|
||||
Fixed:
|
||||
- [x] `reassignTeamMembers` (`event_race_logic.js`, new) strips a driver/car being saved onto one team out of every *other* team in the same event - both the create-team and edit-team submit handlers now call it before writing, so ticking a driver onto a new team genuinely moves them rather than duplicating them.
|
||||
- [x] The team edit/create checkbox list now shows "Redan i <team> - kryssar du i flyttas den hit" next to a driver/car already on a different team, so the move is visible *before* saving, not just after.
|
||||
- [x] `getTeamDriverPool` restored to scope by the event's class/configured participants first, falling back to every driver only when that scoped list is empty (so a team can still be set up before participants exist, without silently showing the whole club's roster once they do).
|
||||
- [x] Deleting a driver or car now also removes them from every team's `driverIds`/`carIds`, and from a session's `driverIds`/`manualGridIds`, alongside the existing assignment cleanup.
|
||||
- [x] Added a `duplicate_team_members` Race Day preflight check specifically for `team_race` sessions, naming the driver/car by name - defense in depth for any state saved before this fix, so it's diagnosed accurately instead of surfacing as a confusing "duplicate transponders" error (or nothing at all, if the shared driver has no transponder).
|
||||
|
||||
Verified 2026-09-10: new unit tests (`tests/race_timing_logic.test.js`) cover `reassignTeamMembers` (strips from other teams, leaves the team being saved and non-overlapping teams untouched) and `getTeamDriverPool`'s scoped-then-fallback behavior; new tests (`tests/race_day_logic.test.js`) cover the `duplicate_team_members` preflight check both tripping (naming the shared driver) and staying clear when teams don't overlap. A new permanent browser test (`tests/browser_team_membership.js`) reproduces the user's exact reported scenario end to end against a real race-mode event with a team_race session: creates Team A with Driver A, creates Team B with Driver B, opens Team B's edit form and confirms the "already on Team A" warning appears *before* saving, ticks Driver A onto Team B and saves, confirms Driver A is gone from Team A's roster and present on Team B's (the reported bug, now fixed), then deletes Driver B entirely and confirms they're gone from Team B's roster too.
|
||||
|
||||
## In-app update checker and one-click updater
|
||||
|
||||
Implemented 2026-09-09, requested by the user: an easy way to see a new version is available in the GUI, and an easy way to update for someone not comfortable with `git pull` on their own.
|
||||
|
||||
Reference in New Issue
Block a user