Files
docs/CHANGELOG-2025-12-27.md
T
masoodafar-web 6220049161 feat: Enhance CMS Microservice with SystemConstants and SmsTemplates
- Added SystemConstants class to centralize hardcoded values for club configuration, commission configuration, and package amounts.
- Introduced SmsTemplates class to manage SMS message templates for various user notifications.
- Implemented automatic SMS sending for Daya Loan approval notifications.
- Updated BackOffice UI to include App Version management features.
- Fixed mapping issues in Mapster profiles for improved data handling.
- Updated changelog and documentation to reflect recent changes and configurations.
2025-12-27 05:07:33 +03:30

330 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📝 Changelog - ۷ دی ۱۴۰۴ (27 December 2025)
> **Session**: بهینه‌سازی‌های Mapping + SystemConstants + SMS Templates + AppVersion UI
---
## 🎯 خلاصه Session
این session شامل موارد زیر بود:
1. **SystemConstants** - انتقال مقادیر ثابت از hardcode به کلاس مرکزی
2. **SMS Templates** - متمرکز کردن همه قالب‌های پیامک
3. **SMS for Daya Loan** - ارسال پیامک هنگام تأیید وام دایا
4. **AppVersion UI** - تکمیل صفحه مدیریت نسخه در BackOffice
5. **Mapping Fixes** - رفع مشکلات Mapster
---
## ✨ تغییرات
### 1. 💰 SystemConstants - مقادیر ثابت ✅
**فایل**: `CMSMicroservice.Domain/Common/SystemConstants.cs`
```csharp
public static class SystemConstants
{
// Club Configuration
public const decimal ClubJoiningPercentage = 0.35m; // 35% کمیسیون پیوستن به باشگاه
public const decimal ClubActivationThreshold = 0.5m; // 50% آستانه فعال‌سازی
// Commission Configuration
public const int MaxCalculationAttempts = 3; // حداکثر تلاش محاسبه
public const int DefaultCommissionPoolDays = 7; // روزهای استخر کمیسیون
// Package Amounts
public const long GoldenPackageAmount = 56_000_000; // 56 میلیون - پکیج طلایی
public const long DayaLoanAmount = 56_000_000; // 56 میلیون - وام دایا
}
```
**Handlers آپدیت شده**:
| Handler | تغییر |
|---------|-------|
| `ProcessDayaLoanApprovalCommandHandler` | استفاده از `SystemConstants.DayaLoanAmount` |
| `ValidateGoldenPackagePurchaseQueryHandler` | استفاده از `SystemConstants.GoldenPackageAmount` |
| سایر handlers با 56_000_000 | همه به ثابت تبدیل شدند |
---
### 2. 📱 SmsTemplates - قالب‌های متمرکز پیامک ✅
**فایل جدید**: `CMSMicroservice.Domain/Common/SmsTemplates.cs`
```csharp
public static class SmsTemplates
{
private static string GetUserName(string? firstName)
=> string.IsNullOrWhiteSpace(firstName) ? "کاربر" : firstName;
public static string DayaLoanReceived(string? firstName, long amount)
=> $"{GetUserName(firstName)} عزیز، مبلغ {amount:N0} ریال وام دایا به کیف پول شما واریز شد. کارابازار";
public static string ClubActivated(string? firstName)
=> $"{GetUserName(firstName)} عزیز، حساب باشگاه شما فعال شد. کارابازار";
public static string PackagePurchased(string? firstName, string packageName)
=> $"{GetUserName(firstName)} عزیز، پکیج {packageName} با موفقیت خریداری شد. کارابازار";
public static string CommissionDeposited(string? firstName, long amount)
=> $"{GetUserName(firstName)} عزیز، مبلغ {amount:N0} ریال کمیسیون به کیف پول شما واریز شد. کارابازار";
public static string WithdrawalSuccess(string? firstName, long amount)
=> $"{GetUserName(firstName)} عزیز، درخواست برداشت {amount:N0} ریال با موفقیت انجام شد. کارابازار";
public static string NetworkJoined(string? firstName, string referrerName)
=> $"{GetUserName(firstName)} عزیز، به شبکه {referrerName} پیوستید. کارابازار";
public static string NewDownline(string? firstName, string newMemberName)
=> $"{GetUserName(firstName)} عزیز، {newMemberName} به زیرمجموعه شما اضافه شد. کارابازار";
public static string OtpCode(string code)
=> $"کد تأیید شما: {code}\nکارابازار";
public static string Welcome(string? firstName)
=> $"{GetUserName(firstName)} عزیز، به کارابازار خوش آمدید!";
}
```
---
### 3. 📲 ارسال SMS هنگام تأیید وام دایا ✅
**فایل**: `CMSMicroservice.Application/FinancialCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs`
**تغییرات**:
```csharp
public class ProcessDayaLoanApprovalCommandHandler : IRequestHandler<ProcessDayaLoanApprovalCommand, Unit>
{
private readonly IKavenegarService _smsService; // جدید
private readonly ILogger<ProcessDayaLoanApprovalCommandHandler> _logger; // جدید
// بعد از واریز موفق به کیف پول
private async Task SendDayaLoanSmsAsync(User user)
{
try
{
var message = SmsTemplates.DayaLoanReceived(
user.FirstName,
SystemConstants.DayaLoanAmount);
await _smsService.SendAsync(user.PhoneNumber, message);
_logger.LogInformation("Daya loan SMS sent to user {UserId}", user.Id);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to send Daya loan SMS to user {UserId}", user.Id);
// خطای SMS مانع عملیات اصلی نمی‌شود
}
}
}
```
---
### 4. 🖥️ BackOffice - صفحه مدیریت نسخه اپلیکیشن ✅
#### 4.1 اضافه شدن به منو
**فایل**: `BackOffice/Shared/NavMenu.razor`
```razor
@if (CanViewSettings)
{
<MudNavLink Match="NavLinkMatch.Prefix"
Href="/settings/app-versions"
Icon="@Icons.Material.Filled.PhoneAndroid">
نسخه اپلیکیشن‌ها
</MudNavLink>
}
```
**Permission**: `settings.view`
#### 4.2 دکمه افزودن نسخه جدید
**فایل**: `BackOffice/Pages/Settings/AppVersions.razor`
```razor
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="@OpenCreateDialog">
افزودن نسخه جدید
</MudButton>
```
#### 4.3 Dialog با حالت جدید/ویرایش
**فایل**: `BackOffice/Pages/Settings/Components/AppVersionEditDialog.razor`
```razor
[Parameter]
public bool IsNew { get; set; } = false;
@if (IsNew)
{
<MudSelect @bind-Value="Model.AppName"
Label="نام اپلیکیشن"
Required="true">
<MudSelectItem Value="@("KaraBazarApp")">کارابازار</MudSelectItem>
<MudSelectItem Value="@("KaraBazarAdminApp")">ادمین کارابازار</MudSelectItem>
</MudSelect>
}
else
{
<MudTextField @bind-Value="Model.AppName"
ReadOnly="true" Disabled="true" />
}
```
#### 4.4 آیکون و رنگ اپلیکیشن‌ها
```csharp
private string GetAppIcon(string appName) => appName switch
{
"KaraBazarApp" => Icons.Material.Filled.ShoppingCart,
"KaraBazarAdminApp" => Icons.Material.Filled.AdminPanelSettings,
_ => Icons.Material.Filled.PhoneAndroid
};
private Color GetAppColor(string appName) => appName switch
{
"KaraBazarApp" => Color.Primary,
"KaraBazarAdminApp" => Color.Secondary,
_ => Color.Default
};
```
---
### 5. 🔧 Mapping Fixes ✅
#### 5.1 CMS - AppVersionProfile
**فایل جدید**: `CMSMicroservice.WebApi/Common/Mappings/AppVersionProfile.cs`
```csharp
public class AppVersionProfile : IRegister
{
public void Register(TypeAdapterConfig config)
{
// Map List<AppVersionItemDto> to GetAllAppVersionsResponse
config.NewConfig<List<AppVersionItemDto>, GetAllAppVersionsResponse>()
.MapWith(src => CreateResponse(src));
// Map AppVersionItemDto to AppVersionItem (proto message)
config.NewConfig<AppVersionItemDto, AppVersionItem>()
.Map(dest => dest.Id, src => src.Id)
.Map(dest => dest.AppName, src => src.AppName)
// ... other mappings
}
private static GetAllAppVersionsResponse CreateResponse(List<AppVersionItemDto> items)
{
var response = new GetAllAppVersionsResponse();
foreach (var item in items)
{
response.Items.Add(item.Adapt<AppVersionItem>());
}
return response;
}
}
```
#### 5.2 BackOffice.BFF - CommissionProfile
**فایل**: `BackOffice.BFF.Application/Common/Mappings/CommissionProfile.cs`
```csharp
// CMS GetAllWeeklyPoolsResponse -> GetAllWeeklyPoolsResponseDto
config.NewConfig<GetAllWeeklyPoolsResponse, GetAllWeeklyPoolsResponseDto>()
.MapWith(src => new GetAllWeeklyPoolsResponseDto
{
MetaData = new MetaDataDto
{
TotalCount = (int)src.MetaData.TotalCount,
PageSize = (int)src.MetaData.PageSize,
CurrentPage = (int)src.MetaData.CurrentPage,
TotalPages = (int)src.MetaData.TotalPage
},
Models = src.Models.Select(m => new WeeklyCommissionPoolDto
{
Id = m.Id,
WeekDefinitionId = m.WeekDefinitionId,
// ... other mappings
}).ToList()
});
```
#### 5.3 BackOffice.BFF - GeneralMapping (Unit to Empty)
**فایل**: `BackOffice.BFF.WebApi/Common/Mappings/GeneralMapping.cs`
```csharp
// MediatR Unit to Google.Protobuf.Empty
config.NewConfig<MediatR.Unit, Google.Protobuf.WellKnownTypes.Empty>()
.MapWith(_ => new Google.Protobuf.WellKnownTypes.Empty());
```
---
## 📦 فایل‌های تغییر یافته
### CMS
| فایل | نوع تغییر |
|------|-----------|
| `Domain/Common/SystemConstants.cs` | Modified - اضافه شدن GoldenPackageAmount, DayaLoanAmount |
| `Domain/Common/SmsTemplates.cs` | **New** - قالب‌های پیامک |
| `Application/.../ProcessDayaLoanApprovalCommandHandler.cs` | Modified - اضافه شدن SMS |
| `WebApi/Common/Mappings/AppVersionProfile.cs` | **New** - Mapster profile |
### BackOffice.BFF
| فایل | نوع تغییر |
|------|-----------|
| `Application/Common/Mappings/CommissionProfile.cs` | Modified - اضافه شدن GetAllWeeklyPools mapping |
| `WebApi/Common/Mappings/GeneralMapping.cs` | Modified - اضافه شدن Unit to Empty |
### BackOffice
| فایل | نوع تغییر |
|------|-----------|
| `Shared/NavMenu.razor` | Modified - اضافه شدن لینک app-versions |
| `Pages/Settings/AppVersions.razor` | Modified - دکمه افزودن + OpenCreateDialog |
| `Pages/Settings/Components/AppVersionEditDialog.razor` | Modified - پارامتر IsNew + Select |
---
## ✅ Build Status
```bash
# CMS
dotnet build CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj
# Build succeeded. 0 Error(s)
# BackOffice.BFF
dotnet build BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj
# Build succeeded. 0 Error(s)
# BackOffice
dotnet build BackOffice/BackOffice.csproj
# Build succeeded. 0 Error(s)
```
---
## 📊 آمار Session
| متریک | مقدار |
|-------|-------|
| فایل‌های جدید | 2 |
| فایل‌های تغییر یافته | 8 |
| خطوط کد اضافه شده | ~300 |
| باگ‌های Mapping رفع شده | 3 |
---
## 🔗 Related Changelogs
- [CHANGELOG-2025-12-26.md](CHANGELOG-2025-12-26.md) - App Version Management + ReferralCode in Tree
- [CHANGELOG-2025-12-25.md](CHANGELOG-2025-12-25.md) - درخت شبکه BackOffice