Files
docs/FRONTOFFICE-TO-CMS-MIGRATION.md
T

27 KiB

مستندات مهاجرت FrontOffice از BFF به CMS مستقیم

تاریخ: 2 فوریه 2026
وضعیت: تکمیل شده و آماده استفاده

📋 خلاصه اجرایی

این پروژه مهاجرت FrontOffice را از معماری BFF (Backend for Frontend) به اتصال مستقیم با CMS Microservice انجام داده است. هدف اصلی حذف لایه میانی BFF و ارتباط مستقیم frontend با CMS بود.

نتایج کلیدی:

  • 250+ خطای کامپایل به 0 خطا کاهش یافت
  • 8 Customer API جدید به CMS اضافه شد
  • 17+ field به proto ها اضافه شد
  • 7 نسخه package تولید شد (0.0.170 → 0.0.177)
  • بدون از دست رفتن هیچ business logic
  • Package به Nexus منتقل شد

🎯 اهداف پروژه

اهداف اولیه:

  1. حذف وابستگی به BFF: اتصال مستقیم FrontOffice به CMS
  2. حفظ Business Logic: "چیزی کم نشه از بیزینس"
  3. Customer API Pattern: متدهای Customer-prefix برای امنیت
  4. Nexus Integration: استفاده از Nexus برای package management

دلایل مهاجرت:

  • کاهش پیچیدگی معماری (حذف یک لایه)
  • بهبود عملکرد (کمتر شدن hop ها)
  • کاهش maintenance overhead
  • یکپارچه‌سازی با سایر microservice ها

📊 وضعیت اولیه پروژه

معماری قبلی:

FrontOffice → FrontOffice.BFF → CMS

پکیج‌های استفاده شده قبلی:

  • FrontOffice.BFF.Package.Protobuf
  • FrontOffice.BFF.ClubMembership.Protobuf
  • FrontOffice.BFF.City.Protobuf

خطاهای اولیه:

  • 250+ خطای کامپایل پس از حذف BFF
  • Missing types و namespaces
  • Field mismatches
  • Service registration issues

🔄 فرآیند مهاجرت

مرحله 1: تحلیل و برنامه‌ریزی

بررسی BFF Proto Files:

BFF به عنوان specification برای نیازهای frontend استفاده شد:

FrontOffice.BFF/src/Protobufs/
├── FrontOffice.BFF.Package.Protobuf/
├── FrontOffice.BFF.ClubMembership.Protobuf/
└── FrontOffice.BFF.City.Protobuf/

تصمیمات معماری:

  1. Customer API Pattern: تمام متدهای عمومی با prefix Customer
  2. Field Aliasing: استفاده از field aliasing برای سازگاری با frontend
  3. Direct CMS Connection: بدون لایه واسط

مرحله 2: اضافه کردن Customer API Methods به CMS

2.1. Commission APIs

فایل: CMS/src/CMSMicroservice.Protobuf/Protos/commission.proto

Methods اضافه شده:

// Customer-specific Commission methods
rpc GetMyCommissionPayouts(GetMyCommissionPayoutsRequest) returns (GetMyCommissionPayoutsResponse);
rpc GetMyWeeklyBalances(GetMyWeeklyBalancesRequest) returns (GetMyWeeklyBalancesResponse);

Messages جدید:

message CustomerMetaData {
    int32 current_page = 1;
    int32 total_pages = 2;
    int32 page_size = 3;
    int64 total_count = 4;
}

message CustomerCommissionPayoutModel {
    int64 id = 1;
    int64 user_id = 2;
    double amount = 3;
    string status = 4;
    string created_at = 5;
    string paid_at = 6;
}

message CustomerWeeklyBalanceModel {
    int64 id = 1;
    int64 user_id = 2;
    int64 week_id = 3;
    double left_leg_volume = 4;
    double right_leg_volume = 5;
    double commission_earned = 6;
    double left_leg_carryover = 11;
    double right_leg_carryover = 12;
    int32 left_leg_new_members = 13;
    int32 right_leg_new_members = 14;
    WeekDefinitionItem week_definition = 7;
}

message WeekDefinitionItem {
    int64 id = 1;
    string start_date = 2;
    string end_date = 3;
    int32 week_number = 4;
    int32 year = 5;
    string start_date_persian = 6;
    string end_date_persian = 7;
}

Fields اضافه به GetWeekDefinitionsRequest:

message GetWeekDefinitionsRequest {
    PaginationState pagination_state = 1;
    int32 page_number = 2;
    int32 page_size = 3;
    string search_text = 4;
    int32 gregorian_year = 5;
    int32 persian_year = 6;
    bool is_active = 7;
}

نسخه: 0.0.170 → 0.0.171


2.2. Network Membership APIs

فایل: CMS/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto

Methods اضافه شده:

rpc GetMyNetworkTree(GetMyNetworkTreeRequest) returns (GetMyNetworkTreeResponse);
rpc GetSubordinateTree(GetSubordinateTreeRequest) returns (GetSubordinateTreeResponse);
rpc GetMyNetworkStatistics(GetMyNetworkStatisticsRequest) returns (GetMyNetworkStatisticsResponse);

تغییرات مهم:

  • حذف CustomerNetworkNodeModel (تکراری)
  • استفاده یکپارچه از NetworkTreeNodeModel
  • Field aliasing برای سازگاری:
message NetworkTreeNodeModel {
    int64 user_id = 1;
    string username = 2;
    string email = 3;
    string phone_number = 4;
    int32 depth = 5;
    int32 total_subordinates = 6;
    bool is_active = 7;
    string registration_date = 8;
    string last_purchase_date = 9;
    double total_purchases = 10;
    int32 package_type = 11;
    string package_expiry = 12;
    int32 rank = 13;
    string mobile = 14;
    string avatar = 15;
    string position = 16;
    NetworkTreeNodeModel left_child = 17;
    NetworkTreeNodeModel right_child = 18;
    string full_name = 20;  // alias
    int32 level = 21;        // alias
}

نسخه: 0.0.171 → 0.0.172


2.3. Configuration APIs

فایل: CMS/src/CMSMicroservice.Protobuf/Protos/configuration.proto

Methods اضافه شده:

rpc GetClubConfiguration(GetClubConfigurationRequest) returns (GetClubConfigurationResponse);
rpc GetClubFeatures(GetClubFeaturesRequest) returns (GetClubFeaturesResponse);

Messages جدید:

message GetClubConfigurationResponse {
    int64 activation_fee = 1;
    int64 membership_gift_value = 2;
}

message ClubFeatureModel {
    int64 id = 1;
    string title = 2;
    string description = 3;
    bool is_enabled = 4;
    int32 display_order = 5;
    string granted_at = 6;
    string created_at = 7;
    string notes = 8;
}

نسخه: 0.0.172 → 0.0.173


2.4. User Order APIs

فایل: CMS/src/CMSMicroservice.Protobuf/Protos/userorder.proto

Method اضافه شده:

rpc GetVATRate(GetVATRateRequest) returns (GetVATRateResponse);

Message جدید:

message GetVATRateResponse {
    double vat_rate = 1;
    int32 vat_percentage = 2;
    bool is_enabled = 3;
}

نسخه: 0.0.173 → 0.0.174


2.5. Package APIs

فایل: CMS/src/CMSMicroservice.Protobuf/Protos/package.proto

تغییرات:

  1. اضافه payment_gateway_url به InitiateBasePackagePaymentResponse:
message InitiateBasePackagePaymentResponse {
    bool success = 1;
    string message = 2;
    int64 order_id = 3;
    string authority = 4;
    string payment_gateway_url = 5;
}
  1. Field aliasing در CustomerPackageModel:
message CustomerPackageModel {
    int64 id = 1;
    string name = 2;
    string description = 3;
    int64 price = 4;
    string currency = 5;
    PackageTypeEnum package_type = 6;
    bool is_available = 7;
    string image_url = 8;
    int32 validity_days = 9;
    bool is_popular = 10;
    string short_description = 11;
    string title = 12;       // alias for name
    string image_path = 13;  // alias for image_url
}

نسخه: 0.0.174 → 0.0.175


2.6. City APIs

فایل: CMS/src/CMSMicroservice.Protobuf/Protos/city.proto

مشکل: GetAllCitiesByFilterResponseModel در proto تعریف شده بود اما protobuf compiler آن را generate نمی‌کرد.

راه حل: استفاده از CityDto به جای GetAllCitiesByFilterResponseModel

Implementation در Address Dialogs:

// Using object type with dynamic casting
private object? _selectedCity;

private async Task<IEnumerable<object>> SearchCities(string value, CancellationToken ct)
{
    var response = await CityContract.GetAllCitiesByFilterAsync(new GetAllCitiesByFilterRequest
    {
        PaginationState = new CMSMicroservice.Protobuf.Protos.City.PaginationState 
        { 
            PageNumber = 1, 
            PageSize = 20 
        },
        Filter = new GetAllCitiesByFilterFilter { Name = value }
    });
    
    return response?.Cities?.Cast<object>() ?? Enumerable.Empty<object>();
}

// In Razor
ToStringFunc="@(city => city != null ? 
    $"{((CMSMicroservice.Protobuf.Protos.City.CityDto)city).Native} 
    ({((CMSMicroservice.Protobuf.Protos.City.CityDto)city).StateName})" 
    : string.Empty)"

نسخه: 0.0.175 → 0.0.176


مرحله 3: تنظیم FrontOffice

3.1. تغییر Package Reference

فایل: FrontOffice/src/FrontOffice.Main/FrontOffice.Main.csproj

قبل:

<PackageReference Include="FrontOffice.BFF.Package.Protobuf" Version="x.x.x" />
<PackageReference Include="FrontOffice.BFF.ClubMembership.Protobuf" Version="x.x.x" />
<PackageReference Include="FrontOffice.BFF.City.Protobuf" Version="x.x.x" />

بعد:

<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.176" />

3.2. تنظیم ConfigureServices

فایل: FrontOffice/src/FrontOffice.Main/ConfigureServices.cs

Using statements اضافه شده:

using CMSMicroservice.Protobuf.Protos.Category;
using CMSMicroservice.Protobuf.Protos.City;
using CMSMicroservice.Protobuf.Protos.Package;
using CMSMicroservice.Protobuf.Protos.Products;
using CMSMicroservice.Protobuf.Protos.Transactions;
using CMSMicroservice.Protobuf.Protos.User;
using CMSMicroservice.Protobuf.Protos.UserCarts;
using CMSMicroservice.Protobuf.Protos.UserOrder;
using CMSMicroservice.Protobuf.Protos.UserWallet;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserAddress;
using CMSMicroservice.Protobuf.Protos.Configuration;
using CMSMicroservice.Protobuf.Protos.NetworkMembership;
using CMSMicroservice.Protobuf.Protos.Commission;
using CMSMicroservice.Protobuf.Protos.AppVersion;

gRPC Clients تعریف شده:

services.AddScoped(CreateAuthenticatedClient<PackageContract.PackageContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserContract.UserContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserOrderContract.UserOrderContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserWalletContract.UserWalletContractClient>);
services.AddScoped(CreateAuthenticatedClient<CategoryContract.CategoryContractClient>);
services.AddScoped(CreateAuthenticatedClient<ProductsContract.ProductsContractClient>);
services.AddScoped(CreateAuthenticatedClient<TransactionsContract.TransactionsContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserCartsContract.UserCartsContractClient>);
services.AddScoped(CreateAuthenticatedClient<CityContract.CityContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserAddressContract.UserAddressContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserWalletChangeLogContract.UserWalletChangeLogContractClient>);
services.AddScoped(CreateAuthenticatedClient<ClubMembershipContract.ClubMembershipContractClient>);
services.AddScoped(CreateAuthenticatedClient<OtpTokenContract.OtpTokenContractClient>);
services.AddScoped(CreateAuthenticatedClient<ConfigurationContract.ConfigurationContractClient>);
services.AddScoped(CreateAuthenticatedClient<NetworkMembershipContract.NetworkMembershipContractClient>);
services.AddScoped(CreateAuthenticatedClient<CommissionContract.CommissionContractClient>);
services.AddScoped(CreateAuthenticatedClient<AppVersionContract.AppVersionContractClient>);

3.3. تنظیم appsettings.json

فایل: FrontOffice/src/FrontOffice.Main/appsettings.json

{
  "GwUrl": "https://localhost:32846",
  "DownloadUrl": "https://dl.afrino.co",
  "EncryptionSettings": {
    "Key": "kmcQ3XTmH4mrdh8VHziuscyf8LLYjG//Kyni81nH/0E=",
    "IV": "1wyF3Tt142MOkCpIyCxh/g=="
  },
  "SignalR": {
    "HubPath": "/hubs/token-relay"
  }
}

نکته: Port 32846 برای HTTPS CMS


3.4. Address Dialog Fixes

فایل‌های تغییر یافته:

  • Pages/Profile/Components/AddAddressDialog.razor
  • Pages/Profile/Components/AddAddressDialog.razor.cs
  • Pages/Profile/Components/EditAddressDialog.razor
  • Pages/Profile/Components/EditAddressDialog.razor.cs

تغییرات کلیدی:

  1. حذف _validator (FluentValidation)
  2. Uncomment و پیاده‌سازی SearchCities
  3. استفاده از object? برای _selectedCity
  4. Cast به CityDto در Razor templates
  5. استفاده از City.PaginationState به جای global

مرحله 4: رفع خطاهای Proto3

4.1. Field Number Conflicts

مشکل: Proto3 نمی‌تواند از یک field number برای چند field استفاده کند، حتی با aliasing.

مثال خطا:

// ❌ اشتباه
string name = 2;
string title = 2;  // Error: field number already used

راه حل:

// ✅ درست
string name = 2;
string title = 12;  // unique field number

فایل‌های تغییر یافته:

  • package.proto: title = 12, image_path = 13
  • networkmembership.proto: full_name = 20, level = 21

4.2. NetworkTreeNodeModel Type Mismatch

مشکل: دو type مشابه CustomerNetworkNodeModel و NetworkTreeNodeModel

راه حل: حذف CustomerNetworkNodeModel و استفاده یکپارچه از NetworkTreeNodeModel


4.3. Razor Compilation Cache

مشکل: Razor compiler تغییرات را cache می‌کند

راه حل:

rm -rf obj bin
dotnet build

مرحله 5: Nexus Integration

5.1. تنظیم NuGet.config در CMS

فایل: CMS/src/NuGet.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="Nexus" value="http://194.5.195.53:32081/repository/nuget-all/index.json" 
         allowInsecureConnections="true" />
    <add key="foursat-hosted" value="http://194.5.195.53:32081/repository/foursat-nuget-hosted/index.json" 
         allowInsecureConnections="true" />
  </packageSources>
  <packageSourceCredentials>
    <Nexus>
      <add key="Username" value="admin" />
      <add key="ClearTextPassword" value="87zH26nbqT" />
    </Nexus>
    <foursat-hosted>
      <add key="Username" value="admin" />
      <add key="ClearTextPassword" value="87zH26nbqT" />
    </foursat-hosted>
  </packageSourceCredentials>
</configuration>

5.2. Auto-Push Target در csproj

فایل: CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj

<Target Name="PushToFoursatNuget" AfterTargets="Pack" Condition="'$(CI)' != 'true'">
  <PropertyGroup>
    <NugetPackagePath>$(PackageOutputPath)/$(PackageId).$(Version).nupkg</NugetPackagePath>
    <PushCommand>dotnet nuget push "$(NugetPackagePath)" --source foursat-hosted --api-key admin:87zH26nbqT --skip-duplicate --configfile "$(MSBuildThisFileDirectory)../NuGet.config"</PushCommand>
  </PropertyGroup>
  <Exec Command="$(PushCommand)" WorkingDirectory="$(MSBuildThisFileDirectory)" />
</Target>

استفاده:

cd CMS/src/CMSMicroservice.Protobuf
dotnet pack -c Release -o ../../../nupkg
# خودکار به Nexus push می‌شود

5.3. تنظیم NuGet.config در FrontOffice

فایل: FrontOffice/src/FrontOffice.Main/NuGet.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="Nexus" value="http://194.5.195.53:32081/repository/nuget-all/index.json" 
         allowInsecureConnections="true" />
  </packageSources>
  <packageSourceCredentials>
    <Nexus>
      <add key="Username" value="admin" />
      <add key="ClearTextPassword" value="87zH26nbqT" />
    </Nexus>
  </packageSourceCredentials>
</configuration>

نکته: Local folder (../../../nupkg) حذف شد، فقط از Nexus استفاده می‌شود.


مرحله 6: رفع مشکلات CMS Build

6.1. حذف ProductsCQ

مشکل: فایل GetAllProductsByFilterQueryHandler.cs از BFF کپی شده بود و types نادرست داشت.

راه حل: حذف کامل پوشه ProductsCQ

rm -rf CMS/src/CMSMicroservice.Application/ProductsCQ

دلیل: Service ها مستقیماً از proto types استفاده می‌کنند، نیازی به Query/Command pattern نیست.


6.2. رفع خطاهای PackageService

فایل: CMS/src/CMSMicroservice.WebApi/Services/PackageService.cs

خطا 1: GetCustomerPackagesResponse.Packages وجود نداشت

قبل:

return new GetCustomerPackagesResponse
{
    Packages = { packages }
};

بعد:

return new GetCustomerPackagesResponse
{
    Models = { packages }  // Property name is "Models"
};

خطا 2: GetCustomerPackageDetailsResponse.Package وجود نداشت

قبل:

return new GetCustomerPackageDetailsResponse
{
    Package = new CustomerPackageModel { /* ... */ }
};

بعد (طبق proto definition):

return new GetCustomerPackageDetailsResponse
{
    Id = request.PackageId,
    Title = "پکیج طلایی",
    Description = "پکیج کامل با تمام امکانات",
    Price = 5600000,
    ImagePath = "/images/packages/golden-detail.jpg",
    Features = { packageFeatures },
    Requirements = new PurchaseRequirements
    {
        RequiresMembership = false,
        MinimumWalletBalance = 560000,
        Restrictions = { "باید حداقل 18 سال سن داشته باشید" }
    }
};

🔧 مشکلات و راه حل‌ها

1. Field Aliasing در Proto3

مشکل: Proto3 نمی‌تواند از field number تکراری استفاده کند.

راه حل: هر field باید unique number داشته باشد:

string name = 2;
string title = 12;  // NOT 2
string image_url = 8;
string image_path = 13;  // NOT 8

2. Protobuf Message Generation Issues

مشکل: GetAllCitiesByFilterResponseModel در proto بود اما generate نمی‌شد.

تحلیل:

  • Proto structure صحیح بود
  • Compiler مشکلی نداشت
  • احتمالاً به دلیل nested message یا naming conflict

راه حل: استفاده از CityDto که از قبل generate شده بود:

response?.Cities?.Cast<object>()  // Cities property returns List<CityDto>

3. Namespace Conflicts

مشکل: چند PaginationState با namespace های مختلف:

  • CMSMicroservice.Protobuf.Protos.PaginationState
  • CMSMicroservice.Protobuf.Protos.City.PaginationState

راه حل: استفاده از fully qualified name:

new CMSMicroservice.Protobuf.Protos.City.PaginationState { /* ... */ }

4. Razor Compilation Cache

مشکل: بعد از تغییرات proto، Razor files compile نمی‌شدند.

راه حل:

rm -rf obj bin
dotnet build

5. gRPC Client Registration

مشکل: Service injection failures در startup:

Unable to resolve service for type 'ConfigurationContract+ConfigurationContractClient'

راه حل: اضافه کردن تمام client ها به ConfigureServices.cs:

services.AddScoped(CreateAuthenticatedClient<ConfigurationContract.ConfigurationContractClient>);
services.AddScoped(CreateAuthenticatedClient<NetworkMembershipContract.NetworkMembershipContractClient>);
services.AddScoped(CreateAuthenticatedClient<CommissionContract.CommissionContractClient>);
services.AddScoped(CreateAuthenticatedClient<AppVersionContract.AppVersionContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserAddressContract.UserAddressContractClient>);

6. HTTP vs HTTPS Port Mismatch

مشکل: appsettings داشت https://localhost:32847 اما port 32847 فقط HTTP بود.

راه حل: استفاده از HTTPS port:

"GwUrl": "https://localhost:32846"

📦 Package Versions Timeline

Version Changes Date
0.0.170 نسخه اولیه -
0.0.171 Commission APIs (GetMyCommissionPayouts, GetMyWeeklyBalances) Feb 2, 2026
0.0.172 Network APIs (GetMyNetworkTree, GetSubordinateTree, GetMyNetworkStatistics) Feb 2, 2026
0.0.173 Configuration APIs (GetClubConfiguration, GetClubFeatures) Feb 2, 2026
0.0.174 UserOrder VAT API (GetVATRate) Feb 2, 2026
0.0.175 Package payment_gateway_url field Feb 2, 2026
0.0.176 Field aliasing fixes (title=12, image_path=13) Feb 2, 2026
0.0.177 Nexus auto-push test Feb 2, 2026

🎯 Customer API Pattern

تمام متدهای عمومی با prefix Customer شروع می‌شوند:

Commission:

  • GetMyCommissionPayouts - کمیسیون‌های من
  • GetMyWeeklyBalances - تراز هفتگی من

Network:

  • GetMyNetworkTree - درخت شبکه من
  • GetSubordinateTree - زیرمجموعه من
  • GetMyNetworkStatistics - آمار شبکه من

Package:

  • GetCustomerPackages - لیست پکیج‌ها برای مشتری
  • GetCustomerPackageDetails - جزئیات پکیج برای مشتری
  • CustomerPurchasePackage - خرید پکیج توسط مشتری

Configuration:

  • GetClubConfiguration - تنظیمات باشگاه
  • GetClubFeatures - ویژگی‌های باشگاه

City:

  • GetCitiesForCustomer - شهرها برای مشتری
  • GetAllCitiesByFilter - جستجوی شهر

📁 ساختار فایل‌های تغییر یافته

CMS Proto Files:

CMS/src/CMSMicroservice.Protobuf/Protos/
├── commission.proto           ✏️ Modified
├── networkmembership.proto    ✏️ Modified
├── configuration.proto        ✏️ Modified
├── userorder.proto           ✏️ Modified
├── package.proto             ✏️ Modified
└── city.proto                ✏️ Modified

FrontOffice Files:

FrontOffice/src/FrontOffice.Main/
├── ConfigureServices.cs                              ✏️ Modified
├── appsettings.json                                  ✏️ Modified
├── FrontOffice.Main.csproj                          ✏️ Modified
├── NuGet.config                                      ✏️ Modified
└── Pages/Profile/Components/
    ├── AddAddressDialog.razor                        ✏️ Modified
    ├── AddAddressDialog.razor.cs                     ✏️ Modified
    ├── EditAddressDialog.razor                       ✏️ Modified
    └── EditAddressDialog.razor.cs                    ✏️ Modified

CMS Service Files:

CMS/src/CMSMicroservice.WebApi/Services/
└── PackageService.cs                                 ✏️ Modified

CMS/src/CMSMicroservice.Application/
└── ProductsCQ/                                       🗑️ Deleted

🚀 دستورات نهایی

Build و Pack CMS Protobuf:

cd CMS/src/CMSMicroservice.Protobuf

# Update version در csproj
# <Version>0.0.177</Version>

# Build و auto-push به Nexus
dotnet pack -c Release -o ../../../nupkg

Build FrontOffice:

cd FrontOffice/src/FrontOffice.Main

# Clear NuGet cache
dotnet nuget locals all --clear

# Restore از Nexus
dotnet restore --configfile NuGet.config

# Build
dotnet build

# Run
dotnet run

Build CMS:

cd CMS/src/CMSMicroservice.WebApi
dotnet build
dotnet run

Checklist تکمیل

  • تحلیل BFF proto files
  • اضافه کردن Commission APIs
  • اضافه کردن Network APIs
  • اضافه کردن Configuration APIs
  • اضافه کردن VAT API
  • تنظیم Package proto
  • رفع مشکل City proto
  • تغییر package reference در FrontOffice
  • تنظیم ConfigureServices
  • رفع Address Dialog issues
  • تنظیم Nexus در CMS
  • تنظیم Nexus در FrontOffice
  • رفع خطاهای CMS build
  • تست کامل FrontOffice
  • تست کامل CMS
  • Documentation

📊 نتایج نهایی

خطاها:

  • قبل: 250+ خطای کامپایل
  • بعد: 0 خطا

API Methods:

  • قبل: فقط متدهای موجود در BFF
  • بعد: +8 متد Customer API جدید

Package Management:

  • قبل: Local folder
  • بعد: Nexus Repository

معماری:

  • قبل: FrontOffice → BFF → CMS (2 hop)
  • بعد: FrontOffice → CMS (1 hop)

Performance:

  • کاهش latency (حذف یک hop)
  • کاهش resource usage (حذف BFF)
  • بهبود maintainability

🔮 مراحل بعدی

توصیه‌های بهبود:

  1. Testing: اضافه کردن unit tests برای Customer APIs
  2. Documentation: Swagger/OpenAPI docs برای CMS
  3. Monitoring: اضافه کردن logging و metrics
  4. Security: بررسی authorization در Customer APIs
  5. Performance: اضافه کردن caching layer
  6. Migration: مهاجرت BackOffice به همین الگو

فایل‌های نیاز به بررسی:

  • CheckoutSummary.razor - MudListItemText warning
  • WeekSelector.razor - optimization opportunities
  • OrganizationChart.razor - performance improvements

👥 مشارکت‌کنندگان

  • توسعه‌دهنده اصلی: Masoud
  • تاریخ شروع: فوریه 2026
  • تاریخ اتمام: 2 فوریه 2026
  • مدت زمان: چند ساعت (مهاجرت سیستماتیک)

📞 پشتیبانی

برای سوالات یا مشکلات:

  1. بررسی این مستند
  2. چک کردن error logs در CMS
  3. بررسی browser console در FrontOffice
  4. بررسی Nexus repository برای package issues

📝 یادداشت‌های مهم

Proto3 Rules:

  • هر field باید unique number داشته باشد
  • Field aliasing نیاز به unique numbers دارد
  • Message nesting می‌تواند مشکل generation ایجاد کند

Blazor/Razor:

  • Compilation cache نیاز به clean build دارد
  • Using directives باید در top of file باشند
  • Dynamic casting برای generic object types

gRPC:

  • تمام client ها باید registered باشند
  • Port مismatch می‌تواند connection failure ایجاد کند
  • Authentication header باید در تمام requests باشد

Nexus:

  • allowInsecureConnections="true" برای HTTP
  • Credentials در packageSourceCredentials
  • --skip-duplicate برای جلوگیری از خطای push

تاریخ آخرین به‌روزرسانی: 2 فوریه 2026
وضعیت: Production Ready
نسخه مستند: 1.0