docs: add ClubMembershipCycle table to preserve activation date

Problem: ActivateClubMembership overwrites ActivatedAt on re-purchase,
losing the original club activation date. Commission check uses
ActivatedAt to determine 'new member this week'.

Solution: New ClubMembershipCycle table
- Each package purchase creates a new cycle record
- ClubMembership.ActivatedAt = first-time only (never overwritten)
- Commission uses Cycle.PackagePurchasedAt instead of ActivatedAt
- IsCurrentCycle flag tracks active cycle
- Full history preserved for all purchase cycles

Also updated:
- SPEC: section 7.5 (entity), 7.6 (migration), 8.2 (SP change), 8.3 (handler)
- PLAN: phase 1 (entity), phase 2 (activate handler), phase 4 (date query)
- Checklist: added 4 new items
This commit is contained in:
masoodafar-web
2026-02-19 02:58:14 +03:30
parent b1dd69b31f
commit 0e61513b0e
2 changed files with 169 additions and 16 deletions
+30 -11
View File
@@ -19,10 +19,13 @@
├── TransactionType.cs → + MagicWalletDeposit=14, MagicWalletBonus=15
├── SystemConstants.cs → + MagicWalletMultiplier, MagicWalletMaxDeposit, MagicWalletMaxCredit
├── UserWalletConfiguration.cs → EF config برای فیلدهای جدید
── Migration: AddMagicWalletFields → dotnet ef migrations add
── ClubMembershipCycle.cs → 🆕 entity جدید (حل مشکل تاریخ کمیسیون)
├── ClubMembershipCycleConfiguration.cs → EF config
├── Migration: AddMagicWalletFields → dotnet ef migrations add
└── Migration: AddClubMembershipCycle → dotnet ef migrations add + data seed
```
**تست:** Migration اجرا بشه، فیلدها در DB ایجاد بشن، default‌ها درست باشن.
**تست:** Migration اجرا بشه، فیلدها در DB ایجاد بشن، default‌ها درست باشن. هر ClubMembership موجود یه رکورد Cycle=1 داشته باشه.
---
@@ -36,6 +39,10 @@
│ ├── بعد از کسر Balance: check ورود به Magic
│ └── بعد از کسر Balance: check خروج از Magic
├── ActivateClubMembershipCommandHandler.cs
│ ├── ActivatedAt فقط بار اول ست بشه (دیگه overwrite نشه)
│ └── هر بار یک ClubMembershipCycle جدید اضافه بشه
├── (Optional) Domain Event: WalletModeChangedEvent
│ └── برای لاگ و نوتیفیکیشن
@@ -85,20 +92,28 @@
---
### فاز ۴ — غیرفعال‌سازی کمیسیون (روز ۴.۵)
### فاز ۴ — غیرفعال‌سازی کمیسیون + تاریخ Cycle (روز ۴.۵)
**هدف:** کاربرهای Magic از کمیسیون خارج بشن
**هدف:** کاربرهای Magic از کمیسیون خارج بشن + تاریخ کمیسیون از Cycle بخونه
```
فایل‌های تغییری:
├── CalculateWeeklyBalancesCommandHandler.cs
── فیلتر: WHERE wallet.WalletMode != Magic
── فیلتر: WHERE wallet.WalletMode != Magic
│ └── تاریخ: ActivatedAt → ClubMembershipCycle.PackagePurchasedAt
── (یا SP اگه از Stored Procedure استفاده میکنه)
└── sp_CalculateWeeklyBalances → + JOIN UserWallets WHERE WalletMode = 0
── sp_CalculateWeeklyBalances.sql
├── + JOIN UserWallets WHERE WalletMode = 0
│ └── WHERE cm.ActivatedAt → cc.PackagePurchasedAt (AND cc.IsCurrentCycle = 1)
└── WeekRepository (اگه date range query داره)
└── آپدیت query
```
**تست:** کاربر Magic در محاسبات هفتگی شرکت نکنه ✅
**تست:**
- کاربر Magic در محاسبات هفتگی شرکت نکنه ✅
- کاربر دور ۲ (پکیج مجدد): با تاریخ PackagePurchasedAt جدید امتیاز بگیره ✅
- تاریخ اصلی ActivatedAt تغییر نکرده باشه ✅
---
@@ -165,19 +180,23 @@
- [ ] **فاز ۱:** WalletMode enum
- [ ] **فاز ۱:** UserWallet entity + 5 فیلد جدید
- [ ] **فاز ۱:** ClubMembershipCycle entity (جدید)
- [ ] **فاز ۱:** TransactionType + 2 مقدار
- [ ] **فاز ۱:** SystemConstants + 3 ثابت
- [ ] **فاز ۱:** EF Configuration
- [ ] **فاز ۱:** Migration
- [ ] **فاز ۱:** EF Configuration (UserWallet + ClubMembershipCycle)
- [ ] **فاز ۱:** Migration: AddMagicWalletFields
- [ ] **فاز ۱:** Migration: AddClubMembershipCycle + data seed
- [ ] **فاز ۲:** Trigger ورود Magic (SubmitShopBuyOrder)
- [ ] **فاز ۲:** Trigger خروج Magic
- [ ] **فاز ۲:** ActivateClubMembership → ActivatedAt نگه‌داشته بشه + Cycle جدید
- [ ] **فاز ۲:** PurchaseCycleCount
- [ ] **فاز ۳:** InitiateMagicChargeCommand + Handler
- [ ] **فاز ۳:** VerifyMagicChargeCommand + Handler
- [ ] **فاز ۳:** MagicWalletController (HTTP callback)
- [ ] **فاز ۳:** gRPC Proto + Service
- [ ] **فاز ۳:** ۲ تراکنش + ۱ لاگ (اجباری)
- [ ] **فاز ۴:** فیلتر کمیسیون (C# یا SP)
- [ ] **فاز ۴:** فیلتر کمیسیون Magic (C# handler + SP)
- [ ] **فاز ۴:** تاریخ کمیسیون: ActivatedAt → Cycle.PackagePurchasedAt (C# + SP)
- [ ] **فاز ۵:** MagicWallet.razor
- [ ] **فاز ۵:** MagicPaymentCallback.razor
- [ ] **فاز ۵:** WalletService gRPC client