Статус устройства (Активен / Выключен / На обслуживании), назначается вручную на экране устройств: колонка «Статус», выбор в диалоге, смена — в журнал. Миграция 0016, существующие устройства — «Активен». В списке адресов префикса колонки «Тип устройства», «Устройство», «Статус устройства» (join без N+1). pytest не прогнан: учётная запись admin из .env отключена на стенде. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.9 KiB
5.9 KiB
Статус устройства и сведения об устройстве в списке адресов префикса (изменение 039)
Context
Сейчас в списке адресов префикса (screens.address) не видно, к какому устройству привязан адрес, — только в диалоге правки.
У устройства нет эксплуатационного статуса. Нужно:
- Ввести статус устройства — «Активен», «Выключен», «На обслуживании». Статус назначается вручную на экране устройств: в диалоге создания и правки, в таблице устройств — новая колонка «Статус».
- В списке адресов префикса — три новые колонки: тип устройства, имя устройства, статус устройства (пусто или «—», если адрес не привязан к устройству).
Модель и миграция 0016_device_status.py
app/models.py:class DeviceStatus(str, enum.Enum): active, off, maintenance.Device.status: Mapped[DeviceStatus]—Enum(DeviceStatus, name="device_status"),default=active,server_default='active', NOT NULL.- Миграция: создать тип
device_status, добавить колонку сserver_default 'active'— существующие устройства станут «Активен».downgrade: удалить колонку и тип.
API
app/schemas.py:DeviceIn.status: DeviceStatus = DeviceStatus.active;DeviceUpdate.status: DeviceStatus | None = None;DeviceOut.status;AddressOut:device_type_name: str | None,device_status: str | None.
app/api/v1/refs.py: создание и правка устройства принимаютstatus. Смена статуса попадает в журнал через существующийapply_update(device.updatedсdiff);_device_outsотдаётstatus.app/api/v1/prefixes.py::list_addresses:- запрос
select(Address, Device.name)расширить:Device.statusиDeviceType.nameчерезouterjoin(DeviceType, …); _addr_out(a, device_name, device_type_name, device_status)— обновить все вызовы;- остальные эндпоинты, возвращающие
AddressOut(создание, правка, автоназначение), отдают поля так же — через общий хелпер или отдельный запрос поdevice_id, без N+1 в списке.
- запрос
- Фильтр и поиск по статусу устройства не требуются.
UI — web/app.js
- Справочник
DEVICE_STATUS = {active: ["green","Активен"], off: ["", "Выключен"], maintenance: ["amber","На обслуживании"]}— цвет бейджа и подпись, по образцуADDR_STATUS. - Экран устройств (
screens.devices):- колонка «Статус» с бейджем (после «Тип»), расширить
selColsи заголовок; - в
deviceDialog—fSelect("status", "Статус", …), по умолчанию «Активен», значение уходит вPOST/PATCH.
- колонка «Статус» с бейджем (после «Тип»), расширить
- Список адресов (
screens.address): после «Описание» колонки «Тип устройства», «Устройство», «Статус устройства».- имя устройства ссылкой не делаем — строка и так кликабельна; у свободных и непривязанных адресов — «—»;
- статус — тем же бейджем;
- ширины подобрать так, чтобы таблица не переполнялась: «Описание» может стать уже; «Изменено» оставить.
- Цвета — только через существующие классы бейджей и токены тёмной темы (изменение 038), без литералов.
Тесты (минимально)
Одна проверка в существующем тесте tests/test_api.py, например в test_in_use_objects_cannot_be_deleted или рядом, без нового файла:
- создать устройство со
status="maintenance", привязать к нему адрес; GET /prefixes/{id}/addresses→ у адресаdevice_name,device_type_name,device_status == "maintenance";PATCH /devices/{id} {"status": "off"}→ 200,status == "off".
Документация
README.md: модель данных — статус устройства; «Интерфейс» — колонки; миграции0001–0016; строка 039 в истории.SUMMARY.md— по завершении (моя часть).
Исполнение
По принятой схеме: код, миграцию, UI и тест пишет агент на Sonnet, он же пересобирает стенд с --force-recreate; тесты он не запускает.
Моя часть — ревью, pytest, проверка миграции и API. UI проверяет пользователь.
Проверка
alembic current=0016,alembic checkчисто; откат до 0015 и повторный upgrade.- Существующие устройства после миграции —
active. pytest -q— все зелёные.- API: статус меняется и пишется в журнал (
device.updated,diff.status); адреса отдают три новых поля; у свободных и непривязанных адресов —null.