docs: package-based transformation — complete roadmap + UX impact + feature backlog
New documents: - roadmap/FEATURE-BACKLOG.md: 12 kept RPCs → feature tasks with priority, target pages, and time estimates (F1-F12) - roadmap/PACKAGE-TRANSFORMATION-UX.md: UX impact analysis — before/after wireframes for 19 pages (10 FO + 9 BO), customer + admin experience changes, future needs prediction - roadmap/PACKAGE-TRANSFORMATION-TASKS.md: step-by-step implementation plan (6 phases, ~13 day critical path), atomic tasks with code diffs, dependency graph, test checklist Updated: - cms/GRPC-SERVICES-AUDIT.md: cross-references to new docs Total: 998 lines of documentation covering: - 12 RPC feature tasks prioritized by package-based relevance - 19 page wireframes (before/after comparison) - 39 transformation tasks broken into 6 phases - 10 predicted future requirements (N1-N10) - Risk analysis + rollback plan + calendar
This commit is contained in:
@@ -207,11 +207,12 @@
|
||||
|
||||
## ⚠️ نکات مهم
|
||||
|
||||
1. **آرشیو ≠ حذف!** — RPCهای آرشیوشده فقط با `// [ARCHIVED]` علامتگذاری میشوند
|
||||
1. **آرشیو ≠ حذف!** — RPCهای آرشیوشده با `[Obsolete]` + `#region [ARCHIVED]` علامتگذاری شدند (کامیت `13dd0f5`)
|
||||
2. RPCهای دسته B (Internal — ۱۰۱ عدد) **حیاتی** هستند — بدون آنها سیستم از کار میافتد
|
||||
3. RPCهای «نگهداری» (۱۲ عدد) کد **کامل و آماده** دارند — فقط نیاز به وصل شدن از فرانت
|
||||
4. **fms.proto** تنها فایل proto کاملاً مُرده است — میتواند از csproj اکسکلود شود
|
||||
5. قبل از هر تغییر، حتماً `grep -rn "RpcName" CMS/src/` بزنید تا مطمئن شوید
|
||||
3. RPCهای «نگهداری» (۱۲ عدد) کد **کامل و آماده** دارند — بکلاگ فیچر: [FEATURE-BACKLOG.md](../roadmap/FEATURE-BACKLOG.md)
|
||||
4. **fms.proto** از csproj اکسکلود شد (کامیت `13dd0f5`)
|
||||
5. نقشهراه تحول پکیجبیس: [PACKAGE-TRANSFORMATION-TASKS.md](../roadmap/PACKAGE-TRANSFORMATION-TASKS.md)
|
||||
6. قبل از هر تغییر، حتماً `grep -rn "RpcName" CMS/src/` بزنید تا مطمئن شوید
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# 📋 فیچر بکلاگ — RPCهای آماده (بدون UI)
|
||||
|
||||
> تاریخ: ۱۴۰۴/۱۲/۰۶
|
||||
> منبع: آدیت gRPC (کامیت `3575e48`) → ۱۲ RPC کامل بدون فرانت
|
||||
> اولویتبندی: بر اساس ارزش کسبوکار + نیازمندی پکیجبیس
|
||||
|
||||
---
|
||||
|
||||
## 🎯 خلاصه
|
||||
|
||||
از ۲۴ RPC مُرده شناساییشده، **۱۲ عدد پیادهسازی کامل** دارند ولی هرگز از فرانتها وصل نشدند. اینها فیچرهای آماده هستند که فقط نیاز به UI دارند.
|
||||
|
||||
---
|
||||
|
||||
## 📊 ماتریس فیچر × اولویت
|
||||
|
||||
### 🔴 اولویت بالا — مرتبط با پکیجبیس کردن
|
||||
|
||||
| # | RPC | تارگت | صفحه | اقدام | تخمین |
|
||||
|---|-----|-------|------|-------|-------|
|
||||
| F1 | `AssignFeatureToMembership` | BackOffice | ClubFeaturesPage.razor | دکمه «اختصاص فیچر به عضو» + ماتریس PackageFeature | ۴ ساعت |
|
||||
| F2 | `ChangeNetworkParent` | BackOffice | UserNetworkInfo.razor | دکمه «جابجایی در شبکه» + مودال انتخاب parent جدید | ۶ ساعت |
|
||||
| F3 | `CalculateOrderPV` | FrontOffice | Checkout.razor + MyPackages.razor | نمایش PV سفارش در چکاوت + PV انباشته در صفحه پکیجها | ۴ ساعت |
|
||||
|
||||
### 🟡 اولویت متوسط — بهبود UX فروشگاه
|
||||
|
||||
| # | RPC | تارگت | صفحه | اقدام | تخمین |
|
||||
|---|-----|-------|------|-------|-------|
|
||||
| F4 | `CustomerReorderPreviousOrder` | FrontOffice | OrderHistory (Store/Discount) | دکمه «تکرار سفارش» در هر ردیف تاریخچه | ۳ ساعت |
|
||||
| F5 | `CustomerTrackOrder` | FrontOffice | OrderTracking.razor | وصل Tracking API → نمایش TrackingCode + وضعیت ارسال | ۴ ساعت |
|
||||
| F6 | `UpdateCustomerSettings` | FrontOffice | Profile/Settings.razor | فرم تنظیمات اعلان (Email/SMS/Push) + دکمه ذخیره | ۳ ساعت |
|
||||
| F7 | `GetLowStockProducts` | BackOffice | LowStockPage.razor | وصل API → فیلتر threshold + هشدار بصری | ۳ ساعت |
|
||||
|
||||
### 🟢 اولویت پایین — گزارشدهی و عملیات انبوه
|
||||
|
||||
| # | RPC | تارگت | صفحه | اقدام | تخمین |
|
||||
|---|-----|-------|------|-------|-------|
|
||||
| F8 | `GetInventorySummary` | BackOffice | InventoryMainPage.razor | کارت خلاصه بالای صفحه (تعداد کل + ارزش ریالی) | ۳ ساعت |
|
||||
| F9 | `GetStockValueReport` | BackOffice | InventoryMainPage.razor | تب «گزارش ارزش» + دانلود Excel | ۴ ساعت |
|
||||
| F10 | `BulkAddStock` | BackOffice | InventoryMainPage.razor | دکمه «افزودن دستهای» + آپلود CSV/فرم چندتایی | ۶ ساعت |
|
||||
| F11 | `BulkUpdateProductStock` | BackOffice | InventoryMainPage.razor | دکمه «بروزرسانی دستهای» (Set/Add/Subtract) | ۶ ساعت |
|
||||
| F12 | `GetConfigurationByKey` | Internal | — | بدون UI — استفاده داخلی بهینه بجای GetAll | ۰ |
|
||||
|
||||
---
|
||||
|
||||
## 📐 نقشه پیادهسازی
|
||||
|
||||
### فاز A — همراه پکیجبیس (فاز ۴ BIZ-PACKAGE-BASED-SYSTEM)
|
||||
|
||||
```
|
||||
F1 (AssignFeatureToMembership) → با T4.6 (ماتریس PackageFeature) ادغام
|
||||
F2 (ChangeNetworkParent) → با تستهای شبکه فاز ۵ ادغام
|
||||
F3 (CalculateOrderPV) → با T4.3 (MyPackages re-purchase) ادغام
|
||||
```
|
||||
|
||||
### فاز B — بعد از پکیجبیس (Sprint بعدی)
|
||||
|
||||
```
|
||||
F4 → F7: بهبود UX فروشگاه و مشتری
|
||||
تخمین: ۱۳ ساعت = ~۲ روز
|
||||
```
|
||||
|
||||
### فاز C — آینده (بدون فوریت)
|
||||
|
||||
```
|
||||
F8 → F12: گزارشدهی و عملیات انبوه
|
||||
تخمین: ۱۹ ساعت = ~۳ روز
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 ارجاعات
|
||||
|
||||
| مستند | محتوا |
|
||||
|-------|-------|
|
||||
| [GRPC-SERVICES-AUDIT.md](../cms/GRPC-SERVICES-AUDIT.md) | آدیت کامل ۳۴۲ RPC — ۱۲ نگهداری + ۱۲ آرشیو |
|
||||
| [BIZ-PACKAGE-BASED-SYSTEM.md](../business/BIZ-PACKAGE-BASED-SYSTEM.md) | طراحی سیستم پکیجبیس — ۳۹ تغییر |
|
||||
|
||||
---
|
||||
|
||||
*آخرین بروزرسانی: ۱۴۰۴/۱۲/۰۶*
|
||||
@@ -0,0 +1,418 @@
|
||||
# 🔄 نقشهراه تحول پکیجبیس — تسکهای گامبهگام
|
||||
|
||||
> **وضعیت:** تاییدشده — آماده شروع
|
||||
> **تاریخ:** ۱۴۰۴/۱۲/۰۶
|
||||
> **پیشنیاز:** [BIZ-PACKAGE-BASED-SYSTEM.md](../business/BIZ-PACKAGE-BASED-SYSTEM.md) v2
|
||||
> **هدف:** شکستن ۳۹ تغییر به تسکهای اتمیک با ترتیب اجرا و وابستگیها
|
||||
|
||||
---
|
||||
|
||||
## 📊 نمای کلی
|
||||
|
||||
```
|
||||
مرحله ۰: فیکس باگ فوری (۱ روز)
|
||||
└─→ مرحله ۱: زیرساخت Domain + DB (۳ روز)
|
||||
├─→ مرحله ۲: منطق کسبوکار (۴ روز) ← موازی
|
||||
│ └─→ مرحله ۴: FrontOffice UI (۳ روز)
|
||||
└─→ مرحله ۳: پورسانت (۳ روز) ← موازی
|
||||
└─→ مرحله ۵: BackOffice UI (۳ روز)
|
||||
└─→ مرحله ۶: تست + استقرار (۲ روز)
|
||||
|
||||
مسیر بحرانی: ۰→۱→۲→۴→۶ = ~۱۳ روز
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۰ — فیکس باگهای فوری
|
||||
|
||||
> ⏱️ ۱ روز | وابستگی: ندارد | ریسک: کم
|
||||
|
||||
### ✅ وضعیت باگها (بررسی اولیه لازم)
|
||||
|
||||
| # | باگ | Handler | شرح فیکس |
|
||||
|---|------|---------|----------|
|
||||
| B1 | DiscountBalance شارژ نمیشود | `VerifyGoldenPackagePurchaseCommandHandler` | اضافه `DiscountBalance += Amount × 2` + WalletChangeLog |
|
||||
| B2 | UserPackagePurchase ساخته نمیشود | `VerifyGoldenPackagePurchaseCommandHandler` | ساخت record بعد verify موفق |
|
||||
| B3 | UserPackagePurchase ساخته نمیشود | `VerifyPackagePurchaseCommandHandler` | ساخت record بعد verify موفق |
|
||||
| B4 | UserPackagePurchase ساخته نمیشود | `VerifyBasePackagePaymentCommandHandler` | ساخت record بعد verify موفق |
|
||||
|
||||
#### دستور کار B1:
|
||||
```
|
||||
1. باز کردن VerifyGoldenPackagePurchaseCommandHandler.cs
|
||||
2. پیدا کردن جایی که Balance شارژ میشود
|
||||
3. اضافه کردن:
|
||||
wallet.DiscountBalance += command.Amount * 2;
|
||||
// + ساخت WalletChangeLog برای DiscountBalance
|
||||
4. تست: verify → چک DiscountBalance در DB
|
||||
```
|
||||
|
||||
#### دستور کار B2-B4 (الگوی مشترک):
|
||||
```
|
||||
1. بعد از verify موفق و شارژ wallet:
|
||||
var purchase = new UserPackagePurchase
|
||||
{
|
||||
UserId = userId,
|
||||
PackageId = packageId, // فعلاً BasePackageId = 4
|
||||
PurchaseDate = DateTime.UtcNow,
|
||||
Amount = amount,
|
||||
PurchaseMethod = purchaseMethod, // ZarinPal, BFF, etc.
|
||||
TransactionId = transactionId,
|
||||
IsVerified = true
|
||||
};
|
||||
_context.UserPackagePurchases.Add(purchase);
|
||||
2. تست: verify → چک UserPackagePurchases table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۱ — زیرساخت (Domain + DB)
|
||||
|
||||
> ⏱️ ۳ روز | وابستگی: مرحله ۰ | ریسک: متوسط (migration)
|
||||
|
||||
### T1.1 — بروزرسانی Package Entity
|
||||
|
||||
**فایل:** `CMS/src/CMSMicroservice.Domain/Entities/Package.cs`
|
||||
|
||||
```diff
|
||||
+ public int SortOrder { get; set; }
|
||||
+ public bool IsActive { get; set; } = true;
|
||||
+ public bool IsBasePackage { get; set; }
|
||||
+ public bool SupportsDayaPurchase { get; set; }
|
||||
+ public bool SupportsDirectPurchase { get; set; } = true;
|
||||
+ public long ActivationFee { get; set; }
|
||||
+ public decimal DiscountMultiplier { get; set; } = 2.0m;
|
||||
+ public decimal MagicWalletMultiplier { get; set; } = 2.5m;
|
||||
+ public virtual ICollection<PackageFeature> PackageFeatures { get; set; }
|
||||
```
|
||||
|
||||
**EF Config:** `PackageConfiguration.cs`
|
||||
- حداکثر یک `IsBasePackage = true` (Index filter)
|
||||
- Precision for decimal fields
|
||||
|
||||
### T1.2 — ایجاد PackageFeature Entity
|
||||
|
||||
**فایل جدید:** `CMS/src/CMSMicroservice.Domain/Entities/PackageFeature.cs`
|
||||
|
||||
```csharp
|
||||
public class PackageFeature : BaseAuditableEntity
|
||||
{
|
||||
public long PackageId { get; set; }
|
||||
public virtual Package Package { get; set; }
|
||||
public long ClubFeatureId { get; set; }
|
||||
public virtual ClubFeature ClubFeature { get; set; }
|
||||
public bool IsIncluded { get; set; } = true;
|
||||
}
|
||||
```
|
||||
|
||||
### T1.3-T1.6 — اضافه PackageId به entityها
|
||||
|
||||
| Entity | فیلد | Required? | توضیح |
|
||||
|--------|------|-----------|-------|
|
||||
| ClubMembership | `long? PackageId` | nullable (بعد migration → required) | آخرین پکیج |
|
||||
| ClubMembershipCycle | `long PackageId` | required | پکیج این چرخه |
|
||||
| WeeklyCommissionPool | `long PackageId` | required + Unique(WeekDefId, PkgId) | Pool هر پکیج |
|
||||
| UserCommissionPayout | `long? PackageId` | nullable | ردیابی |
|
||||
|
||||
### T1.7 — حذف SystemConstants
|
||||
|
||||
**فایل:** `CMS/src/CMSMicroservice.Domain/Common/SystemConstants.cs`
|
||||
|
||||
```diff
|
||||
- public const long BasePackageAmount = 56_000_000;
|
||||
- public const long DayaLoanAmount = 56_000_000;
|
||||
- public const long ClubActivationFee = 25_200_000;
|
||||
- public const long ClubMembershipGiftValue = 25_200_000;
|
||||
- public const decimal MagicWalletMultiplier = 2.5m; // اگر وجود داشت
|
||||
```
|
||||
|
||||
> ⚠️ **قبل از حذف:** grep تمام مصرفکنندهها → جایگزین با `Package.Property`
|
||||
|
||||
### T1.8 — Database Migration
|
||||
|
||||
```bash
|
||||
dotnet ef migrations add AddPackageBasedSystem
|
||||
```
|
||||
|
||||
**شامل:**
|
||||
- ستونهای جدید Package
|
||||
- جدول PackageFeatures
|
||||
- FKها در 4 entity
|
||||
- Unique constraint
|
||||
|
||||
### T1.9 — Data Migration Script
|
||||
|
||||
```sql
|
||||
-- 1. بروزرسانی پکیج فعلی (ID=4 → اضافه فیلدهای جدید)
|
||||
UPDATE "CMS"."Packages" SET
|
||||
"SortOrder" = 2,
|
||||
"IsActive" = true,
|
||||
"IsBasePackage" = true,
|
||||
"SupportsDayaPurchase" = true,
|
||||
"SupportsDirectPurchase" = true,
|
||||
"ActivationFee" = 25200000,
|
||||
"DiscountMultiplier" = 2.0,
|
||||
"MagicWalletMultiplier" = 2.5
|
||||
WHERE "Id" = 4;
|
||||
|
||||
-- 2. Link existing data to base package
|
||||
UPDATE "CMS"."ClubMemberships" SET "PackageId" = 4 WHERE "PackageId" IS NULL;
|
||||
UPDATE "CMS"."ClubMembershipCycles" SET "PackageId" = 4 WHERE "PackageId" IS NULL;
|
||||
UPDATE "CMS"."WeeklyCommissionPools" SET "PackageId" = 4 WHERE "PackageId" IS NULL;
|
||||
UPDATE "CMS"."UserCommissionPayouts" SET "PackageId" = 4 WHERE "PackageId" IS NULL;
|
||||
|
||||
-- 3. Seed Silver package
|
||||
INSERT INTO "CMS"."Packages" (...) VALUES ('پکیج نقرهای', 5600000, ...);
|
||||
```
|
||||
|
||||
### T1.10 — بروزرسانی Protoها
|
||||
|
||||
| Proto File | تغییر |
|
||||
|-----------|-------|
|
||||
| package.proto | فیلدهای جدید Package message |
|
||||
| clubmembership.proto | package_id در request/response |
|
||||
| commission.proto | package_id در pool/payout messages |
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۲ — منطق کسبوکار
|
||||
|
||||
> ⏱️ ۴ روز | وابستگی: مرحله ۱ | ریسک: بالا (رگرسیون)
|
||||
|
||||
### T2.1 — Generic Verify Handler
|
||||
|
||||
**هدف:** ادغام VerifyGolden + VerifyBase + VerifyGeneric → یک handler
|
||||
|
||||
**الگوریتم:**
|
||||
```
|
||||
1. دریافت TransactionId از request
|
||||
2. خواندن Transaction → PackageId → Package entity
|
||||
3. verify با درگاه (ZarinPal/BFF/...)
|
||||
4. اگر موفق:
|
||||
a. wallet.Balance += Package.Price
|
||||
b. wallet.DiscountBalance += Package.Price × Package.DiscountMultiplier
|
||||
c. ساخت WalletChangeLog (Balance)
|
||||
d. ساخت WalletChangeLog (DiscountBalance)
|
||||
e. ساخت UserPackagePurchase record
|
||||
f. اگر اولین خرید: JoinNetwork
|
||||
g. بروزرسانی ClubMembershipCycle.PackageId
|
||||
5. return success + receipt
|
||||
```
|
||||
|
||||
### T2.2 — Generic Purchase Handler
|
||||
|
||||
**هدف:** ادغام PurchaseGolden + PurchasePackage + InitiateBase → یک handler
|
||||
|
||||
**تغییرات:**
|
||||
- حذف فیلتر `Title.Contains("طلایی")`
|
||||
- حذف `BasePackageId = 4`
|
||||
- خواندن Package entity از DB بر اساس `request.PackageId`
|
||||
- Gateway URL + Amount از Package.Price
|
||||
|
||||
### T2.3-T2.4 — ActivateClubMembership بهبود
|
||||
|
||||
**تغییرات:**
|
||||
```diff
|
||||
- var features = await GetAllFeatureIds(); // همه فیچرها
|
||||
+ var features = await GetPackageFeatures(packageId); // فیچرهای پکیج
|
||||
|
||||
- membership.PackageAmount = SystemConstants.BasePackageAmount;
|
||||
+ membership.PackageAmount = package.Price;
|
||||
|
||||
- var activationFee = SystemConstants.ClubActivationFee;
|
||||
+ var activationFee = package.ActivationFee;
|
||||
```
|
||||
|
||||
### T2.5-T2.6 — Re-Purchase Logic
|
||||
|
||||
**EXIT Magic Mode — تغییرات:**
|
||||
```diff
|
||||
wallet.WalletMode = WalletMode.Normal;
|
||||
wallet.MagicCompletedAt = DateTime.UtcNow;
|
||||
cycle.MagicCompletedAt = DateTime.UtcNow;
|
||||
+ user.PackagePurchaseMethod = PackagePurchaseMethod.None;
|
||||
+ membership.IsActive = false;
|
||||
+ cycle.IsCurrentCycle = false;
|
||||
```
|
||||
|
||||
**Guard تغییرات:**
|
||||
```diff
|
||||
- if (user.PackagePurchaseMethod != PackagePurchaseMethod.None)
|
||||
- throw new RpcException("قبلاً پکیج خریداری شده");
|
||||
+ if (user.PackagePurchaseMethod != PackagePurchaseMethod.None
|
||||
+ && !HasCompletedMagicCycle(membership))
|
||||
+ throw new RpcException("چرخه جاری هنوز تکمیل نشده");
|
||||
```
|
||||
|
||||
### T2.7 — JWT Claims جدید
|
||||
|
||||
```diff
|
||||
claims.Add("HasPurchasedPackage", "true");
|
||||
+ claims.Add("CanRepurchase", HasCompletedMagicCycle(membership).ToString());
|
||||
+ claims.Add("PackageId", membership.PackageId?.ToString() ?? "");
|
||||
+ claims.Add("PackageTitle", package?.Title ?? "");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۳ — محاسبه پورسانت (موازی با مرحله ۲)
|
||||
|
||||
> ⏱️ ۳ روز | وابستگی: مرحله ۱ | ریسک: بحرانی (مالی)
|
||||
|
||||
### T3.1-T3.2 — SPs + PackageId
|
||||
|
||||
```sql
|
||||
-- sp_CalculateWeeklyBalances:
|
||||
ALTER PROCEDURE sp_CalculateWeeklyBalances
|
||||
@WeekDefinitionId BIGINT,
|
||||
@PackageId BIGINT -- ← جدید
|
||||
AS
|
||||
BEGIN
|
||||
-- فیلتر بالانسها فقط کاربرانی که این پکیج را دارند
|
||||
INSERT INTO "CMS"."WeeklyBalances" (...)
|
||||
SELECT ...
|
||||
FROM "CMS"."UserWallets" w
|
||||
INNER JOIN "CMS"."ClubMemberships" m ON m."UserId" = w."UserId"
|
||||
WHERE m."PackageId" = @PackageId -- ← فیلتر
|
||||
AND m."IsActive" = true
|
||||
AND w."WalletMode" = 0; -- Normal only
|
||||
END;
|
||||
```
|
||||
|
||||
### T3.3 — Loop Service
|
||||
|
||||
```csharp
|
||||
// WeeklyCommissionCalculationService.cs
|
||||
var activePackages = await _context.Packages
|
||||
.Where(p => p.IsActive && !p.IsDeleted)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var package in activePackages)
|
||||
{
|
||||
_logger.LogInformation("Calculating commission for package {Id}: {Title}",
|
||||
package.Id, package.Title);
|
||||
|
||||
await strategy.CalculateWeeklyBalancesAsync(weekId, package.Id);
|
||||
await strategy.CalculateWeeklyPoolAsync(weekId, package.Id);
|
||||
}
|
||||
```
|
||||
|
||||
### ⚠️ نکته بحرانی
|
||||
|
||||
> پورسانت = پول واقعی. **هر تغییر در SPs باید:**
|
||||
> 1. ابتدا در staging با داده واقعی تست شود
|
||||
> 2. نتایج قبل و بعد مقایسه شوند
|
||||
> 3. Rollback plan آماده باشد
|
||||
> 4. در production ابتدا read-only اجرا شود (بدون commit)
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۴ — FrontOffice UI
|
||||
|
||||
> ⏱️ ۳ روز | وابستگی: مرحله ۲ | ریسک: متوسط
|
||||
|
||||
### T4.1 — کاشیهای پکیج داینامیک
|
||||
|
||||
**فایل:** `FrontOffice/src/.../Pages/Package/Packages.razor`
|
||||
|
||||
```razor
|
||||
@* قبل: hardcoded *@
|
||||
@* بعد: *@
|
||||
@foreach (var package in _packages.OrderBy(p => p.SortOrder))
|
||||
{
|
||||
<PackageCard Package="@package"
|
||||
OnPurchase="StartPurchase"
|
||||
ShowFeatures="true"
|
||||
ShowPV="true" />
|
||||
}
|
||||
```
|
||||
|
||||
### T4.2 — مودال پرداخت شرطی
|
||||
|
||||
```razor
|
||||
@if (_selectedPackage.SupportsDirectPurchase)
|
||||
{
|
||||
<MudButton OnClick="PayOnline">پرداخت آنلاین</MudButton>
|
||||
}
|
||||
@if (_selectedPackage.SupportsDayaPurchase)
|
||||
{
|
||||
<MudButton OnClick="PayDaya">اقساط دایا</MudButton>
|
||||
}
|
||||
```
|
||||
|
||||
### T4.3 — MyPackages + Re-Purchase
|
||||
|
||||
```razor
|
||||
@if (_canRepurchase)
|
||||
{
|
||||
<MudAlert Severity="Severity.Success">
|
||||
🎉 چرخه جادویی تکمیل شد! میتوانید پکیج جدید بخرید.
|
||||
</MudAlert>
|
||||
<MudButton Href="/packages">خرید پکیج جدید</MudButton>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MagicWalletProgress Wallet="@_wallet" Cycle="@_currentCycle" />
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۵ — BackOffice UI
|
||||
|
||||
> ⏱️ ۳ روز | وابستگی: مرحله ۳ | ریسک: کم
|
||||
|
||||
_(تسکها در PACKAGE-TRANSFORMATION-UX.md بخش ۳ مستند شده)_
|
||||
|
||||
---
|
||||
|
||||
## مرحله ۶ — تست و استقرار
|
||||
|
||||
> ⏱️ ۲ روز | وابستگی: مرحله ۴ و ۵
|
||||
|
||||
### Checklist تست
|
||||
|
||||
- [ ] خرید پکیج نقرهای (ZarinPal)
|
||||
- [ ] خرید پکیج پایه (ZarinPal)
|
||||
- [ ] خرید پکیج پایه (Daya Loan)
|
||||
- [ ] خرید پکیج پایه (Manual Payment)
|
||||
- [ ] فعالسازی باشگاه با پکیج نقرهای → فیچرهای محدود
|
||||
- [ ] فعالسازی باشگاه با پکیج پایه → همه فیچرها
|
||||
- [ ] تکمیل چرخه Magic → ریست وضعیت
|
||||
- [ ] خرید مجدد بعد تکمیل چرخه
|
||||
- [ ] Commission Pool جداگانه هر پکیج
|
||||
- [ ] Data Migration — PackageId در رکوردهای قبلی
|
||||
- [ ] JWT claims جدید (CanRepurchase, PackageId)
|
||||
- [ ] UI: کاشیهای داینامیک FrontOffice
|
||||
- [ ] UI: ماتریس فیچر BackOffice
|
||||
- [ ] Rollback: بدون data loss
|
||||
|
||||
---
|
||||
|
||||
## 📅 تقویم پیشنهادی
|
||||
|
||||
| هفته | روز | تسک |
|
||||
|------|-----|------|
|
||||
| هفته ۱ | روز ۱ | مرحله ۰: فیکس ۴ باگ |
|
||||
| | روز ۲-۳ | مرحله ۱: Package entity + PackageFeature |
|
||||
| | روز ۴ | مرحله ۱: FKها + Migration |
|
||||
| هفته ۲ | روز ۵-۶ | مرحله ۲: Generic handlers + re-purchase |
|
||||
| | روز ۵-۶ | مرحله ۳: SP + Loop (موازی) |
|
||||
| | روز ۷-۸ | مرحله ۲: Guards + JWT + Manual |
|
||||
| هفته ۳ | روز ۹-۱۰ | مرحله ۴: FrontOffice UI |
|
||||
| | روز ۱۱ | مرحله ۵: BackOffice UI |
|
||||
| | روز ۱۲-۱۳ | مرحله ۶: تست + deploy |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 ارجاعات
|
||||
|
||||
| مستند | محتوا |
|
||||
|-------|-------|
|
||||
| [BIZ-PACKAGE-BASED-SYSTEM.md](../business/BIZ-PACKAGE-BASED-SYSTEM.md) | طراحی فنی — ۳۹ تغییر + باگها |
|
||||
| [PACKAGE-TRANSFORMATION-UX.md](PACKAGE-TRANSFORMATION-UX.md) | تاثیر UX بر فرانتها |
|
||||
| [FEATURE-BACKLOG.md](FEATURE-BACKLOG.md) | بکلاگ ۱۲ RPC آماده |
|
||||
| [GRPC-SERVICES-AUDIT.md](../cms/GRPC-SERVICES-AUDIT.md) | آدیت ۳۴۲ RPC |
|
||||
|
||||
---
|
||||
|
||||
*آخرین بروزرسانی: ۱۴۰۴/۱۲/۰۶*
|
||||
@@ -0,0 +1,494 @@
|
||||
# 🏗️ تحلیل تحول پکیجبیس — تاثیر بر تجربه کاربر (UX)
|
||||
|
||||
> **وضعیت:** در حال تحلیل
|
||||
> **تاریخ:** ۱۴۰۴/۱۲/۰۶
|
||||
> **پیشنیاز:** [BIZ-PACKAGE-BASED-SYSTEM.md](../business/BIZ-PACKAGE-BASED-SYSTEM.md) v2
|
||||
> **هدف:** مستندسازی تاثیر تغییر رویکرد پکیجبیس بر تجربه مشتری و ادمین در فرانتها
|
||||
|
||||
---
|
||||
|
||||
## فهرست
|
||||
|
||||
1. [چشمانداز کلی](#۱-چشمانداز-کلی)
|
||||
2. [تجربه مشتری (FrontOffice) — قبل و بعد](#۲-تجربه-مشتری-frontoffice--قبل-و-بعد)
|
||||
3. [تجربه ادمین (BackOffice) — قبل و بعد](#۳-تجربه-ادمین-backoffice--قبل-و-بعد)
|
||||
4. [تسکهای تحول — مرحلهبهمرحله](#۴-تسکهای-تحول--مرحلهبهمرحله)
|
||||
5. [پیشبینی نیازمندیهای آینده](#۵-پیشبینی-نیازمندیهای-آینده)
|
||||
6. [ماتریس تاثیرگذاری بر صفحات](#۶-ماتریس-تاثیرگذاری-بر-صفحات)
|
||||
|
||||
---
|
||||
|
||||
## ۱. چشمانداز کلی
|
||||
|
||||
### فلسفه تغییر
|
||||
|
||||
| بُعد | **فعلی (تکپکیج)** | **هدف (چندپکیج)** |
|
||||
|------|-------------------|--------------------|
|
||||
| **مدل قیمتی** | فقط ۵۶M تومان — "همه یا هیچ" | سطوح متنوع (نقرهای ۵.۶M, پایه ۵۶M, ...) — "ورود تدریجی" |
|
||||
| **تجربه ورود** | سنگین — کاربر باید ۵۶M بپردازد | سبک — شروع از ۵.۶M و ارتقا بعدی |
|
||||
| **چرخه عمر** | یکبار خرید → برای همیشه | چندبار خرید → هر چرخه Magic Wallet |
|
||||
| **فیچرها** | ثابت — همه فیچرها برای همه | پویا — هر پکیج فیچرهای خودش |
|
||||
| **کمیسیون** | یک Pool مشترک | Pool جداگانه هر پکیج |
|
||||
| **مدیریت** | hardcoded — تغییر = deploy | داینامیک — ادمین از پنل تغییر میدهد |
|
||||
|
||||
### چه کسانی تاثیر میبینند؟
|
||||
|
||||
```
|
||||
👤 مشتری (FrontOffice):
|
||||
├── ثبتنامکننده جدید: گزینههای بیشتر → تصمیمگیری آسانتر
|
||||
├── مشتری فعال: دکمه "ارتقا" + "خرید مجدد"
|
||||
└── مشتری Magic: نمایش پیشرفت چرخه + آمادهسازی خرید بعدی
|
||||
|
||||
👔 ادمین (BackOffice):
|
||||
├── مدیر محصول: CRUD پکیج + ماتریس فیچر
|
||||
├── مدیر مالی: Commission Pool جداگانه + گزارشها
|
||||
└── پشتیبان: فعالسازی دستی با انتخاب پکیج
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ۲. تجربه مشتری (FrontOffice) — قبل و بعد
|
||||
|
||||
### ۲.۱ صفحه لیست پکیجها (`Packages.razor`)
|
||||
|
||||
#### قبل (فعلی):
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ پکیج طلایی │
|
||||
│ ──────────── │
|
||||
│ ✅ دسترسی به باشگاه مشتریان │
|
||||
│ ✅ کیفپول جادویی │
|
||||
│ ✅ فروشگاه تخفیفی │
|
||||
│ │
|
||||
│ 💰 ۵۶,۰۰۰,۰۰۰ تومان │
|
||||
│ │
|
||||
│ [خرید پکیج] │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### بعد (پکیجبیس):
|
||||
```
|
||||
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
|
||||
│ 🥈 پکیج نقرهای │ │ 🏆 پکیج پایه │ │ 💎 پکیج ویژه │
|
||||
│ ──────────── │ │ ──────────── │ │ ──────────── │
|
||||
│ ✅ باشگاه مشتریان │ │ ✅ باشگاه مشتریان │ │ ✅ باشگاه مشتریان │
|
||||
│ ✅ کیفپول جادویی │ │ ✅ کیفپول جادویی │ │ ✅ کیفپول جادویی │
|
||||
│ ❌ فروشگاه تخفیفی │ │ ✅ فروشگاه تخفیفی │ │ ✅ فروشگاه تخفیفی │
|
||||
│ ❌ پشتیبانی اختصاصی │ │ ❌ پشتیبانی اختصاصی │ │ ✅ پشتیبانی اختصاصی │
|
||||
│ │ │ │ │ │
|
||||
│ 💰 ۵,۶۰۰,۰۰۰ تومان │ │ 💰 ۵۶,۰۰۰,۰۰۰ تومان │ │ 💰 ??? تومان │
|
||||
│ │ │ ⭐ محبوبترین │ │ 🆕 بزودی │
|
||||
│ [خرید] [جزئیات] │ │ [خرید] [جزئیات] │ │ [در انتظار] │
|
||||
│ ────────────────── │ │ ────────────────── │ │ ────────────────── │
|
||||
│ 📊 PV: 5,600,000 │ │ 📊 PV: 56,000,000 │ │ │
|
||||
│ 🎁 هدیه: 11,200,000 │ │ 🎁 هدیه: 112,000,000 │ │ │
|
||||
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
|
||||
```
|
||||
|
||||
**تغییرات کلیدی:**
|
||||
- کاشیها از API میآیند (نه hardcoded)
|
||||
- فیچرهای هر پکیج از `PackageFeature` خوانده میشود
|
||||
- نمایش PV (Point Value) برای هر پکیج
|
||||
- نمایش Gift Value (= `Price × DiscountMultiplier`)
|
||||
- دکمههای شرطی: دایا فقط برای پکیجهای `SupportsDayaPurchase`
|
||||
- Badge «محبوبترین» / «ارزانترین» بر اساس `SortOrder`
|
||||
|
||||
### ۲.۲ صفحه پکیجهای من (`MyPackages.razor`)
|
||||
|
||||
#### قبل:
|
||||
```
|
||||
وضعیت عضویت: فعال ✅
|
||||
پکیج: طلایی
|
||||
تاریخ فعالسازی: ۱۴۰۳/۰۹/۱۵
|
||||
```
|
||||
|
||||
#### بعد:
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 📦 پکیج فعال: پکیج پایه │
|
||||
│ ──────────── │
|
||||
│ وضعیت: فعال ✅ | چرخه: ۲ | مدت: ۱۸۰ روز │
|
||||
│ │
|
||||
│ ┌──── کیفپول جادویی ────┐ │
|
||||
│ │ موجودی: ۱۲,۳۰۰,۰۰۰ │ │
|
||||
│ │ شارژ: ۴۳۵,۰۰۰,۰۰۰ │ │
|
||||
│ │ سقف: ۱,۰۰۰,۰۰۰,۰۰۰ │ │
|
||||
│ │ ████████░░░░ ۴۳.۵% │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──── PV انباشته ────┐ │
|
||||
│ │ PV کل: ۸۹,۶۰۰,۰۰۰ │ │
|
||||
│ │ آخرین سفارش: ۴.۲M │ │
|
||||
│ └─────────────────────┘ │
|
||||
│ │
|
||||
│ ❌ چرخه جادویی تکمیل نشده — هنوز امکان خرید مجدد نیست │
|
||||
│ ───── یا ───── │
|
||||
│ ✅ چرخه جادویی تکمیل شد! [خرید پکیج جدید] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─── تاریخچه چرخهها ───┐
|
||||
│ چرخه ۱: پایه — ۱۴۰۳/۰۹ تا ۱۴۰۴/۰۳ — ✅ تکمیل │
|
||||
│ چرخه ۲: پایه — ۱۴۰۴/۰۳ تا ادامه دارد — 🔄 فعال │
|
||||
└────────────────────────┘
|
||||
```
|
||||
|
||||
**تغییرات کلیدی:**
|
||||
- نمایش شماره چرخه و نوع پکیج
|
||||
- نوار پیشرفت Magic Wallet (چقدر تا تکمیل چرخه)
|
||||
- PV انباشته (از `CalculateOrderPV`)
|
||||
- دکمه شرطی «خرید مجدد» (فقط بعد تکمیل چرخه)
|
||||
- تاریخچه چرخهها (از `ClubMembershipCycle`)
|
||||
|
||||
### ۲.۳ صفحه چکاوت (`Checkout.razor`)
|
||||
|
||||
#### قبل:
|
||||
```
|
||||
سبد خرید:
|
||||
محصول A × 2 = ۲,۰۰۰,۰۰۰ تومان
|
||||
مالیات (۹%): ۱۸۰,۰۰۰ تومان
|
||||
────────────────
|
||||
جمع: ۲,۱۸۰,۰۰۰ تومان
|
||||
```
|
||||
|
||||
#### بعد:
|
||||
```
|
||||
سبد خرید:
|
||||
محصول A × 2 = ۲,۰۰۰,۰۰۰ تومان
|
||||
مالیات (۹%): ۱۸۰,۰۰۰ تومان
|
||||
────────────────
|
||||
جمع: ۲,۱۸۰,۰۰۰ تومان
|
||||
|
||||
📊 PV این سفارش: ۲,۰۰۰,۰۰۰ ← جدید
|
||||
💎 PV انباشته: ۹۱,۶۰۰,۰۰۰ ← جدید
|
||||
```
|
||||
|
||||
### ۲.۴ پرداخت پکیج — مودال خرید
|
||||
|
||||
#### قبل:
|
||||
```
|
||||
┌─── خرید پکیج طلایی ───┐
|
||||
│ │
|
||||
│ مبلغ: ۵۶,۰۰۰,۰۰۰ تومان │
|
||||
│ │
|
||||
│ [پرداخت آنلاین] │
|
||||
│ [اقساط دایا] │
|
||||
│ [پرداخت دستی] │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
#### بعد:
|
||||
```
|
||||
┌─── خرید پکیج نقرهای ───┐ ┌─── خرید پکیج پایه ───┐
|
||||
│ │ │ │
|
||||
│ مبلغ: ۵,۶۰۰,۰۰۰ تومان │ │ مبلغ: ۵۶,۰۰۰,۰۰۰ تومان│
|
||||
│ │ │ │
|
||||
│ سهم باشگاه: ۲,۵۲۰,۰۰۰ │ │ سهم باشگاه: ۲۵,۲۰۰,۰۰│
|
||||
│ شارژ کیفپول: ۵,۶۰۰,۰۰۰ │ │ شارژ کیفپول: ۵۶,۰۰۰,۰│
|
||||
│ هدیه تخفیفی: ۱۱,۲۰۰,۰۰۰ │ │ هدیه تخفیفی: ۱۱۲,۰۰۰,۰│
|
||||
│ │ │ │
|
||||
│ [پرداخت آنلاین] ✅ │ │ [پرداخت آنلاین] ✅ │
|
||||
│ [اقساط دایا] ❌ ندارد │ │ [اقساط دایا] ✅ │
|
||||
│ [پرداخت دستی] ✅ │ │ [پرداخت دستی] ✅ │
|
||||
└────────────────────────────┘ └────────────────────────┘
|
||||
```
|
||||
|
||||
**تغییرات کلیدی:**
|
||||
- نمایش breakdown مالی: سهم باشگاه + شارژ کیفپول + هدیه تخفیفی
|
||||
- دکمههای پرداخت شرطی بر اساس `SupportsDayaPurchase` / `SupportsDirectPurchase`
|
||||
- متن قرارداد داینامیک بر اساس پکیج انتخابشده
|
||||
|
||||
### ۲.۵ صفحه تنظیمات مشتری (`Settings.razor`) — جدید
|
||||
|
||||
```
|
||||
┌─── تنظیمات اعلانها ───┐
|
||||
│ │
|
||||
│ 📧 اعلان ایمیل: [✅] │
|
||||
│ 📱 اعلان SMS: [✅] │
|
||||
│ 🔔 اعلان Push: [❌] │
|
||||
│ │
|
||||
│ [ذخیره تغییرات] │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
> وصل به RPC: `UpdateCustomerSettings`
|
||||
|
||||
### ۲.۶ تاریخچه سفارشات — دکمه تکرار
|
||||
|
||||
```
|
||||
┌─── تاریخچه سفارشات ────────────────────────────────────────┐
|
||||
│ # │ تاریخ │ مبلغ │ وضعیت │ PV │ عملیات │
|
||||
│───┼────────────┼────────────┼───────────┼───────────┼────────│
|
||||
│ 1 │ ۱۴۰۴/۱۱/۰۲│ ۴,۲۰۰,۰۰۰ │ تحویل ✅ │ ۴,۲۰۰,۰۰ │ [🔄] [📍]│
|
||||
│ 2 │ ۱۴۰۴/۱۰/۱۵│ ۱,۸۰۰,۰۰۰ │ ارسال 📦 │ ۱,۸۰۰,۰۰ │ [📍]│
|
||||
│ 3 │ ۱۴۰۴/۰۹/۲۰│ ۳,۵۰۰,۰۰۰ │ تحویل ✅ │ ۳,۵۰۰,۰۰ │ [🔄] [📍]│
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
🔄 = تکرار سفارش (CustomerReorderPreviousOrder)
|
||||
📍 = ردیابی سفارش (CustomerTrackOrder)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ۳. تجربه ادمین (BackOffice) — قبل و بعد
|
||||
|
||||
### ۳.۱ مدیریت پکیجها (`PackageMainPage.razor`)
|
||||
|
||||
#### قبل:
|
||||
```
|
||||
┌─── مدیریت پکیجها ────────────────────────────────┐
|
||||
│ # │ عنوان │ قیمت │ وضعیت │ عملیات │
|
||||
│───┼──────────┼─────────────┼───────┼──────────────│
|
||||
│ 1 │ طلایی │ ۵۶,۰۰۰,۰۰۰ │ فعال │ [ویرایش] │
|
||||
└────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### بعد:
|
||||
```
|
||||
┌─── مدیریت پکیجها ──────────────────────────────────────────────────────┐
|
||||
│ # │ عنوان │ قیمت │ سهم باشگاه │ ضریب │ دایا │ پایه │ ترتیب│ عملیات │
|
||||
│───┼─────────┼─────────────┼────────────┼────────┼──────┼──────┼──────┼───────────────│
|
||||
│ 1 │ نقرهای │ ۵,۶۰۰,۰۰۰ │ ۲,۵۲۰,۰۰۰ │ ×2.0 │ ❌ │ ❌ │ 1 │ [✏️] [📋] [❌] │
|
||||
│ 2 │ پایه │ ۵۶,۰۰۰,۰۰۰ │ ۲۵,۲۰۰,۰۰│ ×2.0 │ ✅ │ ✅ │ 2 │ [✏️] [📋] [❌] │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
✏️ = ویرایش 📋 = مدیریت فیچرها ❌ = حذف
|
||||
```
|
||||
|
||||
### ۳.۲ ماتریس فیچر × پکیج (`PackageFeatureMatrixPage.razor`) — صفحه جدید
|
||||
|
||||
```
|
||||
┌─── ماتریس فیچر × پکیج ─────────────────────────────────────────┐
|
||||
│ │
|
||||
│ فیچر │ نقرهای │ پایه │ ویژه │
|
||||
│ ─────────────────────────┼─────────┼────────┼──────────────────│
|
||||
│ دسترسی به باشگاه │ ✅ │ ✅ │ ✅ │
|
||||
│ کیفپول جادویی │ ✅ │ ✅ │ ✅ │
|
||||
│ فروشگاه عادی │ ✅ │ ✅ │ ✅ │
|
||||
│ فروشگاه تخفیفی │ ❌ │ ✅ │ ✅ │
|
||||
│ محصولات ClubExclusive │ ❌ │ ✅ │ ✅ │
|
||||
│ پشتیبانی اختصاصی │ ❌ │ ❌ │ ✅ │
|
||||
│ کمیسیون شبکه │ ✅ │ ✅ │ ✅ │
|
||||
│ ─────────────────────────┼─────────┼────────┼──────────────────│
|
||||
│ │ [ذخیره] │ [ذخیره]│ [ذخیره] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
ادمین با checkbox فیچرها را به هر پکیج اختصاص میدهد.
|
||||
وصل به RPC: AssignFeatureToMembership
|
||||
```
|
||||
|
||||
### ۳.۳ فعالسازی باشگاه (`ActivateClubDialog.razor`)
|
||||
|
||||
#### قبل:
|
||||
```
|
||||
فعالسازی باشگاه مشتریان
|
||||
کاربر: علی محمدی
|
||||
[فعالسازی] ← hardcoded 56M + همه فیچرها
|
||||
```
|
||||
|
||||
#### بعد:
|
||||
```
|
||||
فعالسازی باشگاه مشتریان
|
||||
کاربر: علی محمدی
|
||||
پکیج: [▼ انتخاب پکیج ▼] ← dropdown از API
|
||||
├── نقرهای (۵,۶۰۰,۰۰۰)
|
||||
└── پایه (۵۶,۰۰۰,۰۰۰)
|
||||
|
||||
جزئیات:
|
||||
سهم باشگاه: _________ (خودکار)
|
||||
فیچرها: _________ (از ماتریس پکیج)
|
||||
|
||||
[فعالسازی]
|
||||
```
|
||||
|
||||
### ۳.۴ داشبورد (`Index.razor`) — بهبود
|
||||
|
||||
```
|
||||
┌─── آمار باشگاه ────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ 👥 کل اعضا: ۱,۲۴۰ │
|
||||
│ 📦 پکیج نقرهای: ۸۲۰ | پکیج پایه: ۴۲۰ │
|
||||
│ 💰 Pool نقرهای: ۲,۰۶۶,۴۰۰,۰۰۰ | Pool پایه: ۱۰,۵۸۴,۰۰۰,۰۰│
|
||||
│ ⚠️ هشدار: ۱۲ محصول موجودی کم │
|
||||
│ │
|
||||
│ ┌── موجودی انبار ──┐ ┌── ارزش کل انبار ──┐ │
|
||||
│ │ ۳,۴۵۰ آیتم │ │ ۸۹,۲۰۰,۰۰۰,۰۰۰ │ │
|
||||
│ │ ۱۲ نوع محصول │ │ ریال │ │
|
||||
│ └───────────────────┘ └───────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
وصل به: GetInventorySummary, GetStockValueReport, GetLowStockProducts
|
||||
```
|
||||
|
||||
### ۳.۵ مدیریت شبکه (`UserNetworkInfo.razor`) — بهبود
|
||||
|
||||
```
|
||||
┌─── مدیریت شبکه ─────────────────────────────────────────┐
|
||||
│ │
|
||||
│ کاربر: سارا احمدی (ID: 1045) │
|
||||
│ پکیج: نقرهای │ چرخه: ۱ │ PV: ۵,۶۰۰,۰۰۰ │
|
||||
│ Parent: علی محمدی (ID: 1001) │
|
||||
│ شاخه: چپ │ عمق: ۳ │
|
||||
│ │
|
||||
│ [جابجایی در شبکه] ← مودال: انتخاب parent جدید │
|
||||
│ │
|
||||
└───────────────────────────────────────────────────────────┘
|
||||
|
||||
وصل به: ChangeNetworkParent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ۴. تسکهای تحول — مرحلهبهمرحله
|
||||
|
||||
### مرحله ۱: زیرساخت Domain + DB (پایه)
|
||||
|
||||
> ⚠️ **بدون این مرحله هیچکدام از تغییرات UI ممکن نیست**
|
||||
|
||||
| # | تسک | لایه | فایلها | شرح |
|
||||
|---|------|------|--------|------|
|
||||
| T1.1 | اضافه ۷ فیلد به Package entity | Domain | Package.cs, PackageConfiguration.cs | SortOrder, IsActive, IsBasePackage, SupportsDayaPurchase, SupportsDirectPurchase, ActivationFee, DiscountMultiplier, MagicWalletMultiplier |
|
||||
| T1.2 | ایجاد PackageFeature entity | Domain | PackageFeature.cs, PackageFeatureConfiguration.cs | join table: Package ↔ ClubFeature |
|
||||
| T1.3 | اضافه PackageId به ClubMembership | Domain | ClubMembership.cs | FK nullable → بعد migration → required |
|
||||
| T1.4 | اضافه PackageId به ClubMembershipCycle | Domain | ClubMembershipCycle.cs | FK nullable → بعد migration → required |
|
||||
| T1.5 | اضافه PackageId به WeeklyCommissionPool | Domain | WeeklyCommissionPool.cs | FK + Unique(WeekDefinitionId, PackageId) |
|
||||
| T1.6 | اضافه PackageId به UserCommissionPayout | Domain | UserCommissionPayout.cs | FK nullable |
|
||||
| T1.7 | حذف ۵ SystemConstants | Domain | SystemConstants.cs | BasePackageAmount, DayaLoanAmount, ClubActivationFee, ClubMembershipGiftValue, MagicWalletMultiplier |
|
||||
| T1.8 | EF Migration + Seed | Infrastructure | Migration file | ۲ پکیج + فیچرها + FKها |
|
||||
| T1.9 | Data Migration Script | Infrastructure | SQL script | کاربران فعلی → PackageId = پکیج پایه |
|
||||
| T1.10 | بروزرسانی Protoها | Proto | package.proto, clubmembership.proto, commission.proto | فیلدهای جدید |
|
||||
|
||||
### مرحله ۲: منطق کسبوکار (Handlers)
|
||||
|
||||
> **هر handler باید از Package entity مقادیر مالی بخواند**
|
||||
|
||||
| # | تسک | فایل | شرح |
|
||||
|---|------|------|------|
|
||||
| T2.1 | Generic Verify Handler | VerifyPackagePurchaseCommandHandler.cs | DiscountMultiplier از Package + ساخت UserPackagePurchase |
|
||||
| T2.2 | Generic Purchase Handler | PurchasePackageCommandHandler.cs | حذف "طلایی" و ID=4 |
|
||||
| T2.3 | ActivateClubMembership بهبود | ActivateClubMembershipCommandHandler.cs | فیچر از PackageFeature + ActivationFee از Package |
|
||||
| T2.4 | EXIT Magic Mode ریست | UserOrderService.cs | PackagePurchaseMethod=None, membership.IsActive=false |
|
||||
| T2.5 | Guards re-purchase | G1-G3 handlers | اجازه خرید اگر MagicCompletedAt پر |
|
||||
| T2.6 | Re-contract | AcceptClubMembershipContractCommandHandler.cs | اجازه قرارداد مجدد |
|
||||
| T2.7 | Manual Payment بهبود | CreateManualPaymentCommandHandler.cs | DiscountMultiplier از Package |
|
||||
| T2.8 | Daya Loan بهبود | CheckAndProcessDayaLoansCommandHandler.cs | حذف ID=4 |
|
||||
| T2.9 | PackageFeature CRUD | جدید | ادمین بتواند فیچر ↔ پکیج مدیریت کند |
|
||||
| T2.10 | JWT claims جدید | JWT builder | اضافه CanRepurchase + PackageType |
|
||||
|
||||
### مرحله ۳: محاسبه پورسانت (Commission)
|
||||
|
||||
| # | تسک | فایل | شرح |
|
||||
|---|------|------|------|
|
||||
| T3.1 | SP WeeklyBalances + PackageId | sp_CalculateWeeklyBalances.sql | فیلتر بر اساس PackageId |
|
||||
| T3.2 | SP CommissionPool + PackageId | sp_CalculateWeeklyCommissionPool.sql | Pool جداگانه هر پکیج |
|
||||
| T3.3 | Loop روی پکیجها | WeeklyCommissionCalculationService.cs | هر پکیج فعال → محاسبه جداگانه |
|
||||
| T3.4 | ORM Strategy بهبود | OrmCommissionCalculationStrategy.cs | فیلتر PackageId |
|
||||
| T3.5 | تست محاسبات | — | با داده واقعی staging |
|
||||
|
||||
### مرحله ۴: FrontOffice UI
|
||||
|
||||
| # | تسک | صفحه | شرح |
|
||||
|---|------|------|------|
|
||||
| T4.1 | کاشیهای داینامیک | Packages.razor | لود از API + فیچر مقایسه |
|
||||
| T4.2 | مودال پرداخت شرطی | PackageDetail.razor | دکمه دایا فقط اگر SupportsDayaPurchase |
|
||||
| T4.3 | MyPackages re-purchase | MyPackages.razor | نوار پیشرفت + دکمه خرید مجدد |
|
||||
| T4.4 | ActivationSection داینامیک | ActivationSection.razor | قیمت از پکیج |
|
||||
| T4.5 | قرارداد داینامیک | ClubMembershipContractDialog.razor | متن متناسب با پکیج |
|
||||
| T4.6 | PV در Checkout | Checkout.razor | نمایش PV سفارش |
|
||||
| T4.7 | تکرار سفارش | Store Orders pages | دکمه 🔄 |
|
||||
| T4.8 | ردیابی سفارش | OrderTracking.razor | وصل به API |
|
||||
| T4.9 | تنظیمات اعلان | Settings.razor | فرم Email/SMS/Push |
|
||||
|
||||
### مرحله ۵: BackOffice UI
|
||||
|
||||
| # | تسک | صفحه | شرح |
|
||||
|---|------|------|------|
|
||||
| T5.1 | CRUD پکیج بهبود | PackageMainPage.razor | فیلدهای جدید + ستونهای اضافه |
|
||||
| T5.2 | ماتریس فیچر | PackageFeatureMatrixPage.razor (جدید) | checkbox grid |
|
||||
| T5.3 | ActivateClub dropdown | ActivateClubDialog.razor | انتخاب پکیج |
|
||||
| T5.4 | داشبورد بهبود | Index.razor | آمار Pool جداگانه + موجودی |
|
||||
| T5.5 | شبکه بهبود | UserNetworkInfo.razor | جابجایی parent |
|
||||
| T5.6 | موجودی کم | LowStockPage.razor | وصل API |
|
||||
| T5.7 | گزارش ارزش انبار | InventoryMainPage.razor | تب گزارش |
|
||||
| T5.8 | عملیات دستهای | InventoryMainPage.razor | Bulk Add/Update |
|
||||
|
||||
### مرحله ۶: تست و استقرار
|
||||
|
||||
| # | تسک | شرح |
|
||||
|---|------|------|
|
||||
| T6.1 | تست خرید هر پکیج | ZarinPal + Manual |
|
||||
| T6.2 | تست re-purchase | تکمیل چرخه → خرید مجدد |
|
||||
| T6.3 | تست Commission Pool | جداگانه بودن هر پکیج |
|
||||
| T6.4 | تست Migration | rollback plan |
|
||||
| T6.5 | Deploy staging → production | blue-green |
|
||||
|
||||
---
|
||||
|
||||
## ۵. پیشبینی نیازمندیهای آینده
|
||||
|
||||
### ۵.۱ نیازمندیهای مشتری (که فعلاً اولویت پایین هستند)
|
||||
|
||||
| # | نیاز | RPC آماده? | توضیح |
|
||||
|---|------|-----------|-------|
|
||||
| N1 | ارتقای پکیج (نقرهای → پایه) | ❌ جدید | پرداخت تفاضل + فعالسازی فیچرهای جدید |
|
||||
| N2 | مقایسه پکیجها side-by-side | ❌ جدید | جدول فیچر مقایسهای (client-side) |
|
||||
| N3 | اعلان قبل از اتمام چرخه | ❌ جدید | Background service: 5 روز قبل → push/SMS |
|
||||
| N4 | گزارش PV ماهانه | CalculateOrderPV ✅ | جدول PV هر ماه + نمودار |
|
||||
| N5 | پروفایل شبکه | ❌ جدید | مشتری درخت خودش را ببیند |
|
||||
|
||||
### ۵.۲ نیازمندیهای ادمین (که فعلاً اولویت پایین هستند)
|
||||
|
||||
| # | نیاز | RPC آماده? | توضیح |
|
||||
|---|------|-----------|-------|
|
||||
| N6 | پکیج تخفیفی زماندار | ❌ جدید | پکیج با قیمت ویژه برای مدت محدود |
|
||||
| N7 | گزارش تبدیل (conversion) | ❌ جدید | چند نفر از نقرهای به پایه ارتقا دادند |
|
||||
| N8 | هشدار Pool خالی | ❌ جدید | اگر Pool یک پکیج خالی شد → هشدار |
|
||||
| N9 | export گزارش مالی | GetStockValueReport ✅ | دانلود Excel |
|
||||
| N10 | تخصیص فیچر bulk | AssignFeatureToMembership ✅ | فیچر به همه اعضای یک پکیج |
|
||||
|
||||
---
|
||||
|
||||
## ۶. ماتریس تاثیرگذاری بر صفحات
|
||||
|
||||
### FrontOffice
|
||||
|
||||
| صفحه | تغییر | شدت | مرحله |
|
||||
|------|-------|------|-------|
|
||||
| Packages.razor | بازنویسی کامل — کاشیهای داینامیک | 🔴 | مرحله ۴ |
|
||||
| PackageDetail.razor | فیچرها از API + دکمه شرطی | 🟡 | مرحله ۴ |
|
||||
| MyPackages.razor | چرخه + پیشرفت + re-purchase | 🔴 | مرحله ۴ |
|
||||
| Checkout.razor | PV display | 🟢 | مرحله ۴ |
|
||||
| ActivationSection.razor | قیمت داینامیک | 🟡 | مرحله ۴ |
|
||||
| ClubMembershipContractDialog.razor | متن داینامیک | 🟡 | مرحله ۴ |
|
||||
| PaymentCallback.razor | تغییر JWT claims | 🟡 | مرحله ۴ |
|
||||
| MembershipPage.razor | نمایش نوع پکیج | 🟢 | مرحله ۴ |
|
||||
| Settings.razor | فرم اعلان جدید | 🟡 | مرحله ۴ |
|
||||
| Store Orders | دکمه تکرار + ردیابی | 🟡 | مرحله ۴ |
|
||||
|
||||
### BackOffice
|
||||
|
||||
| صفحه | تغییر | شدت | مرحله |
|
||||
|------|-------|------|-------|
|
||||
| PackageMainPage.razor | ستونهای جدید + CRUD بهبود | 🟡 | مرحله ۵ |
|
||||
| PackageFeatureMatrixPage.razor | **صفحه کاملاً جدید** | 🔴 | مرحله ۵ |
|
||||
| ActivateClubDialog.razor | dropdown پکیج | 🟡 | مرحله ۵ |
|
||||
| Index.razor (Dashboard) | آمار Pool جداگانه + موجودی | 🟡 | مرحله ۵ |
|
||||
| UserNetworkInfo.razor | جابجایی + نمایش پکیج | 🟡 | مرحله ۵ |
|
||||
| ClubMembers.razor | ستون پکیج | 🟢 | مرحله ۵ |
|
||||
| Statistics.razor | چارت توزیع پکیج | 🟡 | مرحله ۵ |
|
||||
| InventoryMainPage.razor | خلاصه + گزارش + bulk | 🟡 | مرحله ۵ |
|
||||
| LowStockPage.razor | وصل API | 🟢 | مرحله ۵ |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 ارجاعات
|
||||
|
||||
| مستند | ربط |
|
||||
|-------|-----|
|
||||
| [BIZ-PACKAGE-BASED-SYSTEM.md](../business/BIZ-PACKAGE-BASED-SYSTEM.md) | طراحی فنی ۳۹ تغییر |
|
||||
| [FEATURE-BACKLOG.md](FEATURE-BACKLOG.md) | بکلاگ ۱۲ RPC آماده |
|
||||
| [GRPC-SERVICES-AUDIT.md](../cms/GRPC-SERVICES-AUDIT.md) | آدیت ۳۴۲ RPC |
|
||||
| [BUSINESS-01-CLUB-COMMISSION.md](../business/BUSINESS-01-CLUB-COMMISSION.md) | مستند باشگاه و کمیسیون |
|
||||
| [BUSINESS-04-USER-MEMBERSHIP.md](../business/BUSINESS-04-USER-MEMBERSHIP.md) | مستند عضویت کاربر |
|
||||
|
||||
---
|
||||
|
||||
*آخرین بروزرسانی: ۱۴۰۴/۱۲/۰۶*
|
||||
Reference in New Issue
Block a user