16 KiB
📝 Changelog - ۲۹ آذر ۱۴۰۴ (19 December 2025)
Session: مایگریشن از WeekNumber به WeekDefinitionId در سیستم کمیسیون
🎯 هدف اصلی
تغییر از string WeekNumber به long WeekDefinitionId به عنوان Foreign Key به جدول WeekDefinitions در تمام جداول و سرویسهای مرتبط با کمیسیون.
دلایل تغییر:
- یکپارچگی داده: استفاده از FK واقعی به جای string
- بهبود Query Performance: Join بر اساس long id سریعتر از string
- جلوگیری از Orphan Records: FK constraint
- سادگی نامگذاری:
WeekDisplayNameبه جای ترکیبGregorianWeekNumber+PersianWeekNumber
📦 CMS Microservice
Entities (5 entity)
1. NetworkWeeklyBalance
// قبل
public string WeekNumber { get; set; }
// بعد
public long WeekDefinitionId { get; set; }
public virtual WeekDefinition WeekDefinition { get; set; }
2. WeeklyCommissionPool
// قبل
public string WeekNumber { get; set; }
// بعد
public long WeekDefinitionId { get; set; }
public virtual WeekDefinition WeekDefinition { get; set; }
3. UserCommissionPayout
// قبل
public string WeekNumber { get; set; }
// بعد
public long WeekDefinitionId { get; set; }
public virtual WeekDefinition WeekDefinition { get; set; }
4. WorkerExecutionLog
// قبل
public string WeekNumber { get; set; }
// بعد
public long? WeekDefinitionId { get; set; } // nullable برای backward compatibility
public virtual WeekDefinition? WeekDefinition { get; set; }
5. CommissionPayoutHistory
// قبل
public string WeekNumber { get; set; }
// بعد
public long WeekDefinitionId { get; set; }
public virtual WeekDefinition WeekDefinition { get; set; }
EF Configurations
فایلهای آپدیت شده:
NetworkWeeklyBalanceConfiguration.cs- Index و FKWeeklyCommissionPoolConfiguration.cs- Index و FKUserCommissionPayoutConfiguration.cs- Index و FKWorkerExecutionLogConfiguration.cs- Index و FKCommissionPayoutHistoryConfiguration.cs- Index و FK
نمونه تغییرات:
// حذف 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
// قبل
string week_number = 4;
// بعد
int64 week_definition_id = 4;
string week_display_name = 11; // فیلد جدید
UserWeeklyBalanceModel
// قبل
string week_number = 2;
// بعد
int64 week_definition_id = 2;
string week_display_name = 10; // فیلد جدید
Handlers & Mapping Profiles
فایلهای آپدیت شده:
GetAllUserCommissionPayoutsQueryHandler.csGetUserWeeklyBalancesQueryHandler.csCommissionProfile.cs
تغییرات Mapping:
// استفاده از WeekDefinition برای ساخت WeekDisplayName
.Map(dest => dest.WeekDisplayName,
src => $"هفته {src.WeekDefinition.WeekOrder} - {src.WeekDefinition.StartDatePersian}")
🔗 BackOffice.BFF
Proto Files (commission.proto)
WeekInfo
// اضافه شد
int64 week_definition_id = 1; // جدید - برای انتخاب هفته
string display_name = 2; // تغییر نام از week_number
WeeklyCommissionPoolModel
// اضافه شد
string week_display_name = 3; // جدید
WorkerExecutionLogModel
// اضافه شد
string week_display_name = 3; // جدید
Application DTOs
GetAvailableWeeksResponseDto.cs:
public class WeekInfoDto
{
public long WeekDefinitionId { get; set; } // جدید
public string DisplayName { get; set; }
...
}
GetAllWeeklyPoolsResponseDto.cs:
public record WeeklyCommissionPoolDto
{
public string WeekDisplayName { get; init; } // جدید
...
}
GetWorkerExecutionLogsResponseDto.cs:
public class WorkerExecutionLogModel
{
public string WeekDisplayName { get; set; } // جدید
...
}
Mapping Profiles (CommissionProfile.cs)
// 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:
<!-- تغییر از PackageReference به ProjectReference برای 23 proto پروژه -->
<ProjectReference Include="..\..\..\..\BackOffice.BFF\src\Protobufs\BackOffice.BFF.Commission.Protobuf\..." />
<!-- و 22 proto پروژه دیگر -->
Components Updated
WeekNumberPicker.razor.cs
// قبل - فقط 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
// قبل
private string _selectedWeek = "";
// بعد
private long? _selectedWeekDefinitionId;
private WeekInfo? _selectedWeek;
private string _currentWeekDisplayName = string.Empty;
UserPayouts.razor.cs
// قبل
private string _filterWeekNumber = "";
// بعد
private long? _filterWeekDefinitionId;
BalancesReport.razor
// قبل
private string _filterWeekNumber = "";
public string WeekNumber { get; set; }
// بعد
private long? _filterWeekDefinitionId;
public string WeekDisplayName { get; set; }
WeeklyReports.razor
// قبل
public string WeekNumber { get; set; }
// بعد
public long WeekDefinitionId { get; set; }
public string WeekDisplayName { get; set; }
SystemOverview.razor
// قبل
private string _currentWeek = "";
// بعد
private long _currentWeekDefinitionId = 0;
private string _currentWeekDisplayName = string.Empty;
WorkerControl.razor
// قبل
public string WeekNumber { get; set; }
// بعد
public long WeekDefinitionId { get; set; }
public string WeekDisplayName { get; set; }
PayoutDetailsDialog.razor
<!-- قبل -->
@Payout.WeekNumber
<!-- بعد -->
@Payout.WeekDisplayName
🔗 FrontOffice.BFF
Proto Files
commission.proto
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
message UserWithdrawalModel {
int64 week_definition_id = 2; // تغییر از week_number
string week_display_name = 3; // تغییر از week_label
}
Application DTOs
GetMyCommissionPayoutsResponseDto.cs:
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:
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)
// قبل
public record CommissionPayoutDto(
int WeekNumber,
string WeekLabel,
...
);
// بعد
public record CommissionPayoutDto(
long WeekDefinitionId,
string WeekDisplayName,
...
);
// قبل
public record WeeklyBalanceDto(
int WeekNumber,
string WeekLabel,
...
);
// بعد
public record WeeklyBalanceDto(
long WeekDefinitionId,
string WeekDisplayName,
...
);
// قبل
public record WeekDefinitionDto(
...
string GregorianWeekNumber,
string PersianWeekNumber
);
// بعد
public record WeekDefinitionDto(
long Id,
...
// حذف GregorianWeekNumber و PersianWeekNumber
);
Services (CommissionService.cs)
// قبل
public async Task<...> GetMyCommissionPayoutsAsync(int? weekNumber, ...)
// بعد
public async Task<...> GetMyCommissionPayoutsAsync(long? weekDefinitionId, ...)
// قبل
public async Task<WeeklyBalanceDto?> GetMyWeeklyBalanceAsync(string? weekNumber)
// بعد
public async Task<WeeklyBalanceDto?> GetMyWeeklyBalanceAsync(long? weekDefinitionId)
حذف متد: ExtractWeekNumber(string)
Services (WalletService.cs)
// قبل
public record WalletWithdrawal(
long Id,
string WeekNumber,
...
);
// بعد
public record WalletWithdrawal(
long Id,
long WeekDefinitionId,
string WeekDisplayName,
...
);
Components
WeekSelector.razor.cs
// حذف
public WeekDefinitionDto? FindByGregorianWeekNumber(string weekNumber)
// اضافه
public WeekDefinitionDto? FindById(long id)
WeeklyBalancePage.razor.cs
// استفاده از Id به جای GregorianWeekNumber
_selectedWeekDefinition = _weekSelector?.FindById(id);
Razor Templates
CommissionDashboardPage.razor
<!-- قبل -->
<MudChip>@context.WeekLabel</MudChip>
Href="?week={context.WeekNumber}"
<!-- بعد -->
<MudChip>@context.WeekDisplayName</MudChip>
Href="?week={context.WeekDefinitionId}"
CommissionHistoryPage.razor
<!-- قبل -->
<MudChip>@context.WeekLabel</MudChip>
Href="?week={context.WeekNumber}"
<!-- بعد -->
<MudChip>@context.WeekDisplayName</MudChip>
Href="?week={context.WeekDefinitionId}"
WeeklyBalancePage.razor
<!-- قبل -->
<MudText>@_weeklyBalance.WeekLabel</MudText>
<!-- بعد -->
<MudText>@_weeklyBalance.WeekDisplayName</MudText>
WithdrawalRequests.razor
<!-- قبل -->
<MudTd>@context.WeekNumber</MudTd>
<MudText>هفته @wd.WeekNumber</MudText>
<!-- بعد -->
<MudTd>@context.WeekDisplayName</MudTd>
<MudText>@wd.WeekDisplayName</MudText>
Project Reference
FrontOffice.Main.csproj:
<!-- کامنت شد (NuGet قدیمی) -->
<!-- <PackageReference Include="Foursat.FrontOffice.BFF.UserWallet.Protobuf" Version="0.0.15" /> -->
<!-- اضافه شد (ProjectReference برای proto جدید) -->
<ProjectReference Include="...FrontOffice.BFF.UserWallet.Protobuf.csproj" />
📊 خلاصه فایلهای تغییریافته
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 اجرا شود:
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 شوند:
-- مثال برای 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ها آپدیت شوند:
Foursat.CMSMicroservice.Protobuf→ ورژن جدیدFoursat.BackOffice.BFF.Commission.Protobuf→ ورژن جدیدFoursat.FrontOffice.BFF.Commission.Protobuf→ ورژن جدیدFoursat.FrontOffice.BFF.UserWallet.Protobuf→ ورژن جدید
📝 نکته مهم درباره ProjectReference
در این سشن، برای BackOffice Admin و FrontOffice، تمام PackageReference های proto به ProjectReference تغییر داده شدند تا تغییرات proto بدون نیاز به publish فوری قابل تست باشند.