# 📝 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().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 |