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 محلی
|
|||
|
|
|
|||
|
|
بعد از اطمینان نهایی، پنل محصولات حذف میشود و فقط سوپرادمین میماند.
|