From 1b04ba5326151980de26843fdac2e29117d655f6 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Wed, 18 Feb 2026 23:36:39 +0330 Subject: [PATCH] docs: convert all ASCII charts to Mermaid diagrams Converted 40+ ASCII art diagrams across 12 files to Mermaid: - flowchart TD/LR for process flows and architecture - erDiagram for entity relationships - graph TD for tree structures (binary tree, categories) - gantt for roadmap sprints Files: BUSINESS-01 to 05, TECH-01/03/04/05, OVERVIEW-01/02/05 Directory tree structures kept as plain code blocks (Mermaid N/A) --- business/BUSINESS-01-CLUB-COMMISSION.md | 99 +++-- business/BUSINESS-02-PAYMENT-FINANCE.md | 128 +++---- business/BUSINESS-03-ECOMMERCE-STORES.md | 125 +++---- business/BUSINESS-04-USER-MEMBERSHIP.md | 132 +++---- business/BUSINESS-05-CONTENT-MANAGEMENT.md | 74 ++-- overview/OVERVIEW-01-FLOWCHARTS.md | 411 +++++++++------------ overview/OVERVIEW-02-INDEX.md | 47 +-- overview/OVERVIEW-05-ROADMAP.md | 62 ++-- technical/TECH-01-CMS-ARCHITECTURE.md | 82 ++-- technical/TECH-03-DEPLOYMENT-INFRA.md | 54 ++- technical/TECH-04-MIGRATION.md | 48 ++- technical/TECH-05-API-INTEGRATION.md | 21 +- 12 files changed, 544 insertions(+), 739 deletions(-) diff --git a/business/BUSINESS-01-CLUB-COMMISSION.md b/business/BUSINESS-01-CLUB-COMMISSION.md index ab54fcd..dc78640 100644 --- a/business/BUSINESS-01-CLUB-COMMISSION.md +++ b/business/BUSINESS-01-CLUB-COMMISSION.md @@ -18,15 +18,19 @@ ## ۲. ساختار درخت باینری +```mermaid +graph TD + ROOT["Root"] --- L["Left"] + ROOT --- R["Right"] + L --- L1["L1"] & L2["L2"] + R --- R1["R1"] & R2["R2"] + L1 --- L1a["..."] & L1b["..."] + L2 --- L2a["..."] & L2b["..."] + R1 --- R1a["..."] & R1b["..."] + R2 --- R2a["..."] & R2b["..."] ``` - Root - / \ - Left Right - / \ / \ - L1 L2 R1 R2 - / \ / \ / \ / \ - ... ... ... ... ... ← بدون محدودیت عمق -``` + +> ← بدون محدودیت عمق **قوانین:** - هر نود حداکثر ۲ فرزند (Binary) — `MaxDirectChildrenPerLeg = 1` @@ -38,36 +42,24 @@ ## ۳. فلوی عضویت و فعالسازی -``` -خرید پکیج طلایی (56M تومان) - │ - ▼ -نمایش مودال قرارداد (غیرقابل‌بسته‌شدن) - │ - ▼ -مشاهده متن قرارداد ← ReadContract RPC - │ - ▼ -درخواست OTP ← RequestContractOtp (Kavenegar SMS) - │ - ▼ -وارد کردن کد ← VerifyContractOtp - │ - ▼ -امضای قرارداد ← AcceptContract - │ - ├─→ شارژ ۲ کیف پول: Balance += 56M, DiscountBalance += 112M (2×) - │ (NetworkBalance شارژ نمی‌شود — فقط برای کمیسیون) - ├─→ کسر هزینه فعالسازی (25.2M از Balance) - ├─→ واریز 25.2M به Pool هفتگی (ClubActivationFee) - ├─→ قرارگیری در درخت باینری - └─→ رفرش JWT Token (claims جدید) +```mermaid +flowchart TD + A["خرید پکیج طلایی — 56M"] --> B["نمایش مودال قرارداد\nغیرقابل‌بسته‌شدن"] + B --> C["مشاهده متن قرارداد\nReadContract RPC"] + C --> D["درخواست OTP\nRequestContractOtp — Kavenegar"] + D --> E["وارد کردن کد\nVerifyContractOtp"] + E --> F["امضای قرارداد\nAcceptContract"] -⚠️ در خرید با وام دایا: - ├─→ Balance += 56M - └─→ DiscountBalance += 112M (دو برابر — DayaLoanAmount × 2) + F --> G["شارژ ۲ کیف‌پول\nBalance += 56M\nDiscountBalance += 112M"] + F --> H["کسر فعالسازی\n−25.2M از Balance"] + F --> I["واریز 25.2M\nبه Pool هفتگی"] + F --> J["قرارگیری در\nدرخت باینری"] + F --> K["رفرش JWT Token\nclaims جدید"] ``` +> ⚠️ در خرید با وام دایا: Balance += 56M, DiscountBalance += 112M (DayaLoanAmount × 2) +> NetworkBalance شارژ نمی‌شود — فقط برای کمیسیون + --- ## ۴. الگوریتم محاسبه کمیسیون هفتگی @@ -103,12 +95,15 @@ ### ۴.۳ Pool هفتگی و توزیع +```mermaid +flowchart LR + A["هر فعالسازی عضو\n25.2M واریز"] --> B["Pool هفتگی"] + B --> C["sp_CalculateWeeklyBalances"] + C --> D["sp_CalculateWeeklyCommissionPool"] + D --> E["توزیع بر اساس\nUserBalance / TotalBalance"] ``` -منبع Pool: هر فعالسازی عضو → 25.2M واریز به Pool -توزیع: بر اساس WeeklyBalance هر عضو / مجموع WeeklyBalance‌ها -SP: sp_CalculateWeeklyBalances → sp_CalculateWeeklyCommissionPool -فرمت هفته: "YYYY-Www" (شمسی، شنبه‌پایه) -``` + +> فرمت هفته: `YYYY-Www` (شمسی، شنبه‌پایه) --- @@ -141,24 +136,16 @@ SP: sp_CalculateWeeklyBalances → sp_CalculateWeeklyCommissionPool ## ۷. یکپارچه‌سازی وام دایا +```mermaid +flowchart TD + A["Hangfire Worker\nهر ۲۰ دقیقه — */20 * * * *"] --> B["بررسی درخواست‌های pending"] + B --> C["ارسال به API دایا\nMock/Real switchable"] + C --> D["دریافت نتیجه"] + D --> E["Balance += 56M"] + D --> F["DiscountBalance += 112M\nDayaLoanAmount × 2"] ``` -Hangfire Worker (هر ۲۰ دقیقه — cron: */20 * * * *) - │ - ▼ -بررسی درخواست‌های pending - │ - ▼ -ارسال به API دایا (Mock/Real switchable) - │ - ▼ -دریافت نتیجه → شارژ ۲ کیف‌پول - │ - ├─→ Balance += 56M (DayaLoanAmount) - └─→ DiscountBalance += 112M (DayaLoanAmount × 2 — دو برابر) - مجموع: 168M -Hangfire retry: [AutomaticRetry(Attempts = 3)] -``` +> مجموع شارژ: 168M — Hangfire retry: `[AutomaticRetry(Attempts = 3)]` --- diff --git a/business/BUSINESS-02-PAYMENT-FINANCE.md b/business/BUSINESS-02-PAYMENT-FINANCE.md index ef50e16..4314138 100644 --- a/business/BUSINESS-02-PAYMENT-FINANCE.md +++ b/business/BUSINESS-02-PAYMENT-FINANCE.md @@ -7,19 +7,27 @@ ## ۱. معماری کلی مالی -``` -┌──────────────────────────────────────────────────────────────────┐ -│ FourSat Payment Architecture │ -├──────────────┬──────────────┬──────────────┬─────────────────────┤ -│ ZarinPal │ Daya Loan │ Manual Pay │ Discount Wallet │ -│ (IPG) │ (API) │ (Card2Card) │ (Internal) │ -├──────────────┴──────────────┴──────────────┴─────────────────────┤ -│ PYMS (Payment Service) │ -│ gRPC ←→ CMS ←→ FrontOffice/BackOffice │ -├──────────────────────────────────────────────────────────────────┤ -│ 3 Wallet System │ -│ Balance (نقدی) │ NetworkBalance (شبکه) │ DiscountBalance │ -└──────────────────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + subgraph GATEWAYS["درگاه‌ها"] + ZP["ZarinPal\nIPG"] + DL["Daya Loan\nAPI"] + MP["Manual Pay\nCard2Card"] + DW["Discount Wallet\nInternal"] + end + + ZP --> PYMS["PYMS — Payment Service\ngRPC ↔ CMS ↔ FrontOffice/BackOffice"] + DL --> PYMS + MP --> PYMS + DW --> PYMS + + PYMS --> WALLETS + + subgraph WALLETS["3 Wallet System"] + W1["💰 Balance\nنقدی"] + W2["🌟 NetworkBalance\nشبکه"] + W3["🏷️ DiscountBalance\nتخفیفی"] + end ``` --- @@ -28,23 +36,14 @@ ### ۲.۱ فلوی پرداخت -``` -کاربر → انتخاب محصول → درخواست پرداخت - │ - ▼ -CMS → CreatePaymentRequest (gRPC to PYMS) - │ - ▼ -PYMS → ZarinPal API → دریافت Authority - │ - ▼ -Redirect کاربر → صفحه پرداخت ZarinPal - │ - ▼ -بازگشت با Authority → CMS VerifyPayment - │ - ├─→ موفق: ثبت سفارش + شارژ کیف‌پول (در صورت نیاز) - └─→ ناموفق: نمایش پیام خطا +```mermaid +flowchart TD + A["کاربر → انتخاب محصول\nدرخواست پرداخت"] --> B["CMS → CreatePaymentRequest\ngRPC to PYMS"] + B --> C["PYMS → ZarinPal API\nدریافت Authority"] + C --> D["Redirect کاربر\nصفحه پرداخت ZarinPal"] + D --> E["بازگشت با Authority\nCMS VerifyPayment"] + E -->|موفق| F["✅ ثبت سفارش\n+ شارژ کیف‌پول"] + E -->|ناموفق| G["❌ نمایش پیام خطا"] ``` ### ۲.۲ تنظیمات ZarinPal @@ -62,21 +61,14 @@ Redirect کاربر → صفحه پرداخت ZarinPal ### ۳.۱ معماری -``` -Hangfire Recurring Job (هر ۲۰ دقیقه — cron: */20 * * * *) - │ - ▼ -DayaLoanProcessorJob.Execute() - │ - ▼ -بررسی LoanRequests با Status=Pending - │ - ▼ -برای هر درخواست: - ├─→ ارسال به DayaLoan API ([AutomaticRetry(Attempts=3)]) - ├─→ در صورت تأیید: Balance += 56M, DiscountBalance += 112M (2×) - ├─→ ثبت Transaction + Log - └─→ در صورت رد: Status=Rejected + ارسال SMS +```mermaid +flowchart TD + A["Hangfire Recurring Job\nهر ۲۰ دقیقه — */20 * * * *"] --> B["DayaLoanProcessorJob.Execute"] + B --> C["بررسی LoanRequests\nStatus = Pending"] + C --> D["برای هر درخواست:"] + D --> E["ارسال به DayaLoan API\nAutomaticRetry Attempts=3"] + E -->|تأیید| F["✅ Balance += 56M\nDiscountBalance += 112M\n+ ثبت Transaction + Log"] + E -->|رد| G["❌ Status = Rejected\n+ ارسال SMS"] ``` ### ۳.۲ Mock Mode @@ -108,21 +100,14 @@ DayaLoanProcessorJob.Execute() > ⚠️ **وضعیت: طراحی‌شده — پیاده‌سازی نشده** -``` -فلوی پیشنهادی: - کاربر → انتخاب "کارت‌به‌کارت" - │ - ▼ - نمایش شماره‌کارت مقصد + مبلغ - │ - ▼ - کاربر → واریز + آپلود تصویر رسید - │ - ▼ - ادمین BackOffice → مشاهده لیست درخواست‌ها - │ - ▼ - تأیید/رد → شارژ خودکار کیف‌پول +```mermaid +flowchart TD + A["کاربر → انتخاب کارت‌به‌کارت"] --> B["نمایش شماره‌کارت مقصد\n+ مبلغ"] + B --> C["کاربر → واریز\n+ آپلود تصویر رسید"] + C --> D["ادمین BackOffice\nمشاهده لیست درخواست‌ها"] + D --> E{"تأیید / رد؟"} + E -->|تأیید| F["✅ شارژ خودکار کیف‌پول"] + E -->|رد| G["❌ اطلاع‌رسانی به کاربر"] ``` **موجودیت‌های مورد نیاز:** @@ -149,22 +134,13 @@ MaxDiscountPercent محصول = 40% (هر محصول درصد تخفیف مخص ### ۵.۲ فلوی خرید فروشگاه تخفیفی -``` -کاربر (عضو باشگاه) → مشاهده محصول - │ - ▼ -قیمت تخفیف‌خورده نمایش داده می‌شود - │ - ▼ -افزودن به سبد → بررسی DiscountBalance - │ - ├─→ DiscountBalance کافی: - │ سهم تخفیف از DiscountBalance کسر - │ باقیمانده → IPG (ZarinPal) - │ - └─→ DiscountBalance ناکافی: - فقط به اندازه موجودی از تخفیف - باقیمانده بیشتر → IPG +```mermaid +flowchart TD + A["کاربر عضو باشگاه\nمشاهده محصول"] --> B["قیمت تخفیف‌خورده نمایش داده می‌شود"] + B --> C["افزودن به سبد\nبررسی DiscountBalance"] + C --> D{"موجودی کافی؟"} + D -->|کافی| E["سهم تخفیف از DiscountBalance\nباقیمانده → IPG ZarinPal"] + D -->|ناکافی| F["فقط به اندازه موجودی\nباقیمانده بیشتر → IPG"] ``` ### ۵.۳ دسترسی فروشگاه تخفیفی diff --git a/business/BUSINESS-03-ECOMMERCE-STORES.md b/business/BUSINESS-03-ECOMMERCE-STORES.md index 5686ed9..c2f28b6 100644 --- a/business/BUSINESS-03-ECOMMERCE-STORES.md +++ b/business/BUSINESS-03-ECOMMERCE-STORES.md @@ -7,21 +7,31 @@ ## ۱. دو فروشگاه FourSat -``` -┌─────────────────────────────────────────────────────────┐ -│ FourSat Stores │ -├───────────────────────┬─────────────────────────────────┤ -│ Regular Store │ Discount Store │ -│ (/store) │ (/discount-store) │ -├───────────────────────┼─────────────────────────────────┤ -│ • همه کاربران │ • فقط اعضای باشگاه │ -│ • پرداخت 100% نقدی │ • پرداخت ترکیبی (تخفیف+نقد) │ -│ • قیمت عادی │ • تخفیف بر اساس MaxDiscountPercent │ -│ • VAT = 10% │ • VAT = 9% (در کد PlaceOrder) │ -├───────────────────────┴─────────────────────────────────┤ -│ Shared: Products, Categories, │ -│ Inventory, ProductImages (1:1 square) │ -└─────────────────────────────────────────────────────────┘ +```mermaid +flowchart LR + subgraph RS["Regular Store — /store"] + R1["همه کاربران"] + R2["پرداخت 100% نقدی"] + R3["قیمت عادی"] + R4["VAT = 10%"] + end + + subgraph DS["Discount Store — /discount-store"] + D1["فقط اعضای باشگاه"] + D2["پرداخت ترکیبی تخفیف+نقد"] + D3["تخفیف بر اساس MaxDiscountPercent"] + D4["VAT = 9%"] + end + + subgraph SHARED["مشترک"] + S1["Products"] + S2["Categories"] + S3["Inventory"] + S4["ProductImages 1:1"] + end + + RS --> SHARED + DS --> SHARED ``` --- @@ -50,23 +60,14 @@ public async Task GetProductsPagedAsync( ### ۲.۲ پیاده‌سازی UI (هر دو فروشگاه) -``` -بارگذاری اولیه: 12 محصول - │ - ▼ -اسکرول → نمایش دکمه "نمایش محصولات بیشتر" - │ - ▼ -کلیک → LoadMore() → skip += 12 - │ - ▼ -محصولات جدید اضافه به لیست (append) - │ - ▼ -تکرار تا Products.Count >= TotalCount - │ - ▼ -مخفی‌شدن دکمه +```mermaid +flowchart TD + A["بارگذاری اولیه: 12 محصول"] --> B["اسکرول → نمایش دکمه\nنمایش محصولات بیشتر"] + B --> C["کلیک → LoadMore\nskip += 12"] + C --> D["محصولات جدید append به لیست"] + D --> E{"Products.Count >= TotalCount?"} + E -->|خیر| B + E -->|بله| F["مخفی‌شدن دکمه"] ``` --- @@ -100,17 +101,14 @@ public int MaxDiscountPercent { get; set; } // 0 تا 100 — درصد تخفی ### ۳.۳ فلوی سفارش و موجودی -``` -سفارش جدید - │ - ▼ -بررسی Quantity - ReservedQuantity >= OrderQuantity? - │ - ├─→ بله: ReservedQuantity += OrderQuantity - │ پرداخت موفق → Quantity -= OrderQuantity, Reserved -= OrderQuantity - │ پرداخت ناموفق → Reserved -= OrderQuantity (آزادسازی) - │ - └─→ خیر: نمایش "موجودی کافی نیست" +```mermaid +flowchart TD + A["سفارش جدید"] --> B{"Quantity - Reserved >= OrderQty?"} + B -->|بله| C["Reserved += OrderQty"] + C --> D{"پرداخت موفق؟"} + D -->|موفق| E["✅ Quantity -= OrderQty\nReserved -= OrderQty"] + D -->|ناموفق| F["❌ Reserved -= OrderQty\nآزادسازی"] + B -->|خیر| G["نمایش: موجودی کافی نیست"] ``` --- @@ -159,17 +157,11 @@ public class BundleItem { ### ۵.۲ فلو -``` -ادمین → ساخت باندل → انتخاب محصولات + تعیین قیمت - │ - ▼ -نمایش در فروشگاه با تگ "باندل" - │ - ▼ -خرید → تمام محصولات باندل یکجا به سبد - │ - ▼ -پرداخت → کسر موجودی هر محصول جداگانه +```mermaid +flowchart TD + A["ادمین → ساخت باندل\nانتخاب محصولات + تعیین قیمت"] --> B["نمایش در فروشگاه\nبا تگ باندل"] + B --> C["خرید → تمام محصولات\nیکجا به سبد"] + C --> D["پرداخت → کسر موجودی\nهر محصول جداگانه"] ``` --- @@ -207,21 +199,22 @@ public class BundleItem { ## ۷. دسته‌بندی‌ها (Categories) -``` -درختی / سلسله‌مراتبی - │ - ├── سلامت و زیبایی - │ ├── مکمل‌ها - │ ├── مراقبت پوست - │ └── مراقبت مو - ├── تغذیه - │ ├── ارگانیک - │ └── رژیمی - └── ورزشی +```mermaid +graph TD + ROOT["دسته‌بندی‌ها"] --> A["سلامت و زیبایی"] + ROOT --> B["تغذیه"] + ROOT --> C["ورزشی"] -مدل: Category (Id, Name, ParentId?, ImageUrl, IsActive, SortOrder) + A --> A1["مکمل‌ها"] + A --> A2["مراقبت پوست"] + A --> A3["مراقبت مو"] + + B --> B1["ارگانیک"] + B --> B2["رژیمی"] ``` +> مدل: `Category (Id, Name, ParentId?, ImageUrl, IsActive, SortOrder)` + --- ## ۸. خلاصه وضعیت diff --git a/business/BUSINESS-04-USER-MEMBERSHIP.md b/business/BUSINESS-04-USER-MEMBERSHIP.md index 1a35045..2378bc7 100644 --- a/business/BUSINESS-04-USER-MEMBERSHIP.md +++ b/business/BUSINESS-04-USER-MEMBERSHIP.md @@ -7,27 +7,19 @@ ## ۱. فلوی کامل چرخه کاربر -``` -ورود به سایت - │ - ▼ -ثبت‌نام (موبایل + OTP) - │ - ▼ -تکمیل پروفایل - │ - ▼ -┌─────────────────────┬────────────────────────┐ -│ مسیر عادی │ مسیر باشگاه │ -├─────────────────────┼────────────────────────┤ -│ خرید از فروشگاه │ خرید پکیج طلایی (56M) │ -│ مشاهده بلاگ │ امضای قرارداد (OTP) │ -│ استفاده از خدمات │ فعالسازی (25M) │ -│ │ عضویت در درخت باینری │ -│ │ دسترسی فروشگاه تخفیفی │ -│ │ دسترسی فیچرهای باشگاه │ -│ │ کسب کمیسیون هفتگی │ -└─────────────────────┴────────────────────────┘ +```mermaid +flowchart TD + A["ورود به سایت"] --> B["ثبت‌نام — موبایل + OTP"] + B --> C["تکمیل پروفایل"] + C --> D{"مسیر؟"} + + D -->|عادی| E["🛒 خرید از فروشگاه\nمشاهده بلاگ\nاستفاده از خدمات"] + + D -->|باشگاه| F["🏆 خرید پکیج طلایی 56M"] + F --> G["امضای قرارداد OTP"] + G --> H["فعالسازی 25.2M"] + H --> I["عضویت درخت باینری"] + I --> J["دسترسی فروشگاه تخفیفی\nفیچرهای باشگاه\nکمیسیون هفتگی"] ``` --- @@ -36,28 +28,16 @@ ### ۲.۱ فلوی ثبت‌نام +```mermaid +flowchart TD + A["صفحه ثبت‌نام"] --> B["ورود شماره موبایل"] + B --> C["ارسال OTP\nKavenegar SMS API"] + C --> D["تأیید کد OTP"] + D -->|کاربر جدید| E["ساخت User\n+ JWT Token"] + D -->|کاربر موجود| F["ورود\n+ JWT Token"] ``` -صفحه ثبت‌نام - │ - ▼ -ورود شماره موبایل - │ - ▼ -ارسال OTP (Kavenegar SMS API) - │ - ▼ -تأیید کد OTP - │ - ├─→ کاربر جدید: ساخت User + JWT Token - └─→ کاربر موجود: ورود + JWT Token -JWT Claims: - • UserId - • PhoneNumber - • IsClubMember (bool) - • Roles[] (Admin, Customer) - • ReferralCode -``` +**JWT Claims:** `UserId`, `PhoneNumber`, `IsClubMember`, `Roles[]`, `ReferralCode` ### ۲.۲ اصلاحات ثبت‌نام @@ -76,16 +56,15 @@ JWT Claims: ### ۳.۱ مشکل قبلی -``` -قبل: - Admin و Customer هر دو از یک DbContext و Identity استفاده می‌کردند - یک ادمین می‌توانست به صورت Customer هم ظاهر شود ← تداخل Claims +```mermaid +flowchart LR + subgraph BEFORE["قبل — مشکل"] + A1["Admin + Customer"] --> A2["یک DbContext\nیک Identity\nتداخل Claims"] + end -بعد (اصلاح‌شده): - ✅ ICurrentUserService → تشخیص دقیق نقش فعلی - ✅ جداسازی Authorization Policy - ✅ Admin claims فقط در BackOffice - ✅ Customer claims فقط در FrontOffice + subgraph AFTER["بعد — اصلاح‌شده ✅"] + B1["ICurrentUserService"] --> B2["جداسازی Policy\nAdmin → BackOffice\nCustomer → FrontOffice"] + end ``` ### ۳.۲ ICurrentUserService @@ -110,29 +89,16 @@ public interface ICurrentUserService { ### ۴.۱ فلوی امضای قرارداد -``` -خرید پکیج طلایی → Redirect به صفحه قرارداد - │ - ▼ -نمایش Modal غیرقابل‌بسته‌شدن - │ - ▼ -ReadContract RPC → نمایش متن قرارداد (Markdown/HTML) - │ - ▼ -کاربر باید تا انتهای متن اسکرول کند - │ - ▼ -فعال شدن دکمه "ارسال کد تأیید" - │ - ▼ -RequestContractOtp → ارسال SMS - │ - ▼ -ورود کد ← VerifyContractOtp - │ - ├─→ معتبر: AcceptContract → فعالسازی عضویت - └─→ نامعتبر: پیام خطا (حداکثر ۵ تلاش) +```mermaid +flowchart TD + A["خرید پکیج طلایی\nRedirect به صفحه قرارداد"] --> B["نمایش Modal\nغیرقابل‌بسته‌شدن"] + B --> C["ReadContract RPC\nنمایش متن قرارداد"] + C --> D["اسکرول تا انتها"] + D --> E["فعال شدن دکمه\nارسال کد تأیید"] + E --> F["RequestContractOtp\nارسال SMS"] + F --> G["ورود کد\nVerifyContractOtp"] + G -->|معتبر| H["✅ AcceptContract\nفعالسازی عضویت"] + G -->|نامعتبر| I["❌ پیام خطا\nحداکثر ۵ تلاش"] ``` ### ۴.۲ ذخیره‌سازی قرارداد @@ -206,20 +172,12 @@ else ## ۷. کدهای معرف (Referral) -``` -هر عضو باشگاه → یک ReferralCode یکتا -لینک: https://foursat.ir/register?ref={ReferralCode} - -ثبت‌نام با لینک: - │ - ▼ - ذخیره ReferrerId در پروفایل کاربر جدید - │ - ▼ - هنگام خرید پکیج → زیرمجموعه Referrer در درخت باینری - │ - ▼ - Referrer → دریافت bonus (طبق شرایط باشگاه) +```mermaid +flowchart TD + A["هر عضو باشگاه\nیک ReferralCode یکتا"] --> B["لینک:\nhttps://foursat.ir/register?ref=CODE"] + B --> C["ثبت‌نام با لینک\nذخیره ReferrerId"] + C --> D["خرید پکیج\nزیرمجموعه Referrer در درخت"] + D --> E["Referrer\nدریافت bonus"] ``` --- diff --git a/business/BUSINESS-05-CONTENT-MANAGEMENT.md b/business/BUSINESS-05-CONTENT-MANAGEMENT.md index f274302..704f0da 100644 --- a/business/BUSINESS-05-CONTENT-MANAGEMENT.md +++ b/business/BUSINESS-05-CONTENT-MANAGEMENT.md @@ -9,14 +9,15 @@ ### ۱.۱ معماری ساده‌شده (Shopify-style) -``` -قبل (پیچیده): - SitePage → SitePageSetting → SitePageContent → Template → ... (7 جدول) +```mermaid +flowchart LR + subgraph BEFORE["قبل — پیچیده"] + X1["SitePage"] --> X2["SitePageSetting"] --> X3["SitePageContent"] --> X4["Template\n... 7 جدول"] + end -بعد (ساده): - SitePage (PageType, JsonSettings, IsPublished) - │ - └─→ هر PageType → یک typed editor در BackOffice + subgraph AFTER["بعد — ساده ✅"] + Y1["SitePage\nPageType + JsonSettings"] --> Y2["هر PageType\nیک typed editor"] + end ``` ### ۱.۲ انواع صفحات @@ -97,21 +98,14 @@ message GetBlogPostsRequest { ### ۳.۱ معماری +```mermaid +flowchart TD + A["آپلود فایل\nتصویر / سند"] --> B["FileManagementService"] + B --> C["ذخیره در فایل‌سیستم\n+ ثبت در DB"] + C --> D["مسیر: /app/uploads/year/month/guid.ext\nURL: /api/files/guid"] ``` -آپلود فایل (تصویر/سند) - │ - ▼ -FileManagementService → ذخیره در فایل‌سیستم + ثبت در DB - │ - ▼ -مسیر فیزیکی: /app/uploads/{year}/{month}/{guid}.{ext} -مسیر URL: /api/files/{guid} -محدودیت‌ها: - • حداکثر حجم: 10MB (configurable) - • فرمت‌های مجاز: jpg, png, webp, pdf, doc, docx - • تصاویر: resize خودکار به 800×800 (محصولات) -``` +> محدودیت: حداکثر 10MB • jpg, png, webp, pdf, doc, docx • Resize: 800×800 (محصولات) ### ۳.۲ Storage Strategy @@ -198,20 +192,12 @@ CREATE TABLE SystemConfigurations ( ### ۶.۱ معماری -``` -Hangfire Recurring Job (هر ۵ دقیقه) - │ - ▼ -ChatikaJob → بررسی پیام‌های جدید کاربران - │ - ▼ -ارسال به Chatika API (با Polly retry ×3) - │ - ▼ -دریافت پاسخ → ذخیره در ChatMessages - │ - ▼ -نمایش در UI باشگاه (real-time via SignalR planned) +```mermaid +flowchart TD + A["Hangfire Recurring Job\nهر ۵ دقیقه"] --> B["ChatikaJob\nبررسی پیام‌های جدید"] + B --> C["ارسال به Chatika API\nPolly retry ×3"] + C --> D["دریافت پاسخ\nذخیره در ChatMessages"] + D --> E["نمایش در UI باشگاه\nSignalR planned"] ``` ### ۶.۲ فعلی vs آینده @@ -228,20 +214,12 @@ ChatikaJob → بررسی پیام‌های جدید کاربران ### ۷.۱ ساختار -``` -Hero Section (انیمیشن fade-in) - │ - ▼ -ویژگی‌ها (Features Grid — 3 ستونه) - │ - ▼ -محصولات ویژه (Carousel) - │ - ▼ -آمار (Counter animation — اصلاح‌شده) - │ - ▼ -CTA — Call to Action (ثبت‌نام / ورود) +```mermaid +flowchart TD + A["🎨 Hero Section\nانیمیشن fade-in"] --> B["✨ ویژگی‌ها\nFeatures Grid — 3 ستونه"] + B --> C["📦 محصولات ویژه\nCarousel"] + C --> D["📊 آمار\nCounter animation\nlinear interpolation"] + D --> E["🚀 CTA\nثبت‌نام / ورود"] ``` ### ۷.۲ اصلاح انیمیشن Counter diff --git a/overview/OVERVIEW-01-FLOWCHARTS.md b/overview/OVERVIEW-01-FLOWCHARTS.md index 8079eb3..86134ee 100644 --- a/overview/OVERVIEW-01-FLOWCHARTS.md +++ b/overview/OVERVIEW-01-FLOWCHARTS.md @@ -7,283 +7,212 @@ ## ۱. فلوی کلان کاربر (User Journey) -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ FourSat — User Journey │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ [ورود به سایت] │ -│ │ │ -│ ▼ │ -│ ◆ آیا ثبت‌نام کرده؟ ◆──── خیر ───→ [Landing Page] │ -│ │ │ │ -│ بله [ثبت‌نام] │ -│ │ موبایل + OTP │ -│ ▼ │ │ -│ [Login + JWT] ▼ │ -│ │ [پروفایل] │ -│ ▼ │ │ -│ ◆ عضو باشگاه؟ ◆ ▼ │ -│ │ │ ┌───────────────┐ │ -│ بله خیر │ Regular Store │ │ -│ │ │ │ خرید عادی │ │ -│ │ └──────────────→│ IPG پرداخت │ │ -│ │ └───────────────┘ │ -│ ▼ │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ Club Member Dashboard │ │ -│ ├──────────┬──────────┬──────────┬─────────────┤ │ -│ │ فروشگاه │ درخت شبکه │ کمیسیون │ Chatika AI │ │ -│ │ تخفیفی │ باینری │ هفتگی │ │ │ -│ │ (per-product) │ │ │ │ │ -│ └──────────┴──────────┴──────────┴─────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + A["🌐 ورود به سایت"] --> B{"آیا ثبت‌نام کرده؟"} + B -->|خیر| C["Landing Page"] + C --> D["ثبت‌نام\nموبایل + OTP"] + D --> E["پروفایل"] + E --> F + + B -->|بله| G["Login + JWT"] + G --> H{"عضو باشگاه؟"} + H -->|خیر| F["🛒 Regular Store\nخرید عادی — IPG پرداخت"] + H -->|بله| I["🏆 Club Member Dashboard"] + + I --> J["فروشگاه تخفیفی\nper-product MaxDiscount%"] + I --> K["درخت شبکه\nباینری"] + I --> L["کمیسیون\nهفتگی"] + I --> M["Chatika AI"] ``` --- ## ۲. فلوی مالی (Financial Flow) -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ FourSat — Financial Flow │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ═══════════════════ ورودی پول ═══════════════════ │ -│ │ -│ [ZarinPal IPG] ──→ ┐ │ -│ [Daya Loan] ──→ ├──→ [PYMS Service] ──→ [DB Transaction] │ -│ [Manual Pay] ──→ ┘ │ │ -│ ▼ │ -│ ═══════════ توزیع به کیف‌پول‌ها ═══════════ │ -│ │ -│ ┌────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │ -│ │ 💰 Balance │ │ 🌟 NetworkBal │ │ 🏷️ DiscountBal │ │ -│ │ (نقدی) │ │ (طلایی/کمیسیون)│ │ (تخفیفی) │ │ -│ │ │ │ │ │ │ │ -│ │ • IPG: +56M │ │ • شارژ نمی‌شود │ │ • IPG: +112M │ │ -│ │ • Daya: +56M │ │ • فقط برای │ │ • Daya: +112M │ │ -│ │ • فعالسازی │ │ محاسبه │ │ (دو برابر) │ │ -│ │ -25.2M │ │ کمیسیون │ │ • per-product │ │ -│ │ • خرید فروشگاه │ │ • سقف 300/هفته │ │ MaxDiscount% │ │ -│ └───────┬────────┘ └────────┬────────┘ └────────┬─────────┘ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ═══════════════════ خروجی پول ═══════════════════ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ Weekly Commission Pool │ │ -│ │ │ │ -│ │ Source: هر فعالسازی → 25.2M واریز │ │ -│ │ Calculate: sp_CalculateWeeklyBalances │ │ -│ │ Distribute: sp_CalculateWeeklyCommissionPool │ │ -│ │ Formula: UserShare = UserBalance / TotalBalance │ │ -│ │ Cap: MAX 300 per leg per week │ │ -│ │ Carryover: به هفته بعد (max 300, else flush) │ │ -│ │ │ │ -│ │ ┌─ Member A: Balance=150 → Share=150/600 → 25% ─┐ │ │ -│ │ │ Member B: Balance=200 → Share=200/600 → 33% │ │ │ -│ │ │ Member C: Balance=250 → Share=250/600 → 42% │ │ │ -│ │ └─ Total: 600 ─┘ │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + subgraph INPUT["═══ ورودی پول ═══"] + Z1["ZarinPal IPG"] + Z2["Daya Loan"] + Z3["Manual Pay"] + end + + Z1 --> PYMS["PYMS Service"] + Z2 --> PYMS + Z3 --> PYMS + PYMS --> TX[("DB Transaction")] + + TX --> W1 & W2 & W3 + + subgraph WALLETS["═══ توزیع به کیف‌پول‌ها ═══"] + W1["💰 Balance — نقدی\n• IPG: +56M\n• Daya: +56M\n• فعالسازی: −25.2M\n• خرید فروشگاه"] + W2["🌟 NetworkBalance — طلایی\n• شارژ نمی‌شود\n• فقط محاسبه کمیسیون\n• سقف 300/هفته"] + W3["🏷️ DiscountBalance — تخفیفی\n• IPG: +112M\n• Daya: +112M\n• per-product MaxDiscount%"] + end + + W1 & W2 --> POOL + + subgraph POOL["═══ Weekly Commission Pool ═══"] + P1["هر فعالسازی → 25.2M واریز به Pool"] + P2["sp_CalculateWeeklyBalances"] + P3["sp_CalculateWeeklyCommissionPool"] + P4["UserShare = UserBalance / TotalBalance"] + P5["Cap: MAX 300 per leg per week"] + P1 --> P2 --> P3 --> P4 --> P5 + end ``` --- ## ۳. فلوی داده (Data Flow) -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ FourSat — Data Flow │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ [Browser/Client] │ -│ │ │ -│ │ HTTPS │ -│ ▼ │ -│ [nginx / K8s Ingress] │ -│ │ │ -│ ├──→ / ──────────→ [FrontOffice :5003] (Blazor Server) │ -│ │ │ │ -│ ├──→ /admin ─────→ [BackOffice :5002] (Blazor WASM) │ -│ │ │ │ -│ └──→ /hangfire ──→ [CMS :5001] (Dashboard) │ -│ │ │ -│ ┌─────────────────────────────┘ │ -│ │ gRPC (Protobuf v3, HTTP/2) │ -│ ▼ │ -│ [CMS Microservice :5001] │ -│ │ │ -│ ├──→ [MediatR] ──→ Commands/Queries ──→ Handlers │ -│ │ │ │ -│ ├──→ [Hangfire] ──→ Background Jobs │ │ -│ │ • DayaLoan (15min) │ │ -│ │ • Commission (weekly) │ │ -│ │ • Chatika (5min) │ │ -│ │ • InventorySync (hourly) │ │ -│ │ │ │ -│ └──→ [External Services] │ │ -│ • ZarinPal API │ │ -│ • Kavenegar API ▼ │ -│ • DayaLoan API [EF Core 9] │ -│ • Chatika API │ │ -│ ▼ │ -│ [SQL Server 2022] │ -│ Schema: [CMS] │ -│ ~15 main tables │ -│ + 3 Stored Procs │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + CLIENT["🌐 Browser / Client"] -->|HTTPS| NGINX["nginx / K8s Ingress"] + + NGINX -->|"/"| FO["FrontOffice :5003\nBlazor Server"] + NGINX -->|"/admin"| BO["BackOffice :5002\nBlazor WASM"] + NGINX -->|"/hangfire"| CMS + + FO -->|gRPC| CMS["CMS Microservice :5001"] + BO -->|gRPC| CMS + + CMS --> MEDIATR["MediatR\nCommands / Queries → Handlers"] + CMS --> HF["Hangfire\n• DayaLoan — */20 min\n• Commission — Sunday 00:05\n• Chatika — */5 min"] + CMS --> EXT["External Services\n• ZarinPal API\n• Kavenegar API\n• DayaLoan API\n• Chatika API"] + + MEDIATR --> EF["EF Core 9"] + HF --> EF + EF --> DB[("SQL Server 2022\nSchema: CMS\n~15 tables + 3 SPs")] ``` --- ## ۴. درخت باینری شبکه (Network Tree) -``` - ┌─────────┐ - │ Root │ - │ (Admin) │ - └────┬────┘ - ┌─────────┴─────────┐ - ┌────▼────┐ ┌────▼────┐ - │ User A │ │ User B │ - │ L=120 │ │ L=0 │ - │ R=80 │ │ R=150 │ - └────┬────┘ └────┬────┘ - ┌───────┴───────┐ ┌──────┴──────┐ - ┌────▼──┐ ┌────▼──┐ ┌──▼───┐ ┌───▼──┐ - │User C │ │User D │ │User E│ │User F│ - │Active │ │Active │ │Pend. │ │Active│ - └───────┘ └───────┘ └──────┘ └──────┘ +```mermaid +graph TD + ROOT["🔵 Root — Admin"] + ROOT --- A["👤 User A\nL=120 | R=80"] + ROOT --- B["👤 User B\nL=0 | R=150"] -Legend: - L = Left leg sales this week - R = Right leg sales this week - Active = فعال (contract signed) - Pend. = در انتظار فعالسازی - شبکه روی entity User مدل شده (NetworkParentId, LegPosition) - محاسبه کمیسیون تا عمق 15 سطح — درخت بدون محدودیت عمق + A --- C["✅ User C\nActive"] + A --- D["✅ User D\nActive"] + B --- E["⏳ User E\nPending"] + B --- F["✅ User F\nActive"] + + style ROOT fill:#1976D2,color:#fff + style C fill:#4CAF50,color:#fff + style D fill:#4CAF50,color:#fff + style E fill:#FF9800,color:#fff + style F fill:#4CAF50,color:#fff ``` +> **راهنما:** +> - `L` / `R` = فروش پای چپ / راست این هفته +> - **Active** = فعال (قرارداد امضا شده) — **Pending** = در انتظار فعالسازی +> - شبکه روی entity `User` مدل شده (`NetworkParentId`, `LegPosition`) +> - محاسبه کمیسیون تا عمق ۱۵ سطح — درخت بدون محدودیت عمق + --- ## ۵. فلوی خرید — Regular vs Discount Store +### ۵.۱ Regular Store + +```mermaid +flowchart TD + A1["مشاهده محصولات"] --> B1["Lazy Load — 12 per page"] + B1 --> C1["افزودن به سبد"] + C1 --> D1["بررسی موجودی"] + D1 --> E1["Checkout"] + E1 --> F1["ZarinPal IPG\n100% نقدی"] + F1 --> G1["ثبت سفارش"] + G1 --> H1["کسر موجودی"] + H1 --> I1["SMS تأیید"] ``` -┌────────────────────────────────┬──────────────────────────────────┐ -│ Regular Store │ Discount Store │ -├────────────────────────────────┼──────────────────────────────────┤ -│ │ │ -│ [مشاهده محصولات] │ [مشاهده محصولات] ← فقط باشگاه │ -│ │ │ │ │ -│ ▼ │ ▼ │ -│ [Lazy Load — 12 per page] │ [Lazy Load — 12 per page] │ -│ │ │ │ │ -│ ▼ │ ▼ │ -│ [افزودن به سبد] │ [افزودن به سبد] │ -│ │ │ │ │ -│ ▼ │ ▼ │ -│ [بررسی موجودی] │ [بررسی موجودی] │ -│ │ │ [بررسی DiscountBalance] │ -│ ▼ │ │ │ -│ [Checkout] │ ▼ │ -│ │ │ [محاسبه سهم تخفیف (MaxDiscount%)]│ -│ ▼ │ [محاسبه سهم نقدی (باقیمانده)] │ -│ [ZarinPal IPG] │ │ │ -│ [100% نقدی] │ ▼ │ -│ │ │ [کسر از DiscountBalance] │ -│ ▼ │ [ZarinPal IPG برای باقیمانده] │ -│ [ثبت سفارش] │ │ │ -│ │ │ ▼ │ -│ ▼ │ [ثبت سفارش ترکیبی] │ -│ [کسر موجودی] │ [کسر موجودی] │ -│ │ │ │ │ -│ ▼ │ ▼ │ -│ [SMS تأیید] │ [SMS تأیید] │ -│ │ │ -└────────────────────────────────┴──────────────────────────────────┘ + +### ۵.۲ Discount Store + +```mermaid +flowchart TD + A2["مشاهده محصولات\nفقط اعضای باشگاه"] --> B2["Lazy Load — 12 per page"] + B2 --> C2["افزودن به سبد"] + C2 --> D2["بررسی موجودی + DiscountBalance"] + D2 --> E2["محاسبه سهم تخفیف\nMaxDiscount% هر محصول"] + E2 --> F2["محاسبه سهم نقدی\nباقیمانده"] + F2 --> G2["کسر از DiscountBalance"] + G2 --> H2["ZarinPal IPG\nبرای باقیمانده نقدی"] + H2 --> I2["ثبت سفارش ترکیبی"] + I2 --> J2["کسر موجودی"] + J2 --> K2["SMS تأیید"] ``` --- ## ۶. معماری Deployment -``` -┌──────────────────────────────────────────────────────────────┐ -│ Production Server │ -│ 45.149.79.127 │ -├──────────────────────────────────────────────────────────────┤ -│ │ -│ ┌─────────┐ ┌────────────────────────────────────┐ │ -│ │ nginx │────→│ Kubernetes Cluster │ │ -│ │ :80/:443│ │ │ │ -│ └─────────┘ │ ┌───────────┐ ┌───────────────┐ │ │ -│ │ │CMS ×2 │ │FrontOffice ×2 │ │ │ -│ │ │:5001 gRPC │ │:5003 Blazor │ │ │ -│ │ └─────┬─────┘ └───────────────┘ │ │ -│ │ │ │ │ -│ │ ┌─────▼─────┐ ┌───────────────┐ │ │ -│ │ │SQL Server │ │BackOffice ×1 │ │ │ -│ │ │:1433 │ │:5002 Static │ │ │ -│ │ └───────────┘ └───────────────┘ │ │ -│ │ │ │ -│ │ ┌───────────┐ ┌───────────────┐ │ │ -│ │ │Nexus │ │Hangfire │ │ │ -│ │ │:8081 │ │(inside CMS) │ │ │ -│ │ └───────────┘ └───────────────┘ │ │ -│ └────────────────────────────────────┘ │ -│ │ -└──────────────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + subgraph SERVER["🖥️ Production Server — 45.149.79.127"] + NGINX["nginx\n:80 / :443"] + subgraph K8S["☸ Kubernetes Cluster"] + CMS["CMS ×2\n:5001 gRPC"] + FO["FrontOffice ×2\n:5003 Blazor Server"] + BO["BackOffice ×1\n:5002 Static"] + DB[("SQL Server\n:1433")] + NEXUS["Nexus\n:8081"] + HF["Hangfire\ninside CMS"] + end + end + + NGINX --> CMS + NGINX --> FO + NGINX --> BO + CMS --> DB + CMS --> HF + + style SERVER fill:#f5f5f5,stroke:#333 + style K8S fill:#e3f2fd,stroke:#1976D2 ``` --- ## ۷. Entity Relationship (ساده‌شده) -``` -┌──────────┐ ┌──────────────┐ -│ User │────→│ ClubMembership│ -│ +Network │ │ │ -│ ParentId│ └──────────────┘ -│ +LegPos │ -└────┬─────┘ - │ - ├────→ ┌──────────┐ ┌──────────┐ - │ │ Order │────→│ OrderItem│────→ [Product] - │ └──────────┘ └──────────┘ - │ - ├────→ ┌──────────────┐ - │ │ Transaction │ - │ └──────────────┘ - │ - ├────→ ┌──────────────┐ - │ │ UserWallet │────→ Balance + NetworkBalance + DiscountBalance - │ └──────────────┘ - │ - ├────→ ┌──────────────┐ - │ │ UserContract │ - │ └──────────────┘ - │ - └────→ ┌──────────────┐ - │ ChatMessage │ - └──────────────┘ - -┌──────────┐ ┌───────────┐ -│ Product │────→│ Inventory │ -│ │────→│ Category │ -│ │────→│ Images │ -└──────────┘ - -┌──────────┐ ┌──────────────────────┐ -│ SitePage │ │ SystemConfiguration │ -│ (typed) │ │ (key-value) │ -└──────────┘ └──────────────────────┘ - -┌──────────┐ -│ BlogPost │────→ [Tags, Category, Author] -└──────────┘ +```mermaid +erDiagram + User ||--o{ ClubMembership : has + User ||--o| UserWallet : has + User ||--o{ UserContract : signs + User ||--o{ UserOrder : places + User ||--o{ ChatMessage : sends + User }o--o| User : "NetworkParentId" + + UserOrder ||--|{ OrderItem : contains + OrderItem }o--|| Product : references + UserOrder ||--o{ Transaction : has + + Product ||--o| Inventory : has + Product }o--|| Category : belongs_to + Product ||--o{ ProductImage : has + + UserWallet ||--o{ UserWalletChangeLog : logs + + BlogPost }o--|| Category : belongs_to + + UserWallet { + long Balance + long NetworkBalance + long DiscountBalance + } + User { + Guid NetworkParentId + int LegPosition + } + UserContract { + Guid SignGuid + string SignedPdfFile + } ``` diff --git a/overview/OVERVIEW-02-INDEX.md b/overview/OVERVIEW-02-INDEX.md index d806b3d..5fb5a71 100644 --- a/overview/OVERVIEW-02-INDEX.md +++ b/overview/OVERVIEW-02-INDEX.md @@ -71,34 +71,25 @@ totalDoc/ ## نقشه ارتباط فایل‌ها -``` - ┌──────────────┐ - │ O2: INDEX │ ← شما اینجا هستید - └──────┬───────┘ - │ - ┌─────────────────┼──────────────────┐ - │ │ │ - ┌────▼────┐ ┌────▼─────┐ ┌────▼─────┐ - │Business │ │Technical │ │Overview │ - │ (B1-B5) │ │ (T1-T5) │ │ (O1-O5) │ - └────┬────┘ └────┬─────┘ └────┬─────┘ - │ │ │ - ┌────┴────────────────┴──────────────────┴────┐ - │ │ - │ B1 ←→ B2 (مالی/باشگاه) │ - │ B2 ←→ B3 (پرداخت/فروشگاه) │ - │ B3 ←→ B4 (فروشگاه/کاربر) │ - │ B4 ←→ B5 (کاربر/محتوا) │ - │ B1 ←→ T1 (باشگاه/CMS) │ - │ T1 ←→ T2 (CMS/UI) │ - │ T1 ←→ T3 (CMS/Deploy) │ - │ T3 ←→ T4 (Deploy/Migration) │ - │ T1 ←→ T5 (CMS/API) │ - │ O1: دیاگرام = بصری B1-B5 + T1-T5 │ - │ O3: تاریخچه = changelog B1-B5 + T1-T5 │ - │ O5: آینده = roadmap B1-B5 + T1-T5 │ - │ │ - └──────────────────────────────────────────────┘ +```mermaid +graph TD + INDEX["📋 O2: INDEX\nشما اینجا هستید"] + INDEX --> BIZ["📁 Business\nB1-B5"] + INDEX --> TECH["📁 Technical\nT1-T5"] + INDEX --> OVR["📁 Overview\nO1-O5"] + + BIZ --- B12["B1 ↔ B2\nمالی / باشگاه"] + BIZ --- B23["B2 ↔ B3\nپرداخت / فروشگاه"] + BIZ --- B34["B3 ↔ B4\nفروشگاه / کاربر"] + BIZ --- B45["B4 ↔ B5\nکاربر / محتوا"] + + BIZ --- TECH + TECH --- T12["T1 ↔ T2 — CMS/UI"] + TECH --- T13["T1 ↔ T3 — CMS/Deploy"] + TECH --- T34["T3 ↔ T4 — Deploy/Migration"] + TECH --- T15["T1 ↔ T5 — CMS/API"] + + OVR --- OX["O1: دیاگرام‌ها\nO3: تاریخچه\nO5: نقشه راه"] ``` --- diff --git a/overview/OVERVIEW-05-ROADMAP.md b/overview/OVERVIEW-05-ROADMAP.md index 1bf2016..56ae95f 100644 --- a/overview/OVERVIEW-05-ROADMAP.md +++ b/overview/OVERVIEW-05-ROADMAP.md @@ -69,40 +69,42 @@ Documentation ████████████████████ ### Q1 1404 (فروردین-خرداد) -``` -Sprint 1 (فروردین): - ├── H2: Mobile Responsive - ├── H1: Product Bundle - └── M4: SEO Meta Tags - -Sprint 2 (اردیبهشت): - ├── M1: Manual Payment (if approved) - ├── M2: SignalR Chatika - └── M6: Dashboard Charts - -Sprint 3 (خرداد): - ├── M3: Dark Mode - ├── H3: Rate Limiting - └── L1: PWA +```mermaid +gantt + title Q1 1404 — فروردین تا خرداد + dateFormat YYYY-MM-DD + section Sprint 1 فروردین + H2 Mobile Responsive :a1, 2025-03-21, 5d + H1 Product Bundle :a2, after a1, 3d + M4 SEO Meta Tags :a3, after a2, 2d + section Sprint 2 اردیبهشت + M1 Manual Payment :b1, 2025-04-21, 3d + M2 SignalR Chatika :b2, after b1, 2d + M6 Dashboard Charts :b3, after b2, 3d + section Sprint 3 خرداد + M3 Dark Mode :c1, 2025-05-22, 2d + H3 Rate Limiting :c2, after c1, 2d + L1 PWA :c3, after c2, 3d ``` ### Q2 1404 (تیر-شهریور) -``` -Sprint 4 (تیر): - ├── L3: Monitoring - ├── L4: Log Aggregation - └── L2: API Versioning - -Sprint 5 (مرداد): - ├── L5: Product Compare - ├── L6: Wishlist - └── L7: Email Templates - -Sprint 6 (شهریور): - ├── L8: Refund System - ├── Performance Optimization - └── Security Audit +```mermaid +gantt + title Q2 1404 — تیر تا شهریور + dateFormat YYYY-MM-DD + section Sprint 4 تیر + L3 Monitoring :d1, 2025-06-22, 3d + L4 Log Aggregation :d2, after d1, 3d + L2 API Versioning :d3, after d2, 2d + section Sprint 5 مرداد + L5 Product Compare :e1, 2025-07-23, 2d + L6 Wishlist :e2, after e1, 2d + L7 Email Templates :e3, after e2, 2d + section Sprint 6 شهریور + L8 Refund System :f1, 2025-08-23, 5d + Performance Optimization :f2, after f1, 3d + Security Audit :f3, after f2, 3d ``` --- diff --git a/technical/TECH-01-CMS-ARCHITECTURE.md b/technical/TECH-01-CMS-ARCHITECTURE.md index b33c0cb..4345bb7 100644 --- a/technical/TECH-01-CMS-ARCHITECTURE.md +++ b/technical/TECH-01-CMS-ARCHITECTURE.md @@ -22,30 +22,38 @@ ## ۲. معماری لایه‌ای CMS -``` -┌──────────────────────────────────────────────────────┐ -│ Presentation Layer │ -│ FrontOffice (Blazor Server) ←─gRPC─→ CMS │ -│ BackOffice (Blazor WASM) ←─gRPC─→ CMS │ -├──────────────────────────────────────────────────────┤ -│ Application Layer │ -│ Commands (MediatR IRequest) │ -│ Queries (MediatR IRequest) │ -│ Validators (FluentValidation) │ -│ Handlers (IRequestHandler) │ -├──────────────────────────────────────────────────────┤ -│ Domain Layer │ -│ Entities, Enums, Value Objects │ -│ Domain Events, Interfaces │ -├──────────────────────────────────────────────────────┤ -│ Infrastructure Layer │ -│ EF Core DbContext (CMSDbContext) │ -│ Repositories, External Services │ -│ Hangfire Jobs, File Storage │ -├──────────────────────────────────────────────────────┤ -│ Database │ -│ SQL Server — Schema: [CMS] │ -└──────────────────────────────────────────────────────┘ +```mermaid +flowchart TD + subgraph PRES["💻 Presentation Layer"] + FO["FrontOffice\nBlazor Server"] + BO["BackOffice\nBlazor WASM"] + end + + FO & BO -->|gRPC| APP + + subgraph APP["⚙️ Application Layer"] + CMD["Commands\nMediatR IRequest"] + QRY["Queries\nMediatR IRequest"] + VAL["Validators\nFluentValidation"] + HND["Handlers\nIRequestHandler"] + end + + APP --> DOM + + subgraph DOM["📦 Domain Layer"] + ENT["Entities, Enums\nValue Objects\nDomain Events"] + end + + DOM --> INF + + subgraph INF["🔧 Infrastructure Layer"] + EF["EF Core DbContext"] + SVC["External Services"] + HF["Hangfire Jobs"] + FS["File Storage"] + end + + INF --> DB[("🗄️ SQL Server\nSchema: CMS")] ``` --- @@ -191,22 +199,22 @@ Engine: MSSQL 2022-CU16, Collation=Arabic_CI_AS ### ۶.۱ قبل vs بعد -``` -قبل: - FrontOffice → BFF (REST) → CMS (gRPC) - BackOffice → BFF (REST) → CMS (gRPC) +```mermaid +flowchart LR + subgraph BEFORE["قبل"] + F1["FrontOffice"] -->|REST| BFF1["BFF"] + B1["BackOffice"] -->|REST| BFF1 + BFF1 -->|gRPC| C1["CMS"] + end -بعد (فعلی): - FrontOffice → CMS (gRPC مستقیم) - BackOffice → CMS (gRPC مستقیم) - -مزایا: - ✅ حذف لایه واسط → کاهش latency - ✅ حذف maintenance اضافی - ✅ Type-safe از proto تا UI - ✅ کاهش ۱ سرویس در deployment + subgraph AFTER["بعد — فعلی ✅"] + F2["FrontOffice"] -->|gRPC| C2["CMS"] + B2["BackOffice"] -->|gRPC| C2 + end ``` +> مزایا: حذف لایه واسط → کاهش latency • Type-safe از proto تا UI • کاهش ۱ سرویس در deployment + ### ۶.۲ سازگاری API ``` diff --git a/technical/TECH-03-DEPLOYMENT-INFRA.md b/technical/TECH-03-DEPLOYMENT-INFRA.md index fc5a6d7..cb014ed 100644 --- a/technical/TECH-03-DEPLOYMENT-INFRA.md +++ b/technical/TECH-03-DEPLOYMENT-INFRA.md @@ -214,21 +214,21 @@ jobs: ### ۵.۱ فلوی آماده‌سازی -``` -سرور اینترنت‌دار: - 1. pull-base-images.sh → دانلود Docker images - 2. cache-nuget-packages.sh → دانلود NuGet packages - 3. save-images.sh → ذخیره تصاویر به tar - 4. بسته‌بندی همه فایل‌ها +```mermaid +flowchart TD + subgraph ONLINE["🌐 سرور اینترنت‌دار"] + A1["pull-base-images.sh\nدانلود Docker images"] --> A2["cache-nuget-packages.sh\nدانلود NuGet packages"] + A2 --> A3["save-images.sh\nذخیره تصاویر به tar"] + A3 --> A4["بسته‌بندی"] + end -انتقال فیزیکی (USB/HDD): - tar files + nuget packages + k8s manifests + A4 -->|"💾 انتقال فیزیکی\nUSB / HDD"| B1 -سرور آفلاین: - 1. load-images.sh → بارگذاری تصاویر - 2. setup-nexus-complete.sh → راه‌اندازی Nexus (NuGet proxy) - 3. build-all-offline.sh → بیلد با Nexus محلی - 4. k8s-deploy.sh → استقرار در Kubernetes + subgraph OFFLINE["🔒 سرور آفلاین"] + B1["load-images.sh\nبارگذاری تصاویر"] --> B2["setup-nexus-complete.sh\nراه‌اندازی Nexus"] + B2 --> B3["build-all-offline.sh\nبیلد با Nexus محلی"] + B3 --> B4["k8s-deploy.sh\nاستقرار در K8s"] + end ``` ### ۵.۲ اسکریپت‌های کلیدی @@ -250,12 +250,12 @@ jobs: ### ۶.۱ نقش -``` -Nexus (داخلی): - ├── NuGet proxy → cache.nuget.org packages - ├── NuGet hosted → بسته‌های proto داخلی - ├── Docker proxy → cache Docker Hub images - └── Docker hosted → تصاویر داخلی FourSat +```mermaid +graph TD + NEXUS["Nexus داخلی"] --> NP["NuGet proxy\ncache nuget.org"] + NEXUS --> NH["NuGet hosted\nبسته‌های proto داخلی"] + NEXUS --> DP["Docker proxy\ncache Docker Hub"] + NEXUS --> DH["Docker hosted\nتصاویر داخلی FourSat"] ``` ### ۶.۲ NuGet.config @@ -303,17 +303,11 @@ Proto packages: BaGet (internal) at http://localhost:5555 ### ۸.۱ فلوی بسته‌بندی -``` -CMS/src/Protos/*.proto - │ - ▼ -pack-protos.sh → dotnet pack → .nupkg - │ - ▼ -push to BaGet/Nexus - │ - ▼ -BackOffice + FrontOffice → dotnet restore → مصرف proto +```mermaid +flowchart TD + A["CMS/src/Protos/*.proto"] --> B["pack-protos.sh\ndotnet pack → .nupkg"] + B --> C["Push to BaGet / Nexus"] + C --> D["BackOffice + FrontOffice\ndotnet restore → مصرف proto"] ``` ### ۸.۲ نام بسته diff --git a/technical/TECH-04-MIGRATION.md b/technical/TECH-04-MIGRATION.md index ec08f36..342cf82 100644 --- a/technical/TECH-04-MIGRATION.md +++ b/technical/TECH-04-MIGRATION.md @@ -23,30 +23,24 @@ Timeline: ### ۲.۱ قبل +```mermaid +flowchart LR + FO1["FrontOffice"] -->|HTTP/REST| BFF["BFF"] + BO1["BackOffice"] -->|HTTP/REST| BFF + BFF -->|gRPC| CMS1["CMS"] ``` -FrontOffice ──HTTP/REST──→ BFF ──gRPC──→ CMS -BackOffice ──HTTP/REST──→ BFF ──gRPC──→ CMS -BFF مسئولیت‌ها: - • تبدیل REST↔gRPC - • Aggregation - • Auth proxy - • Rate limiting -``` +**BFF مسئولیت‌ها:** تبدیل REST↔gRPC • Aggregation • Auth proxy • Rate limiting ### ۲.۲ بعد (فعلی) +```mermaid +flowchart LR + FO2["FrontOffice"] -->|gRPC| CMS2["CMS مستقیم"] + BO2["BackOffice"] -->|gRPC| CMS2 ``` -FrontOffice ──gRPC──→ CMS (مستقیم) -BackOffice ──gRPC──→ CMS (مستقیم) -مزایا: - ✅ حذف ۱ سرویس از deployment - ✅ کاهش ~50ms latency per request - ✅ Type-safety از proto تا UI - ✅ ساده‌سازی debug و logging - ✅ کاهش maintenance cost -``` +**مزایا:** ✅ حذف ۱ سرویس • کاهش ~50ms latency • Type-safety از proto تا UI • ساده‌سازی debug ### ۲.۳ مراحل مهاجرت @@ -78,18 +72,22 @@ BackOffice ──gRPC──→ CMS (مستقیم) ### ۳.۱ قبل -``` -Client → nginx → Ocelot Gateway → { CMS, BFF, FileService } - ↑ - URL routing, rate limiting, auth +```mermaid +flowchart LR + CL1["Client"] --> NG1["nginx"] --> OC["Ocelot Gateway"] + OC --> CMS3["CMS"] + OC --> BFF2["BFF"] + OC --> FS1["FileService"] ``` ### ۳.۲ بعد -``` -Client → nginx → Ingress → { CMS, BackOffice, FrontOffice } - ↑ - Path-based routing in Ingress +```mermaid +flowchart LR + CL2["Client"] --> NG2["nginx"] --> ING["K8s Ingress"] + ING --> CMS4["CMS"] + ING --> BO3["BackOffice"] + ING --> FO3["FrontOffice"] ``` ### ۳.۳ دلایل حذف diff --git a/technical/TECH-05-API-INTEGRATION.md b/technical/TECH-05-API-INTEGRATION.md index f5be394..7032bf9 100644 --- a/technical/TECH-05-API-INTEGRATION.md +++ b/technical/TECH-05-API-INTEGRATION.md @@ -294,21 +294,12 @@ public class ProductService : IProductService ## ۵. Proto Package Distribution -``` -CMS/src/Protos/*.proto - │ - ▼ -pack-protos.sh - │ - ▼ -Foursat.CMSMicroservice.Protobuf.nupkg (v1.0.x) - │ - ▼ -Push to BaGet (http://localhost:5555) or Nexus - │ - ▼ -BackOffice: -FrontOffice: +```mermaid +flowchart TD + A["CMS/src/Protos/*.proto"] --> B["pack-protos.sh"] + B --> C["Foursat.CMSMicroservice.Protobuf.nupkg\nv1.0.x"] + C --> D["Push to BaGet / Nexus"] + D --> E["BackOffice + FrontOffice\nPackageReference"] ``` ---