diff --git a/business/BIZ-PACKAGE-BASED-SYSTEM.md b/business/BIZ-PACKAGE-BASED-SYSTEM.md
index 11a21a9..861ea41 100644
--- a/business/BIZ-PACKAGE-BASED-SYSTEM.md
+++ b/business/BIZ-PACKAGE-BASED-SYSTEM.md
@@ -1,8 +1,8 @@
# 📦 سیستم مبتنی بر پکیج (Package-Based System)
> **وضعیت:** در حال پیادهسازی — **فاز ۰-۴ تکمیل ✅** | فاز ۵-۶ در انتظار
-> **تاریخ بروزرسانی:** ۷ اسفند ۱۴۰۴
-> **نسخه:** v5 (قرارداد یکبار + فیچر DIFF + تاریخچه فعالسازی)
+> **تاریخ بروزرسانی:** ۸ اسفند ۱۴۰۴
+> **نسخه:** v6 (آستانه موجودی + SP Worker + History Tables + UI Guidance)
> **تاثیرگذاری:** زیاد — **۹۵+** تغییر در ۶ لایه (۵۱ اصلی + ۴۴ سایدافکت)
> **کامیتها:** `8b9c317` (Phase 0) → `ae92ab8` (Phase 1) → `a9cd2fd` (Phase 1.5) → `8e5c7c5` (Phase 2) → `ccb938e` (Phase 3) → `0002a5a` (Phase 4)
@@ -43,6 +43,13 @@
| Q21 | ردیابی فعالسازی ClubMembership | ✅ **FirstActivation + LastActivation** — ۴ فیلد: `FirstActivationDate` + `FirstPackageId` + `LastActivationDate` + `LastPackageId` |
| Q22 | تشخیص فعالشدگان هفته | ✅ **از `LastActivationDate`** — هر کسی که `LastActivationDate` در بازه هفته باشد |
| Q23 | Carryover تعادل هفتگی | ✅ **strictly per-package** — اگر کاربر پکیج عوض کرد، carryover پکیج قبلی شمرده نمیشود |
+| Q24 | آستانه موجودی برای ورود Magic و خرید مجدد | ✅ **کمتر از ۱۰۰,۰۰۰ تومان** — چون قیمت محصولات متفاوته، `Balance == 0` عملاً غیرممکنه. آستانه ثابت ۱,۰۰۰,۰۰۰ ریال |
+| Q25 | DayaLoans محدودیت پکیج | ✅ **فقط پکیج پایه** — `SupportsDayaPurchase` فقط روی پکیج پایه `true` هست. تغییر نمیکنه |
+| Q26 | مدیریت Stored Procedures | ✅ **SP Worker (IHostedService)** — در startup، فایلهای `.sql` از embedded resource خوانده و با checksum مقایسه و اعمال میشوند |
+| Q27 | History Tables یکسانسازی | ✅ **نامگذاری مشابه master** + ثبت خودکار تغییرات در EF interceptor/domain events |
+| Q28 | UI Guidance (آموزش/هشدار) | ✅ **مودال + متن inline** — در سراسر FO/BO توضیحات آموزشی و هشداری برای سیستم پکیجبیس |
+| Q29 | شرط EXIT Magic | ✅ **آخرین پکیج فعال** — از `ClubMembershipCycle.PackageId` (چرخه فعلی) → `Package.MagicWalletMaxDeposit` |
+| Q30 | Carryover توضیح | ✅ **باقیمانده تعادل هفتگی** — پای قویتر surplus نگه میداره. تغییر پکیج = ریست implicit (lookup پکیج جدید → ۰) |
---
@@ -1466,3 +1473,280 @@ SELECT 'Balances', COUNT(*) FROM "CMS"."NetworkWeeklyBalances" WHERE "PackageId"
> فاز ۲ و ۳ **موازی** → مسیر بحرانی: ۰→۱→۲→۴→۵ = **~۲۴ روز**
> نسبت به v4 (**۲۲ روز**): **+۲ روز** بخاطر FeatureDiffService + قرارداد یکبار + First/Last Activation
> نسبت به v3 (**۱۷ روز**): **+۷ روز** — بزرگترین سهم: Magic Wallet + WalletChangeLog + فیچر DIFF + First/Last
+
+---
+
+## ۱۴. تصمیمات جدید v6 (Q24–Q30)
+
+> **تاریخ:** ۸ اسفند ۱۴۰۴
+> **زمینه:** مرور نهایی قبل از تست و استقرار — ۷ نکته جدید شناسایی شد
+
+### Q24 — آستانه موجودی برای ورود به Magic و خرید مجدد 🔴
+
+> **مشکل:** شرط فعلی `wallet.Balance == 0` عملاً غیرممکنه — چون قیمت محصولات متفاوته (مثلاً ۳۵۰,۰۰۰ تومان، ۱,۲۰۰,۰۰۰ تومان، ...) کاربر هیچوقت نمیتونه دقیقاً به صفر برسه.
+
+**تصمیم:** آستانه ثابت **۱,۰۰۰,۰۰۰ ریال (۱۰۰,۰۰۰ تومان)** — هم برای ورود به Magic، هم برای تشخیص تکمیل چرخه.
+
+**مکانهای تاثیر:**
+
+| # | فایل | شرط فعلی | شرط جدید |
+|---|------|----------|----------|
+| 1 | `UserOrderService.cs` L342 | `if (wallet.Balance == 0)` — ورود به Magic | `if (wallet.Balance <= MagicWalletEntryThreshold)` |
+| 2 | `UserOrderService.cs` L342 | `if (wallet.Balance == 0)` — EXIT Magic check | `if (wallet.Balance <= MagicWalletEntryThreshold)` |
+| 3 | خرید مجدد guard | `PackagePurchaseMethod == None` | + `Balance <= Threshold` |
+
+**تعریف ثابت:**
+```csharp
+// SystemConstants.cs یا Package entity
+public const long MagicWalletEntryThreshold = 1_000_000; // 100,000 تومان = 1,000,000 ریال
+```
+
+**فلوی جدید:**
+```
+کاربر خرید میکند → Balance = 850,000 ریال (کمتر از 1M)
+ → سیستم: Balance <= 1,000,000 ✅ → ورود به Magic Mode
+ → قبلاً: Balance == 0 ❌ → کاربر گیر میافتاد!
+
+Magic تکمیل → Balance = 200,000 ریال
+ → سیستم: Balance <= 1,000,000 ✅ → EXIT Magic → مجاز به خرید مجدد
+ → قبلاً: Balance == 0 ❌ → کاربر تا ابد در Magic!
+```
+
+> ⚠️ **نکته:** این آستانه **ثابت (global)** تعریف میشه — نه per-package. چون مربوط به قیمت محصولات فروشگاهه، نه پکیج.
+
+---
+
+### Q25 — DayaLoans فقط پکیج پایه
+
+> **تایید:** وام دایا فعلاً فقط برای پکیج پایه فعاله و تغییر نمیکنه.
+
+**وضعیت فعلی:**
+- فیلد `Package.SupportsDayaPurchase` روی پکیج پایه = `true`، نقرهای = `false`
+- `CheckAndProcessDayaLoansCommandHandler` فقط پکیجهایی که `SupportsDayaPurchase = true` دارن رو بررسی میکنه
+- این یک تصمیم بیزینسی ثابته — اگر در آینده تغییر کرد، ادمین از BackOffice فلگ رو تغییر میده
+
+---
+
+### Q26 — SP Worker (مدیریت خودکار Stored Procedures) 🔴
+
+> **مشکل:** الان SPها **کاملاً دستی** deploy میشن. اگه SP تغییر کنه، باید یادمون باشه دستی اجرا کنیم.
+
+**تصمیم:** یک `IHostedService` به نام `StoredProcedureDeploymentService` ایجاد بشه.
+
+**الگوریتم:**
+```
+1. Startup → خواندن فایلهای .sql از Embedded Resources
+2. برای هر فایل:
+ a. محاسبه SHA256 checksum محتوا
+ b. خواندن checksum قبلی از جدول "CMS"."StoredProcedureVersions"
+ c. اگر وجود نداشت یا checksum فرق داشت:
+ → اجرای CREATE OR ALTER PROCEDURE
+ → ذخیره checksum جدید
+ → لاگ: "SP {name} deployed/updated"
+ d. اگر checksum برابر بود:
+ → لاگ: "SP {name} is up-to-date, skipping"
+3. اجرا بعد از EF Migration (ترتیب startup)
+```
+
+**جدول جدید:**
+```sql
+CREATE TABLE "CMS"."StoredProcedureVersions" (
+ "Id" BIGSERIAL PRIMARY KEY,
+ "Name" VARCHAR(256) NOT NULL UNIQUE, -- نام SP
+ "Checksum" VARCHAR(64) NOT NULL, -- SHA256 hash
+ "DeployedAt" TIMESTAMP NOT NULL, -- آخرین deploy
+ "Version" INT NOT NULL DEFAULT 1 -- شمارنده نسخه
+);
+```
+
+**فایلهای SP فعلی (embed شوند):**
+
+| # | فایل | خطوط |
+|---|------|------|
+| 1 | `sp_CalculateWeeklyBalances.sql` | ۳۷۲ |
+| 2 | `sp_CalculateWeeklyCommissionPool.sql` | ۲۶۷ |
+
+**csproj تغییرات:**
+```xml
+
+
+
+```
+
+---
+
+### Q27 — History Tables — یکسانسازی و ثبت خودکار 🟡
+
+> **مشکل:** نامگذاری history tableها ناسازگاره و ثبت تاریخچه دستیه.
+
+**وضعیت فعلی:**
+
+| Master Entity | History Entity | نامگذاری |
+|---------------|---------------|----------|
+| `UserCommissionPayout` | `CommissionPayoutStatusHistory` | ❌ نام متفاوت |
+| `CommissionCashWithdrawal` | `CommissionCashWithdrawalStatusHistory` | ✅ مشابه |
+| `DiscountOrder` | `DiscountOrderStatusHistory` | ✅ مشابه |
+| `UserWallet` | `UserWalletChangeLog` | ❌ نام متفاوت |
+| `Package` | ❌ ندارد | 🔴 |
+| `ClubMembership` | ❌ ندارد | 🔴 |
+| `ClubMembershipCycle` | ❌ ندارد | 🔴 |
+
+**تصمیم — ۲ بخش:**
+
+**بخش ۱: نامگذاری یکسان**
+```
+الگو: {MasterEntityName}History
+
+مثال:
+ UserCommissionPayout → UserCommissionPayoutHistory (rename از CommissionPayoutStatusHistory)
+ UserWallet → UserWalletHistory (rename از UserWalletChangeLog)
+ Package → PackageHistory (جدید)
+ ClubMembership → ClubMembershipHistory (جدید)
+ ClubMembershipCycle → ClubMembershipCycleHistory (جدید)
+```
+
+**بخش ۲: ثبت خودکار تغییرات**
+```
+دو رویکرد:
+
+A) EF Interceptor (پیشنهادی):
+ → در SaveChangesInterceptor، entityهای تغییریافته شناسایی
+ → برای هر entity که IHasHistory پیاده کرده:
+ snapshot فعلی → رکورد History جدید
+ → مزیت: یکجا و خودکار
+
+B) Domain Events:
+ → هر entity یک EntityChangedEvent publish کنه
+ → Handler مربوطه History ثبت کنه
+ → مزیت: async + decoupled
+```
+
+**Interface پیشنهادی:**
+```csharp
+public interface IHasHistory where THistory : BaseHistoryEntity
+{
+ THistory CreateHistorySnapshot(string action, long? changedBy);
+}
+
+public abstract class BaseHistoryEntity : BaseEntity
+{
+ public long MasterEntityId { get; set; } // FK به entity اصلی
+ public string Action { get; set; } // Created, Updated, StatusChanged, ...
+ public long? ChangedBy { get; set; } // UserId تغییردهنده
+ public DateTime ChangedAt { get; set; } // زمان تغییر
+ public string? Snapshot { get; set; } // JSON snapshot (اختیاری)
+}
+```
+
+---
+
+### Q28 — UI Guidance (آموزش و هشدار در FO/BO) 🟡
+
+> **تصمیم:** در سراسر FrontOffice و BackOffice، متنهای آموزشی و هشداری اضافه بشه.
+
+**انواع Guidance:**
+
+| نوع | جایگاه | مثال |
+|-----|--------|------|
+| **مودال آموزشی** | اولین بار باز کردن صفحه | «سیستم پکیجبیس: شما میتوانید بعد از تکمیل چرخه، پکیج جدید بخرید» |
+| **متن inline** | کنار فیلد/آیتم | «💡 هزینه فعالسازی از قیمت پکیج محاسبه میشود» |
+| **هشدار** | قبل از اقدام بحرانی | «⚠️ با تغییر پکیج، فیچرهای قبلی ممکنه غیرفعال بشن» |
+| **Tooltip** | روی آیکون اطلاعات | «این مبلغ بر اساس پکیج فعال شما محاسبه شده» |
+
+**صفحات هدف FrontOffice:**
+
+| # | صفحه | نوع | محتوا |
+|---|-------|-----|-------|
+| G1 | صفحه پکیجها | مودال (اولین بار) | توضیح سیستم پکیجبیس، تفاوت پکیجها، نحوه خرید |
+| G2 | Checkout | متن inline | «این پکیج {features} را شامل میشود» |
+| G3 | MyPackages | متن inline | «بعد تکمیل چرخه جادویی، میتوانید پکیج جدید بخرید» |
+| G4 | Magic Wallet | هشدار مودال | «سقف واریز و ضریب بر اساس پکیج شماست» |
+| G5 | Commission Dashboard | tooltip | «پاداش بر اساس هر پکیج جداگانه محاسبه میشود» |
+| G6 | قرارداد باشگاه | متن inline | «این قرارداد فقط یکبار امضا میشود» |
+| G7 | ActivationSection | متن inline | «هزینه تخمینی بر اساس پکیج {name} محاسبه شده» |
+
+**صفحات هدف BackOffice:**
+
+| # | صفحه | نوع | محتوا |
+|---|-------|-----|-------|
+| G8 | Package CRUD | متن inline | «تغییر قیمت روی کاربران فعلی اثر ندارد — فقط خریدهای جدید» |
+| G9 | Feature Matrix | tooltip | «فیچرهای تیکخورده برای خریداران این پکیج فعال میشود» |
+| G10 | Manual Payment | هشدار | «مبلغ پرداخت باید مطابق قیمت پکیج انتخابی باشد» |
+| G11 | Commission Reports | متن inline | «هر پکیج Pool پورسانت مستقل دارد» |
+| G12 | User Detail | متن inline | «پکیج فعلی: {name} — چرخه: {n}» |
+| G13 | Club Members | tooltip | «فیلتر بر اساس آخرین پکیج خریداریشده» |
+
+**پیادهسازی فنی:**
+```razor
+@* FrontOffice — کامپوننت Guidance قابل استفاده مجدد *@
+
+
+@* BackOffice — متن inline *@
+
+ 💡 تغییر قیمت روی کاربران فعلی اثر ندارد — فقط خریدهای جدید
+
+```
+
+---
+
+### Q29 — شرط EXIT Magic — تایید: آخرین پکیج فعال
+
+> **تایید:** شرط EXIT از `ClubMembershipCycle` فعلی (`IsCurrentCycle=true`) → `PackageId` → `Package.MagicWalletMaxDeposit` خوانده میشه.
+
+**فلوی دقیق:**
+```
+1. UserOrderService.ProcessOrderAsync → wallet.Balance کم میشه
+2. if (Balance <= Threshold): ← Q24 آستانه جدید
+ a. اگر Normal + خرید کرده + باشگاه فعال → ENTER Magic
+ b. اگر Magic:
+ → خواندن چرخه فعلی → PackageId → Package.MagicWalletMaxDeposit
+ → if (MagicTotalDeposited >= MaxDeposit) → EXIT Magic
+ → else: هنوز Magic (میتونه شارژ کنه)
+```
+
+> **Fallback:** اگه چرخه فعالی نبود → `IsBasePackage = true` (پکیج پایه)
+
+---
+
+### Q30 — Carryover — توضیح ساده
+
+> **Carryover = باقیمانده تعادل از هفته قبل**
+
+**مثال ساده:**
+```
+هفته ۱۰:
+ علی: تیم چپ = ۵۰ نفر فعال، تیم راست = ۳۰ نفر فعال
+ تعادل = MIN(50, 30) = 30
+ باقیمانده: چپ = 50-30 = 20 ← CARRYOVER راست = 0
+
+هفته ۱۱:
+ اعضای جدید: چپ = 5، راست = 10
+ جمع با carryover: چپ = 5+20 = 25، راست = 10+0 = 10
+ تعادل = MIN(25, 10) = 10
+ باقیمانده: چپ = 25-10 = 15 ← CARRYOVER بعدی
+```
+
+**Per-package carryover (Q23):**
+```
+علی پکیج پایه داره:
+ carryover_پایه = {چپ: 20, راست: 0}
+
+علی پکیج رو عوض میکنه → نقرهای:
+ ❌ carryover_پایه دیگه شمرده نمیشه!
+ ✅ carryover_نقرهای = {چپ: 0, راست: 0} ← شروع از صفر
+
+ (چون سیستم هفته بعد دنبال carryover با PackageId=نقرهای
+ میگرده و پیدا نمیکنه → default صفر)
+```
+
+**Cap (سقف):**
+```
+اگه تعادل بیشتر از MaxBalancesPerLeg بشه → بریده میشه (flush):
+ تعادل = 500، سقف = 300 → CappedBalance = 300، Flushed = 200
+ ⚠️ Flushed از بین میره — carry نمیشه!
+```
diff --git a/deployment/PACKAGE-MIGRATION-GUIDE.md b/deployment/PACKAGE-MIGRATION-GUIDE.md
index f6a2a82..ab08bbe 100644
--- a/deployment/PACKAGE-MIGRATION-GUIDE.md
+++ b/deployment/PACKAGE-MIGRATION-GUIDE.md
@@ -629,12 +629,19 @@ kubectl set image deployment/backoffice bo=bo:rollback-point
| F5 | SystemConfiguration per-package | 🟡 | تنظیمات global vs per-package |
| F6 | MagicWalletChargePage hardcoded | 🟡 | ×۲.۵ و سقف در ۶ جا FO |
| F7 | Validators async per-package | 🟢 | سقف 1B → مقدار واقعی |
+| F8 | آستانه موجودی ورود به Magic (Q24) | 🔴 | `Balance == 0` → `Balance <= 1M ریال` |
+| F9 | SP Worker — مدیریت خودکار SP (Q26) | 🔴 | IHostedService + checksum + auto-deploy |
+| F10 | History Tables — یکسانسازی + خودکار (Q27) | 🟡 | نامگذاری + IHasHistory + interceptor |
+| F11 | UI Guidance — آموزش و هشدار (Q28) | 🟡 | مودال + متن inline در FO/BO |
-> **این موارد ریسک عملیاتی ندارند** و میتوانند در فاز بعدی انجام شوند. سیستم فعلی با fallback مناسب کار میکند.
+> **F8 و F9 ریسک عملیاتی دارند** و باید قبل از production پیاده شوند.
+> **F10 و F11** میتوانند در فاز بعدی انجام شوند. سایر موارد (F1-F7) با fallback فعلی مشکلی ندارند.
---
-## ضمیمه: ۲۳ تصمیم بیزینسی پیادهشده
+## ضمیمه: ۳۰ تصمیم بیزینسی (Q1–Q30)
+
+### پیادهشده (Q1–Q23):
| # | تصمیم | وضعیت |
|---|-------|-------|
@@ -662,6 +669,18 @@ kubectl set image deployment/backoffice bo=bo:rollback-point
| Q22 | تشخیص هفته از LastActivationDate | ✅ `607f791` |
| Q23 | Carryover strictly per-package | ✅ `607f791` |
+### تصمیمات جدید v6 (Q24–Q30) — در انتظار پیادهسازی:
+
+| # | تصمیم | وضعیت | اولویت |
+|---|-------|-------|--------|
+| Q24 | آستانه موجودی ≤ ۱۰۰,۰۰۰ تومان (ورود Magic + خرید مجدد) | ⬜ | 🔴 P0 |
+| Q25 | DayaLoans فقط پکیج پایه — تایید (بدون تغییر کد) | ✅ تایید | — |
+| Q26 | SP Worker — auto-deploy با checksum | ⬜ | 🔴 P0 |
+| Q27 | History Tables — نامگذاری یکسان + IHasHistory + interceptor | ⬜ | 🟡 P1 |
+| Q28 | UI Guidance — مودال + متن آموزشی/هشداری در FO/BO | ⬜ | 🟡 P1 |
+| Q29 | شرط EXIT Magic — تایید: آخرین پکیج فعال (بدون تغییر کد) | ✅ تایید | — |
+| Q30 | Carryover — تایید: توضیح مستند شد (بدون تغییر کد) | ✅ تایید | — |
+
---
-*آخرین بروزرسانی: ۸ اسفند ۱۴۰۴ — آماده تست و استقرار*
+*آخرین بروزرسانی: ۸ اسفند ۱۴۰۴ — v6: Q24-Q30 اضافه شد (آستانه موجودی + SP Worker + History + UI Guidance)*