fix: preserve predicted_rating via UPSERT in savePlayerToDB (#11) #28

Merged
shcizo merged 1 commits from fix/upsert-preserve-predicted-rating-11 into main 2026-06-08 09:53:03 +02:00
Owner

Sammanfattning

  • savePlayerToDB använde INSERT OR REPLACE, vilket raderar hela raden och nollställer kolumner som saknas i VALUES (predicted_rating, std_dev, last_round_update, excluded_rounds_count, cutoff_rating). "Refresh all" anropade detta för varje spelare → predicted_rating wipades tabell-brett.
  • Byter till SQLite UPSERT på pdga_number som uppdaterar endast de fyra skrapade kolumnerna in-place och lämnar predicted-kolumnerna + 24h-cooldown-stämpeln orörda.
  • Speglar course.js-mönstret för lastID == 0 (SELECT-fallback) så funktionen fortfarande returnerar ett riktigt spelar-id på update-vägen.

Closes #11

Scope-granskning av övriga INSERT OR REPLACE

  • saveRoundHistoryToDB (round_history): lämnad orörd — enda unika kolumnen är autoincrement-id som aldrig anges, så OR REPLACE kan aldrig trigga; alla datakolumner listas ändå. Ingen wipe möjlig.
  • course.js använder redan korrekt UPSERT; layouts använder avsiktlig INSERT OR IGNORE. Båda OK.

Test plan

  • Isolerat repro-script: 8/8 assertions gröna — predicted_rating, std_dev, excluded_rounds_count, cutoff_rating, last_round_update och row-id överlever en re-save medan current_rating/rating_change uppdateras.
  • Manuellt mot appen: sätt predicted_rating på en spelare → klicka "Refresh all" → Predicted-kolumnen visar fortfarande värdet (tidigare ).
  • last_round_update överlever → 24h-cooldownen för /api/refresh-round-history/:pdgaNumber håller fortfarande.
## Sammanfattning - `savePlayerToDB` använde `INSERT OR REPLACE`, vilket raderar hela raden och nollställer kolumner som saknas i `VALUES` (`predicted_rating`, `std_dev`, `last_round_update`, `excluded_rounds_count`, `cutoff_rating`). "Refresh all" anropade detta för varje spelare → predicted_rating wipades tabell-brett. - Byter till SQLite UPSERT på `pdga_number` som uppdaterar endast de fyra skrapade kolumnerna in-place och lämnar predicted-kolumnerna + 24h-cooldown-stämpeln orörda. - Speglar `course.js`-mönstret för `lastID == 0` (SELECT-fallback) så funktionen fortfarande returnerar ett riktigt spelar-id på update-vägen. Closes #11 ## Scope-granskning av övriga `INSERT OR REPLACE` - `saveRoundHistoryToDB` (`round_history`): lämnad orörd — enda unika kolumnen är autoincrement-`id` som aldrig anges, så `OR REPLACE` kan aldrig trigga; alla datakolumner listas ändå. Ingen wipe möjlig. - `course.js` använder redan korrekt UPSERT; `layouts` använder avsiktlig `INSERT OR IGNORE`. Båda OK. ## Test plan - [x] Isolerat repro-script: 8/8 assertions gröna — predicted_rating, std_dev, excluded_rounds_count, cutoff_rating, last_round_update och row-id överlever en re-save medan current_rating/rating_change uppdateras. - [ ] Manuellt mot appen: sätt predicted_rating på en spelare → klicka "Refresh all" → Predicted-kolumnen visar fortfarande värdet (tidigare `—`). - [ ] `last_round_update` överlever → 24h-cooldownen för `/api/refresh-round-history/:pdgaNumber` håller fortfarande.
shcizo added 1 commit 2026-06-08 09:52:37 +02:00
INSERT OR REPLACE deletes the existing row and resets columns absent from
the VALUES list (predicted_rating, std_dev, last_round_update,
excluded_rounds_count, cutoff_rating) to NULL. Refresh-all called this for
every player, wiping predicted ratings table-wide.

Switch to a SQLite UPSERT keyed on pdga_number that updates only the four
scraped columns in place, leaving the predicted-rating columns and the
24h-cooldown timestamp untouched. Mirror course.js's lastID==0 SELECT
fallback so the function still returns a real player id on the update path.
shcizo merged commit 5198a1c0f4 into main 2026-06-08 09:53:03 +02:00
Sign in to join this conversation.