v1.0.177: History — объединение history+History, 5 подпапок
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
# Архитектура 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 (будет) |
|
||||
Reference in New Issue
Block a user