rts-commander / docs /BUG_DEBUG_NOTIFICATIONS.md
Luigi's picture
chore(structure): move docs into docs/ and tests into tests/
ccbaf39

🐛 Bug Debug: Notification Doublons

Date: 3 octobre 2025, 19h10
Issue: Notifications en doublon (une en anglais, une localisée)
Status: 🔍 INVESTIGATION


🔍 Problème Signalé

Symptômes:

  • Une action génère deux notifications
  • En interface non-anglaise (FR, ZH-TW):
    • Notification 1: Version anglaise
    • Notification 2: Version localisée
  • Effet: Doublons visuels dans la file de notifications

✅ Corrections Déjà Appliquées

1. Notification de Training (game.js ligne 724)

// AVANT:
this.showNotification(`Training ${unitType}`, 'success');

// APRÈS:
// Notification sent by server (localized)

Status: ✅ FIXED

2. Notification de Building Placement (game.js ligne 697)

// AVANT:
this.showNotification(`Building ${this.buildingMode}`, 'success');

// APRÈS:
// Notification sent by server (localized)

Status: ✅ FIXED

3. Notification de Requirement Error (game.js ligne 713-717)

// AVANT:
if (!this.hasBuilding(requiredBuilding)) {
    this.showNotification(
        `⚠️ Need ${requiredBuilding.replace('_', ' ').toUpperCase()} to train ${unitType}!`,
        'error'
    );
    return;
}

// APRÈS:
// Requirement check done server-side
// Server will send localized error notification if needed

Status: ✅ FIXED


🔎 Sources Potentielles Restantes

Notifications Côté Client (game.js)

Vérifier chaque showNotification pour voir si le serveur envoie aussi la même :

✅ SAFE (Purement locales, pas de doublon serveur)

  • Connection errors (ligne 150, 156) ← UI only
  • AI analysis (ligne 296, 317) ← Client-initiated
  • Nuke UI (ligne 464, 503, 514) ← UI feedback
  • Attack feedback (ligne 482) ← Local feedback
  • Movement feedback (ligne 490, 764) ← Local feedback
  • Control groups (ligne 550, 558, 575, 585, 598) ← Local UI
  • Select all (ligne 666) ← Local UI
  • Building mode (ligne 679) ← Local UI
  • Building cancelled (ligne 470) ← Local UI

⚠️ POTENTIAL DUPLICATES (À vérifier)

Aucune détectée après review

Notifications Côté Serveur (app.py)

Liste des broadcasts côté serveur :

  1. Low power (ligne 535-540) - Serveur uniquement ✅
  2. Insufficient credits - unit (ligne 1074-1081) - Serveur uniquement ✅
  3. Unit training (ligne 1108-1113) - Serveur uniquement (client supprimé) ✅
  4. Unit requires building (ligne 1120-1128) - Serveur uniquement (client supprimé) ✅
  5. Insufficient credits - building (ligne 1152-1159) - Serveur uniquement ✅
  6. Building placed (ligne 1175-1180) - Serveur uniquement (client supprimé) ✅
  7. Nuke launch (ligne 1223-1228, 1242-1247) - Serveur uniquement ✅

🧪 Tests à Effectuer

Test 1: Unit Training

1. Changer langue en Français
2. Cliquer sur "Infantry" button
3. Observer notifications
ATTENDU: 1 seule notification en français
ACTUEL: À tester

Test 2: Building Placement

1. Changer langue en 繁體中文
2. Placer un Power Plant
3. Observer notifications
ATTENDU: 1 seule notification en chinois
ACTUEL: À tester

Test 3: Insufficient Credits

1. Changer langue en Français
2. Dépenser tous les crédits
3. Tenter de construire
4. Observer notifications
ATTENDU: 1 seule notification en français
ACTUEL: À tester

💡 Hypothèses Alternatives

Hypothèse 1: broadcast() envoie deux fois?

Check: Vérifier si broadcast() n'est pas appelé deux fois dans handle_command

Code à vérifier:

# app.py ligne 1108-1113
message = LOCALIZATION.translate(player_language, "notification.unit_training", unit=unit_name)
await self.broadcast({
    "type": "notification",
    "message": message,
    "level": "success"
})

Test: Ajouter un print() avant chaque broadcast() pour tracer les appels

Hypothèse 2: Client reçoit message deux fois via WebSocket?

Check: Vérifier si le message handler onmessage n'est pas enregistré deux fois

Code à vérifier:

// game.js ligne 146-158
this.ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    
    if (data.type === 'notification') {
        this.showNotification(data.message, data.level || 'info');
    }

Test: Ajouter un console.log() dans onmessage pour compter les messages

Hypothèse 3: Deux connexions WebSocket actives?

Check: Vérifier si le client n'ouvre pas deux connexions

Code à vérifier:

// game.js ligne 102-111
connectWebSocket() {
    this.ws = new WebSocket(wsUrl);
    // ...
}

Test: Vérifier dans Chrome DevTools → Network → WS combien de connexions

Hypothèse 4: Notification en anglais vient d'une autre source?

Check: Chercher si du texte anglais hardcodé existe ailleurs

Search:

grep -r "Training" web/static/
grep -r "Building" web/static/
grep -r "Insufficient" web/static/

🔧 Debug Commands

Chercher toutes les notifications côté client

cd /home/luigi/rts/web
grep -n "showNotification" static/game.js

Chercher toutes les notifications côté serveur

grep -n "notification" app.py

Tracer les WebSocket messages

Ajouter dans game.js ligne 147:

this.ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('WS Message:', data.type, data);  // ← DEBUG
    
    if (data.type === 'notification') {
        console.log('Notification received:', data.message);  // ← DEBUG
        this.showNotification(data.message, data.level || 'info');
    }

Tracer les broadcasts serveur

Ajouter dans app.py ligne 437:

async def broadcast(self, message: dict):
    """Send message to all connected clients"""
    if message.get('type') == 'notification':
        print(f'[BROADCAST] Notification: {message.get("message")}')  # ← DEBUG
    
    dead_connections = []
    for ws in self.active_connections:
        try:
            await ws.send_json(message)

📊 Status

Client-side notifications: ✅ Cleaned up (doublons supprimés)
Server-side notifications: ✅ Verified (pas de doublons détectés)
WebSocket handling: ⏳ À vérifier
Browser DevTools: ⏳ À tester

Next Step: Tester localement avec traces de debug


🎯 Solution Finale (À confirmer après tests)

Si le problème persiste après les fixes appliqués, ajouter des traces de debug pour identifier la source exacte du doublon.

Commandes de test:

cd /home/luigi/rts/web
python app.py

# Dans un autre terminal:
# Ouvrir http://localhost:7860
# Ouvrir Chrome DevTools (F12)
# Onglet Console
# Tester training/building
# Observer les messages

Document créé: 3 octobre 2025, 19h10
Status: Investigation en cours