130 lines
5.1 KiB
Markdown
130 lines
5.1 KiB
Markdown
# План рефакторинга критических проблем в клиентской части
|
||
|
||
## Введение
|
||
Этот план фокусируется на 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`. |