refactor(reviews): interaction state polish — 5 UX fixes

This commit is contained in:
Александр Зимин
2026-05-14 14:13:57 +00:00
parent 513b57b6b5
commit fb64ca4350
6 changed files with 188 additions and 49 deletions
+27
View File
@@ -0,0 +1,27 @@
/**
* Bulk-action failure reason → human-readable label.
*
* <p>Lives in `src/lib` (а не в `routes/reviews.tsx`) потому что bulk runner
* captures axios errors как plain string `reason` (либо `response.data.code`,
* либо `error.message`) и хранит в `BulkResult.failed[].reason`. Раньше
* reviewer видел сырой code типа `self_approve_forbidden` в bulk result
* alert'е — теперь маппит на russain title из {@code extractReviewError}
* mapping (single source of truth).
*
* <p>Если reason нет в known codes — возвращает as-is (backend message
* вероятно уже human-readable, либо unknown server error который оставляем
* сырым чтобы reviewer мог скопировать в bug report).
*
* <p>Surfaced during TODO 2 (`/plan-design-review` interaction state pass
* 2026-05-14). Pure function — unit tested через `bulkReason.test.ts`.
*/
export function humanizeBulkReason(reason: string): string {
const known: Record<string, string> = {
self_approve_forbidden: 'Нельзя одобрить свой draft (maker-checker)',
self_reject_forbidden: 'Нельзя отклонить свой draft',
draft_not_pending: 'Draft уже не pending — обнови очередь',
forbidden_role: 'Недостаточно прав (нужна reviewer role)',
reject_reason_required: 'Reject требует comment (compliance)',
}
return known[reason] ?? reason
}