203 lines
6.7 KiB
Markdown
203 lines
6.7 KiB
Markdown
# مراحل ساده: مهاجرت SMS و کار موازی
|
||
|
||
هدف: اول داده واقعی همکار/خانگی برود داخل سوپرادمین، بعد هر دو پنل با هم کار کنند تا خودت بگویی پنل محصولات حذف شود.
|
||
|
||
---
|
||
|
||
## الف) یک نسخه پایلوت (مثلاً همکار)
|
||
|
||
جای `DOMAIN` دامنه همان نسخه را بگذار (همان دامنه داخل سوپرادمین).
|
||
|
||
### ۱) اگر قبلاً روی همکار `SUPERADMIN_SMS_*` گذاشتی، موقتاً خاموش کن
|
||
|
||
روی سرور همکار در `.env` این خطوط را کامنت یا حذف کن:
|
||
|
||
```env
|
||
# SUPERADMIN_SMS_BASE_URL=...
|
||
# SUPERADMIN_SMS_SHARED_SECRET=...
|
||
# SUPERADMIN_SMS_DOMAIN=...
|
||
```
|
||
|
||
بعد:
|
||
|
||
```bash
|
||
php artisan config:clear
|
||
php artisan config:cache
|
||
```
|
||
|
||
علت: تا قبل از مهاجرت، پنل همکار باید همان داده واقعی محلی را نشان بدهد.
|
||
|
||
### ۲) اعداد فعلی همکار را یادداشت کن
|
||
|
||
از پنل پیامک ادمین همکار:
|
||
- موجودی
|
||
- قیمت هر پارت
|
||
- وضعیت بلاک
|
||
|
||
### ۳) سوپرادمین را با کد جدید آپدیت کن
|
||
|
||
روی سرور سوپرادمین (بعد از pull/build کد جدید):
|
||
|
||
```bash
|
||
cd /var/www/superadmin/api
|
||
pm2 restart superadmin-api
|
||
```
|
||
|
||
### ۴) مهاجرت خشک (فقط نمایش، بدون نوشتن)
|
||
|
||
روی سرور سوپرادمین، با دسترسی به MySQL همان نسخه همکار:
|
||
|
||
```bash
|
||
cd /var/www/superadmin/api
|
||
|
||
SMS_IMPORT_DRY_RUN=1 \
|
||
SMS_IMPORT_DOMAIN=DOMAIN \
|
||
SMS_IMPORT_PRODUCT=hamkar \
|
||
HAMKAR_DB_HOST=IP_یا_127.0.0.1 \
|
||
HAMKAR_DB_PORT=3306 \
|
||
HAMKAR_DB_USER=USER \
|
||
HAMKAR_DB_PASSWORD='PASS' \
|
||
HAMKAR_DB_DATABASE=DBNAME \
|
||
npm run prisma:import-sms-from-product
|
||
```
|
||
|
||
اگر گفت `SKIP: sms_panel=me` → این نسخه پنل اختصاصی دارد؛ مهاجرت لازم نیست.
|
||
اگر دامنه پیدا نشد → دامنه را با همان مقدار داخل سوپرادمین چک کن.
|
||
|
||
### ۵) مهاجرت واقعی
|
||
|
||
همان دستور بدون `SMS_IMPORT_DRY_RUN=1`:
|
||
|
||
```bash
|
||
SMS_IMPORT_DOMAIN=DOMAIN \
|
||
SMS_IMPORT_PRODUCT=hamkar \
|
||
HAMKAR_DB_HOST=... \
|
||
HAMKAR_DB_PORT=3306 \
|
||
HAMKAR_DB_USER=... \
|
||
HAMKAR_DB_PASSWORD='...' \
|
||
HAMKAR_DB_DATABASE=... \
|
||
npm run prisma:import-sms-from-product
|
||
```
|
||
|
||
### ۶) در سوپرادمین چک کن
|
||
|
||
همان نسخه را باز کن؛ موجودی/تعرفه/بلاک باید با یادداشت مرحله ۲ یکی باشد.
|
||
|
||
### ۷) کد همکار را آپدیت کن و remote را روشن کن
|
||
|
||
بعد از دیپلوی کد جدید همکار، در `.env` همکار:
|
||
|
||
```env
|
||
SUPERADMIN_SMS_BASE_URL=https://adm.montzar.ir/api/remote/sms
|
||
SUPERADMIN_SMS_SHARED_SECRET=همان_رمز_سوپرادمین
|
||
# فقط اگر APP_URL دامنه درست ندارد:
|
||
# SUPERADMIN_SMS_DOMAIN=DOMAIN
|
||
```
|
||
|
||
```bash
|
||
php artisan config:clear
|
||
php artisan config:cache
|
||
```
|
||
|
||
### ۸) تست موازی
|
||
|
||
1. پنل همکار و سوپرادمین را باز کن → موجودی یکی باشد
|
||
2. در سوپرادمین شارژ کن → در همکار رفرش → باید یکی شود
|
||
3. در همکار تعرفه/بلاک عوض کن → در سوپرادمین همان را ببین
|
||
4. یک SMS تست بفرست → موجودی هر دو کم شود
|
||
|
||
---
|
||
|
||
## ب) خانگی (چندنسخهای روی یک سرور)
|
||
|
||
قانون: هر نسخه = یک Tenant = یک MySQL = یک `.env` = یک `SUPERADMIN_SMS_DOMAIN`.
|
||
روی یک سرور فیزیکی ممکن است چند نصب باشد؛ هرگز یک دامنه/DB مشترک برای همه نگذار.
|
||
|
||
### ب-۱) موجودیگیری از سوپرادمین
|
||
|
||
```bash
|
||
cd /var/www/superadmin/api
|
||
git pull
|
||
npm run prisma:inventory-khanegi-sms
|
||
# یا:
|
||
SMS_INVENTORY_FORMAT=json SMS_INVENTORY_OUT=/tmp/khanegi-sms-inventory.json \
|
||
npm run prisma:inventory-khanegi-sms
|
||
```
|
||
|
||
خروجی `syncStatus` / `nextAction` و لیست `multiVersionHosts` را نگه دار.
|
||
|
||
### ب-۲) فایل اهداف ایمپورت
|
||
|
||
از روی موجودی، فایل واقعی بساز (از روی نمونه):
|
||
|
||
`prisma/khanegi-sms-targets.example.json` → مثلاً `prisma/khanegi-sms-targets.json`
|
||
|
||
برای هر دامنه، MySQL **همان نسخه** را بگذار. پایلوت را `"pilot": true` کن.
|
||
|
||
### ب-۳) پایلوت: dry-run سپس import
|
||
|
||
```bash
|
||
cd /var/www/superadmin/api
|
||
|
||
# فقط پایلوت، خشک
|
||
SMS_IMPORT_TARGETS=./prisma/khanegi-sms-targets.json \
|
||
SMS_IMPORT_ONLY_PILOT=1 \
|
||
SMS_IMPORT_DRY_RUN=1 \
|
||
npm run prisma:import-sms-batch
|
||
|
||
# واقعی
|
||
SMS_IMPORT_TARGETS=./prisma/khanegi-sms-targets.json \
|
||
SMS_IMPORT_ONLY_PILOT=1 \
|
||
npm run prisma:import-sms-batch
|
||
```
|
||
|
||
یا تکدامنه:
|
||
|
||
```bash
|
||
bash deploy/khanegi-sms-import-one.sh DOMAIN 127.0.0.1 DB_USER 'DB_PASS' DB_NAME
|
||
bash deploy/khanegi-sms-import-one.sh DOMAIN 127.0.0.1 DB_USER 'DB_PASS' DB_NAME --apply
|
||
```
|
||
|
||
بعد در UI سوپرادمین موجودی/تعرفه/بلاک را با پنل خانگی قبل از روشن کردن remote چک کن.
|
||
ایمپورت موفق `tenants.sms_synced_at` را هم پر میکند.
|
||
|
||
### ب-۴) روشن کردن remote فقط روی `.env` همان نسخه
|
||
|
||
مقدار `SMS_REMOTE_SHARED_SECRET` را از `/var/www/superadmin/api/.env` بردار، بعد روی سرور خانگی:
|
||
|
||
```bash
|
||
# مسیر server همان نسخه
|
||
bash /path/to/khanegi-sms-enable-remote.sh /var/www/CUSTOMER/server DOMAIN 'SHARED_SECRET'
|
||
# یا دستی:
|
||
# SUPERADMIN_SMS_BASE_URL=https://adm.montzar.ir/api/remote/sms
|
||
# SUPERADMIN_SMS_SHARED_SECRET=...
|
||
# SUPERADMIN_SMS_DOMAIN=DOMAIN
|
||
php artisan config:clear && php artisan config:cache
|
||
php artisan sms:superadmin-probe
|
||
```
|
||
|
||
### ب-۵) rollout بقیه
|
||
|
||
همان چرخه نسخه به نسخه (یا batch بدون `ONLY_PILOT`).
|
||
`skip` / `sms_panel=me` / بدون wallet را جدا نگه دار.
|
||
|
||
---
|
||
|
||
## ج) نسخههایی که هنوز فعال نشدهاند
|
||
|
||
- جدول `sms_wallets` ندارند یا خالیاند → اسکریپت skip میکند
|
||
- `sms_panel=me` → skip
|
||
- برای آنها فعلاً کاری نکن تا خودت بگویی
|
||
|
||
---
|
||
|
||
## کار موازی تا اعلام تو
|
||
|
||
تا وقتی بگویی «پنل همکار/خانگی لازم نیست»:
|
||
|
||
- تغییر در **سوپرادمین** → با باز کردن پنل محصول هم دیده میشود (و در MySQL محلی هم mirror میشود)
|
||
- تغییر در **پنل همکار/خانگی** → در سوپرادمین ذخیره میشود
|
||
- ارسال SMS → کسر از سوپرادمین + mirror محلی
|
||
|
||
بعد از اطمینان نهایی، پنل محصولات حذف میشود و فقط سوپرادمین میماند.
|