docs: fix all discrepancies based on comprehensive code audit

Corrections verified against actual CMS/BackOffice/FrontOffice source code:

- ClubActivationFee: 25,200,000 (not 25,000,000)
- Tree depth: no limit (15 is commission calculation depth only)
- IPG wallet charge: Balance=56M + Discount=56M
- DayaLoan wallet charge: Balance=56M + Discount=112M (2×)
- Discount: per-product MaxDiscountPercent (not fixed 30%)
- VAT: 10% (ShopVAT) vs 9% (discount store PlaceOrder)
- Kavenegar template: 'Afrino' only (not verify-foursat)
- SMS sender: 1000001110100
- DayaLoan job: every 20min (not 15min)
- Commission job: Sunday 00:05 (not Saturday)
- Network tree: on User entity (not separate NetworkNode table)
- UserWallets entity (not UserWalletBalances)
- OTP: 6 digits, 5 attempts, 2min TTL, 60s cooldown
- Removed non-existent constants (ClubJoiningPercentage, ClubActivationThreshold)
- Fixed Hangfire Chatika interval: every 5min
- Removed InventorySync from recurring jobs list
This commit is contained in:
masoodafar-web
2026-02-18 22:58:40 +03:30
parent efff5e9cd5
commit 3c729304db
10 changed files with 130 additions and 107 deletions
+13 -11
View File
@@ -63,10 +63,12 @@ JWT Claims:
| مشکل | راه‌حل | وضعیت |
|------|---------|--------|
| OTP تکراری | Rate limiting: ۱ درخواست هر ۶۰ ثانیه | ✅ |
| OTP تکراری | Cooldown: ۶۰ ثانیه بین درخواست‌ها | ✅ |
| شماره نامعتبر | Regex validation ایران `^09\d{9}$` | ✅ |
| حمله brute-force | قفل حساب بعد از ۵ تلاش ناموفق | ✅ |
| Race condition ثبت‌نام | Unique constraint + transaction | ✅ |
| حمله brute-force | MaxAttempts: ۵ تلاش برای تأیید کد | ✅ |
| انقضای کد | TTL: ۲ دقیقه | ✅ |
| طول کد | ۶ رقم | ✅ |
| قالب SMS | Kavenegar template: `Afrino` | ✅ |
---
@@ -136,15 +138,15 @@ RequestContractOtp → ارسال SMS
### ۴.۲ ذخیره‌سازی قرارداد
```csharp
// از کد: UserContract : BaseAuditableEntity
public class UserContract {
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string ContractVersion { get; set; } // e.g., "v1.2"
public string ContractText { get; set; } // snapshot متن
public DateTime AcceptedAt { get; set; }
public string OtpVerificationId { get; set; }
public string IpAddress { get; set; }
public string UserAgent { get; set; }
public long UserId { get; set; }
public virtual User User { get; set; }
public long ContractId { get; set; } // FK → Contract
public virtual Contract Contract { get; set; }
public string SignGuid { get; set; } // GUID یکتای امضا
public string SignedPdfFile { get; set; } // فایل PDF امضاشده
// فیلدهای BaseAuditableEntity: CreatedAt, ModifiedAt, ...
}
```