Files
CRM_Montzar/deploy/DEPLOY.md
T

308 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# استقرار منتکت CRM — `crm.montzar.ir`
> **قفل‌شده:** فقط همین فایل منبع دستورات استقرار است. پکیج‌منیجر = **npm** (نه pnpm/yarn).
> قانون Cursor: `.cursor/rules/deploy.mdc`
## آپدیت سریع (بعد از هر `git push`) — همیشه همین
```bash
ssh -p 3031 montime@185.50.38.53
cd /var/www/crm
git pull
npm run build -w @mento/shared
cd apps/api && npx prisma migrate deploy && npx prisma generate && cd ../..
npm run build -w @mento/api
npm run build -w @mento/web
pm2 restart mento-crm-api
# فقط اگر STT عوض شده:
# pm2 restart mento-stt
```
---
هاست مشترک مونتایم: `185.50.38.53` (SSH پورت `3031`، کاربر `montime`)
دامنه‌ها (همان اپ و همان مسیر): `https://crm.montzar.ir` و `https://crm.montact.ir`
مسیر کد: `/var/www/crm`
پورت داخلی API: `3030`
PM2: `mento-crm-api` (cwd: `apps/api`، اسکریپت: `dist/src/main.js`)
کد از Gitea: `http://get.feep.ir/Mahdi/CRM_Montzar.git`
پورت‌های اشغال‌شده روی همین سرور (دست نزنید):
۳۰۰۰ مونتایم · ۳۰۰۱ فوری‌سند · ۳۰۱۰ سوپرادمین · ۳۰۲۰ کاتالوگ
پورت داخلی STT (فقط localhost، عمومی نکنید): **۳۰۴۰** — PM2 `mento-stt`
---
## کارهایی که شما باید انجام دهید (قبل/همراه استقرار)
1. **DNS:** رکورد `A` برای `crm.montzar.ir` و `crm.montact.ir` مثل `ktg.montzar.ir` / `adm.montzar.ir` روی همان IP.
2. **پروکسی جلویی SSL:** مثل `crm.montzar.ir`، برای `crm.montact.ir` هم HTTPS تمام شود و به این سرور **HTTP :80** برسد.
3. **Postgres:** دیتابیس و کاربر جدا (`mento_crm`) — به دیتابیس مونتایم دست نزنید.
4. **SMS:** همان حساب ترِز/رایگان مونتایم در `.env` (`SMS_USERNAME` / `SMS_PASSWORD` / `SMS_SENDER`).
5. **دسترسی Gitea** برای `git clone` / `git pull` روی سرور.
---
## روی سرور
SSH:
```bash
ssh -p 3031 montime@185.50.38.53
```
### ۱) کلون
```bash
sudo mkdir -p /var/www/crm
sudo chown montime:montime /var/www/crm
git clone http://get.feep.ir/Mahdi/CRM_Montzar.git /var/www/crm
```
### ۲) پورت آزاد باشد
```bash
pm2 list
ss -tlnp | grep -E '3000|3001|3010|3020|3030' || true
```
۳۰۳۰ باید خالی باشد.
### ۳) فایل `.env` API
```bash
cd /var/www/crm
cp deploy/.env.production.example apps/api/.env
nano apps/api/.env
```
نکته‌های حیاتی:
| کلید | مقدار واقعی روی این سرور |
|---|---|
| `DATABASE_URL` | Postgres روی **`127.0.0.1:15432`** است نه `5432` |
| `PORT` | `3030` |
| `CORS_ORIGIN` | `https://crm.montzar.ir,https://crm.montact.ir` |
| `SMS_*` | همان ترِز مونتایم |
| `PORTAL_SHOW_OTP` | در production حتماً `false` |
| `INTEGRATIONS_ENCRYPTION_KEY` | ۶۴ کاراکتر hex برای رمز توکن ته‌حساب (`openssl rand -hex 32`) |
| `PLATFORM_ADMIN_MOBILE` / `PASSWORD` / `NAME` | حساب اولیه سوپرادمین برای `/adm` (با `npx prisma db seed`) |
نمونهٔ اتصال:
```text
DATABASE_URL="postgresql://USER:PASS@127.0.0.1:15432/mento_crm?schema=public"
```
### ۴) نصب وابستگی‌ها
اگر `npm ci` روی سرور timeout زد، از ویندوز بیلد لینوکسی بگیرید و بفرستید:
```powershell
# روی ویندوز، در ریشهٔ ریپو
npm ci --os=linux --cpu=x64
tar -czf crm-node_modules.tgz node_modules
scp -P 3031 crm-node_modules.tgz montime@185.50.38.53:/var/www/crm/
```
روی سرور:
```bash
cd /var/www/crm
tar -xzf crm-node_modules.tgz
chmod +x node_modules/.bin/*
find node_modules -path '*esbuild*' -name 'esbuild' -type f -exec chmod +x {} \;
# مهم: tarball کپی کهنه از @mento/shared می‌گذارد — همیشه symlink بسازید
rm -rf node_modules/@mento/shared
ln -s ../../packages/shared node_modules/@mento/shared
```
اگر `npm ci` روی سرور خودش جواب داد، معمولاً symlink workspace درست است؛ باز هم با `ls -la node_modules/@mento/shared` چک کنید که به `packages/shared` اشاره کند.
### ۵) migrate و بیلد
`dist/` در git نیست؛ همیشه اول `shared` را بیلد کنید.
```bash
cd /var/www/crm
npm run build -w @mento/shared
# Prisma فقط از apps/api/.env می‌خواند — از ریشه بدون env خطا می‌دهد (P1012)
cd /var/www/crm/apps/api
npx prisma migrate deploy
npx prisma generate
cd /var/www/crm
npm run build -w @mento/api
npm run build -w @mento/web
mkdir -p uploads
# اختیاری یک‌بار: npm run db:seed
```
### ۶) تبدیل صوت به متن (Pipecat — Whisper محلی)
فقط STT روی همین سرور؛ **بدون GapGPT**. Python 3.11+ و ترجیحاً `ffmpeg`.
```bash
cd /var/www/crm/apps/stt
python3.11 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env
nano .env
```
در `.env` فقط مدل محلی لازم است (`STT_MODEL=base`، `STT_DEVICE=cpu`).
`OPENAI_API_KEY` برای دیکته لازم نیست.
`STT_INTERNAL_TOKEN` اگر پر شد باید با `apps/api/.env` یکی باشد.
در API: `STT_TIMEOUT_MS=180000` پیشنهاد می‌شود (لود اول مدل طول می‌کشد).
### ۷) PM2 — فقط پروسه‌های جدید
پروسه‌های موجود را stop نکنید.
```bash
pm2 start /var/www/crm/deploy/ecosystem.config.cjs
pm2 save
pm2 list
curl -sI http://127.0.0.1:3030/api/health
curl -s http://127.0.0.1:3040/health
```
باید `200` بیاید. خطا: `pm2 logs mento-crm-api --lines 80` یا `pm2 logs mento-stt --lines 80`
### ۸) Nginx
```bash
sudo cp /var/www/crm/deploy/nginx-crm.montzar.ir.conf /etc/nginx/sites-available/crm.montzar.ir
sudo ln -sf /etc/nginx/sites-available/crm.montzar.ir /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```
فایل vhost هر دو نام را دارد: `crm.montzar.ir` و `crm.montact.ir` → همان `root` و همان API روی پورت ۳۰۳۰.
**HTTPS روی همین باکس:** مثل `ktg.montzar.ir`، فرانت‌پروکسی (`91.247.174.1`) SSL را تمام می‌کند و به این سرور **HTTP :80** می‌زند.
اگر Certbot روی این vhost `return 404` یا فقط HTTPS بگذارد، سایت از بیرون قطع می‌شود — vhost را روی الگوی HTTP نگه دارید (فایل `deploy/nginx-crm.montzar.ir.conf`).
### ۸ب) اضافه کردن دامنهٔ alias (`crm.montact.ir`) روی همین استقرار
بعد از `git pull` و آپدیت سریع:
```bash
# CORS هر دو دامنه
nano /var/www/crm/apps/api/.env
# CORS_ORIGIN=https://crm.montzar.ir,https://crm.montact.ir
sudo cp /var/www/crm/deploy/nginx-crm.montzar.ir.conf /etc/nginx/sites-available/crm.montzar.ir
sudo nginx -t && sudo systemctl reload nginx
pm2 restart mento-crm-api
```
تست: `https://crm.montact.ir` و `https://crm.montzar.ir` هر دو همان پنل را نشان دهند.
### ۹) تست
1. `https://crm.montzar.ir` → ورود پنل
2. دمو: `owner@demo.local` / `demo1234` (اگر seed زده باشید)
3. پرتال: `https://crm.montzar.ir/p/demo-mento` → OTP باید پیامک شود
4. منوها: گزارشات، کاریز پروژه، باشگاه مشتریان، اتوماسیون (مالک/مدیر)
5. سوپرادمین: `https://crm.montzar.ir/adm` (بعد از seed با `PLATFORM_ADMIN_*`)
---
## پنل سوپرادمین (`/adm`)
مسیر جدا روی nginx لازم نیست؛ همان SPA (`crm.montzar.ir`) روت `/adm` را سرو می‌کند. ورود با **موبایل + رمز** است.
1. در `apps/api/.env` این کلیدها را بگذارید (نمونه در `deploy/.env.production.example`):
```text
PLATFORM_ADMIN_MOBILE=09121234567
PLATFORM_ADMIN_PASSWORD=change-me-strong-platform-password
PLATFORM_ADMIN_NAME=سوپرادمین
```
2. بعد از `prisma migrate deploy` یک‌بار seed بزنید تا حساب اولیه ساخته شود:
```bash
cd /var/www/crm/apps/api
npx prisma db seed
```
اگر حساب با همان موبایل از قبل باشد، seed رمز را هم از `.env` به‌روز می‌کند. ادمین‌های بعدی را از داخل پنل (`/adm/admins`) اضافه کنید.
### اشتراک و ماژول‌ها
بعد از این نسخه، `prisma migrate deploy` جدول `BillingAccount` و ستون `enabledModules` را می‌سازد و برای مالکان فعلی trial **۱۵ روزه** می‌سازد. از `/adm/users` پلن را تمدید کنید و از `/adm/organizations` ماژول هر محیط را تنظیم کنید.
3. ورود: `https://crm.montzar.ir/adm` → داشبورد `/adm/dashboard`
توکن سوپرادمین جدا از JWT کاربران سازمانی است.
---
## آپدیت بعدی (بعد از `git push`)
همان بلوک **«آپدیت سریع»** بالای فایل. نکات اضافه فقط در صورت نیاز:
```bash
# اگر node_modules از tarball تازه شد، دوباره symlink:
# rm -rf node_modules/@mento/shared && ln -s ../../packages/shared node_modules/@mento/shared
# chmod +x node_modules/.bin/*
# اگر requirements.txt عوض شد:
# cd apps/stt && .venv/bin/pip install -r requirements.txt && cd ../..
# pm2 restart mento-stt
```
پاک نکنید: `uploads/` و `apps/api/.env`
---
## پیامک (OTP پرتال)
- سرویس: `apps/api/src/common/sms.service.ts` — الگوی ترِز مثل مونتایم
- تنظیمات فقط در `apps/api/.env` (نمونه: `deploy/.env.production.example`)
- کلیدها: `SMS_PROVIDER=trez`، `SMS_USERNAME`، `SMS_PASSWORD`، `SMS_SENDER`، `SMS_BASE_URL`، `SMS_SEND_PATH`، `SMS_OTP_TEMPLATE`
- در production: `PORTAL_SHOW_OTP=false` تا کد فقط با پیامک برود (نه در JSON پاسخ)
- تست: ورود پرتال با موبایل ثبت‌شده روی شخص سازمان
---
## مشکلات رایج (تجربهٔ واقعی همین سرور)
| علامت | علت | راه حل |
|---|---|---|
| Prisma `P1012` / `DATABASE_URL` not found | migrate از `/var/www/crm` بدون `.env` | `cd apps/api` سپس `npx prisma migrate deploy` |
| اتصال DB رد می‌شود با پورت `5432` | Postgres این سرور روی **15432** است | `DATABASE_URL` را با `:15432` بگذارید |
| Nest: `@mento/shared` has no exported member … | `node_modules/@mento/shared` کپی قدیمی از tarball است | `rm -rf node_modules/@mento/shared && ln -s ../../packages/shared node_modules/@mento/shared` سپس بیلد `shared` و `api` |
| بعد از بیلد shared هنوز تایپ‌ها نیستند | همان کپی کهنه | `grep AutomationAction node_modules/@mento/shared/dist/index.d.ts` باید match بدهد |
| `esbuild` / `.bin` Permission denied | tarball از ویندوز بدون بیت اجرایی | `chmod +x node_modules/.bin/*` و باینری esbuild |
| `npm ci` timeout روی سرور | شبکه/رجیستری کند | tarball لینوکسی از ویندوز (`npm ci --os=linux --cpu=x64`) |
| سایت از بیرون 404 بعد از Certbot | SSL روی باکس بک‌اند، پروکسی جلویی HTTP می‌زند | vhost را فقط HTTP :80 مثل ktg نگه دارید |
| PM2 فایل را پیدا نمی‌کند | خروجی Nest زیر `dist/src/main.js` است | `deploy/ecosystem.config.cjs` را عوض نکنید (`cwd` = `apps/api`) |
تشخیص سریع لینک shared:
```bash
ls -la /var/www/crm/node_modules/@mento/shared
# باید شبیه این باشد:
# ... -> ../../packages/shared
grep -c AutomationAction /var/www/crm/packages/shared/dist/index.d.ts
grep -c AutomationAction /var/www/crm/node_modules/@mento/shared/dist/index.d.ts
# هر دو باید یک عدد (>0) باشند
```
---
## تداخل نداشتن
| این پروژه | بقیه — دست نزنید |
|---|---|
| دامنه‌های `crm.montzar.ir` و `crm.montact.ir` | `ktg` / `adm` / مونتایم |
| پورت ۳۰۳۰ و ۳۰۴۰ (STT فقط localhost) | ۳۰۰۰ / ۳۰۰۱ / ۳۰۱۰ / ۳۰۲۰ |
| PM2 نام `mento-crm-api` و `mento-stt` | پروسه‌های موجود |
| `/var/www/crm` | `/var/www/ktg` و … |
| دیتابیس `mento_crm` روی `:15432` | Postgres مونتایم |