docs: add project roadmap and master prompt
This commit is contained in:
323
.ai/ROADMAP.md
Normal file
323
.ai/ROADMAP.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# Ignis Core Roadmap
|
||||
|
||||
Этот roadmap собран по итогам полного обзора текущего состояния `ignis-core`.
|
||||
Он нужен как рабочий план, а не как абстрактный wishlist.
|
||||
|
||||
## Цели проекта
|
||||
|
||||
1. Сделать сервер безопасным по умолчанию.
|
||||
2. Убрать ложные успехи и хрупкое поведение при работе с лампами и сетью.
|
||||
3. Привести API, UI и документацию к одному контракту.
|
||||
4. Подготовить кодовую базу к развитию без накопления хаоса.
|
||||
5. Довести продукт до состояния "можно спокойно жить в проде дома".
|
||||
|
||||
## Текущее состояние в двух словах
|
||||
|
||||
- Бэкенд маленький и понятный, но уже накопил архитектурный долг.
|
||||
- Основная логика работает на in-memory state и прямых вызовах драйвера.
|
||||
- Безопасность и роли реализованы опасно и неполно.
|
||||
- Фронтенд функциональный, но монолитный и плохо масштабируется.
|
||||
- Тестовой, миграционной и операционной инфраструктуры почти нет.
|
||||
|
||||
## P0: Критично исправить прежде всего
|
||||
|
||||
### P0.1 Безопасность по умолчанию
|
||||
|
||||
Проблемы:
|
||||
|
||||
- При пустом `IGNIS_API_KEY` сервер открывает полный доступ всем.
|
||||
- Любой `admin`-ключ может управлять всеми гостевыми ключами.
|
||||
- Полные API-ключи возвращаются из списка ключей.
|
||||
- Текущий ключ хранится в `localStorage`.
|
||||
- UI зависит от внешних CDN, что плохо и для безопасности, и для офлайна.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Перевести авторизацию в `fail-closed`.
|
||||
2. Явно разделить роли `master`, `admin`, `guest`.
|
||||
3. Разрешить управление API-ключами только мастер-доступу.
|
||||
4. Перестать возвращать полные ключи из `GET /api-keys`.
|
||||
5. Возвращать полный токен только в момент создания.
|
||||
6. Продумать более безопасное хранение ключа в браузере.
|
||||
7. По возможности убрать CDN-зависимости или хотя бы сделать локальный fallback.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Сервер без мастер-ключа не выдаёт админ-доступ.
|
||||
- Гостевой `admin` не может создавать или отзывать другие ключи.
|
||||
- Повторный запрос списка ключей не раскрывает секреты.
|
||||
|
||||
### P0.2 Надёжность команд и статусов
|
||||
|
||||
Проблемы:
|
||||
|
||||
- Таймауты WiZ дают `None`, а код затем вызывает `.get(...)`.
|
||||
- Групповое управление отвечает `ok`, даже если отправка провалилась.
|
||||
- Логирование фиксирует действие без подтверждения результата.
|
||||
- Ошибка одной лампы может сломать групповой status endpoint.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Нормализовать ответ драйвера: success, timeout, error, payload.
|
||||
2. Привести все control/status endpoints к одному формату ошибок.
|
||||
3. Возвращать частичный результат по группам, а не фальшивый успех.
|
||||
4. Логировать отдельно intent и фактический outcome.
|
||||
5. Развести ошибки сети, таймауты, офлайн и ошибки протокола.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Один timeout не валит весь запрос.
|
||||
- API честно сообщает, сколько устройств обработано успешно.
|
||||
- Логи не врут о выполнении команды.
|
||||
|
||||
### P0.3 Исправление расписаний
|
||||
|
||||
Проблемы:
|
||||
|
||||
- `cron`-задачи могут затирать друг друга из-за конфликтующих `job_id`.
|
||||
- Расписания умеют почти только `on/off`.
|
||||
- Отсутствует нормальная модель хранения пользовательских задач.
|
||||
- В коде есть мёртвая модель `ScheduleTask`, не совпадающая с реальностью.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Исправить формирование `job_id`.
|
||||
2. Ввести явную доменную модель расписания.
|
||||
3. Решить, где источник истины: APScheduler jobstore, своя таблица или оба слоя.
|
||||
4. Добавить payload для brightness, temp, scene, color.
|
||||
5. Добавить валидацию cron/once запросов.
|
||||
6. Сделать idempotent CRUD для задач.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Разные задачи не затирают друг друга.
|
||||
- Пользователь может создавать и редактировать полезные сценарии, а не только toggle.
|
||||
- В модели и БД нет мёртвых или вводящих в заблуждение сущностей.
|
||||
|
||||
## P1: Высокий приоритет
|
||||
|
||||
### P1.1 Привести API к нормальному контракту
|
||||
|
||||
Проблемы:
|
||||
|
||||
- Почти все POST-эндпоинты принимают query-параметры.
|
||||
- Нет явных request/response schemas.
|
||||
- Нет нормальной валидации диапазонов и конфликтов полей.
|
||||
- `openapi.json`, код и README расходятся.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Перевести команды управления и расписаний на JSON body.
|
||||
2. Описать Pydantic-модели для всех запросов и ответов.
|
||||
3. Добавить строгую валидацию:
|
||||
- brightness range
|
||||
- temp range
|
||||
- RGB range
|
||||
- допустимые комбинации scene/temp/rgb
|
||||
4. Нормализовать коды ошибок и detail messages.
|
||||
5. Генерировать `openapi.json` из кода и перестать хранить его как случайный артефакт.
|
||||
6. Обновить README под фактический API.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Фронт, бэк и OpenAPI описывают одно и то же.
|
||||
- Внешнему клиенту не нужно угадывать, что именно принимает endpoint.
|
||||
|
||||
### P1.2 Починить и переосмыслить discovery
|
||||
|
||||
Проблемы:
|
||||
|
||||
- README обещает broadcast, а код делает unicast по всей подсети.
|
||||
- Фоновый discovery не удаляет офлайн-устройства.
|
||||
- Автоопределение сети упрощённое и часто неверное.
|
||||
- Большие подсети молча режутся.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Определиться с настоящей стратегией discovery.
|
||||
2. Привести README к реальной реализации.
|
||||
3. Добавить понятную стратегию offline detection.
|
||||
4. Развести initial scan, manual rescan и background refresh.
|
||||
5. Сохранять полезные метаданные устройства, если они доступны.
|
||||
6. Логировать сканирование структурированно, а не только строками.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Список устройств стабилен и предсказуем.
|
||||
- Пользователь понимает, что именно сканируется и почему устройство исчезло.
|
||||
|
||||
### P1.3 Привести event log и stats к реальности
|
||||
|
||||
Проблемы:
|
||||
|
||||
- Логируются почти только `toggle_on/off`.
|
||||
- UI уже показывает аналитику по scene/color/brightness/temp, но backend её не считает.
|
||||
- Оценка часов работы грубая и легко искажается.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Сделать нормальную модель событий:
|
||||
- command_requested
|
||||
- command_applied
|
||||
- command_failed
|
||||
- schedule_triggered
|
||||
2. Хранить полезные параметры структурированно.
|
||||
3. Переписать stats на основе реальных типов событий.
|
||||
4. Либо убрать из UI несуществующие метрики, либо реально их реализовать.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Статистика отражает то, что реально происходило.
|
||||
- UI не обещает данные, которых нет.
|
||||
|
||||
## P2: Поддерживаемость и развитие
|
||||
|
||||
### P2.1 Разобрать архитектурный долг
|
||||
|
||||
Проблемы:
|
||||
|
||||
- В одном месте SQLAlchemy-модели, в другом in-memory state, в третьем прямые драйверные вызовы.
|
||||
- Есть мёртвые модели и недоведённый дизайн.
|
||||
- Границы между доменной логикой, API и интеграцией размыты.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Ввести сервисный слой:
|
||||
- auth service
|
||||
- device service
|
||||
- group service
|
||||
- control service
|
||||
- schedule service
|
||||
- stats service
|
||||
2. Отделить transport layer от доменной логики.
|
||||
3. Удалить или довести до конца мёртвые сущности.
|
||||
4. Вынести общие DTO и контракты.
|
||||
5. Перестать хранить SQLAlchemy-объекты прямо в `state_manager`.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Роуты тонкие.
|
||||
- Бизнес-логика тестируется без HTTP.
|
||||
- Структура проекта подсказывает, где что живёт.
|
||||
|
||||
### P2.2 Нормальный фронтенд-контур
|
||||
|
||||
Проблемы:
|
||||
|
||||
- Весь UI живёт в одном `static/index.html`.
|
||||
- Нет компонентности, тестов, сборки и типизации.
|
||||
- Интерфейс уже перерос формат одного файла.
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Решить, остаётся ли UI встроенным SPA или выносится в отдельный frontend package.
|
||||
2. Если остаётся встроенным:
|
||||
- разбить на компоненты
|
||||
- завести build pipeline
|
||||
- локализовать ассеты
|
||||
3. Если выносится:
|
||||
- описать стабильный API-контракт
|
||||
- организовать сборку и публикацию статики
|
||||
4. Добавить базовые UI-тесты хотя бы на критические потоки.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Добавление новой вкладки или формы не требует править гигантский HTML-файл.
|
||||
|
||||
### P2.3 Тесты и инженерная обвязка
|
||||
|
||||
Сейчас не хватает:
|
||||
|
||||
- unit tests
|
||||
- integration tests
|
||||
- API smoke tests
|
||||
- linting
|
||||
- CI
|
||||
- миграций
|
||||
- health endpoint
|
||||
- backup/restore стратегии
|
||||
- нормальной операционной документации
|
||||
|
||||
Что сделать:
|
||||
|
||||
1. Добавить `pytest`.
|
||||
2. Покрыть минимум:
|
||||
- auth
|
||||
- api keys permissions
|
||||
- control param validation
|
||||
- schedules
|
||||
- stats aggregation
|
||||
3. Добавить миграции, вероятнее всего через Alembic.
|
||||
4. Добавить `/health` и `/ready`.
|
||||
5. Добавить базовый CI pipeline.
|
||||
6. Описать развёртывание и обновление без потери данных.
|
||||
|
||||
Критерий готовности:
|
||||
|
||||
- Любое опасное изменение ловится до ручной проверки на живых лампах.
|
||||
|
||||
## P3: Продуктовые улучшения
|
||||
|
||||
### Фичи, которых явно не хватает
|
||||
|
||||
1. Редактирование групп, а не только создание и удаление.
|
||||
2. Нормальные имена устройств и комнат.
|
||||
3. Управление отдельными устройствами из UI.
|
||||
4. Расписания с payload, а не только `on/off`.
|
||||
5. Шаблоны сценариев:
|
||||
- bedtime
|
||||
- morning
|
||||
- away mode
|
||||
- timer presets
|
||||
6. История действий и журнал ошибок в UI.
|
||||
7. Понятный onboarding при первом запуске.
|
||||
8. Индикация реального статуса подключения и последнего ответа лампы.
|
||||
9. Импорт/экспорт конфигурации групп и ключей.
|
||||
10. Более точное разграничение прав между домашними ролями.
|
||||
|
||||
## Рекомендуемый порядок выполнения
|
||||
|
||||
### Этап 1
|
||||
|
||||
- P0.1 Безопасность по умолчанию
|
||||
- P0.2 Надёжность команд и статусов
|
||||
|
||||
### Этап 2
|
||||
|
||||
- P0.3 Расписания
|
||||
- P1.1 Контракт API
|
||||
|
||||
### Этап 3
|
||||
|
||||
- P1.2 Discovery
|
||||
- P1.3 Event log и stats
|
||||
|
||||
### Этап 4
|
||||
|
||||
- P2.1 Архитектурная чистка
|
||||
- P2.3 Тесты и инфраструктура
|
||||
|
||||
### Этап 5
|
||||
|
||||
- P2.2 Фронтенд-контур
|
||||
- P3 Продуктовые улучшения
|
||||
|
||||
## Анти-цели
|
||||
|
||||
Пока не стоит:
|
||||
|
||||
- Бездумно наращивать фичи поверх текущих проблем безопасности.
|
||||
- Делать косметический рефакторинг без закрытия P0.
|
||||
- Добавлять новый клиентский функционал без фикса API-контракта.
|
||||
- Трогать много слоёв сразу без тестового контура.
|
||||
|
||||
## Definition of Done для проекта
|
||||
|
||||
Проект можно считать приведённым в сильное состояние, когда:
|
||||
|
||||
1. Нет полного доступа без явной конфигурации безопасности.
|
||||
2. Команды и расписания честно отражают результат выполнения.
|
||||
3. API, фронтенд и документация синхронизированы.
|
||||
4. Есть тестовый минимум на критические сценарии.
|
||||
5. Нет мёртвых моделей и двусмысленных источников истины.
|
||||
6. UI и backend можно развивать без страха всё сломать.
|
||||
Reference in New Issue
Block a user