refactor(bot)!: rename 'ai procurement' -> 'bot/' so the compose build context is committed
The bot service in docker-compose.yml builds from ./bot, but the agent code lived in 'ai procurement/' and ./bot was only a Windows junction on reza.g's machine (and was gitignored) — exactly as the team reported: 'bot/ was never committed — prod-v7's bot is un-buildable from the repo.' - junction removed; 'ai procurement/' renamed to 'bot/' via git mv (all 41 files keep their history as pure renames) - 'bot/' dropped from .gitignore (voice/ stays ignored — runtime voice notes; bot/.env stays ignored by bot/.gitignore) - compose needs no change: context: ./bot and ./bot/app now resolve to committed files - bot/INTEGRATION-REPORT.md added: full story (problem, root cause, git state, security note on the committed BALE_BOT_TOKEN / AI_API_KEY compose defaults, and usage instructions for the team) Verified: 41 renames staged with zero secret/cache files; voice/ and bot/.env still ignored.
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
# گزارش ادغام ایجنت هوش مصنوعی با ریپوی ERP
|
||||
|
||||
> این سند وضعیت نهایی یکپارچهسازی بات تلگرام/بله (procurement AI agent) با پروژهی ERP را
|
||||
> توضیح میدهد: مشکلی که پیش آمده بود، چه چیزی اصلاح شد، وضعیت فعلی گیت و سرور،
|
||||
> نکات امنیتی و نحوهی استفاده. تاریخ آخرین بهروزرسانی: برنچ `prod-v7`.
|
||||
|
||||
---
|
||||
|
||||
## ۱. مشکل چی بود؟
|
||||
|
||||
سرویس `bot` در `docker-compose.yml` اینطور تعریف شده بود:
|
||||
|
||||
```yaml
|
||||
bot:
|
||||
build:
|
||||
context: ./bot # ← پوشهای که در گیت وجود نداشت!
|
||||
volumes:
|
||||
- ./bot/app:/srv/bot/app
|
||||
```
|
||||
|
||||
اما:
|
||||
|
||||
1. **پوشهی `bot/` هیچوقت کامیت نشده بود** — نه روی `prod-v7` و نه روی هیچ برنچ دیگری.
|
||||
2. کد ایجنت در پوشهای به نام `ai procurement/` (با فاصله در نام) زندگی میکرد که روی `prod-v7` کامیت شده بود، ولی compose به آن اشاره نمیکرد.
|
||||
3. روی دستگاه reza.g یک **Windows Junction** (میانبر سطح NTFS) به نام `bot` وجود داشت که به `ai procurement` اشاره میکرد — به همین دلیل `docker compose build bot` فقط روی ماشین او جواب میداد.
|
||||
4. خود برنچ `prod-v7` هم `bot/` را در `.gitignore` (خط ۳۳) داشت.
|
||||
|
||||
**نتیجه:** روی هر کلون تمیزی از مخزن، `docker compose build bot` شکست میخورد —
|
||||
همان چیزی که تیم گزارش کرد: «bot/ was never committed — prod-v7's bot is un-buildable from the repo.»
|
||||
|
||||
## ۲. راهحل اعمالشده (راهحل شماره ۲)
|
||||
|
||||
1. Junction ویندوزی `bot` حذف شد (فقط میانبر؛ فایلی از دست نرفت).
|
||||
2. پوشهی `ai procurement/` به **`bot/`** تغییر نام یافت — با `git mv`، یعنی
|
||||
**تاریخچهی گیت هر ۴۱ فایل بهصورت rename خالص حفظ شده** (`R` در گیت، نه حذف/افزودن).
|
||||
3. خط `bot/` از `.gitignore` ریشه حذف شد تا پوشهی بات دیگر ignore نشود.
|
||||
(`voice/` سر جایش ماند — نتهای صوتی رuntimes هستند و نباید کامیت شوند.)
|
||||
4. اکنون `docker-compose.yml` **بدون هیچ تغییری** درست کار میکند:
|
||||
`context: ./bot` و `./bot/app` دقیقاً به فایلهای کامیتشده اشاره میکنند.
|
||||
5. همهچیز روی برنچ **`prod-v7`** کامیت و پوش شده تا تیم به فایلها دسترسی داشته باشد.
|
||||
|
||||
### قواعد ignore فعلی (عمدی)
|
||||
|
||||
| مسیر | وضعیت | دلیل |
|
||||
|---|---|---|
|
||||
| `bot/.env` | ignore (توسط `bot/.gitignore`) | کلیدها و توکنها — هرگز کامیت نمیشوند |
|
||||
| `bot/__pycache__/` و `*.pyc` | ignore | خروجی runtime پایتون |
|
||||
| `voice/` | ignore (ریشه) | فایلهای صوتی دریافتی از بله در زمان اجرا |
|
||||
| `procurement_ai_agent.bundle` و `git_history_backup.zip` | **کامیتشده** | بکاپ تاریخچهی اصلی ایجنت (~۲۰۰KB) |
|
||||
|
||||
## ۳. وضعیت فعلی گیت (تاریخ این سند)
|
||||
|
||||
- برنچ فعال: **`prod-v7`** (محلی و `origin/prod-v7` همSHA).
|
||||
- درخت `prod-v7` = کل اپلیکیشن ERP (backend/frontend/…) **بهعلاوهی** `bot/`
|
||||
(کد ایجنت + Dockerfile + docs + integration) + `backend/app/routers/drafts.py`
|
||||
(اندپوینتهای همگامسازی draft بات ↔ ویزارد) + اسکیمای `bot_drafts`.
|
||||
- تاریخچه: از production (d69ec7f) یازده کامیت جلوتر — از «feat(drafts): bot_drafts schema»
|
||||
تا «feat(bot,wizard): smart message filtering…».
|
||||
- بقیهی برنچهای تیم (`prod-v8`، `prod-v9`، `prod_v8`، `production`) **فایلهای بات را ندارند** —
|
||||
ادغام این برنچ با کار جدید تیم، قدم بعدی جداگانه است (با تأیید تیم).
|
||||
|
||||
## ۴. ⚠️ نکتهی امنیتی (مهم — اقدام لازم)
|
||||
|
||||
در همان `docker-compose.yml`، مقادیر **واقعی** بهعنوان پیشفرض env کامیت و پوش شدهاند:
|
||||
|
||||
```yaml
|
||||
PROCUREMENT_BOT_BOT_TOKEN: ${BALE_BOT_TOKEN:-1354444845:yhVMnKZBFuKaU3UW5fP1bHmknEHx99mipWw}
|
||||
PROCUREMENT_BOT_AI_API_KEY: ${AI_API_KEY:-sk-a671eab15be846d494bf0839070a3b32}
|
||||
```
|
||||
|
||||
یعنی توکن بات بله و کلید DeepSeek الان در تاریخچهی مخزن مشترک است و **هر کسی که به ریپو
|
||||
دسترسی دارد میتواند آنها را ببیند** (`.env` کامیت نشده، ولی این پیشفرضها عملاً همان لو رفتن راز است).
|
||||
|
||||
اقدامات توصیهشده (هنوز انجام نشده — نیاز به تصمیم مالک توکنها):
|
||||
|
||||
1. **توکن بات بله را از @BotFather بله باطل و دوباره بسازید** و کلید DeepSeek را rotate کنید.
|
||||
2. مقادیر پیشفرض را از compose حذف کنید و بهجای `${VAR:-secret}` از `${VAR:?set VAR}` استفاده کنید
|
||||
(مثل `TRAEFIK_ACME_EMAIL` در compose پروडاکشن) و مقادیر واقعی فقط در `.env` محلی/سرور بمانند.
|
||||
3. فایل `bot/.env` را از روی `bot/.env.example` بسازید (نمونه در همان پوشه هست).
|
||||
|
||||
## ۵. نحوهی استفاده
|
||||
|
||||
### ۵.۱ اجرای کامل استک (شامل بات) — روی هر ماشین
|
||||
|
||||
```powershell
|
||||
git clone https://git.bennu-api-bahrestan.ir/ali_mohaghegh/ERP.git
|
||||
cd ERP
|
||||
git checkout prod-v7
|
||||
|
||||
# ۱) متغیرهای محیطی بات را بسازید (بدون این، بات توکن ندارد):
|
||||
copy bot\.env.example bot\.env # و مقادیر واقعی را داخلش بگذارید
|
||||
# BALE_BOT_TOKEN=... توکن بات از بله
|
||||
# AI_API_KEY=... کلید سرویس LLM
|
||||
# BALE_ADMIN_CHAT_IDS=... چتآیدی مدیران
|
||||
|
||||
# ۲) کل استک + بات:
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
سرویس `bot` (کانتینر `procurement-bot`) بهصورت long-polling به `tapi.bale.ai` وصل میشود،
|
||||
به `api:8000/api/v1` (همان ERP) و پایگاهدادهی `procurement` وصل است و
|
||||
draft های گفتگو را در جدول `bot_drafts` مینویسد.
|
||||
|
||||
### ۵.۲ اجرای فقط بات (وقتی استک از قبل بالا است)
|
||||
|
||||
```powershell
|
||||
docker compose build bot
|
||||
docker compose up -d bot
|
||||
docker compose logs -f bot
|
||||
```
|
||||
|
||||
### ۵.۳ جریان کاری کاربر نهایی (بات ↔ ERP)
|
||||
|
||||
1. کاربر در بله به بات پیام میدهد (متن یا وویس — وویس با STT به متن تبدیل میشود).
|
||||
2. بات با NLU موجودی/تأمینکننده/کالا را استخراج میکند و یک **draft** میسازد
|
||||
(وضعیت `active` در جدول `bot_drafts`) و کارت پیشنمایش با فیلدهای خالی میفرستد.
|
||||
3. کاربر با دکمهی ✅ تأیید میکند؛ بات draft را به ERP کامیت میکند
|
||||
(از طریق REST: `POST /api/v1/drafts/{id}/commit` با توکن سرویس).
|
||||
4. ویزارد فرانتاند همان draft را از `GET /api/v1/drafts` میخواند و پیشپر میکند —
|
||||
همگامسازی دوطرفه با ذخیرهی خودکار (debounced) بین مرورگر و بات.
|
||||
5. ویرایشِ پاسخِ کاربر به کارت قبلی بات هم پشتیبانی میشود (reply-based edit، بدون کارت تکراری).
|
||||
|
||||
### ۵.۴ تست سریع سلامت
|
||||
|
||||
```powershell
|
||||
docker compose ps bot # باید Up باشد
|
||||
docker compose logs bot | Select-Object -Last 20
|
||||
# داخل کانتینر:
|
||||
docker compose exec bot python -m tools.smoke_test # اگر توکن ست باشد
|
||||
```
|
||||
|
||||
### ۵.۵ مسیرهای مهم
|
||||
|
||||
| مسیر | محتوا |
|
||||
|---|---|
|
||||
| `bot/app/` | کد بات (handlers برای quote/material/supplier/decisions، bale client، NLU، STT، sync) |
|
||||
| `bot/Dockerfile` | ایمیج `python:3.13-slim` + ffmpeg (برای وویس) |
|
||||
| `bot/docs/SETUP.md` | راهاندازی جزئیتر ایجنت |
|
||||
| `bot/integration/` | طرح ادغام: نمونه سرویس compose + پچ `X-Actor-Id` |
|
||||
| `backend/app/routers/drafts.py` | REST drafts (سمت ERP) |
|
||||
| `bot/procurement_ai_agent.bundle` و `bot/git_history_backup.zip` | بکاپ تاریخچهی مستقل قبلی ایجنت |
|
||||
|
||||
## ۶. نکات باقیمانده برای تیم
|
||||
|
||||
- **ادغام با برنچهای جدید تیم:** فایلهای بات فقط روی `prod-v7` هستند؛ `prod-v8`/`prod-v9`
|
||||
آنها را ندارند. برای رسیدن به استقرار نهایی، این برنچ باید با کار تیم merge شود.
|
||||
- **سرویس bot در `docker-compose.prod.yml` و `docker-compose.coolify.yml` نیست** —
|
||||
برای استقرار سرور باید به overlay پروڈ اضافه شود (یا از همان base compose استفاده شود).
|
||||
- نام قدیمی `ai procurement` در برخی مستندات (`bot/docs/SETUP.md`، `bot/integration/`)
|
||||
ممکن است هنوز دیده شود — محتوایی است و عملکردی تحت تأثیر نیست.
|
||||
Reference in New Issue
Block a user