e3850f9dd8
- CHANGELOG: Phase 11 (11a-11f) — ZarinPal verify fix, تومان/ریال مدل, صفحه موفقیت, حذف ×۱۰ دوبار, callback URL امنیت - BUSINESS-02: تصحیح مدل ارزی (DB=تومان نه ریال), ZarinPal verify fix, جدول callback URL امنیت - TECH-01: اضافه CmsBaseUrl/FrontOfficeBaseUrl به appsettings, توضیح امنیت Open Redirect - TECH-02: اضافه PaymentCallback.razor, وضعیتهای جدید - ROADMAP: بروزرسانی Payment 97→99%, اضافه فاز ۱۱ به DONE list
34 KiB
34 KiB
📜 تاریخچه کارهای انجامشده
همه فعالیتهای پروژه به صورت بولت با توضیح یکخطی و درصد تکمیل
آخرین بروزرسانی: اسفند ۱۴۰۴ (بروزرسانی: فاز ۱۱ — فیکسهای پرداخت ZarinPal + امنیت Callback URL + اصلاح تومان/ریال)
خلاصه کلی
| حوزه | تعداد آیتم | تکمیلشده | درصد کل |
|---|---|---|---|
| BackOffice | 67 | 67 | 100% |
| FrontOffice | 60 | 60 | 100% |
| CMS Core | 89 | 89 | 100% |
| Package-Based System | 52 | 52 | 100% |
| Deployment | 22 | 21 | 95% |
| Migration | 21 | 21 | 100% |
| مجموع | 311 | 310 | 99.5% |
۱. BackOffice — فازها (98% کامل)
Phase 1-3: پایه و ساختار
- ✅ ارتقا به MudBlazor v8 — تغییر تمام کامپوننتها به API جدید
- ✅ پیادهسازی MainLayout با Drawer و AppBar — RTL support
- ✅ ایجاد NavMenu با آیکونها و گروهبندی — دستهبندی منطقی
- ✅ پیادهسازی الگوی Code-behind — جدا کردن logic از markup
- ✅ اضافه کردن Theme سفارشی — رنگها و فونت Vazirmatn
Phase 4-6: محصولات و فروشگاه
- ✅ صفحه لیست محصولات — MudDataGrid با pagination
- ✅ فرم ایجاد/ویرایش محصول — MudForm با FluentValidation
- ✅ آپلود تصویر محصول — Drag & drop با preview
- ✅ مدیریت دستهبندیها — CRUD درختی
- ✅ AppImage کامپوننت — تصاویر مربعی ۱:۱ همهجا
Phase 7-9: سفارشات و مالی
- ✅ لیست سفارشات — فیلتر وضعیت، تاریخ، مبلغ
- ✅ جزئیات سفارش — آیتمها + تراکنشها
- ✅ تغییر وضعیت سفارش — با تأیید دیالوگ
- ✅ گزارش مالی — خلاصه تراکنشها
Phase 10-12: کاربران و باشگاه
- ✅ لیست کاربران — جستجو + فیلتر نقش
- ✅ مدیریت عضویت باشگاه — فعال/غیرفعال
- ✅ نمای درخت شبکه — نمایش باینری با سطوح
- ✅ مدیریت کمیسیون — مشاهده Pool هفتگی
Phase 13-15: محتوا و تنظیمات
- ✅ مدیریت بلاگ — CRUD پستها با ادیتور HTML
- ✅ مدیریت صفحات سایت — Shopify-style typed editors
- ✅ HomePageEditor — ویرایش Hero, Featured, Promotion
- ✅ AboutPageEditor — ویرایش متن دربارهما
- ✅ ContactPageEditor — اطلاعات تماس
- ✅ LicensesPageEditor — مجوزها
- ✅ ادیتور SystemConstants — تنظیمات key-value
Phase 16-17: موجودی و نهاییسازی
- ✅ صفحه موجودی — با MudAutocomplete برای انتخاب محصول
- ✅ ایجاد خودکار رکورد موجودی — هنگام ساخت محصول
- ✅ Hangfire InventorySync — ایجاد رکوردهای گمشده
- ⬜ Dark Mode — طراحی نشده (Phase آینده)
Phase 18: بهبود UI ادمین (اسفند ۱۴۰۴)
- ✅ UserAutoComplete در ActivateClubDialog — جایگزین MudNumericField برای انتخاب کاربر
- ✅ فیلتر کاربر در صفحه ClubMembers — UserAutoComplete در تولبار جستجو
- ✅ نمایش نام کاربر در WalletManagementPage — TemplateColumn با UserName + ID
Phase 8b: CRUD پکیج کامل (اسفند ۱۴۰۴)
- ✅ CreateDialog: اضافه ۱۲ فیلد جدید — SortOrder, ActivationFee, DiscountMultiplier, MagicWallet*, MaxBalancesPerLeg, MaxNetworkLevel, IsActive, IsBasePackage, SupportsDirectPurchase, SupportsDayaPurchase
- ✅ UpdateDialog: همان ۱۲ فیلد جدید — ایجاد فرم کامل ادمین
- ✅ PackageMainPage Grid: ۴ ستون جدید — قیمت (N0), ترتیب, وضعیت (فعال/غیرفعال chip), نوع (پایه/عادی chip)
- ✅ فیکس
HasPurchasedGoldenPackage→HasPurchasedPackage— UserNetworkInfo.razor - ✅ NuGet bump 0.0.184 → 0.0.186 + local feed source
۲. FrontOffice — فازها (95% کامل)
UI Modernization Phase 1-3
- ✅ ارتقا به MudBlazor v8 — همه کامپوننتها
- ✅ MainLayout جدید — Header + Footer + RTL
- ✅ AuthLayout — صفحات Login/Register
- ✅ Landing Page — Hero + Features + Counter + CTA
- ✅ اصلاح انیمیشن Counter — linear interpolation
فروشگاه (Phase 4-5)
- ✅ Regular Store — لیست محصولات با Lazy Load (12/page)
- ✅ Discount Store — لیست با Lazy Load + hybrid payment
- ✅ ProductCard مشترک — تصویر مربعی + قیمت + دکمه
- ✅ CategoryFilter — فیلتر دستهبندی sidebar
- ✅ ProductDetail — جزئیات + تصویر بزرگ + سبد
- ✅ سبد خرید — Regular + Discount جداگانه
- ✅ Checkout — پرداخت ZarinPal + ترکیبی
باشگاه (Phase 6)
- ✅ داشبورد باشگاه — ۳ کیفپول + آمار
- ✅ نمای درخت شبکه — باینری بصری
- ✅ امضای قرارداد — OTP + scroll-to-bottom
- ✅ صفحه Chatika — چت AI
- ✅ کیفپول جادویی — MagicWallet.razor + فرم شارژ + پروگرسبار سقف
فعالسازی درگاه پرداخت (اسفند ۱۴۰۴)
- ✅ دکمه پرداخت شارژ کیفپول اعتباری — ChargeDiscountWallet.razor فعال شد (حذف «بزودی»)
- ✅ دکمه پرداخت شارژ کیفپول جادویی — MagicWallet.razor فعال شد (حذف «بزودی»)
- ✅ دکمههای پرداخت مستقیم خرید پکیج — Index.razor هر دو شاخه فعال شدند (حذف «بزودی»)
فیکسهای پرداخت و UX (اسفند ۱۴۰۴ — Phase 11)
- ✅ صفحه موفقیت پرداخت —
TransactionIdبجایRefId+ موجودی واقعی +Href="/profile"(FO:5ded91a) - ✅ حذف دوبار ×۱۰ — FO مستقیم تومان ارسال میکند، CMS/ZarinPal ×۱۰ میکند (FO:
2f9ef15) - ✅ حذف CallbackUrl از درخواست —
Index.razor.csوCheckout.razor.csدیگر URL ارسال نمیکنند (FO:2b1dc47) - ✅ ۳ کامیت، ۷ فایل تغییر
Phase 8a+8c: Checkout + Package Pages (اسفند ۱۴۰۴)
- ✅ Checkout wire-up — مهاجرت به
CustomerPurchasePackageAsync(حذف dead code قدیمی) - ✅ PackageDetail:
GetPackageAsync→GetCustomerPackageDetailsAsync— features/specs از API (نه hardcoded) - ✅ Packages.razor: un-exclude از build + dynamic feature bullets از
CustomerPackageModel - ✅ PackageService:
PackageDtoغنیشده با ۸ فیلد جدید +GetUserPackageStatusAsyncمتصل به RPC واقعی - ✅ NuGet bump 0.0.182 → 0.0.186 + local feed source
- ✅ فیکس GwUrl پروداکشن — تصحیح از cms.kbs1.ir به cms.kbs2.ir
Phase 10a: PackagePurchaseDialog — دیالوگ داینامیک خرید پکیج (اسفند ۱۴۰۴)
- ✅
PackagePurchaseDialog.razor— دیالوگ ۲ مرحلهای: مرحله ۱ = کاشیهای پکیج (responsive grid)، مرحله ۲ = انتخاب روش پرداخت - ✅ حذف دیالوگ inline خرید «پکیج پایه» از
Index.razor— جایگزین با دیالوگ داینامیک - ✅ بارگذاری پکیجها از
PackageService.GetAllPackagesAsync()— نمایش عنوان + قیمت + ویژگیها - ✅ پشتیبانی از ۲ روش پرداخت: مستقیم (درگاه بانکی) + اعتبار دایا (فقط پکیج پایه + دور اول)
- ✅ CSS کلاسهای جدید:
.pkg-tile,.pkg-tile-badge,.pkg-payment-option - ✅ کامیت:
a3681a8(FO)
Phase 10b: ۴ فیکس UI پکیج (اسفند ۱۴۰۴)
- ✅ Toman/Rial: قیمت از سرور به ریال ←
FormattedPriceحالاPrice / 10برای نمایش صحیح تومان - ✅ لیبل: «ضریب تخفیف» → «ضریب اعتبار» (دیالوگ + صفحه لیست پکیجها)
- ✅ دکمه بازگشت: وجود داشت (
ArrowForward+BackToList) — تأیید عملکرد - ✅ HTML Description:
@((MarkupString)pkg.Description)بجای متن ساده - ✅ کامیت:
3c1a8ff(FO)
Phase 11: فیکسهای پرداخت + تومان/ریال + امنیت Callback URL (اسفند ۱۴۰۴)
11a: اصلاح مدل تومان/ریال (CMS+FO)
تصحیح مهم: دیتابیس به تومان ذخیره میکند نه ریال. فقط درگاه ZarinPal ریال نیاز دارد (×۱۰).
- ✅
ZarinPalPaymentService.InitiatePaymentAsync— مبلغ ×۱۰ تبدیل به ریال فقط هنگام ارسال به ZarinPal - ✅
ZarinPalPaymentService.VerifyPaymentWithAmountAsync— مبلغ ×۱۰ هنگام verify - ✅ FrontOffice نمایش مستقیم مبلغ تومان (بدون
/10) — فیکسMagicWallet.razor,ChargeDiscountWallet.razor.cs - ✅ حذف
Price / 10اضافی درClubMembershipContractDialog.razor
11b: فیکس ZarinPal Verify — رفع خطای Code=-1 (CMS:721661a)
باگ:
VerifyPaymentAsyncبا ۲ آرگومان مبلغ صفر (0) ارسال میکرد → ZarinPal Code=-1 برمیگرداند
- ✅
PackageService— lookupPaymentTransaction.Amount+ استفاده از overload ۳ آرگومانه - ✅
TransactionsService— همان فیکس - ✅
VerifyDiscountWalletChargeCommandHandler— مبلغ ازPaymentTransaction+ رفع کپیپیست باگ - ✅
VerifyPackagePurchaseCommandHandler— مبلغ ازPaymentTransaction - ✅
IPaymentGatewayService— default impl ۳ آرگومانه باNotImplementedException - ✅
MockPaymentGatewayService+DayaPaymentService— اضافه overload ۳ آرگومانه - ✅ ۷ فایل تغییر
11c: بهبود صفحه موفقیت پرداخت (FO:5ded91a)
- ✅
PaymentCallback.razor— نمایشTransactionIdبجایRefIdبرای کد رهگیری - ✅ نمایش موجودی واقعی کیفپول از
WalletService.GetBalancesAsync()(نه مقدار ثابت) - ✅ دکمه بازگشت:
Href="/profile"بجایhistory.back()(جلوگیری از حلقه بازگشت به درگاه)
11d: حذف دوبار ×۱۰ شارژ کیفپول (FO:2f9ef15)
باگ: FO مبلغ تومان را ×۱۰ تبدیل به ریال میکرد، سپس CMS/ZarinPal دوباره ×۱۰ → مبلغ ۱۰۰ برابر
- ✅
MagicWallet.razor.cs— حذف تبدیل ×۱۰ (ارسال مستقیم تومان) - ✅
MagicWallet.razor— فیکس Max و فیلتر preset مبالغ - ✅
ChargeDiscountWallet.razor.cs— حذف تبدیل ×۱۰ - ✅
ClubMembershipContractDialog.razor— حذفPrice/10اضافی - ✅ ۴ فایل تغییر
11e: فیکس مسیر Callback کیفپول (CMS:ed2b20a)
- ✅
PaymentCallbackController— مسیر redirect از/magic-walletبه/profile/magic-wallet - ✅ ایجاد
appsettings.Development.json— URLهای محلی (localhost:32846وlocalhost:5268) - ✅ تصحیح کامنتهای proto: «ریال» → «تومان»
11f: امنیت Callback URL — حذف از ورودی کاربر (CMS:0107308, FO:2b1dc47)
اصلاح امنیتی: هیچ callback URL نباید از ورودی کاربر بیاید — همه از
appsettings.jsonخوانده شوند
- ✅
PackageService— خواندنFrontOfficeBaseUrlازIConfigurationبجایrequest.CallbackUrl - ✅
TransactionsService— همان فیکس، خواندن از config - ✅ تأیید:
MagicWalletوDiscountWalletاز قبل ازCmsBaseUrlconfig میخوانند ✅ - ✅ تأیید:
DiscountShop PlaceOrderاز قبل ازCmsBaseUrlconfig میخواند ✅ - ✅ FO: حذف
CallbackUrlازIndex.razor.csوCheckout.razor.cs - ✅ جدول Callback URLها:
| فلو | Callback URL | منبع |
|---|---|---|
| خرید پکیج | FrontOfficeBaseUrl/profile/payment-callback?orderId=X |
config |
| کیفپول جادویی | CmsBaseUrl/api/wallet/verify-magic-charge |
config |
| کیفپول اعتباری | CmsBaseUrl/api/wallet/verify-discount-charge |
config |
| فروشگاه اعتباری | CmsBaseUrl/api/payment/discount-order/callback?orderId=X |
config |
| تراکنش عمومی | FrontOfficeBaseUrl/profile/payment-callback |
config |
محتوا و ناوبری
- ✅ بلاگ — لیست + جزئیات + pagination
- ✅ صفحات سایت — About, Contact, FAQ, Terms, Privacy, Licenses
- ✅ ناوبری Auth-Aware — مسیردهی بر اساس نقش
- ✅ Home → Club Dashboard / Store بر اساس وضعیت
- ⬜ Mobile Responsive — Phase 7 (برنامهریزیشده)
- ⬜ PWA — نیاز به Service Worker
- ⬜ Bottom Navigation (موبایل) — طراحی نشده
۳. CMS Core (97% کامل)
ساختار و معماری
- ✅ CQRS با MediatR — Commands + Queries + Handlers
- ✅ gRPC Services — ۱۱ سرویس اصلی
- ✅ EF Core 9 — Migrations + Seeding
- ✅ Hangfire — ۴ Background Job
- ✅ JWT Authentication — Claims-based
- ✅ ICurrentUserService — جداسازی Admin/Customer
محصولات و فروشگاه
- ✅ Product CRUD — با auto-inventory
- ✅ Category CRUD — درختی
- ✅ Inventory management — auto-create + sync job
- ✅ GetProductsPaged — با PaginationState
- ✅ File upload/download — streaming gRPC
مالی و پرداخت
- ✅ ZarinPal Integration — IPG + Verify
- ✅ PYMS Service — سرویس مرکزی پرداخت
- ✅ ۳ Wallet System — Balance, Network, Discount
- ✅ Transaction logging — همه تراکنشها
باشگاه
- ✅ Binary Tree — SP_GetNetworkTree
- ✅ Weekly Balance Calculation — sp_CalculateWeeklyBalances
- ✅ Commission Pool — sp_CalculateWeeklyCommissionPool
- ✅ Contract System — OTP + acceptance
- ✅ Club Features — activate/deactivate
- ✅ DayaLoan Integration — Hangfire + Polly
🪄 کیفپول جادویی (Magic Wallet) — فاز 1-6 ✅
- ✅ فاز ۱: WalletMode enum + UserWallet fields + ClubMembershipCycle entity + TransactionType (14,15)
- ✅ فاز ۲: Trigger ورود/خروج Magic در SubmitShopBuyOrder + ActivateClubMembership Cycle
- ✅ فاز ۳: ChargeMagicWallet + VerifyMagicWalletCharge + HTTP callback + gRPC RPCs
- ✅ فاز ۴: فیلتر Magic از کمیسیون (C# + SP) + تاریخ Cycle
- ✅ فاز ۵: MagicWallet.razor UI + WalletService + تایل داشبورد
- ✅ فاز ۶: محدودیت دایا بعد از دور اول + محدودیت فعالسازی در حالت Magic
VAT
- ✅ اصلاح VAT از 9% به 10% در همه فایلها (VatCalculator, UserOrderService, Checkout, VATService)
فعالسازی درگاه و تنظیمات محیطی (اسفند ۱۴۰۴)
- ✅ تنظیم MerchantId جدید ZarinPal —
4225d555-5fa9-4df0-9b61-1ce152cbbba8 - ✅ تنظیمات محیطی — Staging: UseSandbox=true / Production: UseSandbox=false
- ✅ فعالسازی MagicWalletCycleSeed در Production
- ✅ تنظیم Kestrel Http2 + Seq logging برای Production
- ✅ بهبود user_name در proto — فیلد جدید در GetAllUserWalletByFilterResponseModel
- ✅ اغنای پاسخ UserWalletService — join با جدول Users برای نمایش نام کاربر
- ✅ ارتقای Proto NuGet به نسخه 0.0.183
فیکسهای پرداخت و امنیت (اسفند ۱۴۰۴ — Phase 11)
- ✅ ZarinPal Verify fix — رفع باگ amount=0 در VerifyPaymentAsync (Code=-1) — ۳ آرگومانه overload
- ✅ تصحیح مدل تومان/ریال — DB به تومان ذخیره میکند، فقط ZarinPal ریال (×۱۰) نیاز دارد
- ✅ Callback URL از config —
PackageServiceوTransactionsServiceازFrontOfficeBaseUrlconfig میخوانند (نه از ورودی) - ✅ فیکس مسیر redirect —
/magic-wallet→/profile/magic-walletدر PaymentCallbackController - ✅ appsettings.Development.json — URLهای محلی برای توسعه (CmsBaseUrl + FrontOfficeBaseUrl)
- ✅ کامیتها:
721661a→ed2b20a→0107308
محتوا
- ✅ Blog CRUD — با pagination
- ✅ SitePage Settings — JSON typed
- ✅ SystemConfigurations — key-value
- ⬜ Product Bundle — طراحیشده، پیادهسازی نشده
- ⬜ Manual Payment — طراحیشده، پیادهسازی نشده
- ⬜ API Rate Limiting — برنامهریزیشده
۴. Deployment و زیرساخت (95% کامل)
- ✅ Docker Compose — تمام سرویسها
- ✅ Dockerfile (CMS) — multi-stage build
- ✅ K8s Manifests — Deployment + Service + Ingress
- ✅ CI/CD Pipeline — Gitea Actions
- ✅ Nexus Repository — NuGet + Docker proxy
- ✅ Offline Deployment — کامل با اسکریپتها
- ✅ Proto Package — NuGet packaging + distribution
- ✅ Health Check scripts — K8s + service
- ✅ Mirror Configuration — Docker + NuGet
- ✅ Base Image Caching — pull + save + load
- ✅ مرج پروداکشن CMS — حل conflict در appsettings.Production.json + حذف migration تکراری u21
- ✅ مرج پروداکشن FrontOffice — ۲۱ فایل، ۴۰۰ insertion + فیکس GwUrl
- ✅ مرج پروداکشن BackOffice — ۳۶ فایل، بدون conflict
- ✅ اجرای Migration روی پروداکشن — ExpandDiscountProductFullInformation روی DB کیبیاس
- ⬜ Monitoring (Prometheus/Grafana) — برنامهریزیشده
- ⬜ Log Aggregation (ELK/Seq) — Seq تنظیم شده در Production (http://seq-svc:5341)
۵. Migration (100% کامل)
- ✅ FrontOffice REST → gRPC — همه سرویسها migrate شدند
- ✅ BackOffice REST → gRPC — همه سرویسها migrate شدند
- ✅ BFF حذف — یک لایه کمتر در deployment
- ✅ API Gateway (Ocelot) حذف — K8s Ingress جایگزین
- ✅ Data Migration — Users, Products, Orders, Club
- ✅ Geography Seeder — ۳۱ استان + ۱۲۰۰ شهر
- ✅ SQL Scripts — ۱۴ اسکریپت مهاجرت اجرا شدند
- ✅ Proto Package Unification — یک package مشترک
- ✅ Binary Tree Reconstruction — از سیستم قدیم
DataMigration Tool (اسفند ۱۴۰۴)
- ✅ ابزار مستقل مهاجرت داده — .NET 9 Console + Dapper + Polly + Serilog
- ✅ Smart Retry Policy — فقط خطاهای transient SQL (deadlock, timeout, transport) — نه خطاهای منطقی
- ✅ FK Disable/Enable —
NOCHECK/CHECKحول مهاجرت برای حل FK violation - ✅ TruncateTargetTables — حل مشکل duplicate key (IX_ClubMembership_UserId)
- ✅ Fallback Table Name — اگر جدول مقصد rename شده (
UserWalletChangeLogs→UserWalletHistories) - ✅ PostMigration SQL — همه مراحل با
IF COL_LENGTH/OBJECT_IDguard شده - ✅ کامیتها:
0e8c6fd→8385c90→31cc464
EF Migration — Staging (اسفند ۱۴۰۴)
- ✅ اعمال migrations روی DB استیجینگ KBS (
185.252.31.42,2019/KBS) — موفق - ✅ اعمال migrations روی DB اپلیکیشن (
194.5.195.53,31433/Foursat) — موفق - ✅ آخرین migration:
20260227024734_Q27_HistoryTables_And_RenameWalletHistory(۵۵ migration مجموع) - ✅ حل خطای لاگین
Invalid column name 'FirstActivationDate'— دو DB مختلف بودند
۶. مستندات (100% کامل)
- ✅ ایجاد totalDoc repository — مخزن مرکزی docs
- ✅ جمعآوری ۵۳ فایل از ۵ مخزن مختلف
- ✅ تجمیع به ۱۵ فایل ساختارمند — Business + Technical + Overview
- ✅ Index و Cross-reference — نقشه ارتباطات
- ✅ واژهنامه و استانداردها
- ✅ نقشه راه آینده
۷. تحول سیستم پکیجبیس (Package-Based Transformation) — 90%
📦 تبدیل سیستم تکپکیجی hardcoded به معماری چندپکیجی داینامیک مرجع: BIZ-PACKAGE-BASED-SYSTEM.md | PACKAGE-TRANSFORMATION-TASKS.md
Phase 0 — فیکس باگهای فوری ✅ (8b9c317, fe3edd1)
- ✅ B1: DiscountBalance شارژ نمیشد در VerifyGoldenPackagePurchase — اضافه
DiscountBalance += Amount × 2+ WalletChangeLog - ✅ B2: UserPackagePurchase ساخته نمیشد در VerifyGoldenPackagePurchase — ساخت record بعد verify
- ✅ B3: UserPackagePurchase ساخته نمیشد در VerifyPackagePurchase — ساخت record
- ✅ B4: UserPackagePurchase ساخته نمیشد در VerifyBasePackagePayment — ساخت record
- ✅ B6: EXIT Magic Mode — ریست PackagePurchaseMethod + بستن چرخه فعلی
Phase 1 — زیرساخت Domain ✅ (ae92ab8)
- ✅ T1.1: Package Entity — ۱۱ فیلد جدید (SortOrder, IsActive, IsBasePackage, DiscountMultiplier, MagicWalletMultiplier, ...)
- ✅ T1.2: PackageFeature Entity — رابطه M:N بین Package و ClubFeature
- ✅ T1.3: ClubMembership — ۴ فیلد First/Last Activation + PackageId
- ✅ T1.4-T1.6: اضافه PackageId به ClubMembershipCycle, WeeklyCommissionPool, UserCommissionPayout, NetworkWeeklyBalance, UserWalletChangeLog
- ✅ T1.7: علامتگذاری ۹ SystemConstants بهعنوان [Obsolete]
- ✅ T1.8: EF Configurations — Index, Precision, FK relations
Phase 1.5 — Migration + Data Seed ✅ (a9cd2fd)
- ✅ EF Migration
AddPackageBasedSystem— ستونها + جداول + ایندکسها - ✅ Golden Package Seed (Id=1) — Price=56M, ActivationFee=25.2M, DiscountMultiplier=2.0, MagicWalletMultiplier=2.5
- ✅ Data Backfill — تمام رکوردهای موجود → PackageId=1
- ✅ فیکس nullable DateTime/long در ClubMembership
- ✅ فیکس Shadow FK PackageId1
Phase 2 — منطق کسبوکار ✅ (8e5c7c5)
- ✅ T2.1: ActivateClubMembership — ActivationFee از Package entity
- ✅ T2.2: AcceptClubMembershipContract — Package features از DB
- ✅ T2.3: CalculateWeeklyBalances — MaxBalancesPerLeg per-package
- ✅ T2.4: ProcessUserPayouts — PackageId tracking
- ✅ T2.5: DayaLoans — Package.Price بجای hardcoded
- ✅ T2.6: ManualPayment — Package.Price بجای hardcoded
- ✅ T2.7: InitiateBasePackage/VerifyBasePackage — Package-based
- ✅ T2.8: ChargeMagicWallet/VerifyMagicWalletCharge — MagicWalletMultiplier per-package
- ✅ T2.9: OrmCommissionCalculationStrategy — MaxBalancesPerLeg/MaxNetworkLevel per-package
- ✅ T2.10: ConfigurationService/UserOrderService/UserWalletService — Package reads
- ✅ نتیجه: صفر مصرف SystemConstants deprecated باقی مانده
Phase 3 — بازسازی لایه Package ✅ (ccb938e)
- ✅ Proto: ۱۱ فیلد جدید در ۵ message (CreateNewPackageRequest, UpdatePackageRequest, GetPackageResponse, ...)
- ✅ GetUserPackageStatus — پیادهسازی (قبلاً NotImplementedException بود!)
- ✅ CustomerVerifyPackagePurchase — شارژ کیفپول اضافه شد (قبلاً missing بود!)
- ✅ VerifyGoldenPackagePurchase —
package.DiscountMultiplierبجای hardcoded ×2 - ✅ GetAllPackageByFilter — فیلتر IsDeleted
- ✅ GetCustomerPackages — فیلتر IsDeleted + IncludeInactive + SortOrder
- ✅ GetCustomerPackageDetails — PackageFeatures از DB
- ✅ GetCustomerPurchaseHistory — Include Transaction
- ✅ UpdatePackageCommand — ۱۲ فیلد جدید
Phase 4 — تکمیل CRUD + Legacy Fixes ✅ (0002a5a)
- ✅ CreateNewPackageCommand — ۱۲ فیلد جدید با defaultهای مناسب
- ✅ GetPackageResponseDto — ۱۲ فیلد جدید (Mapster auto-map)
- ✅ GetAllPackageByFilterResponseModel — ۱۲ فیلد جدید
- ✅ PurchaseGoldenPackage — حذف Title string match شکننده (
"طلایی"/"golden") →IsDeleted/IsActive/SupportsDirectPurchase - ✅ VerifyPackagePurchase — حذف hardcoded
order.Amount × 2→package.DiscountMultiplierاز DB
Phase 5 — پورسانت per-package + پاکسازی golden ✅ (607f791, 7176fe4)
- ✅ ORM Commission: per-user-package calculation via
ClubMembership.LastPackageId- userPackageMap، per-user maxBalancesPerLeg/maxNetworkLevel
- Carryover keyed by (UserId, PackageId) tuple
- ✅ SP Commission: loop over packages، pass
@PackageId/@InputMaxBalancesPerLeg/@InputMaxNetworkLevel - ✅ sp_CalculateWeeklyBalances: ۳ پارامتر جدید، فیلتر
cm.LastPackageId = @PackageId، ستون PackageId در INSERT - ✅ Fix:
cm.PackageId→cm.LastPackageId— match actual DB column name - ✅ Fix golden/طلایی string refs in user-facing messages (ActivateClubMembership)
- ✅ Rename
HasPurchasedGoldenPackage→HasPurchasedPackage(DTO + Handler + Proto + Mapping)
Phase 6 — Deprecation cleanup + ConfigurationService ✅ (d19c569)
- ✅ Mark
PurchaseGoldenPackage/VerifyGoldenPackagePurchaseRPCs asdeprecated = true - ✅ Mark
InitiateBasePackagePayment/VerifyBasePackagePaymentRPCs asdeprecated = true - ✅ Remove deprecated SystemConstants from
GetAllAsDict/GetAllWithDescriptionshelpers - ✅ Add MagicWallet per-package values to ConfigurationService (Multiplier, MaxDeposit, MaxCredit)
- ✅ تأیید: صفر رفرنس فعال به ۹ SystemConstants منسوخ — dead code آماده حذف
Phase 7 — UI ✅ (گزارش per-package)
- ⬜ FrontOffice: کاشیهای داینامیک پکیج
- ⬜ FrontOffice: MyPackages + re-purchase
- ✅ FrontOffice: Commission Dashboard per-package — فیلتر dropdown پکیج + ستون پکیج + MudChip (دسکتاپ + موبایل)
- ✅ FrontOffice: WeeklyBalance per-package — فیلتر MudSelect پکیج + MudChip اطلاعات هفته
- ✅ BackOffice: فیلتر پکیج در گزارشها — PackageSelect component + UserPayouts + BalancesReport
Phase 8e — Per-Package Commission Reports ✅ (CMS:aaaf7fc FO:a956cb9 BO:8be98ae)
- ✅ Proto: اضافه
package_idفیلتر به ۴ request +package_id/package_titleبه ۴ response model - ✅ CMS: اضافه PackageId فیلتر به ۴ query + handler + ۳ DTO + CommissionProfile mapping
- ✅ BO: کامپوننت PackageSelect + فیلتر و ستون پکیج در UserPayouts + BalancesReport
- ✅ FO: فیلتر و ستون پکیج در CommissionDashboard + WeeklyBalance
- ✅ NuGet:
0.0.186→0.0.187
Phase 9 — Q24-Q30 Business Decisions + History Infrastructure ✅
9a: Q24+Q26 — Balance Threshold + SP Worker ✅ (CMS:a1024a3)
- ✅ Q24: آستانه موجودی
Balance <= 1_000_000ریال برای ورود Magic و خرید مجدد (بجای== 0) - ✅ Q26:
StoredProcedureDeploymentService(IHostedService) — خواندن فایلهای.sqlاز embedded resource، مقایسه checksum و اعمال خودکار در startup
9b: Q27 — History Tables Entities ✅ (CMS:fdbb91d)
- ✅
PackageHistoryentity — فیلدهای Old*/New* برای Price, ActivationFee, MagicMultiplier, MagicMaxDeposit, MaxBalancesPerLeg, IsActive - ✅
ClubMembershipCycleHistoryentity — فیلدهای Old*/New* برای IsCurrentCycle, MagicStartedAt, MagicCompletedAt - ✅
PackageActionوClubMembershipCycleActionenums - ✅ EF Configurations + DbSets + Navigation Properties
9c: Q28 — UI Guidance ✅ (FO:474d364 BO:6939780)
- ✅ FrontOffice: ۷ صفحه با MudAlert (G1-G7) — Packages, Checkout, MyPackages, MagicWallet, Commission, Membership, ActivationSection
- ✅ BackOffice: ۶ صفحه با MudAlert (G8-G13) — PackageCRUD, ClubFeatures, ManualPayments, Commission Dashboard, UserPayouts, ClubMembers
9d: Rename + History Interceptor + Migration ✅ (CMS:10d2ca2)
- ✅ تغییر نام
UserWalletChangeLog→UserWalletHistoryدر ۵۴+ فایل (entities, configs, DTOs, commands, queries, protos, services) - ✅ تغییر نام ۳۴ فایل و ۱۱ دایرکتوری
- ✅ تغییر نام proto:
userwalletchangelog.proto→userwallethistory.proto - ✅
IHasHistory<T>generic interface — متدCreateHistorySnapshotبرای ثبت خودکار - ✅
HistoryTrackingSaveChangesInterceptor— reflection-based، auto-fill Old* از OriginalValues - ✅
PackageimplementsIHasHistory<PackageHistory> - ✅ EF Migration
Q27_HistoryTables_And_RenameWalletHistory— RenameTable (حفظ داده) + rename PK/FK/Index via sp_rename - ✅ NuGet:
0.0.187→0.0.188
Phase 10 — استقرار + DataMigration + UI خرید پکیج ✅
10a: DataMigration Tool ✅ (Local — بدون remote)
- ✅ ابزار مستقل مهاجرت داده — .NET 9 Console app + Dapper (bulk copy) + Polly (retry) + Serilog (logging)
- ✅ مهاجرت ۱۸ جدول از DB پروداکشن (
185.252.31.42,2019/Foursat) به استیجینگ (KBS) - ✅ Smart Retry — فقط خطاهای transient (deadlock/timeout/transport)، نه خطاهای منطقی
- ✅ FK Disable/Enable —
ALTER TABLE NOCHECK/CHECK CONSTRAINTحول هر مهاجرت - ✅ TruncateTargetTables — حل duplicate key (
IX_ClubMembership_UserId) هنگام اجرای مجدد - ✅ Fallback Table Name — جدول مقصد rename شده؟ (
UserWalletChangeLogs→UserWalletHistories) - ✅ PostMigration SQL — همه مراحل با
IF COL_LENGTH/OBJECT_IDguard شده (سازگار با هر دو schema) - ✅ کامیتها:
0e8c6fd→8385c90(MERGE fix) →31cc464(FK+truncate+PostMigration)
10b: EF Migration Staging ✅
- ✅ اعمال ۵۵ migration روی DB استیجینگ KBS (
185.252.31.42,2019;Database=KBS) - ✅ اعمال ۵۵ migration روی DB اپلیکیشن (
194.5.195.53,31433;Database=Foursat) - ✅ آخرین migration:
20260227024734_Q27_HistoryTables_And_RenameWalletHistory - ✅ حل خطای لاگین:
Invalid column name 'FirstActivationDate'— CMS به DB دیگری وصل بود
10c: PackagePurchaseDialog — دیالوگ داینامیک خرید (FO:a3681a8)
- ✅
PackagePurchaseDialog.razor— دیالوگ ۲ مرحلهای جایگزین دیالوگ hardcoded «پکیج پایه» - ✅ مرحله ۱: نمایش کاشیهای پکیج (responsive grid 2-3 ستونه) با عنوان + قیمت + ویژگیها + badge «پایه»
- ✅ مرحله ۲: انتخاب روش پرداخت (مستقیم + اعتبار دایا) با خلاصه پکیج انتخابی
- ✅ بارگذاری از
PackageService.GetAllPackagesAsync()+PackagePurchaseResultrecord - ✅ محدودیت دایا: فقط
SupportsDayaPurchase && PurchaseCycleCount == 0 - ✅ CSS:
.pkg-tile,.pkg-tile-badge,.pkg-payment-optionدرsite.css - ✅ NuGet:
0.0.188→0.0.189
10d: ۴ فیکس UI پکیج (FO:3c1a8ff)
- ✅ Toman/Rial: قیمت از سرور به ریال ←
FormattedPriceحالاPrice / 10برای نمایش صحیح تومان - ✅ لیبل: «ضریب تخفیف» → «ضریب اعتبار» (دیالوگ + صفحه لیست پکیجها)
- ✅ دکمه بازگشت: وجود داشت (
ArrowForward+BackToList) — تأیید عملکرد - ✅ HTML Description:
@((MarkupString)pkg.Description)بجای متن ساده
۸. Timeline (جدول زمانی)
| زمان | رویداد | درصد پروژه |
|---|---|---|
| مهر ۱۴۰۳ | شروع پروژه، معماری CMS | 10% |
| آبان ۱۴۰۳ | CQRS + gRPC + EF Core | 20% |
| آذر ۱۴۰۳ | باشگاه + درخت باینری + کمیسیون | 35% |
| دی ۱۴۰۳ | فروشگاه عادی + پرداخت از کیفپول | 45% |
| بهمن ۱۴۰۳ | فروشگاه اعتباری + وام دایا | 55% |
| اسفند ۱۴۰۳ (هفته ۱) | UI Modernization Phase 1-3 | 65% |
| اسفند ۱۴۰۳ (هفته ۲) | Site Pages + BackOffice audit | 75% |
| اسفند ۱۴۰۳ (هفته ۳) | Inventory + Lazy Load + Images | 85% |
| اسفند ۱۴۰۳ (هفته ۴) | مستندات + نهاییسازی | 95% |
| اسفند ۱۴۰۴ (هفته ۱-۲) | 🪄 کیفپول جادویی (فاز 1-6) + اصلاح VAT 10% | 96% |
| اسفند ۱۴۰۴ (هفته ۳) | 🚀 فعالسازی درگاه + بهبود UI ادمین + مرج پروداکشن | 97% |
| اسفند ۱۴۰۴ (هفته ۴) | 📦 تحول پکیجبیس فاز ۰-۶ (Domain → Migration → Business → Package → CRUD → Commission per-pkg → Deprecation) | 97% |
| اسفند ۱۴۰۴ (هفته ۵) | 📦 فاز 8e: گزارشهای پورسانت per-package (Proto + CMS + BO + FO) | 98% |
| اسفند ۱۴۰۴ (هفته ۶) | 📦 فاز ۹: Q24-Q30 (آستانه + SP Worker + History Tables + UI Guidance + Rename + Interceptor + Migration) | 99% |
| اسفند ۱۴۰۴ (هفته ۷) | 📦 فاز ۱۰: DataMigration Tool + EF Staging + PackagePurchaseDialog + UI Fixes (Toman/Rial + لیبل + HTML) | 99.5% |
| اسفند ۱۴۰۴ (هفته ۸) | 💳 فاز ۱۱: فیکس ZarinPal Verify + اصلاح تومان/ریال + صفحه موفقیت + حذف دوبار ×۱۰ + امنیت Callback URL | 99.5% |