From e43c502bcb1de71cf48566ba16ca1866493bbbfb Mon Sep 17 00:00:00 2001 From: IgorRachkov <89467086+igor04091968@users.noreply.github.com> Date: Sun, 7 Jun 2026 13:32:57 +0300 Subject: [PATCH] Update TASK_002_PRODUCTION_HARDENING.md --- docs/roadmap/TASK_002_PRODUCTION_HARDENING.md | 392 +++++++++++++++++- 1 file changed, 375 insertions(+), 17 deletions(-) diff --git a/docs/roadmap/TASK_002_PRODUCTION_HARDENING.md b/docs/roadmap/TASK_002_PRODUCTION_HARDENING.md index 54f6efb..8b864d4 100644 --- a/docs/roadmap/TASK_002_PRODUCTION_HARDENING.md +++ b/docs/roadmap/TASK_002_PRODUCTION_HARDENING.md @@ -1,25 +1,383 @@ -# TASK 002: Production Hardening +docs/roadmap/TASK_002_PRODUCTION_HARDENING.md -## Цель +Рекомендуемые параметры -Повысить надежность промышленного контура AWatch-rus при отказах источников, -перегрузке сервисов и частичной потере данных. +Mode: xhigh +Reasoning: maximum +Task type: production hardening / reliability / observability +Quality bar: production-ready +Breaking changes: forbidden +Architecture changes: minimal +Simplifications: forbidden +Security posture: fail closed -## Объем +Required checks: -- Fail-closed поведение для критичных API. -- Bounded timeouts и отсутствие каскадных тяжелых повторов. -- Stale cache fallback там, где это безопасно. -- Health/status, которые честно показывают degraded-состояние. -- Операторские runbook для восстановления. +cargo fmt --all --check +cargo clippy --all-targets --all-features -- -D warnings +cargo test --all +cargo build --release -## Ограничения +Если есть smoke scripts — выполнить их. +Если smoke scripts отсутствуют — добавить минимальный smoke script. -- Не скрывать degraded-состояния за зеленым health. -- Не делать ClickHouse обязательной зависимостью worktime reports. -- Не логировать чувствительные runtime-идентификаторы. +--- -## Результат +Задача -Система контролируемо деградирует, не создает каскадную нагрузку и дает -оператору понятный порядок восстановления. +Усилить production-ready слой AWatch-rus после Pilot v1 без изменения основной архитектуры. + +--- + +Цель + +Добавить: + +- "/healthz" +- "/readyz" +- "/version" +- "/metrics" +- строгую валидацию конфигурации +- request id / correlation id +- structured JSON logging +- Prometheus metrics +- request timeout / payload limits / page limits +- защиту от тяжелых API-запросов +- smoke-тесты +- документацию + +--- + +Контекст проекта + +AWatch-rus — Workforce-first система с модулями: + +- Executive +- Workforce +- Security +- Forensics +- Admin + +Текущий стек: + +- Rust backend +- Rust server-rendered HTML + HTMX portal +- API contracts +- Dioxus не используется +- React/Tauri не трогать +- ML/LLM не добавлять + +--- + +Что реализовать + +1. Health endpoint + +Добавить: + +GET /healthz + +Поведение: + +- отвечает "200 OK", если процесс жив; +- не проверяет внешние зависимости; +- ответ JSON. + +Пример: + +{ + "status": "ok" +} + +--- + +2. Readiness endpoint + +Добавить: + +GET /readyz + +Поведение: + +- отвечает "200 OK", если приложение готово обслуживать запросы; +- проверяет только реально существующие зависимости; +- если зависимостей нет — явно вернуть local-ready состояние; +- не делать ложных claim о pfSense ingestion, SIEM, DLP или внешних интеграциях. + +Пример: + +{ + "status": "ready", + "checks": { + "config": "ok", + "storage": "not_configured", + "pfsense": "contract_only" + } +} + +При ошибке готовности: + +- вернуть "503"; +- JSON должен объяснять причину. + +--- + +3. Version endpoint + +Добавить: + +GET /version + +Ответ должен включать: + +{ + "app_version": "0.2.0", + "git_commit": "unknown", + "build_time": "unknown", + "schema_version": "pilot-v1", + "environment": "local" +} + +Требования: + +- если git commit/build time недоступны — не падать; +- не раскрывать секреты; +- использовать безопасные значения по умолчанию. + +--- + +4. Metrics endpoint + +Добавить: + +GET /metrics + +Формат: + +Prometheus text format + +Минимальные метрики: + +- "awatch_http_requests_total" +- "awatch_http_request_duration_seconds" +- "awatch_reports_generated_total" +- "awatch_ingestion_records_total" +- "awatch_ingestion_rejected_total" +- "awatch_role_denied_total" +- "awatch_readyz_status" + +Labels: + +- "method" +- "route" +- "status" +- "module" + +Запрещено использовать high-cardinality labels: + +- user_id +- employee_id +- ip +- raw URL +- query params + +--- + +5. Валидация конфигурации + +Добавить централизованную проверку конфигурации при старте. + +Проверить: + +- host +- port +- max page size +- default page size +- max report date range +- request timeout +- payload size limit +- environment name +- enabled modules + +Поведение: + +- при невалидной конфигурации приложение должно завершиться с понятной ошибкой; +- секреты не логировать; +- небезопасные значения не подставлять молча. + +Добавить unit tests: + +- valid config +- invalid port +- invalid page size +- invalid report range +- invalid timeout + +--- + +6. Request ID / Correlation ID + +Добавить middleware: + +- принимать входящий "X-Request-Id"; +- если его нет — генерировать новый; +- принимать входящий "X-Correlation-Id"; +- если его нет — использовать request_id; +- возвращать оба header в response; +- добавлять оба значения в logs. + +Headers: + +X-Request-Id +X-Correlation-Id + +--- + +7. Structured JSON logging + +HTTP request logs должны включать: + +- timestamp +- level +- request_id +- correlation_id +- method +- path +- status +- latency_ms +- user_role, если известна +- error_code, если есть + +Запрещено логировать: + +- токены +- секреты +- полные body payload +- персональные данные + +--- + +8. Timeouts and limits + +Добавить защитные лимиты: + +- max request body size +- max report date range +- max page size +- default page size +- request timeout +- slow request logging threshold + +Поведение: + +- слишком большой body → "413" +- слишком большой page_size → "400" +- слишком широкий report range → "400" +- timeout → "408" или "504", согласно текущей архитектуре + +--- + +9. Защита тяжелых API-запросов + +Проверить и защитить: + +- "/api/reports" +- "/api/executive" +- "/api/workforce" +- "/api/security" +- "/api/forensics" +- "/api/ueba" +- "/api/pfsense" + +Требования: + +- не должно быть неограниченных выборок; +- date range должен иметь максимум; +- page size должен иметь максимум; +- ошибки должны быть понятными; +- role gates не должны быть сломаны. + +--- + +10. Документация + +Добавить: + +docs/PRODUCTION_READINESS_RU.md + +Описать: + +- "/healthz" +- "/readyz" +- "/version" +- "/metrics" +- конфигурацию +- лимиты +- формат логов +- список метрик +- smoke checks +- что является "contract_only" + +--- + +11. Smoke tests + +Smoke должен проверять: + +- "/healthz" возвращает 200 +- "/readyz" возвращает 200 или ожидаемый 503 с JSON +- "/version" содержит "app_version" и "schema_version" +- "/metrics" возвращает Prometheus text +- "X-Request-Id" возвращается в headers +- слишком большой "page_size" отклоняется +- слишком широкий report range отклоняется +- role gates работают + +--- + +Запрещено + +Не делать: + +- Dioxus +- React +- Tauri +- ML +- LLM +- новую БД +- SaaS-зависимости +- ложные заявления о pfSense/SIEM/DLP ingestion +- переписывание архитектуры +- удаление существующих API +- поломку HTML/HTMX portal + +--- + +Критерии приемки + +Задача считается выполненной, если: + +- endpoints добавлены; +- лимиты работают; +- конфиг валидируется; +- metrics доступны; +- request id/correlation id работают; +- structured logs работают; +- heavy API requests ограничены; +- документация добавлена; +- все проверки проходят; +- существующий Pilot v1 функционал не сломан. + +--- + +Финальный отчет должен содержать + +1. Краткое описание изменений. +2. Список измененных файлов. +3. Добавленные endpoints. +4. Добавленные лимиты. +5. Добавленные метрики. +6. Добавленные тесты. +7. Результаты команд проверки. +8. Результат smoke. +9. Известные ограничения