162 lines
5.8 KiB
Markdown
162 lines
5.8 KiB
Markdown
# Архитектура Contracts App
|
|
|
|
## Обзор
|
|
|
|
Сервис **Сверка договоров** — автоматизированная обработка договоров и допников (docx/pdf)
|
|
с извлечением структурированных данных, отслеживанием изменений и восстановлением
|
|
истории договора во времени.
|
|
|
|
## Принципы
|
|
|
|
1. **НЕ МОНОЛИТ** — каждый слой независим, отдельный файл, своя зона ответственности
|
|
2. **Данные не покидают облако** — всё в PostgreSQL внутри кластера
|
|
3. **Ничего не терять** — парсер отдаёт полный слепок документа, LLM решает что важно
|
|
4. **Исключения — не фантазировать** — нерешаемые подзадачи отмечать явно
|
|
|
|
---
|
|
|
|
## Слои приложения
|
|
|
|
```
|
|
┌─────────────────────────────────────────────┐
|
|
│ app.py │
|
|
│ ContractsApp (сборка) │
|
|
├──────────┬──────────┬──────────┬────────────┤
|
|
│ db.py │ parser.py│ test_ │ (будущие) │
|
|
│ (БД) │ (парсинг)│ routes.py │ llm.py │
|
|
│ │ │ (/test) │ upload.py│
|
|
└──────────┴──────────┴──────────┴────────────┘
|
|
```
|
|
|
|
| Слой | Файл | Что делает | Статус |
|
|
|---|---|---|---|
|
|
| Ядро | `app.py` | Flask-приложение, инициализация, регистрация Blueprint | ✅ |
|
|
| БД | `db.py` | `connect()`, `query()`, `_pg_connect()` | ✅ |
|
|
| Тесты | `test_routes.py` | Blueprint `/test` — мост к БД извне | ✅ |
|
|
| Парсер | `parser.py` | `parse(bytes, mime) → elements` для docx/pdf/doc/zip | ✅ |
|
|
| LLM | `llm.py` | Нормализация строк через aillm.ru (120B) | ⬜ |
|
|
| Загрузка | `upload.py` | Приём файлов, сохранение в БД | ⬜ |
|
|
|
|
---
|
|
|
|
## Поток обработки документа
|
|
|
|
```
|
|
Пользователь
|
|
│
|
|
▼
|
|
POST /upload (файл .docx/.pdf/.doc/.zip)
|
|
│
|
|
▼
|
|
upload.py: сохранить в contract_docs (original_bytes)
|
|
│
|
|
▼
|
|
parser.py: parse(bytes, mime) → elements JSON
|
|
│
|
|
▼
|
|
db.py: сохранить parsed_json в contract_docs
|
|
│
|
|
▼
|
|
llm.py: отправить elements → LLM → нормализованные spec_rows
|
|
│
|
|
▼
|
|
db.py: сохранить в spec_rows, сравнить с предыдущими → spec_history
|
|
│
|
|
▼
|
|
GET /contract/{id}/history → полная история изменений
|
|
```
|
|
|
|
---
|
|
|
|
## Схема БД (план)
|
|
|
|
```
|
|
contract_docs — исходные файлы + сырой парсинг
|
|
id UUID PK
|
|
contract_id → contracts.id
|
|
filename TEXT
|
|
mime_type TEXT
|
|
original_bytes BYTEA ← сам файл
|
|
parsed_json JSONB ← выдача parser.py
|
|
created_at TIMESTAMPTZ
|
|
|
|
contracts — договоры
|
|
id UUID PK
|
|
number TEXT ← номер договора
|
|
client TEXT ← клиент
|
|
date DATE
|
|
status TEXT
|
|
|
|
supplements — допники
|
|
id UUID PK
|
|
contract_id → contracts.id
|
|
number TEXT
|
|
date DATE
|
|
type TEXT ← новый / изменение / расторжение
|
|
doc_id → contract_docs.id
|
|
|
|
spec_rows — строки спецификаций
|
|
id UUID PK
|
|
supplement_id → supplements.id
|
|
row_num INT
|
|
name TEXT ← наименование услуги
|
|
price NUMERIC
|
|
qty NUMERIC
|
|
sum NUMERIC
|
|
date_start DATE
|
|
date_end DATE
|
|
|
|
spec_history — история изменений
|
|
id UUID PK
|
|
spec_row_id → spec_rows.id
|
|
supplement_id → supplements.id
|
|
change_type TEXT ← added / changed / deleted / unchanged
|
|
old_values JSONB
|
|
new_values JSONB
|
|
```
|
|
|
|
---
|
|
|
|
## API эндпоинты
|
|
|
|
| Метод | Путь | Слой | Что |
|
|
|---|---|---|---|
|
|
| GET | `/` | app.py | Главная (HTML) |
|
|
| GET | `/health` | app.py | Health check → "OK" |
|
|
| GET | `/test` | test_routes | Статус БД + список команд |
|
|
| POST | `/test` `{"action":"status"}` | test_routes | Статус БД |
|
|
| POST | `/test` `{"action":"createdb"}` | test_routes | Создать БД contracts |
|
|
| POST | `/test` `{"action":"tables"}` | test_routes | Список таблиц |
|
|
| POST | `/test` `{"action":"sql","sql":"..."}` | test_routes | Произвольный SQL |
|
|
|
|
---
|
|
|
|
## Технологии
|
|
|
|
| Компонент | Выбор |
|
|
|---|---|
|
|
| Язык | Python 3.12 |
|
|
| Фреймворк | Flask |
|
|
| БД | PostgreSQL (внутрикластерный) |
|
|
| Парсинг docx | python-docx |
|
|
| Парсинг .doc | LibreOffice (headless) |
|
|
| Парсинг PDF | pdfplumber |
|
|
| LLM | aillm.ru API (120B модель) |
|
|
| Деплой | pythonk8s.services.ngcloud.ru |
|
|
| Репозиторий | gitea.services.ngcloud.ru/Nail/contracts-app.git |
|
|
|
|
---
|
|
|
|
## Конфигурация (переменные окружения)
|
|
|
|
| Переменная | Назначение |
|
|
|---|---|
|
|
| `DB_HOST` | Хост PostgreSQL |
|
|
| `DB_PORT` | Порт (5432) |
|
|
| `DB_NAME` | Имя БД (contracts) |
|
|
| `DB_USER` | Пользователь |
|
|
| `DB_PASS` | Пароль |
|
|
| `DB_SSLMODE` | SSL mode (disable) |
|
|
| `LLM_API_KEY` | Ключ aillm.ru (будет) |
|
|
| `LLM_API_URL` | URL LLM API (будет) |
|