# 📝 Changelog - ۳ دی ۱۴۰۴ (23 December 2025)

> **Session**: فعال‌سازی چتیکا، اصلاح ثبت‌نام شبکه، بهبود فرایند باشگاه مشتریان

---

## 🎯 خلاصه Session

این session شامل موارد زیر بود:
1. اصلاح SQL Scripts برای مهاجرت باشگاه مشتریان
2. اضافه کردن `LegPosition` در ثبت‌نام کاربران جدید
3. همگام‌سازی `AcceptClubMembershipContractCommandHandler` با `ActivateClubMembershipCommandHandler`
4. ایجاد `ClubFeatureType` Enum برای جایگزینی hardcoded IDs
5. **پیاده‌سازی Worker چتیکا** - فعال‌سازی خودکار حساب هوش مصنوعی

---

## 🐛 Bug Fixes

### 1. SQL Script - `IsActive` Column Missing ✅

**مشکل**: خطای `Invalid column name 'IsActive'` در stage database

**علت**: ستون `IsActive` در جدول `ClubMemberships` وجود نداشت

**راه‌حل**: اجرای migration script یا حذف ستون از INSERT

**فایل**: `dbbkup/MigrateUsersToClubMembership.sql`

---

### 2. SQL Script - `WeekNumber` → `WeekDefinitionId` Migration ✅

**مشکل**: خطای `Invalid column name 'WeekNumber'` در `WeeklyCommissionPools`

**علت**: ستون قبلاً به `WeekDefinitionId` تغییر نام داده شده بود

**راه‌حل**: تغییر Query برای استفاده از `WeekDefinitions` table:
```sql
-- قبل
INSERT INTO WeeklyCommissionPools (WeekNumber, ...) VALUES (1, ...)

-- بعد  
DECLARE @CurrentWeekId BIGINT
SELECT @CurrentWeekId = Id FROM WeekDefinitions 
WHERE StartDate <= GETDATE() AND EndDate >= GETDATE()

INSERT INTO WeeklyCommissionPools (WeekDefinitionId, ...) VALUES (@CurrentWeekId, ...)
```

**فایل**: `dbbkup/MigrateSpecificUsersToClubMembership.sql`

---

### 3. SQL Script - `DECLARE/SET` Syntax Error ✅

**مشکل**: خطای syntax در `DECLARE @var = value`

**علت**: FreeTDS/older SQL Server syntax نیاز به جداسازی DECLARE و SET دارد

**راه‌حل**:
```sql
-- قبل
DECLARE @CurrentWeekId BIGINT = (SELECT ...)

-- بعد
DECLARE @CurrentWeekId BIGINT
SET @CurrentWeekId = (SELECT ...)
```

**فایل**: `dbbkup/MigrateSpecificUsersToClubMembership.sql`

---

## ✨ New Features

### 4. اضافه کردن `LegPosition` در ثبت‌نام کاربران جدید ✅

**مشکل**: کاربران جدید بدون `LegPosition` در درخت شبکه ثبت می‌شدند

**راه‌حل**: اضافه کردن منطق تعیین دست چپ/راست:

```csharp
// تعیین موقعیت در دست چپ یا راست
var existingChildren = await _context.Users
    .Where(x => x.NetworkParentId == parent.Id && !x.IsDeleted)
    .Select(x => x.LegPosition)
    .ToListAsync(cancellationToken);

NetworkLeg newUserLegPosition;
if (!existingChildren.Any(x => x == NetworkLeg.Left))
    newUserLegPosition = NetworkLeg.Left;
else if (!existingChildren.Any(x => x == NetworkLeg.Right))
    newUserLegPosition = NetworkLeg.Right;
else
    return Error("Parent already has both legs filled");

user = new User { ..., LegPosition = newUserLegPosition };
```

**فایل**: `CMS/src/CMSMicroservice.Application/OtpTokenCQ/Commands/VerifyOtpToken/VerifyOtpTokenCommandHandler.cs`

---

### 5. همگام‌سازی `AcceptClubMembershipContractCommandHandler` ✅

**مشکل**: منطق فعال‌سازی باشگاه در `AcceptClubMembershipContractCommandHandler` ناقص بود

**راه‌حل**: کپی کامل منطق از `ActivateClubMembershipCommandHandler`:

**اضافات**:
- خواندن `GiftValue` و `ActivationFee` از Configuration
- ثبت `ClubMembershipHistory`
- ثبت در `WeeklyCommissionPool`
- اختصاص `UserClubFeatures` (همه 4 فیچر)

```csharp
// 6. ثبت تاریخچه
var history = new ClubMembershipHistory
{
    ClubMembershipId = membership.Id,
    ActionType = ClubMembershipActionType.Activated,
    PerformedBy = _currentUserService.UserId ?? membership.UserId,
    ...
};

// 7. ثبت در استخر کمیسیون هفتگی
var currentWeek = _weekRepository.GetCurrentWeek();
var pool = new WeeklyCommissionPool { ... };

// 8. اختصاص فیچرهای باشگاه
var featureIds = ClubFeatureTypeExtensions.GetAllFeatureIds();
foreach (var featureId in featureIds) { ... }
```

**فایل**: `CMS/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandHandler.cs`

---

### 6. ایجاد `ClubFeatureType` Enum ✅

**مشکل**: استفاده از آرایه hardcoded `new long[] { 1, 2, 3, 4 }` در کد

**راه‌حل**: ایجاد Enum با Extension Method:

```csharp
public enum ClubFeatureType
{
    Chatika = 1,  // چتیکا - دستیار هوش مصنوعی
    Bime = 2,     // بیمه - خدمات بیمه‌ای
    Trip = 3,     // تریپ - خدمات سفر و گردشگری
    Learn = 4     // لرن - آموزش و یادگیری
}

public static class ClubFeatureTypeExtensions
{
    public static long[] GetAllFeatureIds() => 
        Enum.GetValues<ClubFeatureType>().Select(f => (long)f).ToArray();
    
    public static string GetPersianTitle(this ClubFeatureType featureType) => featureType switch
    {
        ClubFeatureType.Chatika => "چتیکا",
        ClubFeatureType.Bime => "بیمه",
        ClubFeatureType.Trip => "تور و سفر",
        ClubFeatureType.Learn => "آموزش",
        _ => featureType.ToString()
    };
}
```

**فایل جدید**: `CMS/src/CMSMicroservice.Domain/Enums/ClubFeatureType.cs`

**فایل‌های آپدیت شده**:
- `ActivateClubMembershipCommandHandler.cs`
- `AcceptClubMembershipContractCommandHandler.cs`

---

### 7. 🤖 پیاده‌سازی Worker چتیکا (Chatika Account Activation) ✅

**نیاز**: فعال‌سازی خودکار حساب چتیکا برای اعضای جدید باشگاه

**معماری**:

```
┌─────────────────────────────────────────────────────────────┐
│                    Hangfire Scheduler                        │
│                   (Every 5 minutes)                          │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│            ChatikaAccountActivationJob                       │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ 1. Find users with:                                  │    │
│  │    - ClubMembership.IsActive = true                  │    │
│  │    - ClubFeatureId = 1 (Chatika)                     │    │
│  │    - Notes IS NULL (not processed yet)               │    │
│  └─────────────────────────────────────────────────────┘    │
│                          │                                   │
│                          ▼                                   │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ 2. For each user:                                    │    │
│  │    - Call Chatika API                                │    │
│  │    - Update Notes with description                   │    │
│  │    - Set IsActive = true                             │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│                  Chatika External API                        │
│  POST /api/v1/organizations/register-user                    │
│  Header: X-API-Key                                           │
│  Body: { "mobile_number": "09..." }                          │
└─────────────────────────────────────────────────────────────┘
```

**فایل‌های جدید**:

| فایل | توضیح |
|------|-------|
| `IChatikaApiService.cs` | Interface سرویس چتیکا |
| `ChatikaApiService.cs` | پیاده‌سازی با HttpClient |
| `ChatikaAccountActivationJob.cs` | Hangfire Background Job |

**تنظیمات** (`appsettings.json`):
```json
"Chatika": {
  "BaseUrl": "https://api.chatika.ir",
  "ApiKey": "tIukvL8dnV4cB3yVWcCD9Xyfbj8rBxm5wPt2mLyJCgTsBBoMTWjt6mFEqQwpw-er"
}
```

**توضیحات فیچر چتیکا** (در `Notes` ذخیره می‌شود):
```
🎉 تبریک! حساب هوش مصنوعی چتیکا شما فعال شد.

برای استفاده از امکانات رایگان چتیکا:
1️⃣ به وب‌سایت chatika.ir مراجعه کنید
2️⃣ شماره موبایل خود را وارد کنید
3️⃣ از دستیار هوشمند چتیکا لذت ببرید!

🔗 لینک ورود: https://chatika.ir
```

**جلوگیری از تکرار**: با چک کردن `Notes != null` از کال مجدد API جلوگیری می‌شود

---

## 📁 فایل‌های تغییر یافته

### CMS Microservice

| فایل | نوع تغییر | توضیح |
|------|----------|-------|
| `Domain/Enums/ClubFeatureType.cs` | **NEW** | Enum برای فیچرهای باشگاه |
| `Application/Common/Interfaces/IChatikaApiService.cs` | **NEW** | Interface سرویس چتیکا |
| `Infrastructure/Services/ChatikaApiService.cs` | **NEW** | پیاده‌سازی API چتیکا |
| `Infrastructure/BackgroundJobs/ChatikaAccountActivationJob.cs` | **NEW** | Hangfire Job |
| `Infrastructure/ConfigureServices.cs` | Modified | رجیستر سرویس‌ها |
| `WebApi/Program.cs` | Modified | ثبت Recurring Job |
| `WebApi/appsettings.json` | Modified | تنظیمات چتیکا |
| `OtpTokenCQ/.../VerifyOtpTokenCommandHandler.cs` | Modified | اضافه شدن LegPosition |
| `ClubMembershipCQ/.../AcceptClubMembershipContractCommandHandler.cs` | **REWRITTEN** | منطق کامل فعال‌سازی |
| `ClubMembershipCQ/.../ActivateClubMembershipCommandHandler.cs` | Modified | استفاده از Enum |

### SQL Scripts

| فایل | نوع تغییر | توضیح |
|------|----------|-------|
| `dbbkup/MigrateUsersToClubMembership.sql` | Modified | اضافه شدن PerformedBy, GiftValue |
| `dbbkup/MigrateSpecificUsersToClubMembership.sql` | Modified | تغییر WeekNumber به WeekDefinitionId |

---

## 🔧 تنظیمات جدید

### appsettings.json
```json
{
  "Chatika": {
    "BaseUrl": "https://api.chatika.ir",
    "ApiKey": "YOUR_API_KEY_HERE"
  }
}
```

---

## ✅ Build Status

```bash
cd /home/masoud/Apps/project/FourSat/CMS/src
dotnet build CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj --no-restore

# Result: Build succeeded. 0 Error(s)
```

---

## 📊 آمار Session

| متریک | مقدار |
|-------|-------|
| فایل‌های جدید | 4 |
| فایل‌های تغییر یافته | 8 |
| خطاهای رفع شده | 3 |
| قابلیت‌های جدید | 4 |
| خطوط کد اضافه شده | ~400 |
