Реестр MODULE_MOUNTS: API, ui_router, фрагменты главной, EventBus. Главная и страницы модулей с правой навигацией из реестра; wrap_module_html_page. Ingress: публикация alert.received после сохранения в БД. Документация MODULES.md; pytest покрывает API, UI и навигацию. Made-with: Cursor
4.6 KiB
4.6 KiB
Разработка функционала через модули
Цель: новые возможности добавляются в onguard24/modules/, без правок «размазанных» по main.py, с явной подпиской на события и своим веб-UI (HTML и API в одном файле пакета).
Что уже есть в ядре
| Механизм | Назначение |
|---|---|
modules/registry.py |
Список MODULE_MOUNTS: API, метаданные UI, register_events. |
modules/ui_support.py |
safe_fragment — безопасный вызов фрагмента главной: ошибка одного модуля не роняет /. |
app.state.event_bus |
InMemoryEventBus — публикация после сохранения ingress (alert.received). |
domain/events.py |
Имена событий, AlertReceived. |
| Ingress | INSERT … RETURNING id → publish_alert_received. |
Веб-UI: главная и полные страницы
- Главная
/автоматически подтягивает карточки изMODULE_MOUNTS: заголовок, превью (render_home_fragment), ссылка на полный UI. - Правое меню («Разделы») строится из того же реестра: пункт «Главная» и по одному пункту на каждый модуль с
ui_router(текст пункта = полеtitleвModuleMount). Новый модуль с UI появляется в меню без правок шаблона — только запись в реестре. - Полный интерфейс модуля —
/ui/modules/<slug>/, страница собирается черезwrap_module_html_page(ui_support.py): тот же каркас и правое меню, активный пункт подсвечивается (current_slug). - Всё, что относится к модулю (JSON API, HTML, события), живёт в одном файле модуля + строка в реестре.
Изоляция сбоев
- Ошибка в
render_home_fragmentперехватывается вsafe_fragment: на главной показывается блок с классомmodule-err, остальные модули и таблица статусов отображаются. - Ошибка в обработчике полной страницы
/ui/modules/...даёт 500 только для этого запроса; процесс и остальные маршруты продолжают работать. - Рекомендуется не полагаться на глобальное состояние между модулями; общение — через БД и
event_bus.
Фронт в web/ (Vite) остаётся опциональным; серверный HTML — основной путь для встроенного UI.
Добавить новый модуль (чеклист)
-
Файл
onguard24/modules/<имя>.py:router— JSON API под/api/v1/modules/<имя>/.- Опционально
ui_router—APIRouter(include_in_schema=False), маршруты полных HTML-страниц (корень/→/ui/modules/<slug>/). - Опционально
async def render_home_fragment(request) -> str— HTML-фрагмент (без<html>) для карточки на главной. register_events(_bus)— подписки на шину.
-
Регистрация в
onguard24/modules/registry.py— объектModuleMount:router,url_prefix,register_events,slug,title, опциональноui_router,render_home_fragment.
-
Миграции — если нужны таблицы:
alembic revision,alembic upgrade head. -
Тесты — API, при необходимости GET
/и/ui/modules/<slug>/.
main.py не меняется — только реестр.
События
- Из ingress публикуется
alert.received(AlertReceived). - Обработчик:
async def h(event: DomainEvent) -> None; удобноisinstance(event, AlertReceived).
Ограничения
- Шина in-process; несколько воркеров — позже общая очередь.
- Auth на модули пока нет — сеть / reverse proxy.
См. DOMAIN.md, ARCHITECTURE.md.