2026-04-03 08:30:56 +03:00
# Архитектура onGuard24 (для разработки и доработок)
2026-04-03 08:36:35 +03:00
Цель продукта: **модульный монолит** в духе IRM — ядро + подключаемые области (дежурства, контакты, «светофор» по сервисам). Текущая версия — **каркас v1.1** : HTTP, БД, ingress Grafana, проверки интеграций, Alembic, задел домена в `onguard24/domain/` .
2026-04-03 08:30:56 +03:00
## Дерево пакетов
```
onGuard24/
2026-04-03 08:36:35 +03:00
├── alembic/ # Ревизии миграций PostgreSQL (Alembic)
├── alembic.ini
2026-04-03 08:30:56 +03:00
├── onguard24/
│ ├── main.py # FastAPI app, lifespan, маршруты верхнего уровня
│ ├── config.py # Settings: .env из корня репозитория (не от cwd)
2026-04-03 08:36:35 +03:00
│ ├── db.py # asyncpg pool (без DDL)
│ ├── domain/ # Сущности и шина событий (задел под модули)
2026-04-03 08:30:56 +03:00
│ ├── status_snapshot.py # Единый сборщик JSON для /api/v1/status
│ ├── root_html.py # HTML главной страницы с о статусами
│ ├── vaultcheck.py # Vault /v1/sys/health
│ ├── ingress/grafana.py # POST webhook Grafana → INSERT ingress_events
│ ├── integrations/
│ │ ├── grafana_api.py # Grafana HTTP API (Bearer SA)
│ │ └── forgejo_api.py # Forgejo/Gitea API (token + probe/fallback)
│ └── modules/ # Заглушки: schedules, contacts, statusboard
├── web/ # Vite + React (опционально)
├── pyproject.toml
2026-04-03 08:36:35 +03:00
├── pytest.ini
├── tests/ # pytest: health, status, ingress
2026-04-03 08:30:56 +03:00
├── CHANGELOG.md
└── docs/
```
## Поток данных (сейчас)
1. **Grafana** (отдельно настроенный contact point) шлёт **POST** на `/api/v1/ingress/grafana` → тело JSON пишется в ** `ingress_events` **.
2. **Параллельно** Grafana может слать в Mattermost — это вне этого репозитория (конфиг Grafana).
3. **Статус страницы** не ходит в Grafana за алертами — только **проверка доступности API** (токен SA).
## Куда класть новый функционал
| Задача | Место |
|--------|--------|
| Новый HTTP-роут модуля | `onguard24/modules/<name>.py` + `include_router` в `main.py` |
2026-04-03 08:36:35 +03:00
| Общая логика инцидентов / событий | задел: `onguard24/domain/` + [DOMAIN.md ](DOMAIN.md ); позже сервисный слой и БД |
| Новая таблица БД | Alembic: `alembic revision` , правка `alembic/versions/` , `alembic upgrade head` |
2026-04-03 08:30:56 +03:00
| Новая внешняя интеграция | `onguard24/integrations/<name>.py` , вызов из `status_snapshot` при необходимости |
## Конфигурация
В с е секреты только через **переменные окружения** / `.env` (файл **не в git** ). Список ключей — `.env.example` .
## Зависимости между компонентами
- `status_snapshot.build(request)` читает `request.app.state.pool` и `request.app.state.settings` (устанавливаются в `lifespan` ).
2026-04-03 08:36:35 +03:00
- Модули **не** зависят друг от друга; контракт заделан через **доменные события** (`domain/events.py` , `EventBus` ) и описан в [DOMAIN.md ](DOMAIN.md ); проводка в HTTP пока не подключена.
2026-04-03 08:30:56 +03:00
2026-04-03 08:36:35 +03:00
## Известные ограничения
2026-04-03 08:30:56 +03:00
2026-04-03 08:36:35 +03:00
- Нет единой модели «инцидент» в БД — только сырой ingest в `ingress_events` (в коде есть Pydantic-модели в `domain/entities.py` как задел).
2026-04-03 08:30:56 +03:00
- Нет очереди/воркеров для эскалаций.
- Нет auth на GET `/api/v1/status` (только для внутренней сети / за reverse proxy с ограничением).