# Агент: Конвертер выписок (PDF/XLSX → JSON 1.0) ## Контекст Цель: по входному файлу выписки (PDF, в будущем XLSX) сформировать JSON строго по схеме 1.0, описанной в `docs/backlog/format.md`, для дальнейшего импорта в SPA через backend-эндпоинт. Формат JSON 1.0: - `schemaVersion = "1.0"` - `bank = "VTB"` (на старте) - `statement`: - `accountNumber: string` - `currency: string` - `openingBalance: integer` (копейки) - `closingBalance: integer` (копейки) - `exportedAt: string` (ISO 8601 + TZ) - `transactions[]`: - `operationAt: string` (ISO 8601 + TZ) - `amountSigned: integer` (копейки, >0 приход, <0 расход) - `commission: integer` (копейки) - `description: string` ## Задачи агента 1 Конвертация PDF → сырые строки - Использовать доступный инструмент (локальный ИИ/LLM API или библиотеку), чтобы преобразовать PDF-выписку в структурированный текст/табличное представление: - заголовочная часть (счёт, валюта, баланс на начало/конец, дата выгрузки), - таблица операций (дата/время, сумма, комиссия, описание и т.п.). - Корректно обрабатывать переносы строк в описании операции. 2 Маппинг полей в JSON 1.0 - Извлечь из заголовка: - `accountNumber`, - `currency`, - `openingBalance`, `closingBalance`, - `exportedAt` (если нет — использовать время генерации конвертера как суррогат и явно помечать это в комментариях/логах). - Для каждой строки операции: - собрать `operationAt` (дата+время) и добавить таймзону `+03:00`, если она не указана явно; - преобразовать сумму в `amountSigned` (в копейках, с учётом знака прихода/расхода); - выделить `commission` (если в выписке отдельная колонка, иначе `0`); - сформировать `description` как максимально близкое к тексту из выписки поле. 3 Нормализация сумм - Все суммы, которые приходят в формате `12345.67`, должны быть преобразованы в целое число копеек: - `12345.67 → 1234567`. - Важно избегать ошибок округления (использовать работу со строками, а не float). 4 Проверка целостности (по возможности) - При наличии `openingBalance` и `closingBalance`: - проверить, что `openingBalance + Σ(amountSigned) == closingBalance` (с допустимой погрешностью, если есть комиссии/особые операции); - если проверка не проходит, вернуть предупреждение вместе с JSON (или отдельный отчёт). 5 Выходной результат - Агент должен возвращать один JSON-объект строго по схеме 1.0. - Дополнительно может возвращаться диагностическая информация (лог), но она должна быть отделена от финального JSON. ## Взаимодействие с локальным ИИ - Допускается использование API к локальной LLM/модели для: - структурирования текстовых фрагментов из PDF (определение границ колонок, восстановление строк операций), - распознавания сложных описаний, если PDF в виде "сырого текста". - Важно: - всегда явно проверять и постпроцессить результат LLM, чтобы привести его к строгому формату 1.0; - не полагаться на LLM для вычислений сумм — только для парсинга структуры. ## Ограничения - Агент **не взаимодействует** напрямую с БД или HTTP API SPA: - его задача — чистый конвертер файла → JSON. - Нельзя менять схему JSON 1.0 без обновления `docs/backlog/format.md`. - Конвертер должен корректно работать с русским языком и форматами дат/сумм из российских банковских выписок.