maps: fix — репо-папки как обычные файлы (было submodule/gitlink), 45 MAP.md теперь в репо

This commit is contained in:
german
2026-07-12 20:21:49 +03:00
parent 7faebe0a06
commit 4bfad7475f
90 changed files with 2217 additions and 45 deletions
Submodule KPgenerator deleted from 28a313742c
+119
View File
@@ -0,0 +1,119 @@
# KPgenerator
## Назначение
Генератор коммерческих предложений (КП) для МПО-Информ / servaki. Реализован **не как обычное приложение, а как набор n8n-воркфлоу** (`http://192.168.1.158:5678`, доступ через finik). Репозиторий хранит **исходники Code-нод n8n** (файлы `build_*.js` / `prep_*.js`), shell-воркеры на finik, парсер прайсов и документацию.
Возможности: чат-страница для сборки КП → запись в Postgres (таблица `quotes`), HTML-рендер КП с печатью, генерация PDF (wkhtmltopdf) в MinIO, история/поиск по КП, ИИ-подбор шаблона (Ollama qwen2.5:1.5b с откатом на regex-правила), прайс-лист (`price_list`, импорт/поиск), отправка КП в Telegram (sendDocument) и голосовые комментарии (Voicebox TTS → sendVoice). Секреты вырезаны (хранятся на Я.Диске).
- **Язык:** JavaScript (тела n8n Code-нод) + Bash-воркеры + Python (парсер прайсов).
- **LOC (исходники):** ~731 (JS ≈ 542, Bash ≈ 91, Python ≈ 78). Плюс не-код артефакты: README (~500 стр.), HTML-снапшот базы знаний, дубли zip.
- **Ключевые ID:** воркфлоу «KP Dialog» `JT6mVXd7LV8Dmuog`, «Price List API» `mxPgqVNbxALGrMYx`, «KP CRUD» `kpgencrud01`; Postgres cred `kpgenpg0001`.
## Архитектура
```mermaid
graph TD
subgraph Client["Браузер / чат kp.servaki.online"]
PAGE["prep_page.js — SPA-чат + Telegram-логин"]
VIEW["build_view.js — HTML/PDF рендер КП"]
end
subgraph N8N["n8n .158 — воркфлоу KP Dialog / Price API"]
CREATE["prep_create.js — создать КП"]
HIST["prep_history.js — история/поиск"]
TPL["build_templates.js — шаблоны КП"]
AI["build_ai.js — ИИ-подбор шаблона"]
SETPDF["prep_setpdf.js — запись pdf_url"]
TG["build_tg.js / prep_tg.js — отправка в Telegram"]
TGAUTH["build_tgauth.js — проверка Telegram-подписи"]
VENQ["prep_voice_enq.js — очередь голоса"]
VPEND["prep_voice_pending.js — выдача задач воркеру"]
VDONE["prep_voice_done.js — отметка готово"]
end
subgraph DB["Postgres (.158)"]
QUOTES[("quotes")]
PRICE[("price_list")]
VQ[("tg_voice_queue")]
end
subgraph Workers["finik — cron-воркеры"]
PDFSH["kp-pdf.sh — wkhtmltopdf → MinIO"]
VOICESH["kp-voice.sh — TTS → MinIO → sendVoice"]
end
IMP["catalog-source/import_prices.py — парсер xlsx"]
MINIO["MinIO aimedia / s3.servaki.online"]
OLLAMA["Ollama .158:11434"]
VOICEBOX["Voicebox 89.125.89.16:5501"]
TGAPI["api.telegram.org @servaki_online_bot"]
PAGE --> CREATE --> QUOTES
PAGE --> HIST --> QUOTES
PAGE --> TPL
PAGE --> AI --> OLLAMA
PAGE --> VIEW
PAGE --> TGAUTH --> TGAPI
VIEW --> TG --> TGAPI
VIEW --> VENQ --> VQ
IMP --> PRICE
PDFSH --> VIEW
PDFSH --> MINIO
PDFSH --> SETPDF --> QUOTES
VOICESH --> VPEND --> VQ
VOICESH --> VOICEBOX
VOICESH --> MINIO
VOICESH --> TGAPI
VOICESH --> VDONE --> VQ
```
## Entry-points / маршруты
База: `http://192.168.1.158:5678/webhook`. Price-эндпоинты защищены заголовком `X-API-Key` (иначе 403).
| Метод | Путь | Исходник | Назначение |
|-------|------|----------|-----------|
| GET | `/webhook/kp-chat` | prep_page.js | Главная SPA-страница чата + Telegram-логин |
| POST | `/webhook/kp-chat/create` | prep_create.js | Создать КП (INSERT в `quotes`) |
| GET | `/webhook/kp-chat/view?id=&pdf=` | build_view.js | HTML/PDF-рендер КП (`?pdf=1` — режим для wkhtmltopdf) |
| GET | `/webhook/kp-chat/history?q=` | prep_history.js | История/поиск по `quotes` (ILIKE, LIMIT 50) |
| — | (templates) | build_templates.js | Каталог шаблонов КП |
| POST | `/webhook/kp-chat/ai` | build_ai.js | ИИ-подбор шаблона (Ollama + откат на правила) |
| POST | `/webhook/kp-chat/setpdf` | prep_setpdf.js | UPDATE `quotes.pdf_url` (только эта колонка) |
| POST | `/webhook/kp-chat/telegram` | build_tg.js / prep_tg.js | sendDocument/sendMessage КП в Telegram |
| POST | `/webhook/kp-chat/tg-auth` | build_tgauth.js | Проверка Telegram-подписи (чистый JS SHA-256/HMAC) |
| POST | `/webhook/kp-chat/voice` | prep_voice_enq.js | Enqueue голосового комментария (`tg_voice_queue`) |
| GET | `/webhook/kp-chat/voice-pending?key=` | prep_voice_pending.js | Выдача задач воркеру (key-protected) |
| POST | `/webhook/kp-chat/voice-done` | prep_voice_done.js | Отметка задачи выполненной |
| GET | `/webhook/kp` | (n8n нода) | Список КП (используется kp-pdf.sh) |
| GET | `/webhook/price/init` | (Price API) | Создать таблицу `price_list` (идемпотентно) |
| POST | `/webhook/price/import` | (Price API) | UPSERT позиций прайса |
| GET | `/webhook/price/search?q=&category=` | (Price API) | Поиск позиций (LIMIT 50) |
| PUT | `/api/v1/workflows/JT6mVXd7LV8Dmuog` | n8n API | Деплой/откат воркфлоу из бэкапа |
## Ключевые цепочки вызовов
1. **Ручная сборка КП:** `/kp-chat` (prep_page) → правка позиций → `POST /kp-chat/create` (prep_create → INSERT `quotes`) → `GET /kp-chat/view?id=` (build_view) → кнопка «Печать».
2. **PDF-пайплайн (cron */5 на finik):** kp-pdf.sh берёт `GET /webhook/kp` → для КП без pdf_url `wkhtmltopdf '<view>?pdf=1'` → `mc cp` в MinIO `aimedia/kp/` → `POST /kp-chat/setpdf {id,pdf_url}` → публичная ссылка `s3.servaki.online:8443/aimedia/kp/...`.
3. **ИИ-подбор:** `POST /kp-chat/ai {text}` (build_ai) → regex-правила (база) + попытка Ollama `qwen2.5:1.5b` на `.158:11434` (извлекает объект) → при таймауте/ошибке автооткат на правила → загрузка шаблона в чат.
4. **Отправка в Telegram:** кнопка «В Telegram» (build_view) → `POST /kp-chat/telegram {id,chat_id}` (build_tg) → sendDocument PDF из MinIO через @servaki_online_bot (chat_id из Telegram-логина, tg-auth → build_tgauth).
5. **Голосовой комментарий (cron * на finik):** кнопка «Голосом» → `POST /kp-chat/voice` (enq → `tg_voice_queue`) → kp-voice.sh: `GET /voice-pending?key=` → Voicebox TTS (89.125.89.16) → `mc cp` opus в MinIO → sendVoice по URL → `POST /voice-done`.
6. **Импорт прайса:** `catalog-source/import_prices.py` парсит `.xlsx` (openpyxl) → `_catalog_import.json` → `POST /webhook/price/import` (через finik).
## Тех-долг
_Пометка: всё ниже — предположение по грепу/структуре; точность — через codebase-memory-mcp._
- **Дубли-артефакты (dead):** `zi2jSxII` (56622 б = байт-в-байт `kpgen-full.zip`) и `ziB7i0OA` (55738 б = `kpgen-full-project.zip`) — безымянные копии архивов, кандидаты на удаление. Плюс три zip (`KP_Generator_MPOall.zip`, `kpgen-full.zip`, `kpgen-full-project.zip`) — снапшоты, не участвуют в рантайме.
- **Не-код в репо:** `KP-knowledge-base-2026-06-27.html` — статический снапшот базы знаний (документация, не исполняется).
- **`build_templates.js`** — не найдено явного webhook-роута в коде/README (шаблоны, вероятно, отдаются из prep_page или отдельной ноды); проверить, живой ли (ПРЕДПОЛОЖЕНИЕ).
- **Токены/секреты** зашиты в `build_tg.js` (санитизированы в Gitea) — риск рассинхрона с Я.Диском.
- **Хрупкость деплоя:** правка нод n8n только base64/quoted-heredoc (bash раскрывает `${...}`/`$json`); нет CI — откат вручную через `PUT /api/v1/workflows`.
- **Общий прод-бот** @servaki_online_bot делится с ТИНКО-парсером на Proxmox — трогать webhook/getUpdates нельзя (жёсткая внешняя связанность).
## Cross-service links
- **finik** — шлюз к n8n `.158`, хост cron-воркеров (kp-pdf.sh, kp-voice.sh), Caddy для публичных ссылок (kp-pdf.sh, kp-voice.sh, import_prices.py, README).
- **vm-mts / .158** — `192.168.1.158`: n8n :5678, Postgres, Ollama :11434 (build_ai.js, kp-pdf.sh, kp-voice.sh).
- **s3.servaki.online / MinIO aimedia** — хранилище PDF и voice-ogg (kp-pdf.sh, kp-voice.sh).
- **kp.servaki.online** — домен чата (Telegram `/setdomain`).
- **Telegram @servaki_online_bot** (id 8142796440) — общий прод-бот, только исходящие (build_tg.js, kp-voice.sh, build_tgauth.js).
- **Voicebox/Piper** `89.125.89.16:5501` — TTS (kp-voice.sh).
- **Внешние:** Ollama, api.telegram.org, прайсы Wirenboard/ТИНКО. Ссылок на другие наши репо из списка (agent-sync, Heritage, egorin, orbit-bot и т.д.) — **не обнаружено**.
## TODO для Лилии (codebase-memory-mcp)
- **Точный call-graph:** воркфлоу собран из n8n-нод — граф связей восстановлен по README/грепу, а не из JSON воркфлоу. Дообогатить из экспортов `JT6mVXd7LV8Dmuog` / `mxPgqVNbxALGrMYx` (реальные связи WH→Prep→PG→Build→Resp).
- **Dead-code:** подтвердить, что `zi2jSxII`/`ziB7i0OA` = дубли zip и удалимы; проверить живость `build_templates.js` (есть ли входящий роут).
- **Cross-service:** зафиксировать рёбра KPgenerator → finik / .158 / MinIO / Voicebox / Telegram; свести с картами servaki-infra и orbit-bot (общий бот).
- **Секреты:** сверить санитизированные `build_tg.js` / voice-скрипты с полной версией на Я.Диске.
- **Снапшот `graph.db.zst`:** сохранить call-graph + маршруты + cross-service рёбра для инкрементального обновления при правке нод.