26 KiB
document-review-ui Specification
Purpose
Аналитик проверяет распознанный документ и подтверждает его: форма ББ/ОФР рядом со сканом PDF (правка значений и шапки, проверки и их акцепт) [41]/[41-02], ОСВ-документ — таблицей строк в порядке файла (как в 1С) только для чтения.
Requirements
Requirement: Экран документа
Маршрут /documents/:document_id SHALL загрузить GET /documents/{id} и показать вид по document_type: BALANCE и
INCOME — проверка формы, OSV — просмотр ОСВ; для прочих типов — карточку документа без данных. Шапка экрана SHALL
показывать тип, ЮЛ-владельца, период и статус документа, кнопку «Назад».
Scenario: Открытие формы баланса
- WHEN аналитик открывает документ
BALANCE - THEN показан экран проверки формы
Requirement: Скан рядом с формой
Для ББ/ОФР экран SHALL показывать исходный файл документа: PDF — постранично через pdf.js из байт
GET /files/{file_id}/content?disposition=inline, полученных клиентом API с токеном (не через <iframe> и не прямой
ссылкой); изображение (png/jpg) — тегом <img> из blob; xlsx — без превью, с кнопкой «Скачать исходник».
Scenario: PDF под CSP sandbox
- WHEN сервер отдаёт PDF с
Content-Security-Policy: sandbox - THEN страницы PDF отрисованы на canvas и листаются
Requirement: Форма ББ/ОФР — просмотр и правка
Экран SHALL показывать GET /documents/{id}/statement: шапку (ИНН, дата отчёта, единицы — значение и исходное при
правке; наименование, ОКУД/ОКПО) и таблицу «строка (код, наименование) × колонки» с суммами из values[], включая
строки и ячейки, достроенные сервером по справочнику редакции (id = null). Ячейки с needs_review = true SHALL
подсвечиваться как «требует внимания» (подсветки напрямую по confidence < 100 или is_recognized = false нет), с
is_modified = true — как «исправлено» с исходным значением original_amount в подсказке; пустая достроенная ячейка не
подсвечивается. Строки «БАЛАНС» формы BALANCE (коды 1600 и 1700) SHALL выделяться фоном #f9f0ff и жирным шрифтом;
подсветка ячейки перекрывает фон строки. Единицы (header.units) SHALL выводиться над таблицей. Пока документ не
CONFIRMED, ячейка SHALL быть редактируемой: ввод проверяется по формату суммы (до 2 знаков после точки, знак минус
допустим, пустое — null), сохранение отправляет PATCH /documents/{id}/statement {values: [...]} суммой-строкой:
ячейка строки из БД — {line_id, column_id, amount}, ячейка достроенной строки (id = null) — {line_code, column_id, amount}; ответ заменяет состояние экрана. Правка шапки (ИНН, дата отчёта, единицы, наименование
организации) SHALL отправляться тем же PATCH в header; inn: null не отправляется. Правка строк, колонок и
подтверждений в том же PATCH (columns, lines, values[].confirmed) описана в требовании «Правка строк, колонок и
подтверждение в режиме «Редактировать»».
Scenario: Исправление ячейки
- WHEN аналитик меняет значение ячейки и сохраняет
- THEN ячейка помечена «исправлено», проверки пересчитаны по ответу сервера, акцепт снят
Scenario: Заполнение строки, которой не было в распознавании
- WHEN у формы нет строки 1700 из источника, аналитик вводит сумму в достроенную строку 1700 и сохраняет
- THEN уходит
{line_code: "1700", column_id, amount}, по ответу строка получилаid, ячейка помечена «исправлено»
Scenario: Строки «БАЛАНС»
- WHEN открыта форма
BALANCE - THEN строки 1600 и 1700 выделены цветом и жирным, у ОФР выделения нет
Scenario: Неверный формат суммы
- WHEN аналитик вводит «12,3,4»
- THEN запрос не отправляется, поле показывает ошибку формата
Requirement: Проверки и их акцепт
Экран SHALL показывать checks: жёсткие (failed), мягкие (soft_failed), межформенную (cross_form) и акцепт
(accepted: кто, когда, комментарий). При непустом failed и accepted = null SHALL быть доступно «Принять с
комментарием»: комментарий 1–2000 символов → POST /documents/{id}/statement/checks/accept {comment}.
Scenario: Акцепт нарушений
- WHEN есть жёсткие нарушения и аналитик принимает их с комментарием
- THEN блок проверок показывает акцепт, нарушения остаются видимыми
Requirement: Подтверждение документа
Кнопка «Подтвердить данные» SHALL отправлять POST /documents/{id}/confirm и быть недоступна для CONFIRMED и ERROR, а
также при наличии строк unreadable / missing с суммой или нераспознанным текстом в ячейках (подсказка «Разберите
строки без кода: N» с переходом к первой такой строке). При 409 CHECKS_NOT_PASSED экран SHALL показать
detail.failures[] и предложить акцепт; при 409 PERIOD_REQUIRED — подсказать исправить дату отчёта; при 409
LINES_UNRESOLVED — показать тот же текст, что у отключённой кнопки; при 409 DUPLICATE_FORM — со ссылкой на
подтверждённую форму; прочие ошибки — message. После успеха экран SHALL перейти в режим только чтения.
Scenario: Подтверждение с неакцептованными нарушениями
- WHEN аналитик подтверждает форму с жёсткими нарушениями без акцепта
- THEN показан список нарушений из ответа и кнопка «Принять с комментарием»
Scenario: Дубль подтверждённой формы
- WHEN сервер отвечает 409
DUPLICATE_FORM - THEN экран показывает ошибку со ссылкой на уже подтверждённую форму
Requirement: ОСВ-документ
Для OSV экран SHALL показывать строки GET /documents/{id}/entries (все страницы, limit ≤ 2000) таблицей в порядке
файла, как в 1С (AURORA-1702): строки счёта, субсчетов и подразделений, у которых есть вложенные строки, — строки-группы
(жирным, со своими сальдо и оборотами), вложенные строки — с отступом по уровню в колонке аналитики. Договоры отдельными
строками не идут — их сумма в строке контрагента; субсчёт или подразделение без вложенных строк и без сумм не выводится.
Строки-показатели колонки «Показатели» и строки «Кол.», «Вал.» (§1.3 правил предметной области: group_type = OTHER,
data_type не BU/SUM и не равен виду родителя — NU, QUANTITY, CURRENCY или пусто у «ПР»/«ВР») в рублёвую таблицу
SHALL NOT попадать и родителя группой не делают: строка БУ остаётся строкой с наименованием и суммами в рублях
(AURORA-1703). Колонки: субсчёт, подразделение (если в файле есть этот уровень), аналитика (у строки счёта — её текст),
ИНН (если есть контрагенты), сальдо на начало Дт/Кт, обороты Дт/Кт, сальдо на конец Дт/Кт (суммы — строками с
разделителями разрядов, рубли), только чтение. Фильтр по счёту оставляет счёт и все его субсчета («62» — 62, 62.01,
62.02), при поиске по аналитике или ИНН строки-группы скрываются. Кнопка «Подтвердить» — как для форм.
Заголовок колонки аналитики SHALL зависеть от вида строк-листьев (структурные строки субсчёта и подразделения,
строки-группы и строки-показатели не учитываются, договоры строками не идут): только COUNTERPARTY — «Контрагент»; один другой вид — его group_name
(«Основные средства»); смесь видов или вид без group_name — «Аналитика», а перечень видов — во всплывающей подсказке
заголовка. Колонка «ИНН» и подсказка поиска «Контрагент или ИНН» SHALL показываться только при наличии контрагентов
(COUNTERPARTY); иначе колонки ИНН нет, а поиск подписан «Поиск по аналитике».
Scenario: ОСВ по основным средствам
- WHEN листья документа — аналитика с
group_name«Основные средства», контрагентов нет - THEN колонка называется «Основные средства», колонки ИНН нет, поиск подписан «Поиск по аналитике»
Scenario: Строки счёта и субсчетов
- WHEN аналитик открывает ОСВ по счёту 62 с субсчетами 62.01 и 62.02 и контрагентами под ними
- THEN в таблице жирным видны строки 62, 62.01, 62.02 с их сальдо и оборотами, контрагенты — под своим субсчётом с отступом
Scenario: ОСВ с колонкой «Показатели»
- WHEN у позиции номенклатуры счёта 41 в файле строки «БУ» и «Кол.»
- THEN в таблице строка позиции с наименованием и суммами в рублях, строки «Кол.» нет
Scenario: Подтверждение ОСВ
- WHEN аналитик подтверждает ОСВ-документ
NEEDS_CHECK - THEN документ становится «Загружен», версия, к которой он подходит, переходит в
DATA_CORRECTION
Requirement: Виртуализация таблицы ОСВ-документа
Таблица строк ОСВ-документа SHALL быть виртуализирована: в DOM находятся только видимые строки, остальные не отрисовываются. Строки по-прежнему загружаются целиком, поиск по аналитике (и ИНН) и фильтр по счёту — клиентские; серверной пагинации нет. Высота области прокрутки считается числом по высоте окна и пересчитывается при его изменении. Строка «Итого по документу» закреплена внизу и выровнена по колонкам, двухъярусная шапка и колонка «Субсчёт» закреплены, горизонтальная прокрутка сохраняется. ОСВ любого размера (десятки тысяч строк) SHALL открываться без падения вкладки.
Scenario: Большая ОСВ
- WHEN аналитик открывает ОСВ-документ на ~29 000 строк
- THEN документ открывается, число строк в DOM не зависит от размера документа, прокрутка до конца, поиск и фильтр по субсчёту работают, «Итого по документу» совпадает с суммой по всему документу
Requirement: Раскладка строк формы со статусами
Экран проверки формы ББ/ОФР ([41]) SHALL сохранять раскладку «как на бумаге» (Р-14): разделы, внутри — строки ok по
возрастанию кода, несколько строк одного кода — в порядке файла (row_index), шаблонные строки на своих местах,
пятизначные подстроки под родителем. Строка unreadable / missing SHALL стоять под ближайшей предыдущей по
row_index строкой, размещённой по коду, а без такой — в начале первого раздела; она подсвечена целиком, в ячейке
кода серым — сырой текст line_code_text с подсказкой. Строки detail SHALL быть скрыты под переключателем
«Показать расшифровки (N)» и показываться под родителем (parent_row_index) с отступом. Экран показывает справочное
имя строки (reference_name), файловое (line_name) — рядом, если отличается. Переключателя «как в файле» нет.
Scenario: Код-мусор на своём месте
- WHEN строка
unreadable«ИЧ,250» в файле стоит после строки 1240 - THEN на экране она стоит сразу под 1240, подсвечена, в ячейке кода серым «ИЧ,250»
Scenario: Расшифровки скрыты
- WHEN у формы три строки
detail - THEN по умолчанию их не видно, переключатель «Показать расшифровки (3)»; включённый показывает их под родителями
Requirement: Подсветка и предупреждения у места
Экран SHALL подсвечивать ячейки только по needs_review (в подсказке — text и уверенность), строки — по
needs_review строки, поля шапки — по needs_review_fields (в подсказке у поля — header.source.<поле>: сырой текст и
уверенность). Предупреждения и нарушения (issues, checks) SHALL показываться у места: у строк (line_ids), ячеек
(line_ids + column_id), полей шапки (field) или у документа (в том числе запись с column_index без column_id —
столбец вне колонок формы); уровень error отличается от info. Подсветки по confidence < 100 и is_recognized = false напрямую нет. У значений строк detail needs_review всегда false (Р-23): при показанных расшифровках их
сомнительные ячейки не подсвечиваются, но подсказка с text и уверенностью есть.
Scenario: Догадка подтверждена проверкой
- WHEN значение
is_recognized = false,needs_review = false - THEN ячейка не подсвечена; в подсказке сырой текст и уверенность
Requirement: Правка строк, колонок и подтверждение в режиме «Редактировать»
В режиме «Редактировать» экран SHALL давать: у unreadable / missing — поле ввода кода с подсказкой из справочника
(код → справочное имя) и пункт меню строки «Это расшифровка»; у detail — «Назначить код»; у строки ok — «Сделать
расшифровкой», смену кода и «Подтвердить код» у строки с needs_review; подтверждение ячейки без правки; ввод даты у
колонки без даты (period_kind = none) или с предупреждением о дате (в том числе подтверждение той же даты); снятие подтверждения ячейки и кода (confirmed: false); правка наименования организации в шапке; подтверждение даты отчёта из needs_review_fields без изменения (тем
же значением). «Сохранить» отправляет один PATCH …/statement (header, values, columns, lines). Кнопка «Подтвердить данные» при строках unreadable / missing с суммами
SHALL быть отключена с подсказкой «Разберите строки без кода: N» и переходом к первой такой строке; ответ сервера 409
LINES_UNRESOLVED показывается тем же текстом, 409 DUPLICATE_FORM — со ссылкой на подтверждённую форму, 409
LINE_CODE_TAKEN — у поля кода. Кнопка «Подтвердить данные» учитывает строки unreadable / missing с суммой или
нераспознанным текстом в ячейках.
Scenario: Назначить код
- WHEN аналитик вводит 1250 в ячейку кода строки
unreadableи сохраняет - THEN уходит
PATCHсlines: [{line_id, line_code: "1250"}]; после ответа строка встаёт на место 1250
Scenario: Подтверждение заблокировано
- WHEN у формы две строки
missingс суммами - THEN «Подтвердить данные» отключена, подсказка «Разберите строки без кода: 2», клик по подсказке ведёт к первой
Requirement: Предупреждения ОСВ-документа
Экран ОСВ-документа SHALL показывать предупреждения документа из DocumentOut.issues[] (коды OSV_*) блоком над
таблицей; все записи относятся к документу (строки ОСВ line_ids не адресуются); уровень error отличается от info.
Scenario: Предупреждение листа ОСВ
- WHEN у ОСВ-документа в
issuesесть запись с кодомOSV_* - THEN над таблицей показан блок предупреждений с текстом записи и уровнем
Requirement: Переключатель документа
В шапке экрана документа SHALL быть выпадающий список «Документ» с документами файлов того же ЮЛ в той же консолидации,
что и файл открытого документа (файл вне консолидации — все файлы ЮЛ): у пункта имя файла, вторая строка (тип · формат ·
дата) и статус; пункты, которые нельзя открыть, неактивны. Выбор пункта SHALL открывать /documents/:document_id
выбранного документа заменой текущей записи истории браузера, без новой записи: кнопка «Назад» экрана и браузера
возвращает на экран, с которого открыт первый документ, а не к предыдущему выбранному. Если первый документ открыт из
панели «Первичные документы» консолидации, «Назад» SHALL открывать экран консолидации с этой панелью той же организации.
Scenario: Назад после перебора документов
- WHEN аналитик открыл документ из панели «Первичные документы» организации в карточке консолидации, выбрал в списке «Документ» подряд ещё два документа и нажал «Назад»
- THEN открыт экран консолидации с той же выбранной версией и открытой панелью «Первичные документы» той же организации
Scenario: Документ открыт прямой ссылкой
- WHEN документ открыт прямой ссылкой в новой вкладке, аналитик выбрал в списке «Документ» другой документ и нажал «Назад» экрана
- THEN открыт список групп компаний
/groups
Requirement: Комментарии к документу
Экран документа SHALL показывать в шапке кнопку «Комментарии (N)», где N — comments_count документа из
GET /documents/{id}. Кнопка SHALL открывать боковую панель «Комментарии к документу» со списком
GET /documents/{id}/comments (запрос при каждом открытии) по возрастанию времени: ФИО автора, дата и время по Москве
(«dd.mm.yyyy hh:mm»), текст с переносами строк; без комментариев — «Комментариев нет»; ошибка запроса — «Не удалось
загрузить комментарии». Под списком SHALL быть поле ввода (до 4000 символов) и кнопка «Добавить», неактивная при пустом
тексте после обрезки пробелов; добавление — POST /documents/{id}/comments {text}. После успешного добавления поле
SHALL очищаться, список — перечитываться, счётчик на кнопке — обновляться из GET /documents/{id}. При ошибке
добавления SHALL показываться сообщение сервера, текст в поле сохраняется. Правки и удаления комментариев нет.
Scenario: Добавленный комментарий виден после перезагрузки
- WHEN аналитик открыл «Комментарии (0)», добавил «нет подписи руководителя» и перезагрузил страницу
- THEN на кнопке «Комментарии (1)», в панели — комментарий с его ФИО, датой и временем
Scenario: Причина замены документа
- WHEN документ заменён из панели «Первичные документы» с причиной «новая редакция от клиента»
- THEN в комментариях заменённого документа есть «Замена документа: новая редакция от клиента»
Scenario: Ошибка добавления
- WHEN сервер отклоняет добавление (403 или 422)
- THEN показано сообщение сервера, введённый текст остаётся в поле, список не меняется