Files
vue-pult/plans/client-critical-refactor-plan.md
2025-10-01 11:54:13 +03:00

5.1 KiB
Raw Blame History

План рефакторинга критических проблем в клиентской части

Введение

Этот план фокусируется на 3 самых критических проблемах, выявленных в анализе:

  1. BOM в main.js - Может сломать загрузку app.
  2. Race conditions в router guards - Неправильные redirects и access leaks.
  3. Memory leaks в composables - Утечки памяти от timers/WS.

План пошаговый, с оценкой effort. После фиксов - manual testing. Timeline: 4-6 часов.

1. Удаление BOM в main.js

Описание

Невидимый BOM-символ (EF BB BF) в начале файла приводит к SyntaxError в парсинге JS.

Приоритет: High (App crash)

Влияние: Полный отказ загрузки в некоторых браузерах/builds.

Шаги реализации

  1. Открыть client/src/main.js в редакторе с hex-view (VSCode + Hex Editor extension).
  2. Удалить первые 3 байта (BOM).
  3. Сохранить как UTF-8 without BOM (VSCode: File > Save with Encoding > UTF-8).
  4. Проверить: Нет  перед import.

Затронутые файлы

  • client/src/main.js

Effort: Low (15 мин)

Тестирование

  • npm run dev - No console errors.
  • npm run build && npm run preview - App mounts correctly.
  • Open in browser: Inspect source - no BOM.

2. Fix race conditions в router guards

Описание

reauth() в beforeEach синхронный, но может быть async (WS/API) - guard не ждет, leading to wrong next().

Приоритет: High (Security/UX)

Влияние: Access to / without auth, infinite redirects.

Шаги реализации

  1. В useAuth.js: Сделать reauth async:
    const reauth = async () => {
      if (user.value) return true;
      const localData = localStorage.getItem('user_data');
      if (localData) { user.value = JSON.parse(localData); return true; }
      try { await apiReauth(); return !!user.value; } catch { return false; }
    };
    
  2. В router/index.js: Async guard:
    router.beforeEach(async (to, from, next) => {
      try {
        const isAuth = await reauth();
        if (to.meta.requiresAuth && !isAuth) { next('/login'); return; }
        if (to.meta.requiresGuest && isAuth) { next('/'); return; }
        next();
      } catch (error) {
        console.error('Router error:', error);
        next('/login');
      }
    });
    
  3. Добавить global loading в App.vue:
    <template> <div v-if="loadingAuth">Loading...</div> <RouterView v-else /> </template>
    <script setup> const { loadingAuth } = useAuth(); </script>
    

Затронутые файлы

  • client/src/composables/useAuth.js
  • client/src/router/index.js
  • client/src/App.vue

Effort: Medium (1 час)

Тестирование

  • Clear localStorage, navigate / - redirect to /login.
  • Slow network (DevTools): No access to HomePage until reauth done.
  • Login -> / - no loop.

3. Cleanup в composables (Fix memory leaks)

Описание

Timers (setInterval), WS connections, watchers не очищаются onUnmounted.

Приоритет: High (Performance)

Влияние: Memory leaks в long sessions, ghost WS.

Шаги реализации

  1. В каждом composable (useWebSocket, useTime, useGamePorts, etc.):
    • Import onUnmounted from 'vue'.
    • В setup:
      let intervalId;
      onUnmounted(() => {
        if (intervalId) clearInterval(intervalId);
        if (ws) ws.close();
        // Cleanup watchers: unwatch();
      });
      
  2. Для WS-specific (useWebSocket.js):
    • В connect: ws.onclose = () => { clearTimeout(heartbeat); };
    • В sendMessage: AbortController для timeout cleanup.
  3. Для global (useWebSocketGlobal.js): Track active components, cleanup on last unmount.
  4. Добавить в useAuth/logout: Cleanup WS if global.

Затронутые файлы

  • client/src/composables/useWebSocket.js
  • client/src/composables/useWebSocketGlobal.js
  • client/src/composables/useTime.js
  • client/src/composables/game/useGamePorts.js
  • client/src/composables/shift/useShiftOperations.js
  • Другие composables с timers/watch

Effort: Medium (2-3 часа, multiple files)

Тестирование

  • Navigate Login <-> Home multiple times.
  • DevTools > Memory: Heap snapshot - no growth.
  • Network: No duplicate WS connects on route change.
  • Long run (5+ min): No console spam from ghosts.

Заключение

  • Общий timeline: 3-4 часа (High first).
  • Commit strategy: Separate commits: "Fix BOM in main.js", "Async router guards", "Cleanup composables".
  • Post-fix: Full manual test: Auth, navigate, WS actions (start game, shift open), memory check.
  • Риски: Low - isolated changes. Backup branch перед.

Файл создан: plans/client-critical-refactor-plan.md.