- 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
12 KiB
📝 Changelog - ۳ دی ۱۴۰۴ (23 December 2025)
Session: فعالسازی چتیکا، اصلاح ثبتنام شبکه، بهبود فرایند باشگاه مشتریان
🎯 خلاصه Session
این session شامل موارد زیر بود:
- اصلاح SQL Scripts برای مهاجرت باشگاه مشتریان
- اضافه کردن
LegPositionدر ثبتنام کاربران جدید - همگامسازی
AcceptClubMembershipContractCommandHandlerباActivateClubMembershipCommandHandler - ایجاد
ClubFeatureTypeEnum برای جایگزینی hardcoded IDs - پیادهسازی 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:
-- قبل
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 دارد
راهحل:
-- قبل
DECLARE @CurrentWeekId BIGINT = (SELECT ...)
-- بعد
DECLARE @CurrentWeekId BIGINT
SET @CurrentWeekId = (SELECT ...)
فایل: dbbkup/MigrateSpecificUsersToClubMembership.sql
✨ New Features
4. اضافه کردن LegPosition در ثبتنام کاربران جدید ✅
مشکل: کاربران جدید بدون LegPosition در درخت شبکه ثبت میشدند
راهحل: اضافه کردن منطق تعیین دست چپ/راست:
// تعیین موقعیت در دست چپ یا راست
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 فیچر)
// 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:
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.csAcceptClubMembershipContractCommandHandler.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):
"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
{
"Chatika": {
"BaseUrl": "https://api.chatika.ir",
"ApiKey": "YOUR_API_KEY_HERE"
}
}
✅ Build Status
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 |