Files
docs/CHANGELOG-2025-12-23.md
T
masoodafar-web e7d979117c feat: Add Chatika integration and Club Features system documentation
- Implement Chatika account activation via background job
- Create IChatikaApiService interface and its implementation
- Add Club Features system documentation detailing features and entities
- Introduce ClubFeatureType enum to replace hardcoded IDs
- Update SQL scripts for Club Membership migration
- Fix various bugs in BackOffice UI and improve Products page functionality
2025-12-24 01:07:49 +03:30

311 lines
12 KiB
Markdown

# 📝 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 |