Files
contracts/History/llm-analysis/opus-decoupling-request.md
T

5.1 KiB

Запрос для Opus — Рефакторинг фронтенда Contracts

Контекст

Проект: сверка договоров через LLM (colocation, ЦОД). Фронтенд — ванильный JS (app.js ~51KB + app_utils.js ~4KB). Бэкенд — Python http.server на ВМ. Фронт управляет пайплайном:

Загрузка → Парсинг → Классификация → Группировка → Сравнение

Текущая проблема

Код эволюционировал organically. Глобальные переменные (fileQueue, contractId, batchId), манипуляции с DOM через innerHTML, состояние размазано по DOM и JS-переменным. Последствия:

  • Сложно тестировать (нет изолированных юнитов)
  • Сложно отлаживать (состояние не в одном месте)
  • Баги с гонками, затиранием данных, повторными срабатываниями кнопок
  • Любое изменение ломает что-то в другом месте

Идея заказчика (НЕ догма — оцени и предложи лучшее)

Разбить на независимые функции-пайплайн:

upload(files)       → [{ id, name, parsed }]
classify(docs)      → [{ id, name, parsed, type, number, date, counterparty }]
group(classified)   → [{ contract, documents[] }]
compare(group)      → { contract, documents[], results[], expandable }
render(state)       → DOM

Каждая функция: чистые входные данные → новые выходные, не мутирует, не трогает DOM. Рендеринг — отдельно. Состояние хранится в одном месте.

Что нужно от тебя

  1. Оценить идею. Это правильный подход для ванильного JS? Или есть более подходящий паттерн (state machine, pub/sub, flux-like store)? Не изобретай велосипед — бери best practices для проектов такого масштаба (~50KB JS).

  2. Предложить архитектуру. Как организовать код чтобы:

    • Каждый этап пайплайна тестируем изолированно
    • Состояние предсказуемо и отлаживаемо (console.log одного объекта показывает всё)
    • DOM-рендеринг отделён от логики
    • Минимальные изменения в текущем коде (не переписывать с нуля)
  3. План миграции. Как перейти от текущего состояния к новому постепенно, не ломая работающий функционал.

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

  • contractor/deploy/app.js — весь фронтенд (~51KB): renderTable, runClassify, loadGroups, runCompareForGroup, buildGroupCard, markGroupDone, syncDB, stepper, toggleClassifyDetail, showText, SSE handlers
  • contractor/deploy/app_utils.js — утилиты: removeFile, escHtml, formatSize, formatDate, openAbout
  • contractor/index.cfm — HTML-оболочка, DOM-структура

Игнорировать

  • contractor/deploy/convert_server.py и все Python-файлы — бэкенд, не рефакторим
  • contractor/deploy/db/, contractor/deploy/services/ — бэкенд
  • contractor/*.cfm кроме index.cfm — старый Lucee-код
  • contracts-app/, contracts-vm/, History/, DOC/, FILES/ — не относится

Ключевые функции для анализа

Функция Строки (app.js) Что делает
renderTable 57-75 Рендер таблицы файлов
fileInput change 76-290 Загрузка + парсинг
runClassify 308-360 Классификация
loadGroups 362-430 Группировка + рендер карточек
buildGroupCard 433-442 Карточка необработанной группы
markGroupDone 444-478 Карточка обработанной группы
runCompareForGroup 483-590 Сравнение группы (apply → SSE)
toggleClassifyDetail 91-130 Раскрытие промежуточных результатов
syncDB 26-34 Синхронизация БД с таблицей
stepper 38-56 StepDone/StepActive/ResetStepper

Ограничения

  • Без фреймворков (ванильный JS)
  • Без классов и наследования (не ООП)
  • Минимум зависимостей между модулями
  • Фокус на тестируемость и отлаживаемость
  • Не переписывать с нуля — мигрировать постепенно