feat: Add monitoring alerts skeleton and enhance worker with notifications
This commit is contained in:
225
docs/migration-network-parent-guide.md
Normal file
225
docs/migration-network-parent-guide.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# 🔄 Migration Guide: ParentId → NetworkParentId
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
در سیستم قدیمی، کاربران با استفاده از `User.ParentId` به هم متصل میشدند (Parent-Child relationship).
|
||||
سیستم جدید **Network-Club-Commission** از یک **Binary Tree** استفاده میکند که نیاز به:
|
||||
- `User.NetworkParentId` (شناسه پدر در شبکه باینری)
|
||||
- `User.LegPosition` (Left یا Right)
|
||||
|
||||
برای اجرای صحیح Worker و محاسبات، **باید** تمام کاربران قدیمی Migrate شوند.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Critical Issues
|
||||
|
||||
### مشکل 1: Binary Tree Constraint
|
||||
- هر Parent فقط میتواند **2 فرزند** داشته باشد (Left & Right)
|
||||
- اگر کاربری در سیستم قدیمی بیشتر از 2 فرزند دارد، Migration فقط **2 فرزند اول** را میگیرد
|
||||
|
||||
### مشکل 2: Orphaned Nodes
|
||||
- اگر `ParentId` اشاره به یک کاربر نامعتبر (حذف شده) باشد، آن User **Orphaned** است
|
||||
- Orphaned nodes در Binary Tree نادیده گرفته میشوند
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Migration Methods
|
||||
|
||||
### روش 1: Automatic (Seeder - توصیه میشود)
|
||||
|
||||
Migration به صورت خودکار در `Program.cs` در حالت **Development** اجرا میشود:
|
||||
|
||||
```csharp
|
||||
// در Program.cs
|
||||
var migrationSeeder = new NetworkParentIdMigrationSeeder(dbContext, logger);
|
||||
await migrationSeeder.SeedAsync();
|
||||
```
|
||||
|
||||
**مزایا:**
|
||||
- ✅ Idempotent (میتوان چندین بار اجرا کرد، فقط یکبار تاثیر میگذارد)
|
||||
- ✅ Validation اتوماتیک
|
||||
- ✅ Logging کامل
|
||||
|
||||
**کجا اجرا میشود؟**
|
||||
- فقط در **Development** environment
|
||||
- هر بار که پروژه Run شود
|
||||
|
||||
---
|
||||
|
||||
### روش 2: Manual (Command)
|
||||
|
||||
اگر نیاز به اجرای دستی دارید:
|
||||
|
||||
```csharp
|
||||
// درخواست از طریق MediatR
|
||||
var result = await _mediator.Send(new MigrateNetworkParentIdCommand());
|
||||
|
||||
if (result.Success)
|
||||
{
|
||||
Console.WriteLine($"Migrated: {result.MigratedCount}");
|
||||
Console.WriteLine($"Skipped: {result.SkippedCount}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error: {result.Message}");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### روش 3: SQL Script
|
||||
|
||||
برای Production یا اجرای مستقیم روی Database:
|
||||
|
||||
```bash
|
||||
# فایل: CMSMicroservice.Infrastructure/Migrations/Scripts/20250601_MigrateParentIdToNetworkParentId.sql
|
||||
```
|
||||
|
||||
**نکته مهم:**
|
||||
قبل از اجرا، **حتماً** بررسی کنید که آیا کاربری بیش از 2 فرزند دارد:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
ParentId,
|
||||
COUNT(*) as ChildCount,
|
||||
STRING_AGG(CAST(Id AS VARCHAR), ', ') as ChildIds
|
||||
FROM Users
|
||||
WHERE ParentId IS NOT NULL
|
||||
GROUP BY ParentId
|
||||
HAVING COUNT(*) > 2;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Validation After Migration
|
||||
|
||||
### 1. بررسی تعداد کاربران Migrate شده
|
||||
|
||||
```csharp
|
||||
var stats = await _context.Users
|
||||
.GroupBy(u => 1)
|
||||
.Select(g => new
|
||||
{
|
||||
TotalUsers = g.Count(),
|
||||
UsersWithNetworkParent = g.Count(u => u.NetworkParentId != null),
|
||||
LeftChildren = g.Count(u => u.LegPosition == NetworkLeg.Left),
|
||||
RightChildren = g.Count(u => u.LegPosition == NetworkLeg.Right)
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
```
|
||||
|
||||
### 2. بررسی Orphaned Nodes
|
||||
|
||||
```sql
|
||||
SELECT Id, NetworkParentId
|
||||
FROM Users
|
||||
WHERE NetworkParentId IS NOT NULL
|
||||
AND NetworkParentId NOT IN (SELECT Id FROM Users);
|
||||
```
|
||||
|
||||
### 3. بررسی Binary Tree Violation
|
||||
|
||||
```sql
|
||||
SELECT NetworkParentId, COUNT(*) as ChildCount
|
||||
FROM Users
|
||||
WHERE NetworkParentId IS NOT NULL
|
||||
GROUP BY NetworkParentId
|
||||
HAVING COUNT(*) > 2;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Algorithm Details
|
||||
|
||||
### مراحل Migration:
|
||||
|
||||
1. **Find Users**: یافتن کاربران با `ParentId != NULL` و `NetworkParentId == NULL`
|
||||
2. **Group by Parent**: گروهبندی بر اساس ParentId
|
||||
3. **Check Constraint**: اگر Parent بیش از 2 فرزند دارد، فقط 2 تا اول را بگیر
|
||||
4. **Assign Values**:
|
||||
```csharp
|
||||
child.NetworkParentId = parentId;
|
||||
child.LegPosition = (i == 0) ? NetworkLeg.Left : NetworkLeg.Right;
|
||||
```
|
||||
5. **Save & Validate**: ذخیره و اعتبارسنجی Binary Tree
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### مشکل: Parent has more than 2 children
|
||||
|
||||
**راه حل:**
|
||||
تصمیم دستی بگیرید که کدام 2 فرزند را نگه دارید:
|
||||
|
||||
```sql
|
||||
-- بررسی کنید که کدام Parent مشکل دارد
|
||||
SELECT ParentId, COUNT(*) as ChildCount
|
||||
FROM Users
|
||||
WHERE ParentId = 123
|
||||
GROUP BY ParentId;
|
||||
|
||||
-- لیست فرزندان را ببینید
|
||||
SELECT Id, FullName, CreatedAt
|
||||
FROM Users
|
||||
WHERE ParentId = 123
|
||||
ORDER BY CreatedAt;
|
||||
|
||||
-- دستی NetworkParentId را برای 2 فرزند انتخابی Set کنید
|
||||
UPDATE Users
|
||||
SET NetworkParentId = 123, LegPosition = 0 -- Left
|
||||
WHERE Id = 456;
|
||||
|
||||
UPDATE Users
|
||||
SET NetworkParentId = 123, LegPosition = 1 -- Right
|
||||
WHERE Id = 789;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### مشکل: Orphaned Nodes (Parent doesn't exist)
|
||||
|
||||
**راه حل:**
|
||||
ParentId را NULL کنید یا به یک Parent معتبر متصل کنید:
|
||||
|
||||
```sql
|
||||
-- گزینه 1: NULL کردن (Root شدن)
|
||||
UPDATE Users
|
||||
SET ParentId = NULL, NetworkParentId = NULL
|
||||
WHERE ParentId = 999; -- 999 وجود ندارد
|
||||
|
||||
-- گزینه 2: اتصال به Parent دیگر
|
||||
UPDATE Users
|
||||
SET ParentId = 1, NetworkParentId = 1
|
||||
WHERE ParentId = 999;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist Before Production
|
||||
|
||||
- [ ] Migration در Development اجرا شده؟
|
||||
- [ ] Validation Errors بررسی شد؟
|
||||
- [ ] Orphaned Nodes رفع شدند؟
|
||||
- [ ] Binary Tree Violations رفع شدند؟
|
||||
- [ ] Backup از Database گرفته شده؟
|
||||
- [ ] Migration Script برای Production آماده است؟
|
||||
- [ ] Testing کامل انجام شده؟
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Files
|
||||
|
||||
- **Seeder**: `CMSMicroservice.Infrastructure/Data/Seeding/NetworkParentIdMigrationSeeder.cs`
|
||||
- **Command**: `CMSMicroservice.Application/UserCQ/Commands/MigrateNetworkParentId/`
|
||||
- **SQL Script**: `CMSMicroservice.Infrastructure/Migrations/Scripts/20250601_MigrateParentIdToNetworkParentId.sql`
|
||||
- **Entity**: `CMSMicroservice.Domain/Entities/User.cs` (خطوط 16, 45, 49)
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
اگر مشکل خاصی با Migration پیدا کردید:
|
||||
1. Log های Seeder را بررسی کنید
|
||||
2. ValidationErrors را چک کنید
|
||||
3. SQL Script را به صورت دستی اجرا کنید
|
||||
Reference in New Issue
Block a user