feat: Add presence heartbeat for Matrix online status

- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
This commit is contained in:
Apple
2025-11-27 00:19:40 -08:00
parent 5bed515852
commit 3de3c8cb36
6371 changed files with 1317450 additions and 932 deletions

View File

@@ -0,0 +1,215 @@
# ✅ Перевірка Swapper Service в кабінетах НОД
**Дата:** 2025-11-23
**Статус:** ✅ Виправлено та перевірено
---
## 🎯 Мета
Переконатися, що Swapper Service відображається **тільки** в кабінетах НОД і працює в реальному часі.
---
## ✅ Виконані зміни
### 1. Видалено зайві використання Swapper Service
**Видалено:**
-`SwapperWidget` з `ConsolePage` - видалено компонент та імпорт
-`SwapperPage` - видалено окрему сторінку
- ✅ Посилання на `/swapper` з `Navigation` - видалено з навігації
- ✅ Посилання на `/swapper` з `HomePage` - видалено картку Swapper
**Результат:**
-`http://localhost:8899/swapper` - більше не доступна
- ❌ Swapper Widget в Console - видалено
- ✅ Swapper Service тільки в кабінетах НОД
---
### 2. Покращено оновлення в реальному часі
**Файли:**
- `src/components/swapper/SwapperComponents.tsx`
- `src/components/swapper/SwapperDetailedMetrics.tsx`
**Зміни:**
#### SwapperStatusCard:
```typescript
useEffect(() => {
fetchStatus();
const interval = setInterval(fetchStatus, 30000); // Update every 30 seconds
return () => clearInterval(interval);
}, [nodeId, swapperUrl]); // Додано залежності для правильного оновлення
```
#### SwapperMetricsSummary:
```typescript
useEffect(() => {
const loadMetrics = async () => {
const data = await fetchMetrics();
setMetrics(data);
setLoading(false);
};
loadMetrics();
const interval = setInterval(loadMetrics, 30000); // Update every 30 seconds
return () => clearInterval(interval);
}, [nodeId, swapperUrl]); // Додано залежності для правильного оновлення
```
#### SwapperDetailedMetrics:
```typescript
useEffect(() => {
const fetchData = async () => {
// ... fetch logic
};
fetchData();
const interval = setInterval(fetchData, 30000); // Оновлюємо кожні 30 секунд
return () => clearInterval(interval);
}, [nodeId, swapperUrl]); // Залежності для правильного оновлення при зміні ноди
```
**Результат:**
- ✅ Оновлення кожні 30 секунд
- ✅ Правильне оновлення при зміні ноди
- ✅ Правильне визначення URL для кожної ноди
---
### 3. Покращено визначення URL Swapper Service
**Функція `getSwapperUrl`:**
```typescript
const getSwapperUrl = (nodeId?: string): string => {
if (!nodeId) {
return import.meta.env.VITE_SWAPPER_URL || 'http://localhost:8890';
}
// НОДА1: node-1, node-1-hetzner-gex44, або будь-який ID що містить 'node-1'
if (nodeId === 'node-1' || nodeId === 'node-1-hetzner-gex44' || nodeId.includes('node-1')) {
return import.meta.env.VITE_SWAPPER_NODE1_URL || 'http://144.76.224.179:8890';
}
// НОДА2: node-2 або будь-який ID що містить 'node-2'
if (nodeId === 'node-2' || nodeId.includes('node-2')) {
return import.meta.env.VITE_SWAPPER_NODE2_URL || 'http://192.168.1.244:8890';
}
return import.meta.env.VITE_SWAPPER_URL || 'http://localhost:8890';
};
```
**Підтримувані формати nodeId:**
- `node-1``http://144.76.224.179:8890`
- `node-1-hetzner-gex44``http://144.76.224.179:8890`
- `node-2``http://192.168.1.244:8890`
- Будь-який ID що містить `node-1`НОДА1
- Будь-який ID що містить `node-2`НОДА2
---
## 📊 Структура відображення
### Кабінет НОДА1 (`/nodes/node-1`)
**Вкладка "Сервіси":**
```
🔄 Swapper Service
├── SwapperStatusCard
│ ├── Статус сервісу
│ ├── Активна модель
│ └── Список моделей
├── SwapperMetricsSummary
│ ├── Всього моделей
│ ├── Активних
│ ├── Доступних
│ └── Uptime
└── SwapperDetailedMetrics
├── Статус сервісу (CPU, RAM, VRAM, Uptime)
├── Конфігурація
├── Моделі (таблиця)
├── Спеціалісти
└── Активна модель
```
**URL Swapper Service:** `http://144.76.224.179:8890`
---
### Кабінет НОДА2 (`/nodes/node-2`)
**Вкладка "Сервіси":**
```
🔄 Swapper Service
├── SwapperStatusCard
├── SwapperMetricsSummary
└── SwapperDetailedMetrics
```
**URL Swapper Service:** `http://192.168.1.244:8890`
---
## 🔍 Перевірка
### 1. Перевірити відображення
1. **НОДА1:**
- Відкрити: `http://localhost:8899/nodes/node-1`
- Перейти на вкладку "Сервіси"
- Перевірити наявність секції "🔄 Swapper Service"
- Перевірити відображення всіх компонентів
2. **НОДА2:**
- Відкрити: `http://localhost:8899/nodes/node-2`
- Перейти на вкладку "Сервіси"
- Перевірити наявність секції "🔄 Swapper Service"
- Перевірити відображення всіх компонентів
### 2. Перевірити оновлення в реальному часі
1. Відкрити кабінет НОДА1
2. Перейти на вкладку "Сервіси"
3. Спостерігати за оновленням метрик
4. Перевірити, що дані оновлюються кожні 30 секунд
### 3. Перевірити правильність URL
1. Відкрити DevTools → Network
2. Перевірити запити до Swapper Service
3. Для НОДА1: `http://144.76.224.179:8890/api/cabinet/swapper/status`
4. Для НОДА2: `http://192.168.1.244:8890/api/cabinet/swapper/status`
---
## ✅ Результат
### До виправлення:
- ❌ Swapper Service відображався в Console
- ❌ Окрема сторінка `/swapper`
- ❌ Посилання в навігації та на головній сторінці
- ⚠️ Неправильне оновлення при зміні ноди
### Після виправлення:
- ✅ Swapper Service тільки в кабінетах НОД
- ✅ Оновлення в реальному часі (кожні 30 секунд)
- ✅ Правильне визначення URL для кожної ноди
- ✅ Правильне оновлення при зміні ноди
-Всі зайві використання видалено
---
## 🎯 Висновок
**Swapper Service тепер:**
- ✅ Відображається тільки в кабінетах НОД
- ✅ Працює в реальному часі з оновленням кожні 30 секунд
- ✅ Правильно визначає URL для кожної ноди
- ✅ Правильно оновлюється при зміні ноди
**Всі кабінети НОД мають повну інформацію про Swapper Service!** 🎉