Skip to content

fix(vote): éviter les double-votes sur VoteBox (chargement + double-clic) - #269

Closed
hboisgibault wants to merge 1 commit into
masterfrom
fix/votebox-double-vote
Closed

fix(vote): éviter les double-votes sur VoteBox (chargement + double-clic)#269
hboisgibault wants to merge 1 commit into
masterfrom
fix/votebox-double-vote

Conversation

@hboisgibault

Copy link
Copy Markdown
Collaborator

Objectif

Éviter les double-votes côté interface sur les votes de groupe/débat (VoteBox, voteable_type: "Group"), qui provoquent côté API une PG::UniqueViolation → HTTP 500 (LogoraAPI #763).

Cause racine (côté interface)

Dans VoteBox, le vote existant de l'utilisateur est récupéré de façon asynchrone (GET /votes/{type}/{id}) et les boutons de vote sont cliquables immédiatement. Tant que currentVote n'est pas chargé, un clic part en POST /votes (create) au lieu d'un PATCH (update), même si l'utilisateur a déjà voté. Un double-clic / retry / re-clic rapide peut donc envoyer plusieurs create pour la même cible → contrainte d'unicité DB → 500.

Correctifs

  1. Bloquer le vote tant que le vote existant est en cours de chargement : handleVote ignore les clics tant que isLoadingVote est vrai.
  2. Verrou synchrone anti double-clic (useRef + état voteDisabled) : pendant qu'un create/update est en vol, tout nouveau clic est ignoré (la garde est posée de façon synchrone, pas seulement via setState).
  3. Les deux appels API (api.create, api.update) relâchent le verrou via finally.

Tests

  • should not create a vote while the existing vote is still loading : pendant le chargement, le clic ne déclenche aucun POST.
  • should not trigger multiple vote creations on rapid clicks : deux clics rapides ne produisent qu'un seul POST.
  • Mise à jour du harnais de test (isLoggingIn: false + voteableType) pour que le chargement du vote existant soit réellement exécuté, et du test « redirect » pour qu'il soit déterministe.

Note

Correctif côté interface uniquement. Une idempotence côté API (VotesController#create) reste recommandée en défense en profondeur (voir issue LogoraAPI #763).

Ce PR a été créé par un agent IA (OpenHands) pour le compte de l'utilisateur.

Block vote actions while the user's existing vote is being loaded
(isLoadingVote) and lock the create/update request synchronously so that
rapid double clicks cannot send a second POST/PATCH for the same target.

Fixes the interface side of the double-vote that leads to
PG::UniqueViolation (HTTP 500) on Logora/LogoraAPI when a user votes a
second time on a group/debate.
@hboisgibault

Copy link
Copy Markdown
Collaborator Author

PR remplacé par une version simplifiée et plus élégante : voir #271 (verrou synchrone minimal anti envoi multiple). La protection définitive contre les doublons restants est portée côté API (Logora/LogoraAPI#779, création idempotente).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants