From 858933daa560d48606dc2b441164f22c97fcf9c6 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Thu, 25 Dec 2025 02:23:00 +0330 Subject: [PATCH] docs: add CHANGELOG-2025-12-25 - Chatika flag, DayaLoan fix, BackOffice tree rewrite with org-chart, SP_GetNetworkTree --- 00-INDEX.md | 19 +- 03-BACKEND/CMS/implementation-status.md | 45 ++- 04-FRONTEND/BackOffice/ui-status.md | 24 +- CHANGELOG-2025-12-25.md | 421 ++++++++++++++++++++++++ 4 files changed, 494 insertions(+), 15 deletions(-) create mode 100644 CHANGELOG-2025-12-25.md diff --git a/00-INDEX.md b/00-INDEX.md index db30ce7..a65cd3b 100644 --- a/00-INDEX.md +++ b/00-INDEX.md @@ -1,7 +1,7 @@ # 📚 FourSat Project - فهرست جامع مستندات -> **نسخه**: 2.3 -> **آخرین بروزرسانی**: ۳ دی ۱۴۰۴ (December 23, 2025) +> **نسخه**: 2.4 +> **آخرین بروزرسانی**: ۵ دی ۱۴۰۴ (December 25, 2025) > **وضعیت**: ✅ تجمیع و بازسازی کامل --- @@ -28,7 +28,7 @@ ### Backend Services: | سرویس | وضعیت | تکمیل | فایل مرجع | |-------|------|------|-----------| -| **CMS Microservice** | ✅ Production Ready | 96% | [`03-BACKEND/CMS/implementation-status.md`](03-BACKEND/CMS/implementation-status.md) | +| **CMS Microservice** | ✅ Production Ready | 97% | [`03-BACKEND/CMS/implementation-status.md`](03-BACKEND/CMS/implementation-status.md) | | **BackOffice.BFF** | ✅ Production Ready | 100% | [`03-BACKEND/BackOffice.BFF/handlers-status.md`](03-BACKEND/BackOffice.BFF/handlers-status.md) | | **FrontOffice.BFF** | 🚧 In Progress | 60% | [`03-BACKEND/FrontOffice.BFF/README.md`](03-BACKEND/FrontOffice.BFF/README.md) | @@ -38,12 +38,13 @@ | **BackOffice UI** | ✅ Production Ready | 100% | [`04-FRONTEND/BackOffice/ui-status.md`](04-FRONTEND/BackOffice/ui-status.md) | | **FrontOffice UI** | 🚧 In Progress | 75% | [`04-FRONTEND/FrontOffice/README.md`](04-FRONTEND/FrontOffice/README.md) | -### آخرین دستاوردها (۳ دی): -- ✅ **Chatika Integration**: Worker خودکار فعال‌سازی حساب چتیکا -- ✅ **ClubFeatureType Enum**: جایگزینی hardcoded IDs با Enum -- ✅ **LegPosition**: تنظیم خودکار دست چپ/راست در ثبت‌نام شبکه -- ✅ **AcceptClubMembershipContract**: همگام‌سازی کامل با ActivateClubMembership -- ✅ **SQL Scripts**: اصلاح اسکریپت‌های مهاجرت باشگاه +### آخرین دستاوردها (۵ دی): +- ✅ **Chatika Enabled Flag**: قابلیت فعال/غیرفعال کردن Worker چتیکا از Config +- ✅ **DayaLoan Fix**: جلوگیری از استعلام مجدد مشتریان با قرارداد +- ✅ **BackOffice Tree Rewrite**: بازنویسی کامل صفحه درخت شبکه با d3-org-chart +- ✅ **Node Tooltip**: نمایش اطلاعات کاربر روی hover +- ✅ **Week Filter Visual**: تمایز بصری کاربران فعال شده در هفته فیلتر شده +- ✅ **GetNetworkTree SP**: Stored Procedure برای بهبود سرعت + حذف محدودیت عمق --- diff --git a/03-BACKEND/CMS/implementation-status.md b/03-BACKEND/CMS/implementation-status.md index 020a8b0..c818045 100644 --- a/03-BACKEND/CMS/implementation-status.md +++ b/03-BACKEND/CMS/implementation-status.md @@ -4,8 +4,8 @@ **Project**: CMS Microservice - Network & Club System **Architecture**: Clean Architecture (Domain → Application → Infrastructure → WebApi/Protobuf) -**Last Updated**: 2024-12-04 -**Current Phase**: Club Discount Shop System Complete ✅ +**Last Updated**: 2025-12-25 +**Current Phase**: Performance Optimization & Integration Enhancements ✅ ### 🎯 Completion Statistics - ✅ **Fully Completed**: 12 phases (100%) @@ -21,7 +21,46 @@ --- -## 🆕 Recent Updates (2025-12-09) +## 🆕 Recent Updates (2025-12-25) + +### ✅ Chatika Integration Enhancements + +**Date**: 2025-12-25 +**Feature**: بهبودات یکپارچگی چتیکا + +**Changes**: +1. **Enabled Flag**: اضافه شدن `Chatika.Enabled` در appsettings.json برای فعال/غیرفعال کردن Worker +2. **ChatikaAccountActivationJob**: چک کردن فلگ Enabled قبل از اجرای Job + +### ✅ DayaLoan Worker Fix + +**Date**: 2025-12-25 +**Feature**: اصلاح DayaLoanCheckWorker + +**Problem**: Worker برای مشتریانی که قبلاً قرارداد گرفته‌اند مجدداً استعلام می‌زد + +**Solution**: فیلتر کردن کاربرانی که `ContractNumber` دارند از لیست پردازش + +### ✅ GetNetworkTree Stored Procedure + +**Date**: 2025-12-25 +**Feature**: بهبود Performance درخت شبکه با Stored Procedure + +**Changes**: +1. **SP_GetNetworkTree.sql**: Stored Procedure با CTE recursive +2. **GetNetworkTreeQueryHandler**: بازنویسی برای استفاده از SP +3. **NetworkTreeNodeDto**: DTO جدید برای نتیجه SP +4. **No Depth Limit**: حذف محدودیت عمق با `OPTION (MAXRECURSION 0)` + +**Parameters**: +- `@RootUserId`: کاربر ریشه +- `@MaxDepth`: حداکثر عمق (پیش‌فرض: 100) +- `@IsClubActive`: فیلتر فعال بودن باشگاه +- `@ActivationWeekDefinitionId`: فیلتر هفته فعال‌سازی + +--- + +## 🆕 Previous Updates (2025-12-09) ### ✅ Club Membership Auto-Features Enhancement diff --git a/04-FRONTEND/BackOffice/ui-status.md b/04-FRONTEND/BackOffice/ui-status.md index e3b1c28..61a7fc5 100644 --- a/04-FRONTEND/BackOffice/ui-status.md +++ b/04-FRONTEND/BackOffice/ui-status.md @@ -1,6 +1,6 @@ # گزارش وضعیت UI پنل مدیریت (BackOffice) -تاریخ گزارش: ۳۰ آذر ۱۴۰۴ (2025-12-20) +تاریخ گزارش: ۵ دی ۱۴۰۴ (2025-12-25) وضعیت کلی: **آماده برای Production - 100% کامل** 🎉 --- @@ -19,7 +19,25 @@ --- -## 🆕 آخرین تغییرات (۳۰ آذر ۱۴۰۴) +## 🆕 آخرین تغییرات (۵ دی ۱۴۰۴) + +### بازنویسی صفحه درخت شبکه با d3-org-chart: +- ✅ `Network/NetworkTreeViewer.razor` - بازنویسی کامل با d3-org-chart +- ✅ `wwwroot/js/admin-org-chart.js` - Wrapper جدید برای org-chart +- ✅ `wwwroot/css/admin-org-chart.css` - استایل کارت‌های نود +- ✅ Tooltip روی hover با اطلاعات کامل کاربر +- ✅ فیلتر بصری هفته فعال‌سازی (disabled style برای کاربران خارج از هفته) +- ✅ Navigation history (breadcrumb) برای drill-down +- ✅ Export to PNG +- ✅ DataGrid زیر چارت + +### کتابخانه‌های جدید: +- ✅ `d3-org-chart3.js` - کپی از FrontOffice +- ✅ `d3-flextree.min.js` - Dependency + +--- + +## 🆕 تغییرات قبلی (۳۰ آذر ۱۴۰۴) ### باگ‌های رفع شده: - ✅ `/network/balances` - ValidationException برطرف شد (Mapster mapping) @@ -54,7 +72,7 @@ - ✅ Commission/Withdrawals.razor - درخواست‌های برداشت (لیست، فیلتر وضعیت، دکمه‌های Approve/Reject/Process متصل به API، نمایش BankReferenceId / TrackingCode / PaymentFailureReason) ### 3. شبکه (3 صفحه) -- ✅ Network/Tree.razor - درخت شبکه +- ✅ Network/Tree.razor - درخت شبکه (بازنویسی شده با d3-org-chart) - ✅ Network/Balances.razor - گزارش موجودی‌ها - ✅ Network/Statistics.razor - آمار شبکه diff --git a/CHANGELOG-2025-12-25.md b/CHANGELOG-2025-12-25.md new file mode 100644 index 0000000..ae4dedc --- /dev/null +++ b/CHANGELOG-2025-12-25.md @@ -0,0 +1,421 @@ +# 📝 Changelog - ۵ دی ۱۴۰۴ (25 December 2025) + +> **Session**: فلگ فعال‌سازی چتیکا، اصلاح DayaLoan، بازنویسی صفحه درخت شبکه با org-chart، Stored Procedure برای GetNetworkTree + +--- + +## 🎯 خلاصه Session + +این session شامل موارد زیر بود: +1. **Chatika Enabled Flag** - اضافه کردن فلگ فعال/غیرفعال برای Worker چتیکا +2. **DayaLoanCheckWorker Fix** - جلوگیری از استعلام مجدد مشتریان با قرارداد +3. **BackOffice Network Tree Rewrite** - بازنویسی کامل با d3-org-chart +4. **Tooltip on Hover** - نمایش اطلاعات کاربر روی hover +5. **Week Filter Visual** - تمایز بصری کاربران فعال شده در هفته فیلتر شده +6. **Stored Procedure** - SP برای GetNetworkTree جهت بهبود performance + +--- + +## ✨ New Features + +### 1. Chatika Enabled Flag ✅ + +**نیاز**: قابلیت غیرفعال کردن موقت Worker چتیکا از طریق Config + +**راه‌حل**: اضافه کردن فلگ `Enabled` در تنظیمات + +**تغییرات در `appsettings.json`**: +```json +"Chatika": { + "Enabled": false, // ← فلگ جدید + "BaseUrl": "https://api.chatika.ir", + "ApiKey": "..." +} +``` + +**تغییرات در `ChatikaAccountActivationJob.cs`**: +```csharp +public async Task ExecuteAsync() +{ + // Check if Chatika integration is enabled + var isEnabled = _configuration.GetValue("Chatika:Enabled", false); + if (!isEnabled) + { + _logger.LogDebug("Chatika integration is disabled. Skipping job execution."); + return; + } + + // ... rest of the job +} +``` + +**فایل‌های تغییر یافته**: +- `CMSMicroservice.WebApi/appsettings.json` +- `CMSMicroservice.Infrastructure/BackgroundJobs/ChatikaAccountActivationJob.cs` + +--- + +### 2. DayaLoanCheckWorker - Exclude Existing Contracts ✅ + +**مشکل**: Worker استعلام دایا برای مشتریانی که قبلاً قرارداد گرفته‌اند مجدداً کال می‌شد + +**راه‌حل**: فیلتر کردن کاربرانی که `ContractNumber` دارند + +**کد اضافه شده**: +```csharp +// Get national codes of users who already have contracts +var existingContractNationalCodes = await _dbContext.DayaLoanContracts + .Where(c => !c.IsDeleted && !string.IsNullOrEmpty(c.ContractNumber)) + .Select(c => c.NationalCode) + .Distinct() + .ToListAsync(stoppingToken); + +// Filter out users who already have contracts +var usersToProcess = eligibleUsers + .Where(u => !existingContractNationalCodes.Contains(u.NationalCode)) + .ToList(); + +_logger.LogInformation( + "Filtered users: {TotalEligible} eligible, {WithContract} already have contracts, {ToProcess} to process", + eligibleUsers.Count, + eligibleUsers.Count - usersToProcess.Count, + usersToProcess.Count); +``` + +**فایل**: `CMSMicroservice.WebApi/Workers/DayaLoanCheckWorker.cs` + +--- + +### 3. 🌳 BackOffice Network Tree - Complete Rewrite with d3-org-chart ✅ + +**نیاز**: استفاده از پلاگین org-chart به جای D3 دستی برای نمایش درخت شبکه در پنل ادمین + +**معماری جدید**: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ NetworkTreeViewer.razor │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ MudToolBar: │ │ +│ │ [Search] [Week Filter] [Expand] [Collapse] [Export] │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Navigation History (Breadcrumb) │ │ +│ │ User 123 → User 456 → User 789 │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ d3-org-chart Container (#admin-org-chart) │ │ +│ │ │ │ +│ │ ┌──────┐ │ │ +│ │ │ Root │ │ │ +│ │ └──┬───┘ │ │ +│ │ ┌───┴───┐ │ │ +│ │ ┌──┴──┐ ┌──┴──┐ │ │ +│ │ │Left │ │Right│ │ │ +│ │ └─────┘ └─────┘ │ │ +│ │ │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ MudDataGrid (Table View) │ │ +│ │ Mobile | Name | Level | Position | Status | Actions │ │ +│ └─────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +**فایل‌های جدید**: + +| فایل | توضیح | +|------|-------| +| `wwwroot/js/admin-org-chart.js` | Wrapper برای d3-org-chart با امکانات ادمین | +| `wwwroot/css/admin-org-chart.css` | استایل کارت‌های نود با رنگ‌بندی چپ/راست | +| `wwwroot/js/d3-org-chart3.js` | کتابخانه d3-org-chart (کپی از FrontOffice) | +| `wwwroot/js/d3-flextree.min.js` | Dependency برای org-chart | + +**فایل‌های تغییر یافته**: +- `NetworkTreeViewer.razor` - بازنویسی کامل +- `wwwroot/index.html` - اضافه شدن رفرنس‌های JS/CSS + +--- + +### 4. 💬 Tooltip on Hover ✅ + +**نیاز**: نمایش اطلاعات کامل کاربر هنگام hover روی نود + +**پیاده‌سازی در `admin-org-chart.js`**: + +```javascript +// Tooltip container +const tooltip = d3.select('body').append('div') + .attr('class', 'admin-org-tooltip') + .style('opacity', 0); + +// Node hover events +.on('mouseover', function(event, d) { + tooltip.transition().duration(200).style('opacity', .95); + tooltip.html(` +
${d.data.firstName} ${d.data.lastName}
+
📱 ${d.data.mobile}
+
📊 سطح: ${d.data.networkLevel}
+
📍 ${d.data.legPosition === 1 ? 'چپ' : 'راست'}
+ ${d.data.isClubActive ? + `
باشگاه فعال
` : + `
باشگاه غیرفعال
` + } + ${d.data.activationWeekDisplayName ? + `
📅 ${d.data.activationWeekDisplayName}
` : '' + } + `) + .style('left', (event.pageX + 15) + 'px') + .style('top', (event.pageY - 10) + 'px'); +}) +``` + +**استایل Tooltip**: +```css +.admin-org-tooltip { + position: absolute; + background: rgba(33, 33, 33, 0.95); + color: white; + padding: 12px 16px; + border-radius: 8px; + font-size: 13px; + box-shadow: 0 4px 20px rgba(0,0,0,0.3); + pointer-events: none; + z-index: 10000; + direction: rtl; +} +``` + +--- + +### 5. 🎨 Week Filter Visual Distinction ✅ + +**نیاز**: وقتی هفته فیلتر می‌شه، کاربران فعال شده در اون هفته متمایز باشن + +**پیاده‌سازی**: + +```javascript +// Apply week filter styling +applyWeekFilter: function(weekId) { + if (!this.chart || !this.chartData) return; + + d3.selectAll('.admin-node-card').each(function() { + const nodeData = d3.select(this).datum(); + if (nodeData && nodeData.data) { + if (weekId && nodeData.data.activationWeekDefinitionId !== weekId) { + d3.select(this).classed('disabled', true); + } else { + d3.select(this).classed('disabled', false); + } + } + }); +} +``` + +**استایل**: +```css +/* کاربرانی که در هفته فیلتر شده فعال نشدن */ +.admin-node-card.disabled { + opacity: 0.35; + filter: grayscale(70%); +} + +/* کاربران فعال شده در هفته هدف */ +.admin-node-card:not(.disabled) { + animation: target-glow 2s ease-in-out infinite; +} + +@keyframes target-glow { + 0%, 100% { box-shadow: 0 0 5px rgba(76, 175, 80, 0.3); } + 50% { box-shadow: 0 0 20px rgba(76, 175, 80, 0.6); } +} +``` + +--- + +### 6. ⚡ Stored Procedure for GetNetworkTree ✅ + +**نیاز**: بهبود سرعت لود درخت شبکه + حذف محدودیت عمق + +**Stored Procedure** (`dbbkup/SP_GetNetworkTree.sql`): + +```sql +CREATE PROCEDURE [CMS].[GetNetworkTree] + @RootUserId BIGINT, + @MaxDepth INT = 100, + @IsClubActive BIT = NULL, + @ActivationWeekDefinitionId BIGINT = NULL +AS +BEGIN + SET NOCOUNT ON; + + -- CTE برای پیمایش درخت باینری به صورت recursive + ;WITH NetworkTreeCTE AS ( + -- Base case: ریشه درخت + SELECT + u.Id AS UserId, + u.Mobile, + u.FirstName, + u.LastName, + u.LegPosition, + u.NetworkParentId AS ParentId, + 0 AS NetworkLevel, + u.Created AS UserCreated + FROM [CMS].[Users] u + WHERE u.Id = @RootUserId AND u.IsDeleted = 0 + + UNION ALL + + -- Recursive case: فرزندان + SELECT + u.Id, u.Mobile, u.FirstName, u.LastName, u.LegPosition, + u.NetworkParentId, parent.NetworkLevel + 1, u.Created + FROM [CMS].[Users] u + INNER JOIN NetworkTreeCTE parent ON u.NetworkParentId = parent.UserId + WHERE u.IsDeleted = 0 AND parent.NetworkLevel < @MaxDepth + ) + -- Join با ClubMemberships و WeekDefinitions + SELECT + t.UserId, t.Mobile, t.FirstName, t.LastName, t.LegPosition, + t.ParentId, t.NetworkLevel, + cm.ActivatedAt AS ClubActivatedAt, + ISNULL(cm.IsActive, 0) AS IsClubActive, + wd.Id AS ActivationWeekDefinitionId, + wd.DisplayName AS ActivationWeekDisplayName, + CASE WHEN @ActivationWeekDefinitionId IS NOT NULL + AND wd.Id = @ActivationWeekDefinitionId THEN 1 ELSE 0 + END AS IsActivatedInTargetWeek, + t.UserCreated + FROM NetworkTreeCTE t + LEFT JOIN [CMS].[ClubMemberships] cm ON cm.UserId = t.UserId AND cm.IsDeleted = 0 + LEFT JOIN [CMS].[WeekDefinitions] wd ON cm.ActivatedAt >= wd.StartDate + AND cm.ActivatedAt < wd.EndDate + WHERE (@IsClubActive IS NULL OR ISNULL(cm.IsActive, 0) = @IsClubActive + OR t.NetworkLevel = 0) + ORDER BY t.NetworkLevel, t.ParentId, t.LegPosition + OPTION (MAXRECURSION 0); -- بدون محدودیت recursion +END +``` + +**تغییرات در Application Layer**: + +**فایل جدید**: `NetworkTreeNodeDto.cs` +```csharp +public class NetworkTreeNodeDto +{ + public long UserId { get; set; } + public string? Mobile { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + public int? LegPosition { get; set; } + public long? ParentId { get; set; } + public int NetworkLevel { get; set; } + public DateTime? ClubActivatedAt { get; set; } + public bool IsClubActive { get; set; } + public long? ActivationWeekDefinitionId { get; set; } + public string? ActivationWeekDisplayName { get; set; } + public bool IsActivatedInTargetWeek { get; set; } + public DateTimeOffset UserCreated { get; set; } +} +``` + +**بازنویسی `GetNetworkTreeQueryHandler.cs`**: +- استفاده از ADO.NET برای اجرای SP +- تبدیل نتیجه flat به ساختار درختی +- پشتیبانی از همه پارامترهای فیلتر + +**پکیج جدید**: +```xml + +``` + +--- + +## 📁 فایل‌های تغییر یافته + +### CMS Microservice + +| فایل | نوع تغییر | توضیح | +|------|----------|-------| +| `WebApi/appsettings.json` | Modified | اضافه شدن `Chatika.Enabled` | +| `Infrastructure/BackgroundJobs/ChatikaAccountActivationJob.cs` | Modified | چک فلگ Enabled | +| `WebApi/Workers/DayaLoanCheckWorker.cs` | Modified | فیلتر کاربران با قرارداد | +| `Application/CMSMicroservice.Application.csproj` | Modified | پکیج Relational | +| `Application/Common/Interfaces/IApplicationDbContext.cs` | Modified | اضافه شدن DatabaseFacade | +| `Application/NetworkMembershipCQ/Queries/GetNetworkTree/GetNetworkTreeQueryHandler.cs` | **REWRITTEN** | استفاده از SP | +| `Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeNodeDto.cs` | **NEW** | DTO برای نتیجه SP | + +### BackOffice + +| فایل | نوع تغییر | توضیح | +|------|----------|-------| +| `Pages/Network/NetworkTreeViewer.razor` | **REWRITTEN** | استفاده از org-chart | +| `wwwroot/index.html` | Modified | رفرنس‌های JS/CSS | +| `wwwroot/js/admin-org-chart.js` | **NEW** | Wrapper برای org-chart | +| `wwwroot/css/admin-org-chart.css` | **NEW** | استایل نودها | +| `wwwroot/js/d3-org-chart3.js` | **NEW** | کتابخانه org-chart | +| `wwwroot/js/d3-flextree.min.js` | **NEW** | Dependency | + +### SQL Scripts + +| فایل | نوع تغییر | توضیح | +|------|----------|-------| +| `dbbkup/SP_GetNetworkTree.sql` | **NEW** | Stored Procedure | + +--- + +## 🔧 تنظیمات جدید + +### appsettings.json - Chatika +```json +{ + "Chatika": { + "Enabled": false, // ← جدید: فعال/غیرفعال کردن Worker + "BaseUrl": "https://api.chatika.ir", + "ApiKey": "YOUR_API_KEY_HERE" + } +} +``` + +--- + +## 🗄️ Database Changes + +### اجرای Stored Procedure +```bash +# اجرای اسکریپت در SQL Server +sqlcmd -S -d -i dbbkup/SP_GetNetworkTree.sql +``` + +--- + +## ✅ Build Status + +```bash +cd /home/masoud/Apps/project/FourSat/CMS/src +dotnet build +# Result: Build succeeded. 0 Error(s) + +cd /home/masoud/Apps/project/FourSat/BackOffice/src +dotnet build BackOffice/BackOffice.csproj +# Result: Build succeeded +``` + +--- + +## 📊 آمار Session + +| متریک | مقدار | +|-------|-------| +| فایل‌های جدید | 6 | +| فایل‌های تغییر یافته | 8 | +| قابلیت‌های جدید | 6 | +| خطوط کد اضافه شده | ~800 | +| Stored Procedure | 1 | + +--- + +## 🔗 Related Changelogs + +- [CHANGELOG-2025-12-23.md](CHANGELOG-2025-12-23.md) - پیاده‌سازی Worker چتیکا +- [CHANGELOG-2025-12-20.md](CHANGELOG-2025-12-20.md) - بهبودات قبلی