ifnex/README-INSTALL.md
Kazem Alghasi b9ede16613 refactor(core): harden production environment and fix discount logic
Implement critical security hardening and resolve a P0 bug in the
discount code consumption flow. This update transitions the system
from a development-heavy configuration to a production-ready state.

Key changes:
- Fix P0 bug where `consumeDiscountCode()` was missing, breaking order
  registration; replaced with a robust `DiscountCodeService` using
  `discount_code_usages` for audit trails and idempotency.
- Implement strict production guards for the Zarinpal payment gateway
  to prevent accidental mock processing in live environments.
- Refactor WordPress bridge asset management to use `filemtime` based
  versioning instead of `time()` to prevent unnecessary cache busting.
- Remove debug-only hacks (`opcache_reset`, `header` cache control)
  from the WordPress plugin.
- Enhance file upload security by enforcing strict `mimetypes` validation.
- Update `.gitignore` to exclude sensitive WordPress configuration
  files and local PHPUnit caches.
- Add comprehensive documentation for production deployment, including
  security checklists and key rotation procedures.
- Update test suite to reflect new architecture and ensure 100%
  coverage of the discount service.
2026-10-31 19:18:58 +03:30

111 lines
5.7 KiB
Markdown
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.

# 📦 بسته بروزرسانی IFNEX — فاز ۳.۸.۱ (سخت‌سازی Production)
**تاریخ:** ۳۱ اکتبر ۲۰۲۶
**تعداد فایل‌ها:** ۲۱ فایل + این راهنما
**⚠️ شامل یک فیکس بحرانی (P0):** باگ ثبت سفارش — حتماً اعمال شود
---
## 🚨 مهم‌ترین فیکس: باگ P0 کد تخفیف
در بازبینی امنیتی کشف شد که متد `consumeDiscountCode()` در کنترلر سفارش **صدا زده می‌شد ولی هیچ‌جا تعریف نشده بود** — یعنی:
> ❌ **ثبت سفارش مشتری در وضعیت فعلی کلاً خطای 500 می‌دهد!**
(این باگ از کامیت فلوی بازبینی/ارسال مجدد وارد کد شده بود و چون تست‌های قدیمی شکسته بودند پنهان مانده بود)
**راه‌حل اعمال‌شده در این بسته:**
- سرویس جدید `DiscountCodeService` + جدول `discount_code_usages`
- مصرف یک‌بار هر کد + رکورد Audit کامل (چه کسی، چه سفارشی، چه مبلغی)
- قفل رقابتی (`lockForUpdate`) — دو ثبت همزمان نمی‌توانند ظرفیت را دور بزنند
- خطای 422 با پیام واضح اگر کد بین محاسبه و ثبت منقضی شود
- گارد ظرفیت در قیمت‌گذاری هم
---
## 🔧 بقیه تغییرات (سخت‌سازی Production)
| # | فیکس | توضیح |
|---|------|-------|
| ۱ | **گارد Mock Gateway** | اگر روی سرور `APP_ENV=production` باشد و درگاه تستی تنظیم شده باشد، پردازش با خطای صریح مسدود می‌شود (قبلاً خطر پرداخت مجازی واقعی وجود داشت!) |
| ۲ | **حذف هک‌های دیباگ وردپرس** | `opcache_reset()` و `header('Cache-Control: no-store')` از ۵ فایل پلاگین حذف شد — در Production باعث header error و شکستن کش می‌شد |
| ۳ | **نسخه‌بندی سالم assetها** | cache-buster `'2.0.0-' . time()` (هر بار کش را می‌شکست) با `filemtime` جایگزین شد — کش فقط وقتی فایل عوض شود باطل می‌شود |
| ۴ | **سخت‌سازی آپلود تعهدنامه** | `mimetypes` اضافه شد — محتوای واقعی فایل بررسی می‌شود نه فقط پسوند |
| ۵ | **`.env.example` بروز** | بلوک Production (لاگ روزانه، APP_DEBUG=false، کش‌ها) + `IFNEX_BRIDGE_API_KEY` + راهنمای چرخش کلید |
| ۶ | **سند استقرار** | بخش جدید «۴.۴ چک‌لیست امنیتی سخت‌سازی» در `DEPLOYMENT_HANDOFF.md` |
| ۷ | **تعمیر و توسعه تست‌ها** | ۷ تست شکستهٔ قدیمی تعمیر شد + ۹ تست جدید → **۳۳ تست پاس، ۱۰۱ assertion** ✅ |
---
## ⚠️ دو فایل از گیت حذف شده‌اند (اقدام دستی لازم!)
این بسته شامل حذف ۲ فایل از **ایندکس گیت** است (نه از دیسک!):
| فایل | دلیل |
|------|------|
| `03_WordPress/wp-config.php` | حاوی saltهای واقعی بود — لو‌رفته فرض می‌شود؛ فقط `wp-config-sample.php` در مخزن می‌ماند |
| `04_Laravel/.phpunit.result.cache` | فایل کش محلی — نباید در گیت باشد |
چون ZIP نمی‌تواند حذف انجام دهد، **بعد از اکسترکت** این دو دستور را در ریشه پروژه اجرا کنید:
```bash
git rm --cached 03_WordPress/wp-config.php
git rm --cached 04_Laravel/.phpunit.result.cache
```
> ✅ `.gitignore` بروز شده و بعد از این، این فایل‌ها دیگر کامیت نمی‌شوند.
> فایل `wp-config.php` روی دیسک شما دست‌نخورده باقی می‌ماند.
---
## 📥 روش نصب
1. محتوای پوشه `ifnex-updates/` را **دقیقاً روی ریشه پروژه IFNEX** اکسترکت کنید (Replace)
2. دو دستور `git rm --cached` بالا را اجرا کنید
3. مراحل بعد از اکسترکت (پایین) را انجام دهید
---
## ⚙️ مراحل بعد از اکسترکت
### Laravel:
```bash
cd 04_Laravel
# مایگریشن جدید (جدول discount_code_usages)
php artisan migrate
# اجرای تست‌ها — باید ۳۳ پاس ببینید
php artisan test
```
### WordPress:
- پلاگین `ifnex-bridge` را غیرفعال و دوباره فعال کنید
- اگر کش افزونه دارید، پاکسازی کنید
---
## ✅ چک‌لیست تست سریع
| # | تست | نتیجه مورد انتظار |
|---|-----|-------------------|
| 1 | `php artisan test` | **33 passed, 101 assertions** |
| 2 | `php artisan migrate` | مایگریشن `discount_code_usages` بدون خطا |
| 3 | ثبت سفارش **بدون** کد تخفیف | موفق (این قبلاً 500 می‌داد!) |
| 4 | ثبت سفارش **با** کد تخفیف فعال | موفق + `used_count` کد +1 می‌شود |
| 5 | ثبت سفارش دوم با همان کد (اگر usage_limit=1) | خطای 422 با پیام واضح |
| 6 | فرم سفارش وردپرس | بدون خطای کنسول؛ assetها با `?ver=2.1.0.xxx` لود می‌شوند |
---
## 📤 بعد از تست موفق
```bash
git add -A
git commit -m "apply: IFNEX phase 3.8.1 package (production hardening + P0 discount fix)"
git push origin main
```
> ⚠️ **قبل از دیپلوی روی سرور:** چک‌لیست بخش ۴.۴ فایل `DEPLOYMENT_HANDOFF.md` را حتماً انجام دهید
> (چرخش کلیدها، بازتولید saltهای وردپرس، تنظیم درگاه واقعی، لاگ روزانه، کش‌ها).