# گزارش ادغام ایجنت هوش مصنوعی با ریپوی 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/`) ممکن است هنوز دیده شود — محتوایی است و عملکردی تحت تأثیر نیست.