Журнал проверок quality_analytic
Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев
Журнал проверок quality_analytic
Паспорт документа
- Статус документа: living document
- Актуально на: 28 марта 2026 года
- Владелец: backend/platform-команда
- Пересмотр: при изменении workflow агентов, формата quality review или правил append-only логирования
- Область применения: append-only журнал результатов проверок агента
quality_analyticв репозиторииqadam-core - Связанные документы:
Этот файл является обязательным журналом работы quality_analytic.
Каждый новый запуск агента должен дописывать новый блок в конец файла.
Сообщение в чат или stdout не заменяет запись в этот журнал.
Контракт записи
- Добавлять только новый блок в конец файла.
- Не переписывать и не удалять предыдущие записи.
- Если дефектов нет, всё равно добавлять запись со статусом
ПРИНЯТО. - Если область проверки неочевидна, явно писать, что проверялся текущий
git diffилиworking tree.
Формат записи
## Проверка — [дата] | [область проверки]
**Суть проверки:** [1-3 предложения о том, что проверялось и какой контекст изменения]
### Замечания
#### [КРИТИЧНОСТЬ] — [Краткий заголовок]
- **Файл:** `path/to/file.ts` (строка N)
- **Категория:** Корректность | Архитектура | Тесты | Документация | Производительность | Качество
- **Описание:** В чём проблема и почему она важна в данном контексте.
- **Направление исправления:** Какой класс решения нужен без готового кода.
### Общая оценка
[ПРИНЯТО / ТРЕБУЕТ ВНИМАНИЯ / КРИТИЧНО]
Короткий итог по состоянию изменений.
Проверка — 28 марта 2026 года | Инициализация журнала
Суть проверки: Создан явный append-only журнал для quality_analytic, чтобы результаты каждого прогона фиксировались в docs/quality_report.md, а не терялись в чате. Эта запись задаёт контракт, по которому последующие прогоны должны работать.
Замечания
ИНФО — Журнал был пуст и без контракта записи
- Файл:
docs/quality_report.md(строка 1) - Категория: Документация
- Описание: Ранее файл не содержал ни паспорта документа, ни формата записи, ни прямого требования обязательно append-ить результат каждого запуска. В такой конфигурации агент легко ограничивается текстовым ответом в чат.
- Направление исправления: Держать в файле явный append-only контракт и обязательный шаблон секции для каждого прогона.
Общая оценка
ПРИНЯТО Журнал и формат записи инициализированы; следующие прогоны должны оставлять здесь отдельные записи.
Проверка — 28 марта 2026 года | Текущий working tree: auth, buyer-role, guard quality gate
Суть проверки: Проверен текущий незакоммиченный working tree с фокусом на новый registration/password reset flow, buyer multi-role и auth guard. Дополнительно запущен pnpm test, чтобы проверить реальный статус quality gate, а не опираться только на документацию.
Замечания
КРИТИЧНО — Email reset flow выдаёт боевой reset token прямо в HTTP-ответ
- Файл:
apps/api/src/modules/auth/auth.service.ts(строка 281) - Категория: Корректность
- Описание:
forgotPassword()возвращаетtoken: tokenRecord.tokenдля обоих сценариев восстановления, а email-ветка не требует дополнительной верификации передresetPassword(). В результате любой, кто знает чужой email, может вызватьPOST /auth/forgot-password, получить reset token из ответа и сразу завершитьPOST /auth/reset-password. Это прямой account-takeover. Проблема уже фигурировала в security review и остаётся незакрытой в текущем working tree. - Направление исправления: Для email-flow наружу должен уходить только нейтральный ответ и masked identifier, а боевой reset token должен использоваться только во внешней доставке или внутри отдельно подтверждённого server-side state.
ВЫСОКИЙ — Reset token и SMS-код логируются в открытом виде
- Файл:
apps/api/src/modules/auth/auth.service.ts(строка 269) - Категория: Качество
- Описание: Stub transport пишет
resetCodeиresetTokenв структурные логи. Любой доступ к логам даёт рабочий материал для сброса пароля без контроля над email или телефоном пользователя. С учётом Pino/Axiom-контура это превращает обычный observability поток в канал утечки секретов. - Направление исправления: Убрать из логов боевые секреты полностью; допустимы только masked identifier, тип канала и технический request metadata без кода и токена.
ВЫСОКИЙ — POST /me/profile обходит ролевое ограничение на добавление buyer-роли
- Файл:
apps/api/src/modules/buyer/buyer.controller.ts(строка 66) - Категория: Архитектура
- Описание: Контроллер buyer больше не проверяет
user.type === 'BUYER', аBuyerService.createProfile()не фильтрует тип аккаунта. Из-за этого любой аутентифицированный аккаунт может создать buyer-профиль черезPOST /me/profile, хотя выделенный multi-role endpointPOST /auth/add-buyer-roleявно ограничен seller/seller_staff (apps/api/src/modules/auth/auth.controller.ts, строка 295;docs/product/requirements-api-registration.md, строка 1109). Это ломает границы ролей и позволяет обходить задуманный policy flow. - Направление исправления: Вернуть явную ролевую защиту для
/me/profileлибо централизовать создание buyer-роли в одном проверяемом сценарии и не оставлять параллельный обходной путь.
СРЕДНИЙ — Новый JwtAuthGuard одновременно маскирует доменные причины отказа и держит test gate красным
- Файл:
apps/api/src/common/guards/jwt-auth.guard.ts(строка 39) - Категория: Качество
- Описание: Guard перечитывает аккаунт через
AuthService.getMe(), ноACCOUNT_BLOCKEDиACCOUNT_UNDER_REVIEWперехватываются общимcatchи превращаются в generic401 Invalid or expired token, хотя доменный слой различает эти состояния. Параллельноpnpm testсейчас падает наapps/api/src/common/guards/jwt-auth.guard.spec.ts, потому что spec всё ещё ожидает старый синхронный контракт guard без зависимости отAuthService. В итоге ломается и API-контракт для blocked/review аккаунтов, и базовый quality gate репозитория. - Направление исправления: Пропускать доменные исключения из
getMe()без подмены на generic 401 и синхронно обновить regression tests под async-контракт guard и новую dependency model.
Общая оценка
КРИТИЧНО
Текущий working tree нельзя считать готовым к merge: password reset flow сохраняет прямой account-takeover сценарий, role boundaries для buyer размазаны, а auth guard одновременно нарушает доменный контракт и оставляет pnpm test красным.