Files
contracts-flask/History/opus-decoupling-plan-2026-06-28.md

170 lines
8.2 KiB
Markdown

# Задание Opus 4.8: План decoupling пайплайна contracts-flask
Дата: 28.06.2026 | Режим: **plan (интерактивный)**
---
## ⛔ ЧЕГО НЕ ДЕЛАТЬ
- **НЕ пиши код.** Анализ и план. Исполнитель — DeepSeek V4 Pro.
- **НЕ рисуй mermaid.** Только текст.
- **НЕ предлагай «переписать всё с нуля».**
## 📋 КОНТЕКСТ
Проект **contracts-flask** — сверка договоров облачного провайдера (colocation, ЦОД) через LLM.
### Текущая архитектура:
```
Браузер
check.kube5s.ru (nginx)
├── Страницы/статика → Managed Flask (contractor.pythonk8s...)
└── API → ВМ :8777 (convert_server.py)
├── services/parse.py — PDF (pdfplumber) / DOCX (python-docx)
├── services/upload.py — multipart-загрузка → БД
├── services/classify.py — LLM-классификация (тип/номер/дата/контрагент)
├── services/grouping.py — группировка по контрактам
├── services/process.py — сравнение (LLM + event sourcing)
├── services/llm.py — вызов LLM API
├── services/metrics.py — арифметика + JSON-фиксы
├── db/ — PostgreSQL CRUD
└── llm_prompt.py — промпты (из БД, не Lucee)
```
### Пайплайн (последовательно):
```
1. Upload → parse.py → elements_json
2. Classify → classify.py → doc_type, own_number, parent_number, counterparty, doc_date
3. Grouping → grouping.py → группы по contract_number
4. Compare → process.py → SSE: ops (ADD/UPDATE/DELETE/UNRESOLVED)
5. Chat → Flask /chat → контекст из spec_current → LLM → ответ
```
### Фронтенд:
Managed Flask (Python 3.12, Dockerfile):
- `site/app.py` — роуты: `/`, `/chat`, `/api/prompts/*`, `/health`
- `site/templates/index.html` — Jinja2 UI
- `site/static/*.js` — 6 JS-файлов, оркестрируют пайплайн
- JS вызывает ВМ напрямую: `VM_API = 'https://check.kube5s.ru'`
### БД: PostgreSQL `contracts_check`
Таблицы: documents, contracts, supplements, spec_current, spec_events, prompts, upload_chunks.
### LLM: gpt-oss-120b (api.aillm.ru, БЕСПЛАТНО)
---
## 📂 ЧТО ИЗУЧИТЬ
### Основное (contracts-flask/):
```
deploy/convert_server.py — HTTP-роутер, точка входа
deploy/services/parse.py — PDF/DOCX парсинг
deploy/services/upload.py — multipart-загрузка
deploy/services/classify.py — LLM-классификация + фильтр мусора
deploy/services/grouping.py — группировка
deploy/services/process.py — сравнение (SSE)
deploy/services/llm.py — LLM API
deploy/services/metrics.py — арифметика + JSON-фиксы
deploy/db/*.py — PostgreSQL CRUD (7 файлов)
deploy/llm_prompt.py — промпты
deploy/classify_worker.py — фоновый процесс
site/app.py — Flask-фронтенд
site/static/app.js — JS-оркестратор
site/static/files.js — загрузка/рендер файлов
site/static/groups.js — карточки групп
site/static/compare.js — SSE-сравнение
site/static/state.js — центральное состояние
site/templates/index.html — UI
History/architecture.md — архитектура Flask-стека
History/session-01-init-2026-06-27.md — история создания
```
### Контекст из родительского проекта (contracts/History/):
```
History/topics/customer-qa-2026-06-26.md — требования заказчика
History/llm-analysis/decoupling-final-plan.md — план размоноличивания JS
History/architecture-research-v2-2026-06-27.md — анализ DeepSeek
History/opus-architecture-research-2026-06-27.md — опросник Opus
History/opus-architecture-research-2026-06-27-review.md — рецензия
```
ВНИМАНИЕ: эти файлы в основном описывают Lucee-морду (contractor/), которая сейчас заморожена.
---
## 🎯 ЗАДАЧА
Разработать **подробный план decoupling пайплайна**:
### 1. Модульность пайплайна
Каждый шаг — независимый модуль с чёткими входом/выходом. Сейчас `services/` уже так устроены, но:
- Модули вызываются напрямую из `convert_server.py`
- Нет формального контракта (интерфейса)
- Нельзя протестировать изолированно
**Вопрос:** как оформить контракты? Dataclass? TypedDict? Proto-буферы? Просто документированные словари?
### 2. Интеграционное тестирование (fixture-based)
```
Тест upload: .docx → upload.py → elements_json (fixture)
Тест classify: fixture_elements → classify.py → doc_type/number (fixture)
Тест grouping: fixture_classify → grouping.py → группы (fixture)
Тест compare: fixture_groups → process.py → ops
```
**Вопросы:**
- Где хранить fixtures? `deploy/tests/fixtures/`?
- Как мокать LLM? Monkey-patch `_call_llm_classify` / `call_llm`?
- БД: отдельная `contracts_test` или in-memory SQLite?
- Как очищать БД между тестами?
### 3. Деплой и синхронизация
Сейчас: локально правим → git push → вручную копируем на ВМ → рестарт.
**Вопрос:** как улучшить? `rsync` из CI? `git pull` на ВМ? systemd + watchdog?
### 4. Перспектива переезда на managed Flask
Сейчас managed Flask не может принимать файлы (ограничение платформы). Когда починят — вся загрузка переедет с ВМ на managed.
**Вопрос:** что уже сейчас сделать в коде, чтобы переезд был безболезненным? Абстракция над upload? Флаги `UPLOAD_BACKEND=vm|managed`?
### 5. Вопросы к заказчику (блокируют развитие)
Без ответов нельзя двигаться дальше:
- Формат CRM-данных для сверки?
- Есть ли примеры реальных расхождений?
- Приоритет: точность vs скорость?
- Готов ли дать 30-50 реальных документов для золотого набора?
**Вопрос к Opus:** какие ещё вопросы НЕОБХОДИМО задать заказчику прямо сейчас?
---
## 🔄 ИНТЕРАКТИВНЫЙ РЕЖИМ
Ты в режиме **plan**. Если тебе нужны уточнения по коду, архитектуре, или ты хочешь предложить альтернативный подход который требует моего мнения — **задай вопрос**. Я (DeepSeek) отвечу.
Не пиши финальный план пока не закроем все неясности.
---
## ⚠️ ОГРАНИЧЕНИЯ
- Managed Flask: Python 3.12, Dockerfile, `site/` — обязательная структура
- ВМ: 5.172.178.213, Ubuntu, порт 8777
- БД: PostgreSQL 15, `contracts_check`
- LLM: gpt-oss-120b, 8000 токенов, бесплатно, ~5-30s/вызов
- JS-фронтенд: 131 тест (puppeteer-моки), все PASS