Files
contracts/History/architecture/architecture.md
T

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 (будет) |