fix problème possible de "logique delete + create pouvait créer des conditions de concurrence"

This commit is contained in:
Yannick Le Duc
2025-08-27 00:25:32 +02:00
parent ba3a7c3ea1
commit 8cfa14a693
7 changed files with 231 additions and 27 deletions

View File

@@ -241,7 +241,7 @@ function AdminPageContent() {
) : (
<div className="grid gap-6 group/campaigns">
{campaigns.map((campaign) => (
<Card key={campaign.id} className="group hover:shadow-xl hover:shadow-slate-100 dark:hover:shadow-slate-900/20 transition-all duration-300 border-slate-200 dark:border-slate-700 overflow-hidden group-hover/campaigns:opacity-50 hover:!opacity-100">
<Card key={campaign.id} className="group hover:shadow-xl hover:shadow-slate-100 dark:hover:shadow-slate-900/20 transition-all duration-300 border-slate-200 dark:border-slate-700 overflow-hidden group-hover/campaigns:opacity-30 hover:!opacity-100">
<div className="relative">
<CardHeader className="pb-4">

View File

@@ -37,6 +37,31 @@ export default function PublicVotePage() {
}
}, [campaignId, participantId]);
// Écouter les changements de connectivité réseau
useEffect(() => {
const handleOnline = () => {
console.log('Connexion réseau rétablie');
setError('');
};
const handleOffline = () => {
console.log('Connexion réseau perdue');
setError('Connexion réseau perdue. Veuillez vérifier votre connexion internet.');
};
if (typeof window !== 'undefined') {
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
}
return () => {
if (typeof window !== 'undefined') {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
}
};
}, []);
// Calculer le total voté à partir des votes locaux
useEffect(() => {
const total = Object.values(localVotes).reduce((sum, amount) => sum + amount, 0);
@@ -91,6 +116,13 @@ export default function PublicVotePage() {
const loadData = async () => {
try {
setLoading(true);
setError('');
// Vérifier la connectivité réseau
if (typeof window !== 'undefined' && !navigator.onLine) {
throw new Error('Pas de connexion internet. Veuillez vérifier votre connexion réseau.');
}
const [campaigns, participants, propositionsData] = await Promise.all([
campaignService.getAll(),
participantService.getByCampaign(campaignId),
@@ -147,7 +179,23 @@ export default function PublicVotePage() {
} catch (error) {
console.error('Erreur lors du chargement des données:', error);
setError('Erreur lors du chargement des données');
let errorMessage = 'Erreur lors du chargement des données';
if (error instanceof Error) {
errorMessage = error.message;
} else if (typeof error === 'object' && error !== null) {
// Essayer d'extraire plus d'informations de l'erreur
const errorObj = error as any;
if (errorObj.message) {
errorMessage = errorObj.message;
} else if (errorObj.error) {
errorMessage = errorObj.error;
} else if (errorObj.details) {
errorMessage = errorObj.details;
}
}
setError(errorMessage);
} finally {
setLoading(false);
}
@@ -178,28 +226,39 @@ export default function PublicVotePage() {
setError('');
try {
// Supprimer tous les votes existants pour ce participant
const existingVotes = await voteService.getByParticipant(campaignId, participantId);
for (const vote of existingVotes) {
await voteService.delete(vote.id);
}
// Préparer les votes à sauvegarder (seulement ceux avec amount > 0)
const votesToSave = Object.entries(localVotes)
.filter(([_, amount]) => amount > 0)
.map(([propositionId, amount]) => ({
proposition_id: propositionId,
amount
}));
// Créer les nouveaux votes
for (const [propositionId, amount] of Object.entries(localVotes)) {
if (amount > 0) {
await voteService.create({
campaign_id: campaignId,
participant_id: participantId,
proposition_id: propositionId,
amount
});
}
}
// Utiliser la méthode atomique pour remplacer tous les votes
await voteService.replaceVotes(campaignId, participantId, votesToSave);
setSuccess(true);
} catch (error) {
console.error('Erreur lors de la validation:', error);
setError('Erreur lors de la validation des votes');
// Améliorer l'affichage de l'erreur
let errorMessage = 'Erreur lors de la validation des votes';
if (error instanceof Error) {
errorMessage = error.message;
} else if (typeof error === 'object' && error !== null) {
// Essayer d'extraire plus d'informations de l'erreur
const errorObj = error as any;
if (errorObj.message) {
errorMessage = errorObj.message;
} else if (errorObj.error) {
errorMessage = errorObj.error;
} else if (errorObj.details) {
errorMessage = errorObj.details;
}
}
setError(errorMessage);
} finally {
setSaving(false);
}