veza/config/incus/REMEDIATION_APPLIED.md
senke f0ba7de543 state-ownership: delete unused optimisticStoreUpdates.ts file
- Deleted apps/web/src/utils/optimisticStoreUpdates.ts (unused file)
- File was unused - no imports found in codebase
- Mutations already use React Query's onMutate pattern
- No TypeScript errors after deletion
- Actions 4.4.1.2 and 4.4.1.3 complete
2026-01-15 19:26:53 +01:00

6.1 KiB

REMÉDIATION APPLIQUÉE - BARE METAL vs INCUS

Date: 2026-01-15 Objectif: Corriger l'erreur React.Children et les erreurs 503 intermittentes


CORRECTIONS APPLIQUÉES

1. Stabilisation Réseau Container Web (Correction 503 Intermittent)

Fichier modifié: config/incus/deploy-service-native.sh

Améliorations:

  • Script setup-network.sh amélioré avec retries (5 tentatives)
  • Vérification de connectivité après configuration
  • Service systemd veza-network-setup.service avec:
    • Dépendances réseau correctes (After=network-online.target)
    • Restart automatique en cas d'échec
    • Exécution avant Apache pour garantir l'IP

Code ajouté:

# Script avec retries et vérification
MAX_RETRIES=5
configure_network() {
    # ... configuration avec retries
    # Vérification ping vers gateway
}

2. Désactivation Service Worker (Correction React.Children - P0)

Fichiers modifiés:

  • apps/web/src/services/pwa.ts
  • apps/web/public/sw.js

Modifications:

pwa.ts

  • Service Worker complètement désactivé dans registerServiceWorker()
  • Retour immédiat pour éviter toute enregistrement
  • Commentaire explicatif sur la raison (cache conflicts)

sw.js

  • Event install: Supprime tous les caches existants immédiatement
  • Event activate: Supprime TOUS les caches (pas seulement les anciens)
  • Prend le contrôle immédiatement avec clients.claim()

Code:

// pwa.ts
private async registerServiceWorker(): Promise<void> {
  // CRITICAL FIX: Disable Service Worker completely
  logger.info('[PWA] Service Worker disabled to prevent cache conflicts');
  return;
}

3. Optimisation Build Vite (Ordre des Chunks)

Fichier modifié: apps/web/vite.config.ts

Améliorations:

  • Plugin fix-react-loading-order amélioré
  • Ajout de modulepreload pour vendor-react-core dans le HTML
  • Garantit que React est chargé avant Zustand

Code:

{
  name: 'fix-react-loading-order',
  transformIndexHtml(html) {
    // Ajouter modulepreload pour vendor-react-core
    const reactChunkMatch = html.match(/src="([^"]*vendor-react-core[^"]*\.js)"/);
    if (reactChunkMatch) {
      html = html.replace(
        /<script type="module"/,
        `<link rel="modulepreload" href="${reactChunkMatch[1]}" crossorigin>\n    <script type="module"`
      );
    }
    return html;
  }
}

4. Configuration Apache & Cache Busting

Fichier modifié: config/incus/apache/veza-web.conf

Ajouts:

  • Headers no-cache pour /js/*.js (tous les chunks JS)
  • Headers no-cache pour /sw.js (Service Worker)
  • Headers no-cache pour /index.html (références aux chunks)
  • Cache JavaScript désactivé dans mod_expires

Code:

# CRITICAL FIX: No-cache headers for JS chunks
<LocationMatch "^/js/.*\.js$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires "0"
</LocationMatch>

# CRITICAL FIX: No-cache for Service Worker
<LocationMatch "^/sw\.js$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires "0"
</LocationMatch>

# CRITICAL FIX: No-cache for index.html
<LocationMatch "^/index\.html$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires "0"
</LocationMatch>

🚀 COMMANDES DE REBUILD ET DÉPLOIEMENT

1. Build du Frontend

cd /home/senke/git/talas/veza
./config/incus/build-native.sh web

2. Déploiement du Frontend

./config/incus/deploy-service-native.sh web

Cette commande va:

  • Copier les fichiers build dans le container
  • Copier la nouvelle configuration Apache
  • Reconfigurer le réseau (IP persistante)
  • Redémarrer Apache

3. Vérification du Déploiement

./config/incus/verify-deployment.sh web

4. Test dans le Navigateur

URL: https://10.10.10.6

⚠️ IMPORTANT - Vider le cache avant de tester:

  1. Ouvrir DevTools (F12)
  2. Application > Storage > Clear site data
  3. Application > Service Workers > Unregister (si présent)
  4. Network > Disable cache (pendant les tests)
  5. Hard refresh: Ctrl+Shift+R (ou Cmd+Shift+R sur Mac)

📊 RÉSULTATS ATTENDUS

Avant les corrections:

  • Erreur React.Children: Cannot set properties of undefined (setting 'Children')
  • ⚠️ Frontend 503 intermittent (container perd IP)
  • Application ne se charge pas

Après les corrections:

  • Pas d'erreur React.Children
  • Frontend accessible (pas de 503)
  • Application se charge correctement
  • Chunks JS toujours à jour (pas de cache)

🔍 VALIDATION

Tests à effectuer:

  1. Test réseau:

    incus exec veza-web -- ip addr show eth0 | grep "10.10.10.5"
    # Doit afficher: inet 10.10.10.5/24
    
  2. Test Apache:

    curl -k -I https://10.10.10.6/ | grep "Cache-Control"
    # Doit afficher: Cache-Control: no-cache, no-store, must-revalidate
    
  3. Test JS chunks:

    curl -k -I https://10.10.10.6/js/vendor-react-core-*.js | grep "Cache-Control"
    # Doit afficher: Cache-Control: no-cache, no-store, must-revalidate
    
  4. Test navigateur:

    • Ouvrir https://10.10.10.6
    • Vérifier la console (F12) - pas d'erreur React.Children
    • Vérifier Network tab - chunks JS chargés avec headers no-cache

📝 NOTES IMPORTANTES

  1. Service Worker: Complètement désactivé. Si besoin de réactiver plus tard, il faudra:

    • Réactiver dans pwa.ts
    • S'assurer que le cache ne sert jamais d'anciens chunks JS
    • Implémenter une stratégie de cache busting robuste
  2. Cache navigateur: Les headers no-cache forcent le navigateur à toujours récupérer les chunks JS depuis le serveur. Cela garantit que les dernières versions sont toujours utilisées.

  3. Réseau: Le script de setup réseau avec retries garantit que l'IP est toujours configurée, même après un redémarrage du container.

  4. Ordre de chargement: Le modulepreload garantit que React est chargé avant Zustand, évitant l'erreur React.Children.


Fin du rapport de remédiation