Repository navigation
04 Architecture
index.php ─ Router ─ Controller ─ Service ─ Fornex API
│ │
│ ├── ZonePlanner (правила о записях)
│ └── DnsResolver (проверка)
│
└── View (оболочка SPA) SQLite: audit_events, snapshots,
api_tokens, login_attempts
backend/bin/fornex ─ Cli\Application ─ те же Services
Веб-вход и командная строка вызывают один backend/bootstrap.php, который возвращает App с
контейнером Services. Второй сборки и второй копии правил нет: пресет, применённый из
интерфейса, из скрипта или из php backend/bin/fornex, идёт одним путём
PresetService → ZonePlanner → ZoneService.
| Класс | Ответственность |
|---|---|
Kernel\Env |
читает KEY=VALUE из файла; настоящая переменная окружения важнее файла |
Kernel\Config |
неизменяемое дерево настроек, перекрытие по карте ENV_MAP, path() считает относительные пути от корня приложения |
Kernel\Request |
метод, путь, query, JSON-тело, bearer-токен, адрес клиента |
Kernel\Response |
{ok:true, …} / {ok:false, error:{code, message, details}}
|
Kernel\Router |
табличные маршруты, {name} — один сегмент пути, 404 и 405 различаются |
Kernel\Session |
сессия в cookie, таймаут бездействия, регенерация при входе |
Kernel\Logger |
журнал с ротацией; секрет в него не попадает |
Kernel\App |
выполняет маршрут, применяет флаги auth/csrf/write, превращает исключения в ответы |
| Сервис | Ответственность |
|---|---|
Fornex\Client |
HTTP к ru.fornex.com/api, браузерный User-Agent, повторы на сеть и 5xx, FornexException с кодом и сообщением |
Service\ZoneService |
читает зону, снимает снимок перед каждой записью, выполняет добавление/правку/удаление по id
|
Service\ZonePlanner |
правила: дубли, слияние SPF, политика DMARC, форма плана (create, update, skip, conflict) |
Service\PresetService |
пресеты, шаги мастера, поля по шагу, нормализация DKIM, stepsOverview
|
Service\VerifyService |
NS, MX и цели, SPF, DKIM по четырём селекторам, DMARC, A @/www, PTR — один отчёт |
Service\NsService |
состояние делегирования, инструкция регистратору, смена NS для домена, заказанного в Fornex |
Service\TokenService |
выпуск токена (префикс + хэш), проверка, отзыв; по умолчанию только чтение |
Service\AuditService |
запись и чтение audit_events
|
Database\Database |
SQLite, миграции из backend/migrations
|
Любая запись начинается с плана:
{
"create": [{"host": "@", "type": "MX", "value": "SMTP.GOOGLE.COM", "prio": 1, "why": "…"}],
"update": [{"id": 4237354, "from": "…", "to": "…", "why": "…"}],
"skip": [{"id": 4237363, "reason": "уже есть"}],
"conflict": [{"id": 4232119, "reason": "MX на локальный mail мешает Google"}]
}preview возвращает план и ничего не пишет. apply пересчитывает план по текущей зоне и
выполняет create и update; skip и conflict не применяются автоматически никогда. Снимок
снимается между этими шагами, поэтому план, который видел человек, и снимок на диске описывают
одну и ту же зону.
PresetService::stepsOverview считает статус каждого шага:
| Статус | Значение | Что видит человек |
|---|---|---|
done |
запись, которую пишет шаг, уже в зоне (present_if) |
«уже есть» |
todo |
шаг можно применять | активная кнопка |
empty |
шагу не хватает значения в поле | кнопка активна, сервер отвечает списком «чего не хватает» |
blocked |
не выполнен шаг из requires
|
предпросмотр выключен, назван недостающий шаг |
empty намеренно не отказ: шаг DKIM остаётся empty, пока не вставлен ключ, и запрет кнопки
на этом состоянии делал шаг невозможным — сначала нельзя было вставить ключ, потом получить план.
В SQLite лежит только то, чего нет в зоне: audit_events (кто, что, был ли сухой прогон, итог),
snapshots (путь, sha256, число записей), api_tokens (префикс и хэш, никогда сам токен),
login_attempts (ограничение попыток входа). Сама зона читается из API при каждом запросе,
поэтому панель не может показать устаревшую копию.
VerifyService спрашивает два сервера на каждый тип записи: публичный резолвер
(VERIFY_RESOLVER) и авторитетный сервер Fornex (VERIFY_AUTHORITATIVE). В отчёте видно, где
записи действительно нет, а где ответ просто закеширован.
репозиторий · релизы · Fornex Control · MIT · панель для DNS-зон Fornex