Неожиданные 5xx не логируются: HttpExceptionFilter (@Catch()) превращает любое исключение в ответ 500 и не передаёт ошибку в логгер, поэтому pino-http видит только статус. В dev вывод — сырой JSON без цвета (pino-pretty не подключён). Полные тела запросов и ответов не логируются намеренно (ADR 008, backend/.ai/conventions/observability.md) и вне scope этой задачи.
Acceptance Criteria
Неожиданная ошибка (не HttpException) логируется через StructuredLogger.event('error', ...) с полями code, name и stack. Поле message не пишется. Публичный ответ problem+json не меняется.
Для 4xx validation-ошибок в лог попадают имена невалидных полей без значений. Тело ответа не меняется.
В completion-строке HTTP указывается userId, если он есть в res.locals.
В NODE_ENV=development вывод форматируется pino-pretty с цветом уровней. В production пакет не загружается, production-зависимостей не добавляется.
Route для 404 остаётся <unmatched> (защита от кардинальности).
Тесты: HTTP-уровень для фильтра (500 пишет error с полями, ответ не изменён), отсутствие значений в полях 4xx, unit для completion/userId.
Вне scope
Полные тела запросов и ответов (требует нового ADR).
Сбор, хранение и alerting логов.
## Контекст
Неожиданные 5xx не логируются: `HttpExceptionFilter` (`@Catch()`) превращает любое исключение в ответ 500 и не передаёт ошибку в логгер, поэтому pino-http видит только статус. В dev вывод — сырой JSON без цвета (`pino-pretty` не подключён). Полные тела запросов и ответов не логируются намеренно (ADR 008, `backend/.ai/conventions/observability.md`) и вне scope этой задачи.
## Acceptance Criteria
1. Неожиданная ошибка (не `HttpException`) логируется через `StructuredLogger.event('error', ...)` с полями `code`, `name` и stack. Поле `message` не пишется. Публичный ответ problem+json не меняется.
2. Для 4xx validation-ошибок в лог попадают имена невалидных полей без значений. Тело ответа не меняется.
3. В completion-строке HTTP указывается `userId`, если он есть в `res.locals`.
4. В `NODE_ENV=development` вывод форматируется `pino-pretty` с цветом уровней. В production пакет не загружается, production-зависимостей не добавляется.
5. Route для 404 остаётся `<unmatched>` (защита от кардинальности).
6. Тесты: HTTP-уровень для фильтра (500 пишет error с полями, ответ не изменён), отсутствие значений в полях 4xx, unit для completion/`userId`.
## Вне scope
- Полные тела запросов и ответов (требует нового ADR).
- Сбор, хранение и alerting логов.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Контекст
Неожиданные 5xx не логируются:
HttpExceptionFilter(@Catch()) превращает любое исключение в ответ 500 и не передаёт ошибку в логгер, поэтому pino-http видит только статус. В dev вывод — сырой JSON без цвета (pino-prettyне подключён). Полные тела запросов и ответов не логируются намеренно (ADR 008,backend/.ai/conventions/observability.md) и вне scope этой задачи.Acceptance Criteria
HttpException) логируется черезStructuredLogger.event('error', ...)с полямиcode,nameи stack. Полеmessageне пишется. Публичный ответ problem+json не меняется.userId, если он есть вres.locals.NODE_ENV=developmentвывод форматируетсяpino-prettyс цветом уровней. В production пакет не загружается, production-зависимостей не добавляется.<unmatched>(защита от кардинальности).userId.Вне scope