Files
contracts/History/architecture/pipeline.md
T

102 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Пайплайн обработки договора
## Схема
```
┌─────────────────────────────────────────────────────────────────────┐
│ 👤 ПОЛЬЗОВАТЕЛЬ │
│ Открывает / → выбирает файлы → жмёт «Обработать» │
└──────────────────────────┬──────────────────────────────────────────┘
│ multipart/form-data (files)
┌─────────────────────────────────────────────────────────────────────┐
│ app.py: _upload_page() POST │
│ Принимает файлы, запускает пайплайн │
└──────────────────────────┬──────────────────────────────────────────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
file.docx file.pdf file.zip
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ ① parser.py │
│ docx → python-docx → elements JSON │
│ pdf → pdfplumber → elements JSON │
│ doc → libreoffice → docx → python-docx │
│ zip → zipfile → каждый файл рекурсивно │
│ │
│ Выход: [{type:"paragraph", style, text}, {type:"table", rows}] │
│ НИЧЕГО не фильтрует, не теряет │
└──────────────────────────┬──────────────────────────────────────────┘
│ elements JSON
┌─────────────────────────────────────────────────────────────────────┐
│ ② textify.py │
│ elements → линейный текст │
│ │
│ [No Spacing] Приложение № 1 │
│ [Heading 3] Состав и стоимость Услуг │
│ --- Таблица (9×6) --- │
│ | № | Наименование | Цена | Объем | Сумма | Дата | │
│ | 1 | Аренда стойко-места | 213 905 | 3 | 641 716 | 01.04.2026 | │
└──────────────────────────┬──────────────────────────────────────────┘
│ текст (строка)
┌─────────────────────────────────────────────────────────────────────┐
│ ③ extractor.py + llm_client.py │
│ текст → промпт → LLM (gpt-oss-120b) → JSON │
│ │
│ Промпт: «Найди таблицы услуг, извлеки строки в JSON» │
│ Ответ: [{"row_num":1, "name":"Аренда...", "price":213905, │
│ "qty":3, "sum":641716, "date_start":"2026-04-01"}, ...] │
└──────────────────────────┬──────────────────────────────────────────┘
│ строки спецификации
┌─────────────────────────────────────────────────────────────────────┐
│ ④ differ.py │
│ Сравнение с предыдущим допником │
│ │
│ rows_old vs rows_new → changes: │
│ added: новая услуга │
│ changed: цена 213905 → 250000, дата 01.04 → 25.04 │
│ deleted: услуга убрана │
│ unchanged: без изменений │
└──────────────────────────┬──────────────────────────────────────────┘
│ изменения
┌─────────────────────────────────────────────────────────────────────┐
│ ⑤ Сохранение в PostgreSQL │
│ │
│ documents ← исходный файл + распарсенный текст │
│ contracts ← договор │
│ supplements ← допник │
│ spec_rows ← строки спецификации │
│ spec_history ← история изменений │
└──────────────────────────┬──────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ Ответ пользователю: HTML-страница с таблицей результатов │
│ «Извлечено 14 строк, добавлено 14, изменено 0, удалено 0» │
│ + полная таблица услуг с ценами │
└─────────────────────────────────────────────────────────────────────┘
```
## Кратко
```
файлы → parser → textify → LLM → differ → PostgreSQL → HTML-страница
```
## Слои
| # | Слой | Что делает |
|---|---|---|
| ① | `parser.py` | docx/pdf/doc/zip → JSON |
| ② | `textify.py` | JSON → текст |
| ③ | `extractor.py` + `llm_client.py` | текст → LLM → строки |
| ④ | `differ.py` | сравнение с предыдущим |
| ⑤ | `db.py` + `schema.py` | сохранение в БД |
| — | `app.py` | сборка, приём формы, отдача HTML |