# 📝 Changelog - ۲۹ آذر ۱۴۰۴ (19 December 2025) > **Session**: مایگریشن از WeekNumber به WeekDefinitionId در سیستم کمیسیون --- ## 🎯 هدف اصلی تغییر از `string WeekNumber` به `long WeekDefinitionId` به عنوان **Foreign Key** به جدول `WeekDefinitions` در تمام جداول و سرویس‌های مرتبط با کمیسیون. ### دلایل تغییر: 1. **یکپارچگی داده**: استفاده از FK واقعی به جای string 2. **بهبود Query Performance**: Join بر اساس long id سریع‌تر از string 3. **جلوگیری از Orphan Records**: FK constraint 4. **سادگی نام‌گذاری**: `WeekDisplayName` به جای ترکیب `GregorianWeekNumber` + `PersianWeekNumber` --- ## 📦 CMS Microservice ### Entities (5 entity) #### 1. NetworkWeeklyBalance ```csharp // قبل public string WeekNumber { get; set; } // بعد public long WeekDefinitionId { get; set; } public virtual WeekDefinition WeekDefinition { get; set; } ``` #### 2. WeeklyCommissionPool ```csharp // قبل public string WeekNumber { get; set; } // بعد public long WeekDefinitionId { get; set; } public virtual WeekDefinition WeekDefinition { get; set; } ``` #### 3. UserCommissionPayout ```csharp // قبل public string WeekNumber { get; set; } // بعد public long WeekDefinitionId { get; set; } public virtual WeekDefinition WeekDefinition { get; set; } ``` #### 4. WorkerExecutionLog ```csharp // قبل public string WeekNumber { get; set; } // بعد public long? WeekDefinitionId { get; set; } // nullable برای backward compatibility public virtual WeekDefinition? WeekDefinition { get; set; } ``` #### 5. CommissionPayoutHistory ```csharp // قبل public string WeekNumber { get; set; } // بعد public long WeekDefinitionId { get; set; } public virtual WeekDefinition WeekDefinition { get; set; } ``` ### EF Configurations **فایل‌های آپدیت شده**: - `NetworkWeeklyBalanceConfiguration.cs` - Index و FK - `WeeklyCommissionPoolConfiguration.cs` - Index و FK - `UserCommissionPayoutConfiguration.cs` - Index و FK - `WorkerExecutionLogConfiguration.cs` - Index و FK - `CommissionPayoutHistoryConfiguration.cs` - Index و FK **نمونه تغییرات**: ```csharp // حذف Index قدیمی builder.HasIndex(e => e.WeekNumber); // اضافه کردن FK جدید builder.HasIndex(e => e.WeekDefinitionId); builder.HasOne(e => e.WeekDefinition) .WithMany() .HasForeignKey(e => e.WeekDefinitionId) .OnDelete(DeleteBehavior.Restrict); ``` ### Proto Files (commission.proto) #### UserCommissionPayoutModel ```protobuf // قبل string week_number = 4; // بعد int64 week_definition_id = 4; string week_display_name = 11; // فیلد جدید ``` #### UserWeeklyBalanceModel ```protobuf // قبل string week_number = 2; // بعد int64 week_definition_id = 2; string week_display_name = 10; // فیلد جدید ``` ### Handlers & Mapping Profiles **فایل‌های آپدیت شده**: - `GetAllUserCommissionPayoutsQueryHandler.cs` - `GetUserWeeklyBalancesQueryHandler.cs` - `CommissionProfile.cs` **تغییرات Mapping**: ```csharp // استفاده از WeekDefinition برای ساخت WeekDisplayName .Map(dest => dest.WeekDisplayName, src => $"هفته {src.WeekDefinition.WeekOrder} - {src.WeekDefinition.StartDatePersian}") ``` --- ## 🔗 BackOffice.BFF ### Proto Files (commission.proto) #### WeekInfo ```protobuf // اضافه شد int64 week_definition_id = 1; // جدید - برای انتخاب هفته string display_name = 2; // تغییر نام از week_number ``` #### WeeklyCommissionPoolModel ```protobuf // اضافه شد string week_display_name = 3; // جدید ``` #### WorkerExecutionLogModel ```protobuf // اضافه شد string week_display_name = 3; // جدید ``` ### Application DTOs **GetAvailableWeeksResponseDto.cs**: ```csharp public class WeekInfoDto { public long WeekDefinitionId { get; set; } // جدید public string DisplayName { get; set; } ... } ``` **GetAllWeeklyPoolsResponseDto.cs**: ```csharp public record WeeklyCommissionPoolDto { public string WeekDisplayName { get; init; } // جدید ... } ``` **GetWorkerExecutionLogsResponseDto.cs**: ```csharp public class WorkerExecutionLogModel { public string WeekDisplayName { get; set; } // جدید ... } ``` ### Mapping Profiles (CommissionProfile.cs) ```csharp // WeekInfo mapping .Map(dest => dest.WeekDefinitionId, src => src.WeekDefinitionId) // WeeklyCommissionPoolModel mapping WeekDisplayName = m.WeekDisplayName ?? string.Empty, // WeeklyBalanceModel mapping WeekDisplayName = m.WeekDisplayName ?? string.Empty, ``` --- ## 🖥️ BackOffice Admin (Blazor) ### Project Reference **BackOffice.csproj**: ```xml ``` ### Components Updated #### WeekNumberPicker.razor.cs ```csharp // قبل - فقط string binding [Parameter] public string? SelectedWeekNumber { get; set; } // بعد - dual binding support [Parameter] public string? SelectedWeekNumber { get; set; } // for DisplayName [Parameter] public long? SelectedWeekDefinitionId { get; set; } // for API calls ``` #### Dashboard.razor.cs ```csharp // قبل private string _selectedWeek = ""; // بعد private long? _selectedWeekDefinitionId; private WeekInfo? _selectedWeek; private string _currentWeekDisplayName = string.Empty; ``` #### UserPayouts.razor.cs ```csharp // قبل private string _filterWeekNumber = ""; // بعد private long? _filterWeekDefinitionId; ``` #### BalancesReport.razor ```csharp // قبل private string _filterWeekNumber = ""; public string WeekNumber { get; set; } // بعد private long? _filterWeekDefinitionId; public string WeekDisplayName { get; set; } ``` #### WeeklyReports.razor ```csharp // قبل public string WeekNumber { get; set; } // بعد public long WeekDefinitionId { get; set; } public string WeekDisplayName { get; set; } ``` #### SystemOverview.razor ```csharp // قبل private string _currentWeek = ""; // بعد private long _currentWeekDefinitionId = 0; private string _currentWeekDisplayName = string.Empty; ``` #### WorkerControl.razor ```csharp // قبل public string WeekNumber { get; set; } // بعد public long WeekDefinitionId { get; set; } public string WeekDisplayName { get; set; } ``` #### PayoutDetailsDialog.razor ```razor @Payout.WeekNumber @Payout.WeekDisplayName ``` --- ## 🔗 FrontOffice.BFF ### Proto Files #### commission.proto ```protobuf message UserCommissionPayoutModel { int64 week_definition_id = 4; // تغییر از week_number string week_display_name = 11; // جدید } message UserWeeklyBalanceModel { int64 week_definition_id = 2; // تغییر از week_number string week_display_name = 10; // جدید } ``` #### userwallet.proto ```protobuf message UserWithdrawalModel { int64 week_definition_id = 2; // تغییر از week_number string week_display_name = 3; // تغییر از week_label } ``` ### Application DTOs **GetMyCommissionPayoutsResponseDto.cs**: ```csharp public class CommissionPayoutItem { // حذف public int WeekNumber { get; set; } public string WeekLabel { get; set; } // اضافه public long WeekDefinitionId { get; set; } public string WeekDisplayName { get; set; } } ``` **GetMyWeeklyBalancesResponseDto.cs**: ```csharp public class WeeklyBalanceItem { // حذف public int WeekNumber { get; set; } public string WeekLabel { get; set; } // اضافه public long WeekDefinitionId { get; set; } public string WeekDisplayName { get; set; } } ``` ### Handlers **GetMyCommissionPayoutsQueryHandler.cs**: - Mapping از `WeekDefinitionId` و `WeekDisplayName` **GetMyWeeklyBalancesQueryHandler.cs**: - Mapping از `WeekDefinitionId` و `WeekDisplayName` --- ## 🖥️ FrontOffice (Blazor) ### DTOs (CommissionDtos.cs) ```csharp // قبل public record CommissionPayoutDto( int WeekNumber, string WeekLabel, ... ); // بعد public record CommissionPayoutDto( long WeekDefinitionId, string WeekDisplayName, ... ); ``` ```csharp // قبل public record WeeklyBalanceDto( int WeekNumber, string WeekLabel, ... ); // بعد public record WeeklyBalanceDto( long WeekDefinitionId, string WeekDisplayName, ... ); ``` ```csharp // قبل public record WeekDefinitionDto( ... string GregorianWeekNumber, string PersianWeekNumber ); // بعد public record WeekDefinitionDto( long Id, ... // حذف GregorianWeekNumber و PersianWeekNumber ); ``` ### Services (CommissionService.cs) ```csharp // قبل public async Task<...> GetMyCommissionPayoutsAsync(int? weekNumber, ...) // بعد public async Task<...> GetMyCommissionPayoutsAsync(long? weekDefinitionId, ...) ``` ```csharp // قبل public async Task GetMyWeeklyBalanceAsync(string? weekNumber) // بعد public async Task GetMyWeeklyBalanceAsync(long? weekDefinitionId) ``` **حذف متد**: `ExtractWeekNumber(string)` ### Services (WalletService.cs) ```csharp // قبل public record WalletWithdrawal( long Id, string WeekNumber, ... ); // بعد public record WalletWithdrawal( long Id, long WeekDefinitionId, string WeekDisplayName, ... ); ``` ### Components #### WeekSelector.razor.cs ```csharp // حذف public WeekDefinitionDto? FindByGregorianWeekNumber(string weekNumber) // اضافه public WeekDefinitionDto? FindById(long id) ``` #### WeeklyBalancePage.razor.cs ```csharp // استفاده از Id به جای GregorianWeekNumber _selectedWeekDefinition = _weekSelector?.FindById(id); ``` ### Razor Templates #### CommissionDashboardPage.razor ```razor @context.WeekLabel Href="?week={context.WeekNumber}" @context.WeekDisplayName Href="?week={context.WeekDefinitionId}" ``` #### CommissionHistoryPage.razor ```razor @context.WeekLabel Href="?week={context.WeekNumber}" @context.WeekDisplayName Href="?week={context.WeekDefinitionId}" ``` #### WeeklyBalancePage.razor ```razor @_weeklyBalance.WeekLabel @_weeklyBalance.WeekDisplayName ``` #### WithdrawalRequests.razor ```razor @context.WeekNumber هفته @wd.WeekNumber @context.WeekDisplayName @wd.WeekDisplayName ``` ### Project Reference **FrontOffice.Main.csproj**: ```xml ``` --- ## 📊 خلاصه فایل‌های تغییریافته ### CMS (15+ فایل): | فایل | تغییر | |------|-------| | `NetworkWeeklyBalance.cs` | Entity + FK | | `WeeklyCommissionPool.cs` | Entity + FK | | `UserCommissionPayout.cs` | Entity + FK | | `WorkerExecutionLog.cs` | Entity + FK (nullable) | | `CommissionPayoutHistory.cs` | Entity + FK | | `NetworkWeeklyBalanceConfiguration.cs` | EF Config | | `WeeklyCommissionPoolConfiguration.cs` | EF Config | | `UserCommissionPayoutConfiguration.cs` | EF Config | | `WorkerExecutionLogConfiguration.cs` | EF Config | | `CommissionPayoutHistoryConfiguration.cs` | EF Config | | `commission.proto` | Proto models (WeeklyCommissionPoolModel, WorkerExecutionLogModel) | | `CommissionProfile.cs` | Mapster mapping | | `GetAllUserCommissionPayoutsQueryHandler.cs` | Include WeekDefinition | | `GetUserWeeklyBalancesQueryHandler.cs` | Include WeekDefinition | | `GetAvailableWeeksQueryHandler.cs` | WeekDefinitionId in WeekInfo | ### BackOffice.BFF (8 فایل): | فایل | تغییر | |------|-------| | `commission.proto` | WeekInfo, WeeklyCommissionPoolModel, WorkerExecutionLogModel | | `GetAvailableWeeksResponseDto.cs` | WeekDefinitionId in WeekInfoDto | | `GetAllWeeklyPoolsResponseDto.cs` | WeekDisplayName | | `GetWorkerExecutionLogsResponseDto.cs` | WeekDisplayName | | `GetAvailableWeeksQueryHandler.cs` | Mapping WeekDefinitionId | | `CommissionProfile.cs` | Mapster config for new fields | ### BackOffice Admin (12 فایل): | فایل | تغییر | |------|-------| | `BackOffice.csproj` | 23 ProjectReference به جای PackageReference | | `WeekNumberPicker.razor.cs` | Dual binding (string + long) | | `Dashboard.razor` | WeekDefinitionId selector | | `Dashboard.razor.cs` | _selectedWeekDefinitionId, _currentWeekDisplayName | | `UserPayouts.razor` | WeekDisplayName column | | `UserPayouts.razor.cs` | _filterWeekDefinitionId | | `BalancesReport.razor` | WeekDisplayName column, filter | | `WeeklyReports.razor` | WeekDefinitionId, WeekDisplayName | | `SystemOverview.razor` | _currentWeekDisplayName | | `WorkerControl.razor` | WeekDisplayName in logs | | `PayoutDetailsDialog.razor` | WeekDisplayName | ### FrontOffice.BFF (8 فایل): | فایل | تغییر | |------|-------| | `commission.proto` | week_definition_id, week_display_name | | `userwallet.proto` | week_definition_id, week_display_name | | `GetMyCommissionPayoutsResponseDto.cs` | DTO fields | | `GetMyWeeklyBalancesResponseDto.cs` | DTO fields | | `GetUserWithdrawalsResponseDto.cs` | DTO fields | | `GetMyCommissionPayoutsQueryHandler.cs` | Mapping | | `GetMyWeeklyBalancesQueryHandler.cs` | Mapping | | `CommissionProfile.cs` | Mapster config | ### FrontOffice (12 فایل): | فایل | تغییر | |------|-------| | `CommissionDtos.cs` | DTOs | | `CommissionService.cs` | Service methods | | `WalletService.cs` | WalletWithdrawal record | | `WeekSelector.razor` | UI | | `WeekSelector.razor.cs` | FindById method | | `WeeklyBalancePage.razor` | WeekDisplayName | | `WeeklyBalancePage.razor.cs` | WeekDefinitionId | | `CommissionDashboardPage.razor` | Links & display | | `CommissionHistoryPage.razor` | Links & display | | `WithdrawalRequests.razor` | WeekDisplayName | | `FrontOffice.Main.csproj` | ProjectReference | --- ## ⚠️ نکات مهم ### Migration مورد نیاز قبل از deploy، باید EF migration اجرا شود: ```bash cd CMS/src dotnet ef migrations add MigrateWeekNumberToWeekDefinitionId -p CMSMicroservice.Infrastructure -s CMSMicroservice.WebApi dotnet ef database update -p CMSMicroservice.Infrastructure -s CMSMicroservice.WebApi ``` ### Data Migration داده‌های موجود باید migrate شوند: ```sql -- مثال برای NetworkWeeklyBalance UPDATE NetworkWeeklyBalances SET WeekDefinitionId = ( SELECT Id FROM WeekDefinitions WHERE CONCAT(Year, '-', LPAD(WeekOrder, 2, '0')) = NetworkWeeklyBalances.WeekNumber ) WHERE WeekDefinitionId IS NULL; ``` ### FK Constraint جدول `WorkerExecutionLogs` ممکن است رکوردهایی با `WeekNumber` نامعتبر داشته باشد که باید قبل از اعمال FK constraint اصلاح شوند. --- ## ✅ وضعیت Build | پروژه | وضعیت | |-------|--------| | CMS | ✅ Build Succeeded | | BackOffice.BFF | ✅ Build Succeeded | | BackOffice Admin | ✅ Build Succeeded | | FrontOffice.BFF | ✅ Build Succeeded | | FrontOffice | ✅ Build Succeeded | --- ## 🔄 تغییرات Proto NuGet برای publish نهایی، باید proto packageها آپدیت شوند: 1. `Foursat.CMSMicroservice.Protobuf` → ورژن جدید 2. `Foursat.BackOffice.BFF.Commission.Protobuf` → ورژن جدید 3. `Foursat.FrontOffice.BFF.Commission.Protobuf` → ورژن جدید 4. `Foursat.FrontOffice.BFF.UserWallet.Protobuf` → ورژن جدید --- ## 📝 نکته مهم درباره ProjectReference در این سشن، برای BackOffice Admin و FrontOffice، تمام `PackageReference` های proto به `ProjectReference` تغییر داده شدند تا تغییرات proto بدون نیاز به publish فوری قابل تست باشند.