efff5e9cd5
- business/ (5): club-commission, payment, ecommerce, membership, content - technical/ (5): cms-arch, ui, deployment, migration, api - overview/ (5): flowcharts, index, changelog, glossary, roadmap - Removed all old folders: backoffice, cms, deployment, docs, frontoffice, migration, ui-modernization, business (old) - Updated internal links with relative folder paths
8.9 KiB
8.9 KiB
⚙️ معماری CMS و زیرساخت فنی
منابع ادغامشده:
CMS-README.md,ICURRENTUSERSERVICE-IMPLEMENTATION.md,FILE-MANAGEMENT-ARCHITECTURE.md,FRONTOFFICE-CMS-API-COMPATIBILITY.md,BFF-REMOVAL-PLAN.md,system-constants.md
آخرین بروزرسانی: اسفند ۱۴۰۴
۱. Stack فنی
| لایه | تکنولوژی | نسخه |
|---|---|---|
| Runtime | .NET | 9.0 |
| ORM | Entity Framework Core | 9.0 |
| Communication | gRPC (Protobuf) | v3 |
| Pattern | CQRS + MediatR | — |
| Database | SQL Server (MSSQL) | 2022-CU16 |
| Job Scheduler | Hangfire | — |
| Auth | JWT Bearer + Identity | — |
| API Gateway | حذفشده (Direct gRPC) | — |
۲. معماری لایهای CMS
┌──────────────────────────────────────────────────────┐
│ Presentation Layer │
│ FrontOffice (Blazor Server) ←─gRPC─→ CMS │
│ BackOffice (Blazor WASM) ←─gRPC─→ CMS │
├──────────────────────────────────────────────────────┤
│ Application Layer │
│ Commands (MediatR IRequest<T>) │
│ Queries (MediatR IRequest<T>) │
│ Validators (FluentValidation) │
│ Handlers (IRequestHandler<TReq, TRes>) │
├──────────────────────────────────────────────────────┤
│ Domain Layer │
│ Entities, Enums, Value Objects │
│ Domain Events, Interfaces │
├──────────────────────────────────────────────────────┤
│ Infrastructure Layer │
│ EF Core DbContext (CMSDbContext) │
│ Repositories, External Services │
│ Hangfire Jobs, File Storage │
├──────────────────────────────────────────────────────┤
│ Database │
│ SQL Server — Schema: [CMS] │
└──────────────────────────────────────────────────────┘
۳. CQRS با MediatR
۳.۱ ساختار فولدرها
CMS/src/
├── CMSMicroservice/
│ ├── Features/
│ │ ├── Products/
│ │ │ ├── Commands/
│ │ │ │ ├── CreateProductCommand.cs
│ │ │ │ └── CreateProductCommandHandler.cs
│ │ │ ├── Queries/
│ │ │ │ ├── GetProductsQuery.cs
│ │ │ │ └── GetProductsQueryHandler.cs
│ │ │ └── Validators/
│ │ │ └── CreateProductCommandValidator.cs
│ │ ├── Orders/
│ │ ├── Users/
│ │ ├── Club/
│ │ ├── Payment/
│ │ └── Blog/
│ ├── Services/
│ │ ├── gRPC/ ← gRPC service implementations
│ │ ├── Background/ ← Hangfire jobs
│ │ └── External/ ← ZarinPal, Kavenegar, Daya, Chatika
│ ├── Infrastructure/
│ │ ├── Persistence/ ← DbContext, Migrations
│ │ └── Identity/ ← JWT, Claims, ICurrentUserService
│ └── Protos/ ← .proto files
۳.۲ مثال Command
// Command
public record CreateProductCommand(
string Name, string Description, decimal Price,
Guid CategoryId, string ImageUrl
) : IRequest<Guid>;
// Handler
public class CreateProductCommandHandler
: IRequestHandler<CreateProductCommand, Guid>
{
private readonly CMSDbContext _db;
public async Task<Guid> Handle(
CreateProductCommand request, CancellationToken ct)
{
var product = new Product { /* map fields */ };
_db.Products.Add(product);
// Auto-create inventory record
_db.Inventories.Add(new Inventory { ProductId = product.Id });
await _db.SaveChangesAsync(ct);
return product.Id;
}
}
۴. gRPC Services
۴.۱ لیست سرویسها
| سرویس | proto | متدهای اصلی |
|---|---|---|
ProductService |
product.proto | GetProducts, GetProduct, Create, Update, Delete |
OrderService |
order.proto | CreateOrder, GetOrders, UpdateStatus |
UserService |
user.proto | Register, Login, GetProfile, UpdateProfile |
ClubService |
club.proto | GetNetworkTree, GetBalance, AcceptContract |
PaymentService |
payment.proto | CreatePayment, VerifyPayment |
BlogService |
blog.proto | GetPosts, GetPost, Create, Update |
InventoryService |
inventory.proto | GetInventory, UpdateStock |
FileService |
file.proto | Upload, Download, Delete |
SitePageService |
sitepage.proto | GetPage, SaveSettings |
CategoryService |
category.proto | GetCategories, Create, Update |
SystemConfigService |
config.proto | GetConfig, UpdateConfig |
۴.۲ PaginationState (مشترک)
message PaginationState {
int32 skip = 1;
int32 take = 2;
}
Namespace صحیح:
using CMSMicroservice.Protobuf.Protos.PaginationState;
// ⚠️ نه: CMSMicroservice.Protobuf.Protos.PublicMessages.PaginationState
۵. Database
۵.۱ اتصال
Staging: Server=194.5.195.53; Database=FourSatCMS; Schema=CMS
Production: Server=45.149.79.127; Database=FourSatCMS; Schema=CMS
Engine: MSSQL 2022-CU16, Collation=Arabic_CI_AS
۵.۲ جداول اصلی
| جدول | توضیح | رکوردهای تقریبی |
|---|---|---|
| Users | کاربران | ~5K |
| Products | محصولات | ~200 |
| Categories | دستهبندیها | ~30 |
| Orders | سفارشات | ~2K |
| Inventories | موجودی | ~200 |
| BlogPosts | پستهای بلاگ | ~50 |
| SitePages | صفحات سایت | ~10 |
| UserClubMemberships | عضویت باشگاه | ~500 |
| UserContracts | قراردادها | ~500 |
| NetworkNodes | نودهای درخت باینری | ~500 |
| Transactions | تراکنشها | ~5K |
| SystemConfigurations | تنظیمات | ~30 |
| ChatMessages | پیامهای چاتیکا | ~1K |
۵.۳ Stored Procedures
| SP | کاربرد |
|---|---|
SP_GetNetworkTree |
بازگشتی — استخراج درخت باینری |
sp_CalculateWeeklyBalances |
محاسبه بالانس هفتگی هر عضو |
sp_CalculateWeeklyCommissionPool |
توزیع Pool هفتگی |
۶. حذف BFF / Gateway
۶.۱ قبل vs بعد
قبل:
FrontOffice → BFF (REST) → CMS (gRPC)
BackOffice → BFF (REST) → CMS (gRPC)
بعد (فعلی):
FrontOffice → CMS (gRPC مستقیم)
BackOffice → CMS (gRPC مستقیم)
مزایا:
✅ حذف لایه واسط → کاهش latency
✅ حذف maintenance اضافی
✅ Type-safe از proto تا UI
✅ کاهش ۱ سرویس در deployment
۶.۲ سازگاری API
FrontOffice Service Layer:
• ProductService.cs → gRPC client wrapper
• OrderService.cs → gRPC client wrapper
• UserService.cs → gRPC client wrapper
هر Service:
• Constructor: inject GrpcChannel
• Methods: wrap gRPC calls + map to DTOs
• Error handling: try/catch RpcException
۷. Hangfire Jobs
| Job | فرکانس | کاربرد |
|---|---|---|
DayaLoanProcessorJob |
هر ۱۵ دقیقه | پردازش درخواستهای وام |
WeeklyCommissionJob |
هفتگی (شنبه ۰۰:۰۰) | محاسبه و توزیع کمیسیون |
ChatikaJob |
هر ۵ دقیقه | همگامسازی پیامهای AI |
InventorySyncJob |
هر ساعت | ایجاد رکوردهای موجودی گمشده |
۸. پیکربندی
۸.۱ appsettings.json ساختار
{
"ConnectionStrings": {
"DefaultConnection": "Server=...;Database=FourSatCMS"
},
"Jwt": {
"Secret": "***",
"Issuer": "FourSat",
"ExpiryMinutes": 1440
},
"Grpc": {
"CmsUrl": "https://localhost:5001"
},
"Hangfire": {
"DashboardPath": "/hangfire",
"WorkerCount": 4
},
"Kavenegar": { "ApiKey": "***" },
"ZarinPal": { "MerchantId": "***" },
"DayaLoan": { "UseMock": true }
}