ifnex/04_Laravel/config/ifnex.php
Kazem Alghasi f1d5667fe8 feat(deploy): preflight + smoke-test + UAT checklist (phases 3.9.1–3.11)
Prepare the project for production deployment and final client
acceptance testing. Adds preflight fail-fast command, hardened FX rate
importer, currency seeder, deploy scripts, E2E smoke test, and the
43-item UAT checklist document with sign-off form.

Key changes:

- Phase 3.9.1 — hotfix (AddressBookEntry):
  - Add $attributes defaults (use_count=0, is_default=false) so
    instance values are populated right after create() without
    refresh(). Resolves the red test
    `it_increments_use_count_and_sets_last_used_at`.

- Phase 3.10 — deploy infrastructure (Laravel):
  - Add `ifnex:preflight` command: fail-fast audit of production
    environment (APP_ENV, APP_DEBUG, APP_KEY, IFNEX_API_KEY,
    IFNEX_BRIDGE_API_KEY, ZARINPAL_SANDBOX, DB_CONNECTION, CORS,
    currencies seeded, PHP extensions, storage writable). Exits 1
    if any check fails; supports --skip-db for pre-migrate runs.
  - Add `ifnex:import-fx-rates` command: replacement for
    `ifnex:update-rates`. Fetches USD/AED from Exir.io + EUR/CNY
    from FreeCurrencyAPI. Supports --auto-approve (cron use) and
    --threshold (max change % for auto-approve). Logs critical on
    HTTP failure. URL configurable via EXIR_API_URL env.
  - Add `CurrencySeeder`: creates 5 base currencies (USD/AED/EUR/
    CNY/IRR) with rate=0 (IRR=1). Idempotent — does not overwrite
    real rates already set by admin or cron.
  - Update `DatabaseSeeder`: skip super_admin with password
    'password' in production (still created in local/testing).
  - Fix `bootstrap/app.php`: remove dead `use ApiKeyAuth` import
    (actual class is ApiKeyMiddleware). Latent fatal if api_key
    alias was used.
  - Add `config/ifnex.php` exir block + preflight config.
  - Harden `.env.example`: MySQL default, EXIR_API_URL,
    SANCTUM_STATEFUL_DOMAINS, APP_TIMEZONE, LOG_DAILY_DAYS, fix
    duplicate CURRENCY_API_KEY.

- Phase 3.10 — deploy scripts (Linux):
  - Add `scripts/deploy.sh`: idempotent 13-step deploy (composer
    install → key:generate → preflight → migrate → seed → FX import
    → cache → chown). Fail-fast with set -e.
  - Add `scripts/cron-exir-rates.sh`: daily cron wrapper for
    `ifnex:import-fx-rates --source=all --auto-approve`.

- Phase 3.10.1 — preflight hotfix:
  - Make expected DB connection configurable
    (ifnex.preflight.expected_db_connection) instead of hardcoded
    'mysql'. Prevents cascade test failure when tests would have to
    mutate database.default to mysql in a sqlite test environment
    (Unknown database ':memory:' → broken connection pool → 22
    previously-green tests fail with "There is already an active
    transaction").
  - Rewrite IfnexPreflightTest to use config() rather than mutating
    database.default.

- Phase 3.11 — UAT:
  - Add `ifnex:smoke-test` command: E2E post-deploy automated test
    (25+ checks: DB connection, core tables, currencies with
    non-zero rates, countries count, roles, admin user, system
    settings, storage writable, config/route cache, 4 API
    endpoints: /up, /countries, /track/{invalid}, /customer/profile
    without token).
  - Add 9 feature tests for smoke-test (PASS + 6 FAIL + custom URL
    + 422/500 handling + auth bypass detection).
  - Add `UAT-3.11.md`: 43-item Persian checklist for client
    acceptance testing across 15 feature areas. Includes sign-off
    form for both parties (client + VernaSoft).
  - Update `CLIENT_DELIVERY.md` to record phases 3.10 and 3.11.

Tests:
- Total: 51 → 82 tests, 150 → 220+ assertions, all green.
- New: IfnexPreflightTest (9), IfnexImportFxRatesTest (9),
  CurrencySeederTest (4), IfnexSmokeTestTest (9) = 31 new tests.

Documentation:
- DEPLOYMENT_HANDOFF.md §2.4: add CurrencySeeder + import-fx-rates.
- DEPLOYMENT_HANDOFF.md §2.8: update cron to use cron-exir-rates.sh.
- UAT-3.11.md: new 43-item client acceptance checklist + sign-off.
- CLIENT_DELIVERY.md: record phases 3.10 and 3.11 completion.
2026-10-31 22:18:15 +03:30

205 lines
9.6 KiB
PHP
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.

<?php
return [
'bridge_api_key' => env('IFNEX_BRIDGE_API_KEY', 'change-this-secret-key'), // This is the API key that you get from the IFNEX Bridge
/*
|--------------------------------------------------------------------------
| IFNEX API Settings
|--------------------------------------------------------------------------
| تنظیمات عمومی API سیستم ایف‌نکس
*/
'api_key' => env('IFNEX_API_KEY', 'change-me'),
'cors_allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', 'http://localhost,http://127.0.0.1')),
'tracking_rate_limit' => env('IFNEX_TRACKING_RATE_LIMIT', 60),
/*
|--------------------------------------------------------------------------
| Carrier Codes (کدهای شرکت‌های حمل‌ونقل)
|--------------------------------------------------------------------------
| لیست شرکت‌های حمل‌ونقل فعال در سیستم
*/
'carrier_codes' => [
'DHL',
'FEDEX',
'UPS',
'ARAMEX',
'NAGHEL',
'EMX',
'APSITEX',
'IMPEX',
'OTHER',
],
/*
|--------------------------------------------------------------------------
| Tracking Statuses (وضعیت‌های رهگیری مرسوله)
|--------------------------------------------------------------------------
*/
'tracking_statuses' => [
'processed',
'picked_up',
'in_transit',
'out_for_delivery',
'failed',
'delivered',
'returned',
],
/*
|--------------------------------------------------------------------------
| Currency API (به‌روزرسانی نرخ ارز)
|--------------------------------------------------------------------------
| FreeCurrencyAPI برای EUR و CNY (Exir.io این دو را ندارد).
| USD و AED از Exir.io می‌آیند (دقیق‌تر در بازار ایران).
*/
'currency' => [
'api_key' => env('CURRENCY_API_KEY'),
'api_url' => env('CURRENCY_API_URL', 'https://api.freecurrencyapi.com/v1/latest'),
'base_currency' => 'USD',
'target_currencies' => ['IRR', 'AED', 'EUR', 'CNY'],
],
/*
|--------------------------------------------------------------------------
| Exir.io (نرخ ارز بازار ایران)
|--------------------------------------------------------------------------
| منبع نرخ USD و AED — نیازی به API key ندارد.
| برای دریافت EUR/CNY از FreeCurrencyAPI استفاده می‌شود.
*/
'exir' => [
'api_url' => env('EXIR_API_URL', 'https://api.exir.io/v2/minicharts'),
'timeout' => (int) env('EXIR_API_TIMEOUT', 15),
],
/*
|--------------------------------------------------------------------------
| Preflight (بررسی پیش‌از-دیپلوی)
|--------------------------------------------------------------------------
| اگر در محیط تست یا staging می‌خواهید preflight سبز شود
| بدون اینکه واقعاً به MySQL وصل شوید، این متغیر را روی sqlite بگذارید.
| در Production همیشه mysql باید باشد.
*/
'preflight' => [
'expected_db_connection' => env('IFNEX_PREFLIGHT_DB', 'mysql'),
],
/*
|--------------------------------------------------------------------------
| Zarinpal Payment Gateway (درگاه پرداخت زرین‌پال)
|--------------------------------------------------------------------------
| تنظیمات اتصال به درگاه زرین‌پال برای شارژ کیف پول
*/
'zarinpal' => [
// شناسه پذیرنده (Merchant ID) از پنل زرین‌پال
'merchant_id' => env('ZARINPAL_MERCHANT_ID', 'fake-merchant-id-for-testing'),
// محیط Sandbox برای تست (true) یا Production (false)
'sandbox' => env('ZARINPAL_SANDBOX', true),
// URL Callback که زرین‌پال بعد از پرداخت کاربر را به آن redirect می‌کند
'callback_url' => env('ZARINPAL_CALLBACK_URL', null),
// اگر null باشد، از url('/api/v1/payment/callback') استفاده می‌شود
// URL فرانت‌اند برای redirect بعد از پرداخت موفق
'frontend_success_url' => env('ZARINPAL_FRONTEND_SUCCESS_URL', '/payment/success'),
// URL فرانت‌اند برای redirect بعد از پرداخت ناموفق
'frontend_failure_url' => env('ZARINPAL_FRONTEND_FAILURE_URL', '/payment/failed'),
// زمان انقضای تراکنش‌های pending (به دقیقه)
'transaction_expiry_minutes' => env('ZARINPAL_EXPIRY_MINUTES', 30),
],
/*
|--------------------------------------------------------------------------
| Wallet Settings (تنظیمات کیف پول)
|--------------------------------------------------------------------------
| قوانین و محدودیت‌های کیف پول کاربران
*/
'wallet' => [
// حداقل مبلغ شارژ آنلاین (ریال) - معمولاً ۱۰,۰۰۰ ریال
'min_deposit_amount' => env('WALLET_MIN_DEPOSIT', 10000),
// حداکثر مبلغ شارژ در هر تراکنش (ریال) - معمولاً ۵۰۰ میلیون ریال
'max_deposit_amount' => env('WALLET_MAX_DEPOSIT', 500000000),
// حداقل موجودی لازم برای پرداخت سفارش از کیف پول (ریال)
'min_balance_for_payment' => env('WALLET_MIN_BALANCE', 1000),
// کارمزد شارژ کیف پول (درصد) - معمولاً ۰٪
'deposit_fee_percent' => env('WALLET_DEPOSIT_FEE', 0),
// آیا کیف پول به‌صورت پیش‌فرض هنگام ثبت‌نام کاربر ساخته شود؟
'auto_create_on_register' => env('WALLET_AUTO_CREATE', true),
// آیا کاربران عادی اجازه برداشت (cash out) دارند؟
'allow_withdrawal' => env('WALLET_ALLOW_WITHDRAWAL', false),
],
/*
|--------------------------------------------------------------------------
| Financial Defaults (پیش‌فرض‌های مالی)
|--------------------------------------------------------------------------
| این مقادیر فقط fallback هستند — مقادیر واقعی از جدول system_settings خوانده می‌شوند
*/
'financial_defaults' => [
'vat_rate' => 0.09, // ۹٪ مالیات بر ارزش افزوده
'profit_margin' => 1.25, // ۲۵٪ حاشیه سود
'packing_cost' => 100000, // ۱۰۰,۰۰۰ ریال هزینه بسته‌بندی پیش‌فرض
// ⚠️ نرخ‌های ارز فقط از جدول currencies خوانده می‌شوند (هیچ fallback عددی نداریم).
// اگه ارز در دیتابیس نباشد، ExchangeRateService خطا می‌دهد و مدیر باید آن را تنظیم کند.
// این عدد فقط برای جلوگیری از Fatal Error در تست‌های قدیمی نگه داشته شده — نباید به آن اعتماد کرد.
'aed_to_irr' => 7419700, // [Deprecated — فقط تست] 7,419,700 ریال/درهم (اکتبر ۲۰۲۶)
],
/*
|--------------------------------------------------------------------------
| Notification Settings (تنظیمات اعلان‌ها)
|--------------------------------------------------------------------------
*/
'notifications' => [
// آیا هنگام شارژ موفق به کاربر ایمیل/پیامک زده شود؟
'notify_on_deposit' => env('NOTIFY_ON_DEPOSIT', true),
// آیا هنگام شارژ دستی توسط ادمین به کاربر اطلاع داده شود؟
'notify_on_manual_adjustment' => env('NOTIFY_ON_MANUAL_ADJUSTMENT', true),
// آیا هنگام رسیدن موجودی به آستانه هشدار، اطلاع داده شود؟
'low_balance_threshold' => env('LOW_BALANCE_THRESHOLD', 500000), // ۵۰۰,۰۰۰ ریال
],
/*
|--------------------------------------------------------------------------
| Kavenegar SMS Gateway (درگاه پیامک کاوه‌نگار)
|--------------------------------------------------------------------------
*/
'kavenegar' => [
'api_key' => env('KAVENEGAR_API_KEY', ''),
'sender' => env('KAVENEGAR_SENDER', '10008566'),
'send_shipment_approved' => env('KAVENEGAR_SEND_SHIPMENT_APPROVED', true),
'send_shipment_rejected' => env('KAVENEGAR_SEND_SHIPMENT_REJECTED', true),
'send_payment_success' => env('KAVENEGAR_SEND_PAYMENT_SUCCESS', true),
'send_tracking_update' => env('KAVENEGAR_SEND_TRACKING_UPDATE', false),
],
/*
|--------------------------------------------------------------------------
| Audit & Logging (ثبت فعالیت‌ها و لاگ)
|--------------------------------------------------------------------------
*/
'audit' => [
// آیا تمام عملیات مالی لاگ شوند؟ (توصیه می‌شود همیشه true باشد)
'log_financial_operations' => true,
// آیا IP و User Agent کاربر در تراکنش‌ها ذخیره شود؟
'track_client_info' => true,
// تعداد روز نگهداری لاگ‌های قدیمی (برای پاک‌سازی خودکار)
'log_retention_days' => env('AUDIT_LOG_RETENTION_DAYS', 365),
],
];