ну и ну
This commit is contained in:
parent
941258fbb6
commit
140d43f8fe
2 changed files with 64 additions and 16 deletions
65
CLAUDE.md
65
CLAUDE.md
|
|
@ -36,7 +36,7 @@ utp_service/
|
||||||
├── pages/ # Page-level components
|
├── pages/ # Page-level components
|
||||||
├── api/ # React Query hooks + API calls
|
├── api/ # React Query hooks + API calls
|
||||||
├── hooks/ # useSSE, useMonitorSSE
|
├── hooks/ # useSSE, useMonitorSSE
|
||||||
├── components/ # AppLayout, StatusBadge
|
├── components/ # AppLayout, StatusBadge, DeviceEditModal
|
||||||
└── store/auth.ts # Zustand auth store
|
└── store/auth.ts # Zustand auth store
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -106,10 +106,10 @@ Content-addressed: `SnapshotContent(sha256 PK, content)`, `ConfigSnapshot(device
|
||||||
| global_devices.py | /devices | GET all devices across objects (filters: category, city, client, object_id, status) |
|
| global_devices.py | /devices | GET all devices across objects (filters: category, city, client, object_id, status) |
|
||||||
| racks.py | /objects/{id}/racks | CRUD |
|
| racks.py | /objects/{id}/racks | CRUD |
|
||||||
| zones.py | /objects/{id}/zones | CRUD |
|
| zones.py | /objects/{id}/zones | CRUD |
|
||||||
| tasks.py | /tasks | POST create + GET list/detail + GET /{id}/events (SSE) |
|
| tasks.py | /tasks | POST create + GET list/detail + GET /{id}/events (SSE); GET list accepts `?device_id=X` (JOIN task_results) |
|
||||||
| events.py | /events | GET SSE stream (task_id param) |
|
| events.py | /events | GET SSE stream (task_id param) |
|
||||||
| alerts.py | /alerts | GET list + POST /{id}/acknowledge + POST /{id}/resolve |
|
| alerts.py | /alerts | GET list (filters: status, object_id, device_id) + POST /{id}/acknowledge + POST /{id}/resolve |
|
||||||
| snapshots.py | /snapshots | GET list + GET /{id}/diff |
|
| snapshots.py | /objects/{id}/snapshots | GET list (filter: device_id) + GET /diff?a=&b= + GET /{id} |
|
||||||
| tags.py | /tags | CRUD |
|
| tags.py | /tags | CRUD |
|
||||||
| admin.py | /admin | User mgmt + plugin control + health |
|
| admin.py | /admin | User mgmt + plugin control + health |
|
||||||
|
|
||||||
|
|
@ -160,6 +160,7 @@ SSE fix: `onerror` must `throw err` to prevent fetchEventSource auto-retry loop
|
||||||
/ → redirect to /inventory/objects
|
/ → redirect to /inventory/objects
|
||||||
/inventory/objects → ObjectsPage (mode=inventory) — city-grouped list
|
/inventory/objects → ObjectsPage (mode=inventory) — city-grouped list
|
||||||
/inventory/objects/:id → InventoryObjectDetailPage — device CRUD, SSH discovery
|
/inventory/objects/:id → InventoryObjectDetailPage — device CRUD, SSH discovery
|
||||||
|
/inventory/objects/:id/devices/:deviceId → DeviceDetailPage — device card (4 tabs)
|
||||||
/inventory/objects/:id/snapshots → SnapshotsPage
|
/inventory/objects/:id/snapshots → SnapshotsPage
|
||||||
/work/objects → ObjectsPage (mode=work) — city-grouped list
|
/work/objects → ObjectsPage (mode=work) — city-grouped list
|
||||||
/work/objects/:id → WorkObjectDetailPage — task execution, device status
|
/work/objects/:id → WorkObjectDetailPage — task execution, device status
|
||||||
|
|
@ -168,13 +169,59 @@ SSE fix: `onerror` must `throw err` to prevent fetchEventSource auto-retry loop
|
||||||
|
|
||||||
Layout nav: ИНВЕНТАРЬ (DatabaseOutlined) | РАБОТА (ControlOutlined, AppstoreOutlined)
|
Layout nav: ИНВЕНТАРЬ (DatabaseOutlined) | РАБОТА (ControlOutlined, AppstoreOutlined)
|
||||||
|
|
||||||
|
### DeviceDetailPage (`pages/DeviceDetail.tsx`)
|
||||||
|
|
||||||
|
URL: `/inventory/objects/:id/devices/:deviceId`
|
||||||
|
|
||||||
|
Шапка: IP + live-статус (SSE via `useMonitorSSE`), hostname, теги категории/стойки/вендора, кнопки Редактировать / Удалить.
|
||||||
|
|
||||||
|
Вкладки:
|
||||||
|
- **Основное** — все поля `DeviceItem` через `Descriptions`, `device_meta`/`connection_params` в JSON-блоках, capabilities тегами
|
||||||
|
- **Алерты** — список алертов устройства (`useAlerts({ device_id })`), фильтр по статусу, кнопки acknowledge/resolve
|
||||||
|
- **Снапшоты** — список (`useSnapshots(objId, { device_id })`), выбор двух → цветной diff-viewer через `useSnapshotDiff`
|
||||||
|
- **История задач** — задачи через `useDeviceTasks(deviceId)`, раскрытие строки показывает stdout/stderr из `TaskResult`
|
||||||
|
|
||||||
|
### DeviceEditModal (`components/DeviceEditModal.tsx`)
|
||||||
|
|
||||||
|
Самодостаточный компонент формы редактирования/добавления устройства. Используется в:
|
||||||
|
- `InventoryObjectDetailPage` (кнопки Edit и «Добавить устройство»)
|
||||||
|
- `DeviceDetailPage` (кнопка «Редактировать» в шапке)
|
||||||
|
|
||||||
|
Props: `open`, `device: DeviceItem | null` (null = режим добавления), `objId`, `onClose`, `onSaved?`
|
||||||
|
|
||||||
|
Внутри: `useCreateDevice` / `useUpdateDevice`, `useRacks` для списка стоек.
|
||||||
|
|
||||||
## Frontend API Hooks (`src/api/`)
|
## Frontend API Hooks (`src/api/`)
|
||||||
|
|
||||||
- `objects.ts`: useObjects, useObject, useCreateObject, useUpdateObject, useDeleteObject, useObjectsMeta (cities/clients autocomplete), useDiscoverObject, useSyncFromDB, useSyncFromSheets
|
- `objects.ts`: useObjects, useObject, useCreateObject, useUpdateObject, useDeleteObject, useObjectsMeta,
|
||||||
- `devices.ts`: useDevices, useDevice, useCreateDevice, useUpdateDevice, useDeleteDevice, useImportDevicesPreview, useImportDevices, useAllDevices (global)
|
useDiscoverObject, useSyncObject, useSyncSheets, usePreviewCSV, useImportCSV,
|
||||||
- `tasks.ts`: useTasks, useTaskDetail, useCreateTask, useTaskSSE
|
**useDevices(objId)** — список устройств объекта,
|
||||||
- `alerts.ts`: useAlerts, useAcknowledgeAlert, useResolveAlert
|
**useDevice(objId, deviceId)** — одно устройство (queryKey: `['device', objId, deviceId]`),
|
||||||
- `snapshots.ts`: useSnapshots, useSnapshotDetail, useSnapshotDiff, useCaptureSnapshot
|
useCreateDevice, useUpdateDevice (инвалидирует `['devices', objId]` + `['device', objId, id]`), useDeleteDevice,
|
||||||
|
useDeleteAllDevices, useAllDevices (global, фильтры: category/city/client/object_id/status)
|
||||||
|
- `tasks.ts`: useTasks, useTask, useActions, useCreateTask,
|
||||||
|
**useDeviceTasks(deviceId)** — задачи по устройству (queryKey: `['tasks', 'device', deviceId]`)
|
||||||
|
- `alerts.ts`: useAlerts (params: status, object_id, **device_id**, limit, skip), useAcknowledgeAlert, useResolveAlert
|
||||||
|
- `snapshots.ts`: useSnapshots(objId, params?: {**device_id**?, label?, limit?, skip?}), useSnapshotDetail, useSnapshotDiff(objId, a, b)
|
||||||
|
- `racks.ts`: useRacks, useCreateRack, useUpdateRack, useDeleteRack
|
||||||
|
- `zones.ts`: useZones, useCreateZone, useDeleteZone
|
||||||
|
|
||||||
|
### DeviceItem interface (полный, `api/objects.ts`)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface DeviceItem {
|
||||||
|
id, object_id, ip, hostname, mac
|
||||||
|
vendor, model, firmware_version, external_id
|
||||||
|
category, role, source
|
||||||
|
rack_id, rack_name, rack_type, location
|
||||||
|
ssh_user_override, ssh_port_override
|
||||||
|
device_meta: Record<string, unknown> // JSONB
|
||||||
|
connection_params: Record<string, unknown> // JSONB
|
||||||
|
capabilities: string[]
|
||||||
|
status, last_seen, last_ping_ms, monitor_enabled
|
||||||
|
is_active, notes, created_at, updated_at
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Plugins (builtin)
|
## Plugins (builtin)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import {
|
||||||
Button,
|
Button,
|
||||||
Col,
|
Col,
|
||||||
Descriptions,
|
Descriptions,
|
||||||
|
Divider,
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
Modal,
|
Modal,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue