diff --git a/business/BUSINESS-01-CLUB-COMMISSION.md b/business/BUSINESS-01-CLUB-COMMISSION.md index ec0f757..1f39c69 100644 --- a/business/BUSINESS-01-CLUB-COMMISSION.md +++ b/business/BUSINESS-01-CLUB-COMMISSION.md @@ -9,10 +9,10 @@ | مفهوم | توضیح | |-------|--------| -| **عضویت باشگاه** | خرید پکیج طلایی (۵۶M) → فعالسازی (۲۵M) → عضو فعال باشگاه | -| **درخت باینری** | هر کاربر حداکثر ۲ فرزند مستقیم (چپ/راست) — حداکثر ۱۵ سطح | -| **کمیسیون هفتگی** | محاسبه بر اساس تعادل چپ/راست — هفته شمسی شنبه‌تا‌جمعه | -| **۳ کیف پول** | `Balance` (نقدی) + `NetworkBalance` (شبکه‌ای) + `DiscountBalance` (تخفیفی) | +| **عضویت باشگاه** | خرید پکیج طلایی (۵۶M) → فعالسازی (۲۵.۲M) → عضو فعال باشگاه | +| **درخت باینری** | هر کاربر حداکثر ۲ فرزند مستقیم (چپ/راست) — بدون محدودیت عمق | +| **کمیسیون هفتگی** | محاسبه بر اساس تعادل چپ/راست — یکشنبه ۰۰:۰۵ (Hangfire cron) | +| **۳ کیف پول** | `Balance` (نقدی) + `NetworkBalance` (طلایی/کمیسیون) + `DiscountBalance` (تخفیفی) | --- @@ -25,14 +25,14 @@ / \ / \ L1 L2 R1 R2 / \ / \ / \ / \ - ... ... ... ... ... ← حداکثر ۱۵ سطح + ... ... ... ... ... ← بدون محدودیت عمق ``` **قوانین:** -- هر نود حداکثر ۲ فرزند (Binary) -- جایگذاری: `LegPosition` ∈ {Left, Right} -- عضو جدید → در اولین جای خالی از چپ‌ترین مسیر قرار می‌گیرد -- `SP_GetNetworkTree` — Stored Procedure بازگشتی +- هر نود حداکثر ۲ فرزند (Binary) — `MaxDirectChildrenPerLeg = 1` +- جایگذاری: `LegPosition` ∈ {Left=0, Right=1} (enum `NetworkLeg`) +- مدل شبکه مستقیم روی entity `User` — فیلدهای `NetworkParentId`, `LegPosition`, `NetworkChildren` +- محاسبه کمیسیون تا عمق ۱۵ سطح (`CommissionMaxNetworkLevel = 15`) — اما درخت بدون محدودیت رشد می‌کند --- @@ -56,11 +56,16 @@ ▼ امضای قرارداد ← AcceptContract │ - ├─→ شارژ ۳ کیف پول (Balance=56M, Network=56M, Discount=56M) - ├─→ کسر هزینه فعالسازی (25M از Balance) - ├─→ واریز 25.2M به Pool هفتگی + ├─→ شارژ ۲ کیف پول: Balance += 56M, DiscountBalance += 56M + │ (NetworkBalance شارژ نمی‌شود — فقط برای کمیسیون) + ├─→ کسر هزینه فعالسازی (25.2M از Balance) + ├─→ واریز 25.2M به Pool هفتگی (ClubActivationFee) ├─→ قرارگیری در درخت باینری └─→ رفرش JWT Token (claims جدید) + +⚠️ در خرید با وام دایا: + ├─→ Balance += 56M + └─→ DiscountBalance += 112M (دو برابر — DayaLoanAmount × 2) ``` --- @@ -109,17 +114,18 @@ SP: sp_CalculateWeeklyBalances → sp_CalculateWeeklyCommissionPool ## ۵. تنظیمات سیستمی (SystemConstants) -| ثابت | مقدار | توضیح | +| ثابت (SystemConstants) | مقدار | توضیح | |------|-------|--------| -| `Club.ActivationFee` | 25,000,000 | هزینه فعالسازی (تومان) | -| `Club.GiftValue` | 25,200,000 | واریز به Pool | -| `GoldenPackageAmount` | 56,000,000 | قیمت پکیج طلایی | -| `DayaLoanAmount` | 56,000,000 | مبلغ وام دایا | -| `MaxWeeklyBalancesPerLeg` | 300 | سقف هفتگی هر پا | -| `MaxNetworkLevel` | 15 | حداکثر عمق درخت | -| `ClubJoiningPercentage` | 0.35 | درصد پیوستن | -| `ClubActivationThreshold` | 0.5 | آستانه فعالسازی | -| `MaxCalculationAttempts` | 3 | حداکثر تلاش محاسبه | +| `ClubActivationFee` | 25,200,000 | هزینه فعالسازی (ریال) | +| `ClubMembershipGiftValue` | 25,200,000 | واریز به Pool | +| `BasePackageAmount` | 56,000,000 | قیمت پکیج طلایی (ریال) | +| `DayaLoanAmount` | 56,000,000 | مبلغ وام دایا (ریال) | +| `CommissionMaxWeeklyBalancesPerLeg` | 300 | سقف هفتگی هر پا | +| `CommissionMaxNetworkLevel` | 15 | عمق محاسبه کمیسیون (نه محدودیت درخت) | +| `MaxDirectChildrenPerLeg` | 1 | حداکثر فرزند مستقیم هر پا | +| `MinimumWithdrawAmount` | 1,000,000 | حداقل مبلغ برداشت (ریال) | +| `ShopVAT` | 0.1 (10%) | مالیات ارزش افزوده | +| `CommissionCalculationMethod` | "SP" | روش محاسبه = Stored Procedure | --- @@ -127,8 +133,8 @@ SP: sp_CalculateWeeklyBalances → sp_CalculateWeeklyCommissionPool | سناریو | فلو | وضعیت | |--------|------|--------| -| **وام دایا** | درخواست وام → تأیید خودکار → شارژ ۳ کیف‌پول (۱۶۸M) | ✅ پیاده‌شده | -| **درگاه مستقیم** | IPG (ZarinPal) → callback → شارژ | ✅ پیاده‌شده | +| **وام دایا** | درخواست وام → تأیید → Balance=56M + Discount=112M (مجموع ۱۶۸M) | ✅ پیاده‌شده | +| **درگاه مستقیم** | IPG → callback → Balance=56M + Discount=56M (مجموع ۱۱۲M) | ✅ پیاده‌شده | | **پرداخت دستی** | کارت‌به‌کارت → آپلود رسید → تأیید ادمین → شارژ | ⚠️ طراحی‌شده | --- @@ -136,7 +142,7 @@ SP: sp_CalculateWeeklyBalances → sp_CalculateWeeklyCommissionPool ## ۷. یکپارچه‌سازی وام دایا ``` -Hangfire Worker (هر ۱۵ دقیقه) +Hangfire Worker (هر ۲۰ دقیقه — cron: */20 * * * *) │ ▼ بررسی درخواست‌های pending @@ -145,13 +151,13 @@ Hangfire Worker (هر ۱۵ دقیقه) ارسال به API دایا (Mock/Real switchable) │ ▼ -دریافت نتیجه → شارژ ۳ کیف‌پول +دریافت نتیجه → شارژ ۲ کیف‌پول │ - ├─→ Balance = 56M - ├─→ NetworkBalance = 56M - └─→ DiscountBalance = 56M (مجموع: 168M) + ├─→ Balance += 56M (DayaLoanAmount) + └─→ DiscountBalance += 112M (DayaLoanAmount × 2 — دو برابر) + مجموع: 168M -Polly Retry: 3 attempts, Exponential backoff +Hangfire retry: [AutomaticRetry(Attempts = 3)] ``` --- diff --git a/business/BUSINESS-02-PAYMENT-FINANCE.md b/business/BUSINESS-02-PAYMENT-FINANCE.md index ee0fc44..ef50e16 100644 --- a/business/BUSINESS-02-PAYMENT-FINANCE.md +++ b/business/BUSINESS-02-PAYMENT-FINANCE.md @@ -63,7 +63,7 @@ Redirect کاربر → صفحه پرداخت ZarinPal ### ۳.۱ معماری ``` -Hangfire Recurring Job (هر ۱۵ دقیقه) +Hangfire Recurring Job (هر ۲۰ دقیقه — cron: */20 * * * *) │ ▼ DayaLoanProcessorJob.Execute() @@ -73,10 +73,10 @@ DayaLoanProcessorJob.Execute() │ ▼ برای هر درخواست: - ├─→ ارسال به DayaLoan API (با Polly retry ×3) - ├─→ در صورت تأیید: شارژ ۳ کیف‌پول (هرکدام ۵۶M) + ├─→ ارسال به DayaLoan API ([AutomaticRetry(Attempts=3)]) + ├─→ در صورت تأیید: Balance += 56M, DiscountBalance += 112M (2×) ├─→ ثبت Transaction + Log - └─→ در صورت رد: بروزرسانی Status=Rejected + ارسال SMS + └─→ در صورت رد: Status=Rejected + ارسال SMS ``` ### ۳.۲ Mock Mode @@ -95,9 +95,11 @@ DayaLoanProcessorJob.Execute() | آیتم | مقدار | |------|-------| -| مبلغ وام | ۵۶,۰۰۰,۰۰۰ تومان | -| شارژ هر کیف‌پول | ۵۶,۰۰۰,۰۰۰ تومان | -| مجموع شارژ | ۱۶۸,۰۰۰,۰۰۰ تومان | +| مبلغ وام (DayaLoanAmount) | ۵۶,۰۰۰,۰۰۰ ریال | +| شارژ Balance | ۵۶,۰۰۰,۰۰۰ ریال | +| شارژ DiscountBalance | ۱۱۲,۰۰۰,۰۰۰ ریال (دو برابر — DayaLoanAmount × 2) | +| مجموع شارژ | ۱۶۸,۰۰۰,۰۰۰ ریال | +| NetworkBalance | شارژ نمی‌شود | | بازپرداخت | طبق شرایط دایا | --- @@ -134,13 +136,15 @@ DayaLoanProcessorJob.Execute() ### ۵.۱ فرمول ``` -قیمت محصول = 1,000,000 تومان -تخفیف باشگاه = 30% +قیمت محصول = 1,000,000 ریال +MaxDiscountPercent محصول = 40% (هر محصول درصد تخفیف مخصوص خود را دارد) -پرداخت از DiscountBalance = 1,000,000 × 0.30 = 300,000 -پرداخت نقدی (IPG) = 1,000,000 × 0.70 = 700,000 +سهم تخفیف = MIN(1,000,000 × 40%, DiscountBalanceکاربر) = 400,000 +پرداخت نقدی (IPG) = 1,000,000 - 400,000 = 600,000 ───────── مجموع = 1,000,000 + +ℹ️ تخفیف ثابت ۳۰% نیست — فیلد Product.MaxDiscountPercent (0-100) تعیین‌کننده است. ``` ### ۵.۲ فلوی خرید فروشگاه تخفیفی @@ -204,7 +208,11 @@ service PaymentService { ## ۷. مالیات و VAT ``` -VAT = 10% (configurable via SystemConstants) +دو نرخ VAT در کد: + + SystemConstants.ShopVAT = 0.1 (10%) — تنظیم سیستمی + VAT_RATE = 0.09 (9%) — در فروشگاه تخفیفی (DiscountShop PlaceOrder) + قیمت نمایشی = قیمت پایه × (1 + VAT) در صورتحساب: قیمت پایه + مالیات جداگانه نمایش داده می‌شود ``` diff --git a/business/BUSINESS-03-ECOMMERCE-STORES.md b/business/BUSINESS-03-ECOMMERCE-STORES.md index a6b8d09..5686ed9 100644 --- a/business/BUSINESS-03-ECOMMERCE-STORES.md +++ b/business/BUSINESS-03-ECOMMERCE-STORES.md @@ -16,8 +16,8 @@ ├───────────────────────┼─────────────────────────────────┤ │ • همه کاربران │ • فقط اعضای باشگاه │ │ • پرداخت 100% نقدی │ • پرداخت ترکیبی (تخفیف+نقد) │ -│ • قیمت عادی │ • تخفیف ۳۰% از DiscountBalance │ -│ • بدون محدودیت │ • وابسته به موجودی تخفیفی │ +│ • قیمت عادی │ • تخفیف بر اساس MaxDiscountPercent │ +│ • VAT = 10% │ • VAT = 9% (در کد PlaceOrder) │ ├───────────────────────┴─────────────────────────────────┤ │ Shared: Products, Categories, │ │ Inventory, ProductImages (1:1 square) │ @@ -93,6 +93,9 @@ public class Inventory { public int MinimumStock { get; set; } // حداقل موجودی (هشدار) public bool TrackInventory { get; set; } // آیا موجودی رصد شود؟ } + +// فیلد کلیدی در Product: +public int MaxDiscountPercent { get; set; } // 0 تا 100 — درصد تخفیف در فروشگاه تخفیفی ``` ### ۳.۳ فلوی سفارش و موجودی diff --git a/business/BUSINESS-04-USER-MEMBERSHIP.md b/business/BUSINESS-04-USER-MEMBERSHIP.md index 0764bd6..1a35045 100644 --- a/business/BUSINESS-04-USER-MEMBERSHIP.md +++ b/business/BUSINESS-04-USER-MEMBERSHIP.md @@ -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, ... } ``` diff --git a/business/BUSINESS-05-CONTENT-MANAGEMENT.md b/business/BUSINESS-05-CONTENT-MANAGEMENT.md index b12b1ae..f274302 100644 --- a/business/BUSINESS-05-CONTENT-MANAGEMENT.md +++ b/business/BUSINESS-05-CONTENT-MANAGEMENT.md @@ -132,13 +132,9 @@ FileManagementService → ذخیره در فایل‌سیستم + ثبت در DB { "Kavenegar": { "ApiKey": "***", - "SenderNumber": "10008663", - "Templates": { - "OTP": "verify-foursat", - "ContractOTP": "contract-verify", - "WelcomeClub": "club-welcome", - "OrderConfirm": "order-confirm" - } + "SenderNumber": "1000001110100", + "DefaultTemplate": "Afrino", + "_note": "تمام OTPها با قالب Afrino ارسال می‌شوند" } } ``` @@ -183,16 +179,17 @@ CREATE TABLE SystemConfigurations ( | Category | Key | Value | توضیح | |----------|-----|-------|--------| -| Club | `Club.ActivationFee` | 25000000 | هزینه فعالسازی | -| Club | `Club.GiftValue` | 25200000 | واریز Pool | -| Club | `GoldenPackageAmount` | 56000000 | قیمت پکیج طلایی | -| Club | `MaxNetworkLevel` | 15 | حداکثر عمق درخت | -| Club | `MaxWeeklyBalance` | 300 | سقف هفتگی | -| Payment | `VAT.Percentage` | 10 | مالیات ارزش افزوده | -| Payment | `DayaLoanAmount` | 56000000 | مبلغ وام | -| Store | `DiscountPercentage` | 30 | تخفیف باشگاه | -| Store | `ProductsPerPage` | 12 | تعداد در صفحه | -| System | `SmsProvider` | Kavenegar | ارائه‌دهنده SMS | +| Club | `ClubActivationFee` | 25200000 | هزینه فعالسازی (ریال) | +| Club | `ClubMembershipGiftValue` | 25200000 | واریز Pool | +| Club | `BasePackageAmount` | 56000000 | قیمت پکیج طلایی (ریال) | +| Club | `CommissionMaxNetworkLevel` | 15 | عمق محاسبه کمیسیون | +| Club | `CommissionMaxWeeklyBalancesPerLeg` | 300 | سقف هفتگی | +| Payment | `ShopVAT` | 0.1 (10%) | مالیات (فروشگاه تخفیفی: 9%) | +| Payment | `DayaLoanAmount` | 56000000 | مبلغ وام (ریال) | +| Payment | `MinimumWithdrawAmount` | 1000000 | حداقل برداشت (ریال) | +| Store | `MaxDiscountPercent` | per-product | 0-100، هر محصول جداگانه | +| Store | `ProductsPerPage` | 12 (FO) / 10 (CMS) | تعداد در صفحه | +| System | `CommissionCalculationMethod` | "SP" | Stored Procedure | | System | `MaintenanceMode` | false | حالت تعمیر | --- diff --git a/overview/OVERVIEW-01-FLOWCHARTS.md b/overview/OVERVIEW-01-FLOWCHARTS.md index de9fa80..5a856d0 100644 --- a/overview/OVERVIEW-01-FLOWCHARTS.md +++ b/overview/OVERVIEW-01-FLOWCHARTS.md @@ -35,7 +35,7 @@ │ ├──────────┬──────────┬──────────┬─────────────┤ │ │ │ فروشگاه │ درخت شبکه │ کمیسیون │ Chatika AI │ │ │ │ تخفیفی │ باینری │ هفتگی │ │ │ -│ │ (30%↓) │ │ │ │ │ +│ │ (per-product) │ │ │ │ │ │ └──────────┴──────────┴──────────┴─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘ @@ -56,15 +56,17 @@ │ [Daya Loan] ──→ ├──→ [PYMS Service] ──→ [DB Transaction] │ │ [Manual Pay] ──→ ┘ │ │ │ ▼ │ -│ ═══════════ توزیع به ۳ کیف‌پول ═══════════ │ +│ ═══════════ توزیع به کیف‌پول‌ها ═══════════ │ │ │ │ ┌────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │ -│ │ 💰 Balance │ │ 🌐 NetworkBal │ │ 🏷️ DiscountBal │ │ -│ │ (نقدی) │ │ (شبکه‌ای) │ │ (تخفیفی) │ │ +│ │ 💰 Balance │ │ 🌟 NetworkBal │ │ 🏷️ DiscountBal │ │ +│ │ (نقدی) │ │ (طلایی/کمیسیون)│ │ (تخفیفی) │ │ │ │ │ │ │ │ │ │ -│ │ • خرید فروشگاه │ │ • محاسبه │ │ • فروشگاه تخفیفی │ │ -│ │ • هزینه فعالسازی │ │ کمیسیون │ │ • سهم 30% از │ │ -│ │ (25M) │ │ • سقف 300/هفته │ │ قیمت محصول │ │ +│ │ • IPG: +56M │ │ • شارژ نمی‌شود │ │ • IPG: +56M │ │ +│ │ • Daya: +56M │ │ • فقط برای │ │ • Daya: +112M │ │ +│ │ • فعالسازی │ │ محاسبه │ │ (دو برابر) │ │ +│ │ -25.2M │ │ کمیسیون │ │ • per-product │ │ +│ │ • خرید فروشگاه │ │ • سقف 300/هفته │ │ MaxDiscount% │ │ │ └───────┬────────┘ └────────┬────────┘ └────────┬─────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ @@ -163,7 +165,8 @@ Legend: R = Right leg sales this week Active = فعال (contract signed) Pend. = در انتظار فعالسازی - Max depth = 15 levels + شبکه روی entity User مدل شده (NetworkParentId, LegPosition) + محاسبه کمیسیون تا عمق 15 سطح — درخت بدون محدودیت عمق ``` --- @@ -188,8 +191,8 @@ Legend: │ │ │ [بررسی DiscountBalance] │ │ ▼ │ │ │ │ [Checkout] │ ▼ │ -│ │ │ [محاسبه سهم تخفیف (30%)] │ -│ ▼ │ [محاسبه سهم نقدی (70%)] │ +│ │ │ [محاسبه سهم تخفیف (MaxDiscount%)]│ +│ ▼ │ [محاسبه سهم نقدی (باقیمانده)] │ │ [ZarinPal IPG] │ │ │ │ [100% نقدی] │ ▼ │ │ │ │ [کسر از DiscountBalance] │ @@ -242,17 +245,23 @@ Legend: ## ۷. Entity Relationship (ساده‌شده) ``` -┌──────────┐ ┌──────────────┐ ┌──────────────┐ -│ User │────→│ ClubMembership│────→│ NetworkNode │ -│ │ │ │ │ (BinaryTree)│ -└────┬─────┘ └──────────────┘ └──────────────┘ +┌──────────┐ ┌──────────────┐ +│ User │────→│ ClubMembership│ +│ +Network │ │ │ +│ ParentId│ └──────────────┘ +│ +LegPos │ +└────┬─────┘ │ ├────→ ┌──────────┐ ┌──────────┐ │ │ Order │────→│ OrderItem│────→ [Product] │ └──────────┘ └──────────┘ │ ├────→ ┌──────────────┐ - │ │ Transaction │────→ [Wallet (×3)] + │ │ Transaction │ + │ └──────────────┘ + │ + ├────→ ┌──────────────┐ + │ │ UserWallet │────→ Balance + NetworkBalance + DiscountBalance │ └──────────────┘ │ ├────→ ┌──────────────┐ diff --git a/overview/OVERVIEW-04-GLOSSARY.md b/overview/OVERVIEW-04-GLOSSARY.md index 99368ff..b2f71be 100644 --- a/overview/OVERVIEW-04-GLOSSARY.md +++ b/overview/OVERVIEW-04-GLOSSARY.md @@ -23,7 +23,7 @@ | Pool هفتگی | Weekly Commission Pool | مخزن کمیسیون قابل‌توزیع | | هزینه فعالسازی | Activation Fee | ۲۵M تومان از Balance | | واریز هدیه | Gift Value | ۲۵.۲M واریز به Pool | -| فروشگاه تخفیفی | Discount Store | فروشگاه ۳۰% تخفیف برای اعضا | +| فروشگاه تخفیفی | Discount Store | فروشگاه با تخفیف per-product برای اعضا | | پرداخت ترکیبی | Hybrid Payment | DiscountBalance + IPG | | وام دایا | Daya Loan | وام آنلاین برای خرید پکیج | | کد معرف | Referral Code | کد یکتا هر عضو برای دعوت | @@ -39,9 +39,9 @@ | درگاه پرداخت | Payment Gateway (IPG) | ZarinPal | | سرویس پرداخت | PYMS | Payment Management Service | | کیف‌پول نقدی | Balance Wallet | موجودی قابل‌خرج | -| کیف‌پول شبکه‌ای | Network Balance | برای محاسبه کمیسیون | -| کیف‌پول تخفیفی | Discount Balance | برای فروشگاه تخفیفی | -| بارگذاری تنبل | Lazy Loading | لود محصولات ۱۲تایی | +| کیف‌پول طلایی | Network Balance | برای محاسبه کمیسیون (شارژ نمی‌شود) | +| کیف‌پول تخفیفی | Discount Balance | برای فروشگاه تخفیفی (Daya: 112M, IPG: 56M) | +| بارگذاری تنبل | Lazy Loading | لود محصولات 12تایی (FO) / 10تایی (CMS default) | | صفحات سایت | Site Pages | صفحات قابل‌ویرایش (Shopify-style) | | ثوابت سیستمی | System Constants | تنظیمات key-value | | پردازش پس‌زمینه | Background Job | Hangfire recurring/fire-and-forget | diff --git a/technical/TECH-01-CMS-ARCHITECTURE.md b/technical/TECH-01-CMS-ARCHITECTURE.md index fedca31..b33c0cb 100644 --- a/technical/TECH-01-CMS-ARCHITECTURE.md +++ b/technical/TECH-01-CMS-ARCHITECTURE.md @@ -163,16 +163,16 @@ Engine: MSSQL 2022-CU16, Collation=Arabic_CI_AS | جدول | توضیح | رکوردهای تقریبی | |------|--------|----------------| -| Users | کاربران | ~5K | -| Products | محصولات | ~200 | +| Users | کاربران + فیلدهای شبکه (NetworkParentId, LegPosition) | ~5K | +| Products | محصولات (+ MaxDiscountPercent) | ~200 | | Categories | دسته‌بندی‌ها | ~30 | | Orders | سفارشات | ~2K | | Inventories | موجودی | ~200 | | BlogPosts | پست‌های بلاگ | ~50 | | SitePages | صفحات سایت | ~10 | | UserClubMemberships | عضویت باشگاه | ~500 | -| UserContracts | قراردادها | ~500 | -| NetworkNodes | نودهای درخت باینری | ~500 | +| UserContracts | قراردادها (SignGuid, SignedPdfFile) | ~500 | +| UserWallets | کیف‌پول (Balance, NetworkBalance, DiscountBalance) | ~5K | | Transactions | تراکنش‌ها | ~5K | | SystemConfigurations | تنظیمات | ~30 | | ChatMessages | پیام‌های چاتیکا | ~1K | @@ -225,12 +225,11 @@ FrontOffice Service Layer: ## ۷. Hangfire Jobs -| Job | فرکانس | کاربرد | +| Job | فرکانس (cron) | کاربرد | |-----|---------|--------| -| `DayaLoanProcessorJob` | هر ۱۵ دقیقه | پردازش درخواست‌های وام | -| `WeeklyCommissionJob` | هفتگی (شنبه ۰۰:۰۰) | محاسبه و توزیع کمیسیون | -| `ChatikaJob` | هر ۵ دقیقه | همگام‌سازی پیام‌های AI | -| `InventorySyncJob` | هر ساعت | ایجاد رکوردهای موجودی گمشده | +| `WeeklyCommissionCalculation` | `5 0 * * 0` (یکشنبه ۰۰:۰۵) | محاسبه و توزیع کمیسیون | +| `DayaLoanProcessorJob` | `*/20 * * * *` (هر ۲۰ دقیقه) | پردازش درخواست‌های وام | +| `ChatikaAccountActivation` | `*/5 * * * *` (هر ۵ دقیقه) | فعال‌سازی حساب چاتیکا | --- diff --git a/technical/TECH-04-MIGRATION.md b/technical/TECH-04-MIGRATION.md index a89f9af..ec08f36 100644 --- a/technical/TECH-04-MIGRATION.md +++ b/technical/TECH-04-MIGRATION.md @@ -162,8 +162,8 @@ DataMigration/ | `dbo.Products` | `CMS.Products` | ImageUrl migration needed | | `dbo.Orders` | `CMS.Orders` | Status enum remapping | | `dbo.Categories` | `CMS.Categories` | Hierarchical → ParentId | -| `dbo.NetworkTree` | `CMS.NetworkNodes` | Binary tree reconstruction | -| `dbo.Wallets` | `CMS.UserWalletBalances` | ۳ wallet types split | +| `dbo.NetworkTree` | `CMS.Users` | Binary tree via NetworkParentId + LegPosition روی User | +| `dbo.Wallets` | `CMS.UserWallets` | ۳ wallet types: Balance, NetworkBalance, DiscountBalance | | `dbo.Transactions` | `CMS.Transactions` | Type enum remapping | | `dbo.Memberships` | `CMS.UserClubMemberships` | + Contract creation | diff --git a/technical/TECH-05-API-INTEGRATION.md b/technical/TECH-05-API-INTEGRATION.md index 5fe9e87..f5be394 100644 --- a/technical/TECH-05-API-INTEGRATION.md +++ b/technical/TECH-05-API-INTEGRATION.md @@ -176,10 +176,9 @@ public class ZarinPalService : IPaymentGateway ```csharp public class KavenegarService : ISmsService { - // Templates - const string OTP_TEMPLATE = "verify-foursat"; - const string CONTRACT_TEMPLATE = "contract-verify"; - const string WELCOME_TEMPLATE = "club-welcome"; + // Templates — فقط یک تمپلیت در کد موجود است + const string OTP_TEMPLATE = "Afrino"; // تنها تمپلیت استفاده‌شده + // Sender: "1000001110100" // Rate Limiting // ۱ SMS per phone per 60 seconds @@ -198,7 +197,7 @@ public class KavenegarService : ISmsService ```csharp public class DayaLoanService : ILoanService { - // Hangfire job — هر ۱۵ دقیقه + // Hangfire job — هر ۲۰ دقیقه (*/20 * * * *) // Polly retry: 3 attempts, exponential backoff (2s, 4s, 8s) // Mock mode for staging (auto-approve)