ifnex/AGENT.md
Kazem Alghasi 35fde95f5e docs: finalize deployment handoff and harden API key middleware
- Add DEPLOYMENT_HANDOFF.md for client IT team with full production steps
- Fix ApiKeyMiddleware: correct Response import and fail-closed on unset key
- Remove committed Bridge API secret from all tracked docs
- Document seed, admin provisioning, WP user sync, Kavenegar, and wp-config hardening
- Reformat AGENT.md, README.md, CLIENT_DELIVERY.md to consistent structure
2026-10-04 04:06:32 +03:30

24 KiB
Raw Blame History

راهنمای ایجنت — پروژهٔ IFNEX Logistics

تاریخ: ۲۰۲۶-۱۰-۰۴ نسخه: ۱.۳ تهیه‌کننده: VernaSoft Group — Kazem Alghasi


۱. خلاصهٔ پروژه

سیستم مدیریت لجستیک بین‌المللی با معماری Headless: Laravel 11 به‌عنوان بک‌اند، WordPress به‌عنوان فرانت‌اند و Filament 3.3 به‌عنوان پنل مدیریت. این سیستم جایگزین فرآیندهای دستی مبتنی بر اکسل شده و از Multi-Package، فاکتور گمرکی، کیف پول دیجیتال، درگاه پرداخت Zarinpal، تولید PDF با بارکد، فلوی تأیید سفارش، تعهدنامه، SMS کاوه‌نگار، سیستم اعتبار چندارزی و رهگیری پیشرفته پشتیبانی می‌کند.

وضعیت فعلی

فازهای ۰، ۱، ۲، ۳ و ۳.۵ تکمیل شده‌اند. فاز ۳.۶ (اصلاحات جلسهٔ کارفرما) حدود ۹۵٪ انجام شده است:

  • فلوی کامل سفارش (ثبت ← تأیید ← تعهدنامه ← پرداخت) — تست End-to-End
  • بازطراحی داشبورد و Login پنل Filament (هویت بصری navy + amber)
  • بازطراحی PDFهای AWB، Invoice و Label (dompdf، چیدمان جدولی)
  • صفحهٔ «وضعیت مالی مشتری» در پنل ادمین (۴ KPI + بدهی‌های ارزی + سفارش‌ها و تراکنش‌ها)
  • سیستم اعتبار چندارزی کامل (درخواست ۹) — بدهی به همان ارز، تسویه با نرخ روز
  • ویجت هشدار بدهی‌های ارزی تسویه‌نشده + badge روی منو
  • Rate Limiting روی همهٔ APIها (۶ لایه throttle: auth / sms / public / customer / wallet / staff)
  • چک‌لیست خودکار کارمند پس از تأیید سفارش (درخواست ۵)
  • نمایش بدهی ارزی در پورتال مشتری وردپرس
  • استایل‌دهی صفحهٔ پروفایل مشتری در وردپرس
  • پاک‌سازی کد (حذف فایل‌های تستی، تأیید تمیزی opcache_reset / dd / dump)

چندزبانه (i18n) همچنان به زمان دیپلوی موکول است.


۲. تکنولوژی‌ها و نسخه‌ها

لایه تکنولوژی نسخه / توضیح
Backend Laravel 11.x
زبان PHP ^8.2 (۸.۳ نیز پشتیبانی می‌شود)
پنل مدیریت Filament 3.3.x
فرانت‌اند WordPress 7.x + قالب سفارشی IFNEX
احراز هویت Laravel Sanctum + Bridge Auth بدون رمز عبور (کلید API مشترک)
پرداخت Zarinpal + Mock Gateway (تست) کلید sandbox برای تست لوکال
PDF و بارکد Dompdf + picqer/php-barcode-generator AWB، Invoice، Label، فاکتور واردات
پیامک Kavenegar تأیید موبایل + اعلان وضعیت سفارش
اکسل maatwebsite/excel Import / Export نرخ‌ها و داده‌های تاریخی
تاریخ و زمان morilog/jalali + Carbon تاریخ شمسی در نمایش، میلادی در DB
دیتابیس MySQL 8.0+ (تست‌ها با SQLite)
صف Redis (ترجیحی) / Database برای پردازش‌های سنگین
سرور HestiaCP + Nginx + PHP-FPM تولید (api.ifnex.vernahost.ir)

۳. ساختار دایرکتوری

IFNEX-Logistics/
├── 01_Documents/                      # مستندات فنی
│   ├── IFNEX_File_Map.md               # نقشهٔ ۱۰۰+ فایل پروژه
│   ├── IFNEX_Roadmap.md                # نقشهٔ راه فازی
│   ├── IFNEX_Phase0_Checklist.md       # چک‌لیست تکمیل فازها
│   ├── IFNEX_ADR.md                    # تصمیمات معماری (ADR-001 تا 009)
│   ├── EXCEL_ANALYSIS.md               # تحلیل داده‌های تاریخی
│   ├── IFNEX_I18N_Strategy.md          # استراتژی چندزبانه
│   └── IFNEX_Commercial_Model.md       # مدل تجاری
│
├── 03_WordPress/                      # فرانت‌اند وردپرس
│   └── wp-content/
│       ├── themes/ifnex/               # قالب سفارشی
│       └── plugins/ifnex-bridge/       # پلاگین ارتباط با لاراول
│           ├── includes/               # api-client، user-bridge، shortcodes، tracking-form
│           └── assets/                 # CSS و JS فرم سفارش
│
├── 04_Laravel/                        # بک‌اند لاراول (هستهٔ اصلی)
│   ├── app/
│   │   ├── Enums/                      # ShipmentStatus، ShipmentDirection، ShipmentType، PaymentGateway، TransactionStatus
│   │   ├── Filament/                   # ۱۷ Resource + Pages + Widgets
│   │   ├── Http/
│   │   │   ├── Controllers/Api/        # Track، Pricing، Auth، Bridge، Customer، Wallet، Payment، Staff، CommitmentForm
│   │   │   └── Middleware/             # ApiKeyMiddleware
│   │   ├── Models/                     # ۲۶ مدل Eloquent
│   │   ├── Notifications/              # DB notifications + SMS
│   │   ├── Observers/                  # ShipmentObserver
│   │   ├── Services/                   # PriceCalculator، Pdf، Tracking، OrderPayment، Wallet، Zarinpal، KavenegarSms
│   │   ├── Traits/                     # Auditable
│   │   ├── Imports/                    # OldShipments، ShippingRates
│   │   └── Exports/                    # ShippingRatesTemplateExport
│   ├── database/migrations/           # ۵۲ migration
│   ├── resources/views/pdfs/           # awb، invoice، label، import-invoice
│   └── routes/api.php                  # ۴۰+ endpoint
│
├── AGENT.md                            # همین سند
├── CLIENT_DELIVERY.md                  # چک‌لیست وضعیت تحویل مشتری (منبع اصلی)
├── DEPLOYMENT.md                       # راهنمای استقرار روی سرور
├── DEPLOYMENT_HANDOFF.md               # تحویل استقرار به تیم IT کارفرما
└── README.md                           # معرفی کلی پروژه

۴. مفاهیم کلیدی بیزینس

۴.۱ مرسوله (Shipment)

مورد مقدار
انواع (Type) DOC_NORMAL، DOC_ECONOMY، PARCEL
جهت (Direction) export (صادرات) و import (واردات)
وضعیت (Status) pending_approval ← approved ← processed ← picked_up ← in_transit ← out_for_delivery ← delivered / failed / returned / cancelled (به‌همراه pending_payment legacy و archived)

هر مرسوله دارای چند بسته (packages)، اقلام گمرکی (items — فقط برای PARCEL)، تاریخچهٔ تغییرات وضعیت (statusHistories)، شرکت‌های حمل (carrierMappings)، رویدادهای رهگیری (trackingEvents) و تعهدنامه‌ها (commitmentForms) است.

۴.۲ بسته (Package)

  • هر مرسوله می‌تواند چندین بسته داشته باشد (جدول shipment_packages).
  • وزن حجمی = (Length × Width × Height) / 5000 (استاندارد IATA).
  • وزن قابل پرداخت = max(وزن واقعی، وزن حجمی).

۴.۳ فاکتور گمرکی (Invoice)

  • فقط برای مرسوله‌های نوع PARCEL صادر می‌شود.
  • حداکثر ۹ قلم کالا (شرح، HS Code، تعداد، قیمت واحد، مجموع به USD).
  • مجموع کل فاکتور در shipments.invoice_total_usd ذخیره می‌شود.
  • فاکتور واردات (Import Invoice): فیلدهای brand_fee، report_fee، customs_clearance_cost، order_registration_fee و… به‌همراه قالب PDF مطابق شیت ENG Invoice.

۴.۴ کیف پول (Wallet)

  • هر کاربر یک کیف پول دارد.
  • تراکنش‌ها (WalletTransaction) با نوع deposit، order_payment، refund، withdrawal به‌صورت polymorphic به Payment یا سفارش متصل هستند.
  • پرداخت از کیف پول یا درگاه Zarinpal (با Mock برای تست)، به‌همراه freeze / unfreeze و activity log کامل.

۴.۵ احراز هویت Bridge

  • کاربران وردپرس بدون نیاز به رمز عبور از طریق POST /api/v1/bridge/login با ارسال bridge_api_key و wp_user_id وارد لاراول می‌شوند.
  • پاسخ شامل توکن Sanctum (معتبر ۳۰ روز) و اطلاعات کاربر است.
  • کلید IFNEX_BRIDGE_API_KEY باید در هر دو طرف (.env لاراول و تنظیمات پلاگین وردپرس) یکسان باشد.
  • توکن در usermeta کاربر وردپرس (ifnex_laravel_token) ذخیره می‌شود و روی ۴۰۱ خودکار باطل و تجدید می‌شود.
  • کلید IFNEX_API_KEY کلید عمومی بخش رهگیری است و ApiKeyMiddleware آن را با !== مقایسه می‌کند؛ اگر خالی بماند، درخواست با توکن خالی از guard عبور می‌کند.
  • ⚠️ BridgeAuthController فقط مقدار change-this-secret-key را رد می‌کند. این مقدار عمداً غیرکارکردی است تا جایگزینی‌اش فراموش نشود — هر مقدار دیگری، حتی مواردی که شبیه placeholder باشند، یک کلید معتبر محسوب می‌شود.
  • 🔐 هرگز کلید واقعی را در این فایل، در DEPLOYMENT.md یا در 04_Laravel/README.md ننویس. مقادیری که قبلاً در این مخزن ثبت شده‌اند را لو‌رفته فرض کن و چرخش بده.

۴.۶ رهگیری (Tracking)

  • کاربر با شمارهٔ AWB جستجو می‌کند.
  • سیستم رویدادهای رهگیری را از جدول shipment_tracking_events با فیلد source (manual، api، import، system، customer) نمایش می‌دهد.
  • ایمپورت گروهی وضعیت ترکینگ با CSV از پنل (صفحهٔ BulkTrackingImport) انجام می‌شود.

۴.۷ قیمت‌گذاری (Pricing)

  • بر اساس ۴ زون مجزا (Export/Import × Parcel/Doc) و ۳ نوع سرویس.
  • فرمول: قیمت پایه (AED) × ضریب سود × نرخ تبدیل به ریال + هزینه‌های جانبی (Packing، Domestic Pickup، …) + مالیات بر ارزش افزوده (۹٪).
  • محموله‌های بالای ۳۰ کیلوگرم مشمول نرخ ویژه (Spot Rate) هستند و محاسبهٔ آنلاین ندارند.

۴.۸ فلوی تأیید سفارش (Approval Flow)

  • مشتری بعد از ثبت سفارش مستقیم به درگاه نمی‌رود؛ سفارش با وضعیت pending_approval ثبت می‌شود.
  • کارمند یا مدیر از پنل فیلمنت (اکشن تأیید در ShipmentResource) یا از API (/staff/orders/{id}/approve|reject) تأیید می‌کند.
  • فقط پس از approved، گزینه‌های پرداخت (کیف پول / درگاه) در وردپرس باز می‌شود. پرداخت موفق سفارش را processed می‌کند (PaymentController در callback با is_order_payment در metadata).
  • سفارش‌های approved پرداخت‌نشده روی مانده حساب کاربر (account_balance در پروفایل) اثر می‌گذارند.

۴.۹ تعهدنامه و اسناد سفارش (Commitment Forms)

  • مدیر فرم‌های تعهدنامه را در فیلمنت (CommitmentFormResource) با direction (export / import / both) آپلود می‌کند.
  • مشتری در جزئیات سفارش وردپرس لیست تعهدنامه‌ها را می‌بیند ← دانلود / چاپ / امضا ← آپلود فایل امضاشده (POST /orders/{shipment}/commitment-forms/{form}/upload) که در جدول shipment_commitment_forms ثبت می‌شود.
  • دانلود AWB، Invoice و Label نیز از همین بخش (/orders/{shipment}/pdf/*) انجام می‌شود.
  • ✅ چک مالکیت اعمال شده: ShipmentPolicy + بررسی user_id در کنترلرهای PDF و تعهدنامه (کامیت 8cf4075).
  • دانلود قالب تعهدنامه از route محافظت‌شده با auth (جایگزین asset عمومی) و دانلود ادمین از دیسک secure از طریق روت‌های admin.commitment-forms.* انجام می‌شود.

۴.۱۰ اعلان‌ها و SMS کاوه‌نگار

  • تنظیمات از SystemSetting خوانده می‌شود (kavenegar_api_key به‌همراه سوییچ هر نوع پیام، مانند kavenegar_send_shipment_approved).
  • نوتیفیکیشن‌ها: ShipmentApprovedSms، ShipmentRejectedSms، PaymentSuccessSms، TrackingUpdatedSms به‌همراه کانال SmsChannel.
  • تریگر اصلی: ShipmentObserver (روی تغییر وضعیت Shipment) و PaymentController (پرداخت موفق). تأیید موبایل: MobileVerificationController.
  • در .env لوکال کلید کاوه‌نگار خالی است؛ تا وقتی تنظیم نشود SMS ارسال نمی‌شود (فقط DB notification).

۴.۱۱ اعتبار مشتری (Credit) — چندارزی

  • سیستم کامل با CustomerCreditService (متدهای grantCredit()، settle()، getCustomerDebtsByCurrency()) و جدول‌های customer_credits و credit_settlements پیاده‌سازی شده است.
  • بدهی به همان ارز ثبت می‌شود و تسویه با نرخ روز انجام می‌گیرد. race condition در settle() با lockForUpdate() و بررسی مجدد مانده اصلاح شد.
  • فقط super_admin مجاز به اعطای اعتبار است (Policy).

۴.۱۲ Audit Log

  • trait App\Traits\Auditable روی مدل‌های اصلی (User، Shipment، Wallet و…) اعمال شده و در AuditLogResource قابل مشاهده است.
  • ShipmentStatusHistory دارای ستون‌های from_status / to_status / reason به‌همراه نام کاربر تغییردهنده است.

۵. دستورات روزمره

# نصب وابستگی‌ها
composer install

# تنظیم محیط
cp .env.example .env
php artisan key:generate

# دیتابیس (ابتدا باید ایجاد شود)
php artisan migrate --force
php artisan db:seed --force

# اجرای سرور توسعه
php artisan serve

# اجرای صف (پردازش‌های سنگین)
php artisan queue:work

# تست‌ها
php artisan test

# پاک‌سازی و بازسازی کش
php artisan optimize:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan filament:clear-cached-components

# ایمپورت / اکسپورت نرخ‌ها
php artisan ifnex:import:rates {path}
php artisan ifnex:import:shipments {path}
php artisan ifnex:import:tracking {path}

# به‌روزرسانی نرخ ارز (کرون)
php artisan ifnex:update-rates --source=ecb

# تولید API Token برای ادمین
php artisan ifnex:token

۶. متغیرهای محیطی کلیدی (.env)

APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ifnex_db
DB_USERNAME=root
DB_PASSWORD=

# IFNEX اختصاصی — پیش از استقرار با رشتهٔ تصادفی جایگزین کن
# مقدار change-this-secret-key عمداً غیرکارکردی است تا جایگزینی فراموش نشود
IFNEX_API_KEY=change-this-secret-key
IFNEX_BRIDGE_API_KEY=change-this-secret-key   # باید عیناً با وردپرس یکی باشد
IFNEX_TRACKING_RATE_LIMIT=60

# CORS (فقط دامنه‌های مجاز وردپرس)
CORS_ALLOWED_ORIGINS=http://localhost,http://127.0.0.1

# Zarinpal (برای تست از Mock استفاده کن)
ZARINPAL_MERCHANT_ID=fake-merchant-id-for-testing   # اگر fake باشد، MockGateway فعال می‌شود
ZARINPAL_SANDBOX=true
ZARINPAL_CALLBACK_URL=http://localhost:8000/api/v1/payment/callback
ZARINPAL_FRONTEND_FAILURE_URL=http://localhost/IFNEX-Logistics/03_WordPress/wallet
# نکته: ZARINPAL_FRONTEND_SUCCESS_URL در کد خوانده نمی‌شود؛ ریدایرکت موفق
# از frontend_callback ارسالی وردپرس تعیین می‌شود.

# Kavenegar SMS (خالی = فقط DB notification)
KAVENEGAR_API_KEY=
KAVENEGAR_SENDER=10008566

# Wallet
WALLET_MIN_DEPOSIT=10000
WALLET_MAX_DEPOSIT=500000000
WALLET_AUTO_CREATE=true

۷. خط قرمزها (ممنوعیت‌های مطلق)

❌ هرگز ✅ همیشه
برگرداندن کشورها به ۲ زون ۴ زون مجزا (Export/Import × Parcel/Doc)
استفاده از ۲ نوع سرویس ۳ نوع (DOC_NORMAL، DOC_ECONOMY، PARCEL)
ذخیرهٔ تاریخ شمسی در DB ذخیرهٔ timestamp میلادی + تبدیل در نمایش
CORS * در Production CORS محدود به دامنهٔ وردپرس
کامیت .env در Git قرار دادن .env در .gitignore
APP_DEBUG=true در Production APP_DEBUG=false
PDF فارسی (AWB / Invoice / Label) همیشه انگلیسی (برای حمل بین‌المللی)
کپی از DHL طراحی منحصر به فرد IFNEX
استفاده از wire:click برای دانلود استفاده از <a href> با روت مستقیم
getFormActions() در Custom Pages استفاده از wire:click در Blade
هدایت AJAX به redirect() استفاده از payment_url در response JSON
متدهای نوتیفیکیشن بیرون از کلاس داخل کلاس IFNEX_User_Bridge
روت staff/admin بدون چک نقش چک نقش یا مالکیت در middleware یا ابتدای کنترلر
هدایت مستقیم سفارش به درگاه پس از ثبت فلوی pending_approval ← approved ← پرداخت

۸. نکات ویژه برای ایجنت

اصول کلی

  • هنگام تولید کد جدید، حتماً از Enum‌ها به‌جای رشته‌های سخت‌کدشده استفاده کن.
  • برای هر مدل جدید، migration، مدل و در صورت نیاز کنترلر یا Resource فیلمنت بساز.
  • هنگام استفاده از هر Model در فایل جدید، حتماً use App\Models\... را import کن. (باگ اخیر نبودِ import برای SystemSetting در PaymentController / ShipmentObserver / TrackingService، فلوی تأیید و پرداخت را می‌شکست — کامیت 2737e26).
  • مدیریت تاریخ همیشه با Carbon انجام می‌شود و ذخیره به‌صورت Y-m-d H:i:s در DB است.
  • برای کوئری‌های سنگین از chunk() یا cursor() استفاده کن تا حافظه مصرف نشود.

خطاهای رایج

  • نبودِ فیلد deleted_at در کوئری‌ها (در صورت استفاده از SoftDeletes).
  • فراموشی fillable یا casts در مدل‌ها.
  • فراموشی $with برای بارگذاری روابط در Resourceها.
  • استفاده از redirect() در کنترلرهای API (باید JSON برگردانند).

قواعد حوزهٔ کار

  • برای تغییر وضعیت مرسوله، حتماً تاریخچه را به‌روز کن (ShipmentStatusHistory با from_status / to_status / reason).
  • در فرم سفارش مشتری، مرحلهٔ Invoice فقط برای نوع PARCEL نمایش داده می‌شود.
  • تولید PDF با بارکد به‌صورت base64 embed انجام می‌شود.
  • Bridge Auth نیازی به رمز عبور ندارد و فقط از IFNEX_BRIDGE_API_KEY استفاده می‌کند.
  • تست لوکال پرداخت: از ZARINPAL_MERCHANT_ID=fake-merchant-id-for-testing برای فعال‌سازی Mock Gateway استفاده کن.

هشدارهای تاریخی

  • مارک‌آپ شورت‌کدهای وردپرس: باز و بسته بودن divها را متوازن نگه دار. باگ «مرحلهٔ ۲ فرم سفارش لود نمی‌شود» ریشه‌اش یک div بسته‌نشده در shortcodes.php بود که مراحل را داخل هم nest می‌کرد. هک‌های MutationObserver و setInterval هیچ‌کدام مشکل را حل نکردند و حذف شدند.
  • هک‌های موقت دیباگ: opcache_reset() و header() در بالای فایل‌های پلاگین و cache-buster با time() فقط برای کار لوکال هستند و باید پیش از دیپلوی حذف شوند.

۹. کارهای باقی‌مانده (فاز ۳.۶)

# کار وضعیت
۱ تست انتهای فلوی سفارش: آپلود تعهدنامه ← تأیید کارمند ← پرداخت کیف پول یا درگاه ✅ انجام شد (۲۰۲۶-۱۰-۰۴)
۲ امنیت: چک نقش /staff/*، چک مالکیت PDF و تعهدنامه، محدودسازی discount-codes، rate limiting ✅ انجام شد (۲۰۲۶-۱۰-۰۴)
۳ بازطراحی سیستم اعتبار چندارزی + نمایش در پورتال مشتری + ویجت هشدار داشبورد ✅ انجام شد (۲۰۲۶-۱۰-۰۴)
۴ چک‌لیست خودکار کارمند پس از تأیید سفارش ✅ انجام شد (instantiateChecklist() در approve())
۵ سند پیشنهادی سیستم مالی (درخواست ۱۳ کارفرما) ⏳ موکول به آینده
۶ پاک‌سازی: فایل‌های تستی، cache-busterها، !importantها ✅ انجام شد (۲۰۲۶-۱۰-۰۴)
۷ نمایش وزن واقعی و حجمی در خلاصهٔ قیمت وردپرس ✅ در API موجود است (weight + volumetric_weight در پاسخ)
۸ چندزبانه (i18n) ⏳ موکول به زمان دیپلوی

وضعیت کلی فاز ۳.۶: حدود ۹۵٪ تکمیل. تنها موارد باقی‌مانده: i18n (زمان دیپلوی) و سند پیشنهادی مالی (آینده).


۱۰. مستندات مرجع

فایل محتوا
01_Documents/EXCEL_ANALYSIS.md تحلیل کامل فایل‌های اکسل (۳۹۵۰ رکورد، فرمول‌ها، زون‌ها)
01_Documents/IFNEX_Phase0_Checklist.md چک‌لیست کامل فازها (۰ تا ۳.۵)
01_Documents/IFNEX_Roadmap.md نقشهٔ راه فازی (تا فاز ۳.۶)
01_Documents/IFNEX_File_Map.md نقشهٔ ۱۰۰+ فایل پروژه
01_Documents/IFNEX_I18N_Strategy.md استراتژی چندزبانه (برای زمان دیپلوی)
01_Documents/IFNEX_Commercial_Model.md مدل تجاری و پلن‌های فروش
01_Documents/DESIGN_SYSTEM.md رنگ‌ها، تایپوگرافی، فاصله‌گذاری
DEPLOYMENT.md راهنمای کامل استقرار روی سرور
DEPLOYMENT_HANDOFF.md تحویل استقرار به تیم IT کارفرما
04_Laravel/README.md راهنمای بک‌اند
CLIENT_DELIVERY.md چک‌لیست وضعیت تحویل مشتری (منبع اصلی وضعیت تحویل)