# 📜 تاریخچه کارهای انجام‌شده > **همه فعالیت‌های پروژه به صورت بولت با توضیح یک‌خطی و درصد تکمیل** > **آخرین بروزرسانی:** اسفند ۱۴۰۴ (بروزرسانی: فاز ۱۰ — DataMigration + EF Staging + PackagePurchaseDialog + UI Fixes | NuGet v0.0.189) --- ## خلاصه کلی | حوزه | تعداد آیتم | تکمیل‌شده | درصد کل | |------|-----------|----------|---------| | **BackOffice** | 67 | 67 | **100%** | | **FrontOffice** | 54 | 54 | **100%** | | **CMS Core** | 82 | 82 | **100%** | | **Package-Based System** | 52 | 52 | **100%** | | **Deployment** | 22 | 21 | **95%** | | **Migration** | 21 | 21 | **100%** | | **مجموع** | **298** | **297** | **99%** | --- ## ۱. 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 هر دو شاخه فعال شدند (حذف «بزودی») ### 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` می‌کند برای نمایش صحیح تومان - ✅ تغییر لیبل «ضریب تخفیف» → «ضریب اعتبار» در دیالوگ خرید + صفحه لیست پکیج‌ها - ✅ دکمه بازگشت در مرحله انتخاب روش پرداخت — `MudIconButton ArrowForward` + `BackToList()` (قبلاً وجود داشت، تأیید شد) - ✅ رندر HTML در توضیحات پکیج — `@((MarkupString)pkg.Description)` بجای متن ساده - ✅ کامیت: `3c1a8ff` (FO) ### محتوا و ناوبری - ✅ بلاگ — لیست + جزئیات + 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 ### محتوا - ✅ 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_ID` guard شده - ✅ کامیت‌ها: `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](../business/BIZ-PACKAGE-BASED-SYSTEM.md) | [PACKAGE-TRANSFORMATION-TASKS.md](../roadmap/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`/`VerifyGoldenPackagePurchase` RPCs as `deprecated = true` - ✅ Mark `InitiateBasePackagePayment`/`VerifyBasePackagePayment` RPCs as `deprecated = true` - ✅ Remove deprecated SystemConstants from `GetAllAsDict`/`GetAllWithDescriptions` helpers - ✅ 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`) - ✅ `PackageHistory` entity — فیلدهای Old*/New* برای Price, ActivationFee, MagicMultiplier, MagicMaxDeposit, MaxBalancesPerLeg, IsActive - ✅ `ClubMembershipCycleHistory` entity — فیلدهای Old*/New* برای IsCurrentCycle, MagicStartedAt, MagicCompletedAt - ✅ `PackageAction` و `ClubMembershipCycleAction` enums - ✅ 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` generic interface — متد `CreateHistorySnapshot` برای ثبت خودکار - ✅ `HistoryTrackingSaveChangesInterceptor` — reflection-based، auto-fill Old* از OriginalValues - ✅ `Package` implements `IHasHistory` - ✅ 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_ID` guard شده (سازگار با هر دو 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()` + `PackagePurchaseResult` record - ✅ محدودیت دایا: فقط `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% |