Files
api/deploy/SMS-MIGRATION-STEPS.md

6.7 KiB
Raw Permalink Blame History

مراحل ساده: مهاجرت SMS و کار موازی

هدف: اول داده واقعی همکار/خانگی برود داخل سوپرادمین، بعد هر دو پنل با هم کار کنند تا خودت بگویی پنل محصولات حذف شود.


الف) یک نسخه پایلوت (مثلاً همکار)

جای DOMAIN دامنه همان نسخه را بگذار (همان دامنه داخل سوپرادمین).

۱) اگر قبلاً روی همکار SUPERADMIN_SMS_* گذاشتی، موقتاً خاموش کن

روی سرور همکار در .env این خطوط را کامنت یا حذف کن:

# SUPERADMIN_SMS_BASE_URL=...
# SUPERADMIN_SMS_SHARED_SECRET=...
# SUPERADMIN_SMS_DOMAIN=...

بعد:

php artisan config:clear
php artisan config:cache

علت: تا قبل از مهاجرت، پنل همکار باید همان داده واقعی محلی را نشان بدهد.

۲) اعداد فعلی همکار را یادداشت کن

از پنل پیامک ادمین همکار:

  • موجودی
  • قیمت هر پارت
  • وضعیت بلاک

۳) سوپرادمین را با کد جدید آپدیت کن

روی سرور سوپرادمین (بعد از pull/build کد جدید):

cd /var/www/superadmin/api
pm2 restart superadmin-api

۴) مهاجرت خشک (فقط نمایش، بدون نوشتن)

روی سرور سوپرادمین، با دسترسی به MySQL همان نسخه همکار:

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:

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 همکار:

SUPERADMIN_SMS_BASE_URL=https://adm.montzar.ir/api/remote/sms
SUPERADMIN_SMS_SHARED_SECRET=همان_رمز_سوپرادمین
# فقط اگر APP_URL دامنه درست ندارد:
# SUPERADMIN_SMS_DOMAIN=DOMAIN
php artisan config:clear
php artisan config:cache

۸) تست موازی

  1. پنل همکار و سوپرادمین را باز کن → موجودی یکی باشد
  2. در سوپرادمین شارژ کن → در همکار رفرش → باید یکی شود
  3. در همکار تعرفه/بلاک عوض کن → در سوپرادمین همان را ببین
  4. یک SMS تست بفرست → موجودی هر دو کم شود

ب) خانگی (چندنسخه‌ای روی یک سرور)

قانون: هر نسخه = یک Tenant = یک MySQL = یک .env = یک SUPERADMIN_SMS_DOMAIN.
روی یک سرور فیزیکی ممکن است چند نصب باشد؛ هرگز یک دامنه/DB مشترک برای همه نگذار.

ب-۱) موجودی‌گیری از سوپرادمین

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

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 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 بردار، بعد روی سرور خانگی:

# مسیر 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 محلی

بعد از اطمینان نهایی، پنل محصولات حذف می‌شود و فقط سوپرادمین می‌ماند.