006 Пользователи: API /users (CRUD, смена своего пароля), раздел UI «Пользователи»,
события журнала user.*, защита от отключения/удаления себя и последнего админа.
007 Исправление удаления организации: VRF удаляются явным DELETE до организации
(без relationship() порядок DELETE не гарантирован → ложный 409).
008 Журнал фиксирует отказы в удалении (<entity>.delete_blocked) со списком
мешающих объектов в «Данных»: организация, VRF, тип устройства, префикс, пользователь.
009 Выбор строк чекбоксами и групповые операции в UI (удаление, смена типа устройств,
статус префиксов и адресов, доступ пользователей); цикл запросов из UI, итог и список отказов.
010 Автовыделение следующего вложенного префикса: POST/GET /prefixes/{id}/subnets/next,
первый свободный выровненный блок; пункт «Добавить вложенный (авто)» в меню префикса.
Тесты: 14 (добавлены сценарии для 006, 007/008, 010); исправлена нестабильность
тестов журнала (IPv6-группы с ведущими нулями нормализуются PostgreSQL).
Документация: README.md, docs/changes/006-010 (планы и итоги).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3.4 KiB
Исправление: удаление организации возвращает 409 (изменение 007)
Context
DELETE /api/v1/organizations/5 отвечает 409 «Запись с такими значениями уже существует», хотя у организации нет префиксов, устройств и операторов
(проверено по БД: у org 5 только служебный VRF default). Так же падает удаление организации 4.
Причина (подтверждена логом PostgreSQL)
ERROR: update or delete on table "organizations" violates foreign key constraint "vrfs_organization_id_fkey" ... Key (id)=(5) is still referenced from table "vrfs".
В delete_org (app/api/v1/refs.py:67-79) VRF удаляются через db.delete(v), затем db.delete(o), всё одним commit. Между Vrf и Organization нет ORM-relationship(),
поэтому unit of work не гарантирует порядок DELETE, и DELETE FROM organizations уходит раньше DELETE FROM vrfs. IntegrityError в commit() (app/services.py:52)
превращается в общий 409 с вводящим в заблуждение текстом.
Исправление
app/api/v1/refs.py,delete_org: заменить циклfor v in ...: db.delete(v)наdb.execute(delete(Vrf).where(Vrf.organization_id == id))(добавитьdeleteв импортsqlalchemy) — выполняется немедленно, доdb.delete(o). Аудит и проверка «занято» без изменений.- Схема БД, миграции и UI не меняются.
- Остальные
db.deleteв проекте (vrfs,device-types,devices,isps,prefixes,addresses,users) удаляют одиночную запись без зависимых строк, вне области правки.
Артефакты (правила проекта)
docs/changes/007-org-delete-fix/PLAN.md(этот план) иSUMMARY.md— причина, правка, проверка.README.md: короткая пометка в разделе об удалении организаций/поведении API (если такой раздел есть), иначе строка в списке изменений.
Тест (минимум)
Один тест в tests/test_api.py: создать организацию → DELETE → 204 → GET → 404; организация с префиксом → DELETE → 409 с текстом «Нельзя удалить…».
Проверка
docker compose -p ipam_control_006 up -d --build app(пересборка только приложения; БД и данные сохраняются, прежняя поставкаipam_control-*не затрагивается).venv/bin/python -m pytest -q tests/test_api.py— против запущенного стенда (BASE изtests/conftest.py).- Вручную в UI (http://192.168.5.9:8088): удалить организации «ООО «Дата-Центр»» (id 5) и «ООО «СтройМонтаж»» (id 4) — 204; попытка удалить «ООО «Технологии связи»» (есть префиксы) — 409 «Нельзя удалить…»; записи
organization.deletedпоявились в журнале.