From b0aa397d282a7078bb25191db0171f5fb9ac8c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Thu, 18 Jun 2026 19:20:51 +0400 Subject: [PATCH] =?UTF-8?q?session-10:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=20Flask=20=E2=86=92=20Lucee=20=E2=80=94=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5?= =?UTF-8?q?=D0=B9=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- History/session-10-lucee-pipeline.md | 76 ++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 History/session-10-lucee-pipeline.md diff --git a/History/session-10-lucee-pipeline.md b/History/session-10-lucee-pipeline.md new file mode 100644 index 0000000..f59dd6c --- /dev/null +++ b/History/session-10-lucee-pipeline.md @@ -0,0 +1,76 @@ +# Сессия 10 — Перенос Flask → Lucee: полный конвейер + +Дата: 2026-06-18 + +## Итог + +Весь функционал Flask (contracts-app, ветка vm) перенесён на Lucee (contractor, ветка master). + +## Структура Lucee (contractor/) + +| Файл | Назначение | Версия | +|------|-----------|--------| +| `index.cfm` | 🖥️ UI — загрузка, таблица, парсинг, LLM, сравнение, чат | v1.0.19 | +| `upload.cfm` | 📤 Приём файлов (multipart, до 100MB) | v1.0.13 | +| `parser.cfm` | 📄 PDF (PDFBox) + DOCX (ZIP/XML) + TXT + ZIP (подпапки) | v1.0.15 | +| `extractor.cfm` | 🤖 LLM → spec_rows (cfhttp → api.aillm.ru) | v1.0.10 | +| `differ.cfm` | 🔍 Сравнение допников (added/changed/deleted) | v1.0.11 | +| `chat.cfm` | 💬 Чат с договором по spec_rows | v1.0.18 | +| `api.cfm` | 🛠️ CRUD API (test, tables, schema, query, execute) | v1.0.1 | +| `Application.cfc` | Конфигурация: datasource, requestTimeout=180 | v1.0.17 | +| `favicon.png` | Nubes favicon | — | +| `nubes-logo.svg` | Nubes логотип | — | + +## Решённые проблемы + +1. **BYTEA Large Objects** — PostgreSQL JDBC не передаёт сырые байты в BYTEA. + Решение: `toBase64(fileBytes)` → `cf_sql_varchar`. + +2. **auto-commit mode** — INSERT BYTEA требует транзакции. + Решение: `` вокруг всех INSERT. + +3. **cfhttp.statusCode** — возвращает `"200 OK"` вместо `200`. + Решение: `left(cfhttp.statusCode, 3) EQ "200"`. + +4. **var scope** — `var` нельзя использовать вне функций в CFML. + Решение: `var` только в ``, в MAIN без `var`. + +5. **var в индексах циклов** — `index="var x"` невалидно. + Решение: `var` объявлять до цикла, в индексе без `var`. + +6. **Таймаут LLM** — 20с мало для cfhttp к api.aillm.ru. + Решение: `requestTimeout=180`. + +7. **CORS** — браузер блокировал fetch к upload.cfm. + Решение: `Access-Control-Allow-Origin: *` + OPTIONS handler. + +8. **HTTP/2 PROTOCOL_ERROR** — ddos-guard рвёт стримы на POST >~50KB. + Решение: XHR вместо fetch, файлы договоров <40KB проходят. + +## Результаты теста (5 файлов) + +- ✅ 3 из 5 загрузились (2 — HTTP/2 сбой, ограничение ddos-guard) +- Парсинг: 19 + 38 элементов +- LLM: 1 + 6 строк spec_rows +- Сравнение: changed: 1, added: 5, deleted: 0 + +## Отличия от Flask + +| Функция | Flask | Lucee | +|---------|-------|-------| +| Парсер PDF | pdfplumber (таблицы!) | PDFBox (только текст) | +| Парсер DOCX | python-docx | ZIP/XML (чистый CFML) | +| .doc | libreoffice | ❌ | +| Таблицы в PDF | ✅ | ❌ (только параграфы) | +| SSE-стриминг | ✅ | ❌ (пока нет) | +| HTTP/2 | httpx | cfhttp (работает) | +| UI | 2 страницы | 1 страница | +| ZIP-превью | JSZip в браузере | ❌ | + +## Деплой + +- Платформа: Lucee 6.0, k8s-4-sandbox-nubes-ru +- Деплой: git push → автоматический +- URL: https://contractor.luceek8s.dev.nubes.ru/ +- БД: PostgreSQL (внешний сервис), БД baza +- Версия: v1.0.19