Files
contracts-app/History/session-09-lucee-vm-summary.md
T

7.9 KiB
Raw Blame History

Сессия 09 — Итоги: Flask + Lucee

Дата: 2026-06-18

Общая архитектура

contracts-app/          — Flask прототип (ветка vm)
contractor/             — Lucee production (ветка master)
dogovora/               — тестовые файлы
  примеры_договоров_для_ИИ/   — 5 файлов (docx, doc)
  mix/                        — 25 PDF для тестов парсера

1. Flask прототип (contracts-app, ветка vm)

URL: https://contracts.kube5s.ru/ ВМ: 5.172.178.213, SSH ключ /.ssh/naeel_vm_id_ed25519 Деплой: rsync site/ naeel@5.172.178.213:/contracts/site/ && pm2 restart contracts БД: PostgreSQL localhost, БД contracts, пользователь super, пароль kVTjPsCTT... PM2: contracts (gunicorn, порт 5001) nginx: /etc/nginx/sites-available/contracts → contracts.kube5s.ru

Структура кода

site/
  app.py               — 65 строк, Flask + регистрация маршрутов
  routes/
    __init__.py
    main.py            — index, upload, show_contract (140 строк)
    parse.py           — SSE парсинг (160 строк)
    misc.py            — health, logs (35 строк)
    llm.py             — LLM-извлечение + сравнение + чат (200 строк)
  db.py                — PostgreSQL ThreadedConnectionPool
  schema.py            — DDL: documents, contracts, supplements, spec_rows, spec_history
  parser.py            — pdfplumber (PDF) + python-docx (DOCX) + libreoffice (.doc) + zipfile
  textify.py           — elements → текст для LLM
  extractor.py         — промпт → LLM API → structured rows
  differ.py            — сравнение строк спецификаций
  llm_client.py        — HTTP клиент к api.aillm.ru (gpt-oss-120b)
  mimeutil.py          — определение MIME по расширению
  templates/
    upload.html         — главная: загрузка + парсинг (без LLM)
    llm.html            — /llm: загрузка + парсинг + LLM + сравнение + чат

Эндпоинты

URL Метод Описание
/ GET Страница загрузки
/ POST Приём файлов (multipart)
/parse/ GET SSE парсинг
/health GET Проверка живота
/llm GET Страница LLM
/llm/process/ GET SSE: LLM-извлечение + сравнение
/llm/chat/ POST Задать вопрос по spec_rows
/llm/prompt/ GET/POST Сохранить/получить промпт

Что работает на Flask

  • Загрузка любых форматов (PDF/DOCX/DOC/ZIP), до 100MB
  • Парсинг: параграфы + таблицы, фильтр пустых/мусорных таблиц
  • LLM-извлечение строк спецификации: №, услуга, цена, объём, сумма, дата
  • Сравнение допников: added/changed/deleted с цветовой индикацией
  • Чат с договором: вопрос → LLM на основе spec_rows
  • Редактор промпта с сохранением в localStorage
  • Таймер при загрузке файлов

Результаты теста парсера PDF (25 файлов)

14 из 19 текстовых PDF — таблицы извлечены. 6 сканов — 0 элементов (нет текста). 21 из 25 проверено. Остальные 4 — большие файлы, не дождались.

Результаты LLM-извлечения (5 тестовых файлов)

  • спецификация-XXX001-03700.docx: 14 строк
  • допник-1-XXX002-01200_3.doc: 2 строки
  • допник-1-XXX003-01300_2.docx: 6 строк
  • спецификация-XXX003-01300_2.docx: 1 строка
  • спецификация-ХХХ002-01200_3.docx: 1 строка
  • Всего: 24 строки

Решённые проблемы

  1. HTTP/2 стримы — платформа managed flask рвала соединение после 2-3 запросов. Решение: перенос на ВМ с HTTP/1.1 nginx.
  2. 64KB лимит POST — на платформе нельзя загрузить файл >64KB. На ВМ — 100MB.
  3. apply(null, bytes) — падал на файлах >125KB. Решение: subarray по 32KB.
  4. Пустые таблицы PDF — фильтр: мин 2 строки, 3 колонки, 40% заполнения, мин 4 ячейки.
  5. cid из FormData не читался — request.args vs request.form.
  6. Модальное окно — заголовок скроллился, исправлен на sticky.

Ключ LLM

LLM_API_KEY=sk-ucI5YvOticoOQ9Kuj5K9mQ
LLM_API_URL=https://api.aillm.ru/v1/chat/completions
Модель: gpt-oss-120b

2. Lucee (contractor, ветка master)

URL: https://contractor.luceek8s.dev.nubes.ru/ Платформа: Lucee 6.0, k8s-4-sandbox-nubes-ru БД: PostgreSQL (внешний сервис), БД baza, пользователь super Деплой: git push → автоматический Репозиторий: https://gitea.services.ngcloud.ru/Nail/contractor.git

Структура

contractor/
  Application.cfc      — 23 строки, datasource хардкод
  index.cfm            — health: OK v1.0.1
  api.cfm              — CRUD API (?action=test|tables|schema|query|execute)
  upload.cfm           — приём файлов (cffile, v1.0.1, ждёт деплоя)
  test.cfm             — тест datasource (устарел)
  jars.cfm             — проверка PDFBox/POI (ждёт деплоя)
  db.cfc               — REST API (не используется)

Эндпоинты (v1.0.1)

URL Описание
/ OK v1.0.1
/api.cfm?action=test PostgreSQL connected
/api.cfm?action=schema Создать таблицы
/api.cfm?action=tables Список таблиц
/upload.cfm Приём файлов (ждёт деплоя)

Конфигурация Lucee (личный кабинет)

PostgreSQL (для Lucee)

  • Хост: postgresqlk8s-master.418f9960-2eb7-4429-b2ec-ac64319d7268.svc.cluster.local
  • БД: baza
  • Пользователь: super
  • Пароль: hoHdkA23yxlD9oMUlZ1bIbNyc6DE2mNJmyHMNkEpVD1F4suQs7O2lyN4t0qITyzt

Проблемы Lucee

  1. env vars — баг в ЛК: нельзя удалить/изменить. Префикс pg строчными.
  2. datasource — хардкод в Application.cfc, работает.
  3. Java библиотеки — PDFBox/POI не проверены.
  4. pg_class typo: "Drive" вместо "Driver" — не можем исправить.

3. Что дальше (на Lucee)

  • БД подключена
  • CRUD API работает
  • upload.cfm — проверить после деплоя
  • Парсер PDF/DOCX (PDFBox/POI)
  • LLM-извлечение (cfhttp → api.aillm.ru)
  • Сравнение (differ на CFML)
  • Чат
  • UI (форма загрузки)

4. Гитовые репы

Репа Ветка Назначение
contracts-app vm Flask прототип
contracts-app master Старая платформа (чанки)
contractor master Lucee production
contracts master Документы, ключи

5. Деплой Flask

rsync -az -e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no" \
  site/ naeel@5.172.178.213:~/contracts/site/
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 \
  'pm2 restart contracts'