Files
contracts/History/opus-plan-groups-progress.md
T

7.7 KiB
Raw Blame History

Запрос для Opus — План: группировка, прогресс, промежуточные результаты

Что сказал заказчик (дословно)

Не распознано (8 файлов) [supplement] допник-1-XXX002-01200_3.docx ... — нет базового договора №01219_3 ... зачем нам базовый договор? Вся информация есть в допниках и спеках

Было бы хорошо пояснить или показать процесс, что в каком порядке происходит. Так видно только текущую операцию

наверно я захочу иметь возможность посмотреть любые промежуточные результаты

Что нужно

Заказчик хочет три улучшения (без фанатизма, главное — устойчивость и понятный UI):

#1 — Группировка без базовых договоров

Проблема: сейчас group_documents() требует contract-файл как якорь группы. Без него допники/спеки попадают в unresolved с текстом «нет базового договора №X». Заказчик: «зачем нам базовый договор? Вся информация есть в допниках и спеках».

Нужно: группировать документы по parent_number / own_number, даже если contract-файл отсутствует в загрузке. Создавать «виртуальную» группу без contract-файла.

Вопросы:

  1. Алгоритм: что приоритетнее — parent_number от допника или own_number от спеки? Если оба ссылаются на один нормализованный номер — это одна группа?
  2. Если два допника с одним parent_number, но разными counterparty — одна группа или разные?
  3. Как назвать группу без contract-файла: "№01300_2 — ЗАО XXX003" из данных классификации? Достаточно?
  4. Минимальный diff в group_documents() — чтобы не сломать текущую логику с contract-файлами?

#2 — Прогресс пайплайна

Проблема: юзер видит только статус текущей операции. Непонятно что уже сделано, что предстоит.

Нужно: визуальная шкала этапов с иконками статуса.

Вопросы:

  1. Достаточно 4 этапов: Загрузка → Классификация → Группировка → Сравнение? (Парсинг — подэтап загрузки, не показывать отдельно)
  2. Где разместить: в топбаре (всегда видно, не скроллится) или в карточке с результатами?
  3. При переклассификации после удаления/добавления файла — сбрасывать всю шкалу или только затрагиваемые этапы?

#3 — Промежуточные результаты

Проблема: юзер хочет видеть что LLM вернула на каждом шаге: сырой ответ, как определился номер/тип/дата.

Нужно: раскрывающийся блок с деталями для каждого файла.

Вопросы:

  1. Что хранить: сырой ответ LLM + распарсенный JSON? Достаточно двух новых полей в documents?
  2. Где показывать: раскрывающийся блок под строкой файла в таблице? Или модалка при клике на статус?
  3. Нужно ли для сравнения (process-v2 SSE) или только для классификации?

#4 — Общие ограничения

Что из трёх самое трудозатратное и что можно упростить без потери юзабилити?


Релевантные файлы (читать)

Группировка (#1)

  • contractor/deploy/services/grouping.pygroup_documents(), normalize_number(), apply_groups()
  • contractor/deploy/db/documents.py — поля doc_type, own_number, parent_number, counterparty, classify_status
  • contractor/deploy/db/contracts.pyinsert(), поля number, client
  • contractor/deploy/db/supplements.pyinsert(), list_by_contract()

Прогресс-бар (#2) + Промежуточные результаты (#3)

  • contractor/index.cfm — HTML-оболочка, топбар (.topbar, position: sticky), карточки, модалки
  • contractor/deploy/app.js — весь фронтенд: загрузка, runClassify(), loadGroups(), runCompareForGroup(), showClassifyBtn(), рендеринг таблицы и групп
  • contractor/deploy/app_utils.js — утилиты: removeFile(), renderTable()
  • contractor/deploy/convert_server.py — роутер (do_GET, do_POST, do_DELETE), SSE (_handle_process_v2), эндпоинты /api/classify-batch, /api/groups, /api/batch-progress, /api/sync

Общий контекст

  • contractor/deploy/services/classify.pyclassify_batch(), _smart_extract(), _call_llm_classify(), _safe_json_parse()
  • contractor/deploy/services/process.pyrun_pipeline() (SSE для сравнения: extract/diff)
  • contractor/deploy/services/grouping.pygroup_documents(), apply_groups()
  • contractor/deploy/llm_prompt.pybuild_prompt(), build_classify_prompt()
  • contractor/deploy/db/connection.pyquery(), execute(), execute_returning()

Игнорировать (не относится к делу)

  • contracts-app/ — старый Python-бэкенд (Flask), не используется
  • contracts-vm/ — старые конфиги ВМ
  • DOC/, FILES/ — документация, заметки
  • dogovora/ — тестовые файлы договоров
  • history/, History/ — старые сессионные заметки (кроме этого файла)
  • contractor/*.cfm кроме index.cfm — старый Lucee-код, не используется
  • contractor/deploy/nginx-contracts.conf — конфиг nginx
  • contractor/deploy/convert_doc.py — конвертер .doc → .docx
  • contractor/deploy/sync.sh — скрипт деплоя
  • contractor/upload.cfm, contractor/process.cfm, contractor/parser.cfm и т.д. — старый Lucee-код

Архитектура (кратко)

  • Фронт: index.cfm (Lucee, только HTML-оболочка) → грузит app.js + app_utils.js с ВМ (https://contracts.kube5s.ru/static/)
  • Бэкенд: Python 3.12 http.server + ThreadingMixIn на ВМ (5.172.178.213), порт 8766, systemd-сервис contracts
  • Все endpoint'ы: в convert_server.py (один файл-роутер, ~400 строк)
  • БД: PostgreSQL 16, прямой доступ через psycopg2, connection pool
  • Таблицы: documents, supplements, contracts, spec_events, spec_current, prompts
  • LLM: gpt-oss-120b через api.aillm.ru, httpx с http2, temperature=0.1, max_tokens=8000