## Context API комментариев к документу готов (spec `documents-api`, «Комментарии к документу»; design D-11 Среза 3b): `GET /documents/{id}/comments` → `[{id, text, author: {id, full_name}, created_at}]` по возрастанию `created_at` (`DOCUMENT_VIEW`), `POST …/comments {text}` 1–4000 символов после обрезки (`DOCUMENT_EDIT`) → 201 + комментарий; `comments_count` — в `DocumentBrief` (карточка файла, панель) и `DocumentOut` (экран документа). Правки и удаления нет. Во фронте сейчас: `CommentModal` (экран документа, только добавление) и `postComment` в `FilesDrawer` (причина замены документа). Макет: [39-01] — иконка комментария в строке панели, поповер «Комментарий к документу <файл>» («Комментарий отсутствует», «Закрыть»); [41] — кнопка «Добавить комментарий» в шапке, места под список нет. ## Goals / Non-Goals Goals: комментарий виден после добавления и после перезагрузки; счётчик в панели совпадает с числом комментариев; причина замены видна в комментариях заменённого документа. Non-goals — в proposal. ## Decisions ### D-1. Экран документа: кнопка «Комментарии (N)» + боковая панель Кнопка на месте «Добавить комментарий» (иконка `CommentOutlined`, текст «Комментарии (N)», `N = doc.comments_count`). Клик открывает antd `Drawer` справа «Комментарии к документу»: список комментариев, под ним поле ввода (до 4000 символов, счётчик символов) и кнопка «Добавить» (неактивна при пустом тексте после обрезки). Список запрашивается при каждом открытии панели. После успешного добавления: поле очищается, список перечитывается, экран документа перечитывает `GET /documents/{id}` (счётчик на кнопке). Ошибка добавления — `message.error` с текстом сервера, текст в поле сохраняется. Ошибка загрузки списка — текст «Не удалось загрузить комментарии» вместо списка. Почему не список под формой: экран [41] занят сканом и формой по высоте окна, блок комментариев отнимал бы место у формы; боковая панель не меняет раскладку [41]. Вариант предложен агентом и принят владельцем в чате 27.10.2026. ### D-2. Панель «Первичные документы»: кнопка счётчика + поповер только для чтения В колонке действий строки документа (`documentId != null`) перед «Удалить» — кнопка с `CommentOutlined` и числом `comments_count` (при нуле — только иконка; `aria-label` «Комментарии: N»). Клик — antd `Popover` (trigger click) с заголовком «Комментарии к документу <имя файла>»: список комментариев (запрос при открытии) или «Комментарий отсутствует»; кнопка «Закрыть». Клики внутри поповера и по кнопке не всплывают к `onClick` строки (иначе открывается документ) — тот же приём, что в `FileWarningsPopover`. У строки файла без документов кнопки нет. ### D-3. Общий список `CommentsList` Один компонент для D-1 и D-2: на каждый комментарий — ФИО автора (жирным), дата и время по Москве (`formatMoscowDateTime`, «dd.mm.yyyy hh:mm»), текст с сохранением переносов строк (`white-space: pre-wrap`, `overflow-wrap: anywhere`). Состояния: загрузка (`Spin`), ошибка, пусто (текст пустоты задаёт вызывающий: «Комментариев нет» в D-1, «Комментарий отсутствует» в D-2 — как в макете), список. ### D-4. Счётчик в строке панели — поле `DocumentRow.commentsCount` `buildDocumentRows` переносит `comments_count` документа (ядро без поля — 0); строка файла без документов — 0. Панель после замены документа уже перечитывает список файлов (`reload`), поэтому счётчик заменённого документа обновляется без доработок. ### D-5. `CommentModal` удаляется Добавление переезжает в панель D-1; второе место добавления на экране не нужно. ## Risks / Trade-offs - Тестов компонентов в `web/` нет: покрыты чистые функции (`formatMoscowDateTime`, `buildDocumentRows`), экраны проверяются вручную по сценариям спеки и сверкой с [39-01], [41]. - Поповер в узкой панели: ширина ограничена 420 px, высота — 320 px с прокруткой (как `FileWarningsPopover`). ## Decisions made without discussion | Дата | Решение | Обоснование | Цена ошибки | |---|---|---|---| | 27.10.2026 | R-1: в поповере панели — только чтение, добавление только на экране документа | макет [39-01] показывает поповер без поля ввода; одно место добавления проще | добавить поле в поповер — небольшая правка | | 27.10.2026 | R-2: при нуле комментариев в панели — иконка без числа | макет [39-01] показывает только иконку; «0» шумит в каждой строке | косметика | | 27.10.2026 | R-3: формат времени «dd.mm.yyyy hh:mm» по Москве | даты в панели уже по Москве (`formatMoscowDate`), бэкенд считает даты по Москве | косметика | | 27.10.2026 | R-4: кнопку «Добавить» не прячем без права `DOCUMENT_EDIT`, отказ 403 — сообщением | так работал `CommentModal`; доступ решает сервер (`auth/permissions.ts` — только для меню) | пользователь без права видит кнопку и получает отказ | | 27.10.2026 | R-5: при перечитывании списка после добавления прежний список остаётся на экране до ответа | без мигания индикатора загрузки после «Добавить» | косметика | | 27.10.2026 | R-6: `Drawer size={420}` вместо `width` | antd 6 помечает `width` устаревшим; так же сделано в `FilesDrawer` | нет | | 27.10.2026 | R-7: отступ между полем ввода и «Добавить» — 28 px | счётчик символов `showCount` antd рисуется под полем и наезжал на кнопку (сверка в браузере) | косметика; при смене antd может съехать | | 27.10.2026 | R-8: кнопки строки панели прижаты вправо | кнопка с числом шире пустой, «Удалить» съезжала из столбца | косметика | | 27.10.2026 | R-9: проверка в браузере на копии БД `armka_1683` (alembic 0010), API из worktree с `NATS_ENABLED=false` | общий локальный стенд на 0007, не трогаем | копию удалить при закрытии | | 27.10.2026 | R-10: сценарий спеки «Причина замены документа» в браузере не прогнан | замена требует распознавания (NATS выключен); путь тот же — `postComment` к заменяемому документу + перечитывание панели, список — тот же `GET` | проверить на нашем стенде при выкладке | | 27.10.2026 | R-11: защита от всплытия клика к строке таблицы — обёртка со `stopPropagation` вокруг всего `Popover` (финальное ревью I-1); тот же дефект исправлен и в `FileWarningsPopover` | заголовок, отступы и стрелка поповера antd лежат вне `content`, клик по ним открывал документ; у `FileWarningsPopover` дефект был до ветки, приём тот же | нет | | 27.10.2026 | R-12: `key={doc.id}` на боковой панели экрана документа (финальное ревью I-2, M-2) | `DocumentPage` не пересоздаётся при смене документа — черновик и список прежнего документа переходили на новый, а удалить комментарий нельзя | нет |