feat: update Protobuf definitions and add customer-facing APIs for various services

This commit is contained in:
masoodafar-web
2026-02-01 22:16:36 +03:30
parent 658d076bdf
commit 794dd01ac0
13 changed files with 329 additions and 11 deletions
@@ -0,0 +1,69 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CMSMicroservice.Application.Common.Interfaces;
using Mapster;
using MediatR;
namespace CMSMicroservice.Application.ProductsCQ.Queries.GetAllProductsByFilter;
public class
GetAllProductsByFilterQueryHandler : IRequestHandler<GetAllProductsByFilterQuery, GetAllProductsByFilterResponseDto>
{
private readonly IApplicationDbContext _context;
public GetAllProductsByFilterQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetAllProductsByFilterResponseDto> Handle(GetAllProductsByFilterQuery request,
CancellationToken cancellationToken)
{
var grpcRequest = new CmsProductsProtos.GetAllProductsByFilterRequest
{
PaginationState = request.PaginationState is { } pagination
? new CmsPaginationState
{
PageNumber = pagination.PageNumber,
PageSize = pagination.PageSize
}
: null,
SortBy = request.SortBy,
Filter = BuildFilter(request.Filter)
};
var result = await _context.Product.GetAllProductsByFilterAsync(grpcRequest,
cancellationToken: cancellationToken);
if (request.Filter?.CategoryId is { } categoryId)
{
var matchingModels = result.Models
.Where(model => model.CategoryIds.Contains(categoryId))
.ToList();
result.Models.Clear();
result.Models.AddRange(matchingModels);
}
return result.Adapt<GetAllProductsByFilterResponseDto>();
}
private static CmsProductsProtos.GetAllProductsByFilterFilter? BuildFilter(GetAllProductsByFilterFilter? filter)
{
if (filter is null)
{
return null;
}
return new CmsProductsProtos.GetAllProductsByFilterFilter
{
Id = filter.Id,
Title = filter.Title,
Description = filter.Description,
ShortInfomation = filter.ShortInfomation,
FullInformation = filter.FullInformation,
Price = filter.Price,
Discount = filter.Discount,
Rate = filter.Rate
};
}
}
@@ -3,7 +3,7 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Version>0.0.169</Version> <Version>0.0.177</Version>
<DebugType>None</DebugType> <DebugType>None</DebugType>
<DebugSymbols>False</DebugSymbols> <DebugSymbols>False</DebugSymbols>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild> <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
@@ -66,12 +66,12 @@
<Protobuf Include="Protos\inventory.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\inventory.proto" ProtoRoot="Protos\" GrpcServices="Both" />
</ItemGroup> </ItemGroup>
<Target Name="PushToFoursatNuget" AfterTargets="Pack" Condition="'$(RunPushTarget)' != 'false' AND '$(CI)' != 'true'"> <Target Name="PushToFoursatNuget" AfterTargets="Pack" Condition="'$(CI)' != 'true'">
<PropertyGroup> <PropertyGroup>
<NugetPackagePath>$(PackageOutputPath)$(PackageId).$(Version).nupkg</NugetPackagePath> <NugetPackagePath>$(PackageOutputPath)/$(PackageId).$(Version).nupkg</NugetPackagePath>
<PushCommand>dotnet nuget push **/*.nupkg --source http://194.5.195.53:32081/repository/foursat-nuget-hosted/index.json --api-key admin:87zH26nbqT --skip-duplicate --allow-insecure-connections</PushCommand> <PushCommand>dotnet nuget push "$(NugetPackagePath)" --source foursat-hosted --api-key admin:87zH26nbqT --skip-duplicate --configfile "$(MSBuildThisFileDirectory)../NuGet.config"</PushCommand>
</PropertyGroup> </PropertyGroup>
<Exec Command="$(PushCommand)" /> <Exec Command="$(PushCommand)" WorkingDirectory="$(MSBuildThisFileDirectory)" />
</Target> </Target>
</Project> </Project>
@@ -166,7 +166,7 @@ message GetAllCategoriesForCustomerRequest {
message GetAllCategoriesForCustomerResponse { message GetAllCategoriesForCustomerResponse {
messages.MetaData meta_data = 1; messages.MetaData meta_data = 1;
repeated GetAllCategoryFilterResponseModel categories = 2; repeated GetAllCategoryFilterResponseModel models = 2;
} }
message GetCategoryByIdForCustomerRequest { message GetCategoryByIdForCustomerRequest {
@@ -116,6 +116,8 @@ message GetClubMembershipResponse
bool is_active = 8; bool is_active = 8;
google.protobuf.Timestamp created = 9; google.protobuf.Timestamp created = 9;
repeated MembershipFeatureModel features = 10; repeated MembershipFeatureModel features = 10;
string status = 11; // Trial/Active/Expired/Inactive - for frontend compatibility
int32 days_remaining = 12; // Days until expiration - calculated field
} }
message MembershipFeatureModel message MembershipFeatureModel
@@ -118,6 +118,19 @@ service CommissionContract
}; };
}; };
// Customer-facing APIs
rpc GetMyCommissionPayouts(GetMyCommissionPayoutsRequest) returns (GetMyCommissionPayoutsResponse){
option (google.api.http) = {
get: "/Commission/Customer/MyPayouts"
};
};
rpc GetMyWeeklyBalances(GetMyWeeklyBalancesRequest) returns (GetMyWeeklyBalancesResponse){
option (google.api.http) = {
get: "/Commission/Customer/MyWeeklyBalances"
};
};
// Financial Reports // Financial Reports
rpc GetWithdrawalReports(GetWithdrawalReportsRequest) returns (GetWithdrawalReportsResponse){ rpc GetWithdrawalReports(GetWithdrawalReportsRequest) returns (GetWithdrawalReportsResponse){
option (google.api.http) = { option (google.api.http) = {
@@ -525,6 +538,14 @@ message GetWeekDefinitionsRequest
google.protobuf.StringValue sort_by = 2; google.protobuf.StringValue sort_by = 2;
//فیلتر //فیلتر
GetWeekDefinitionsFilter filter = 3; GetWeekDefinitionsFilter filter = 3;
// Frontend compatibility fields (aliases)
int32 page_number = 20;
int32 page_size = 21;
string search_text = 22;
google.protobuf.Int32Value gregorian_year = 23;
google.protobuf.Int32Value persian_year = 24;
google.protobuf.BoolValue is_active = 25;
} }
message GetWeekDefinitionsFilter message GetWeekDefinitionsFilter
@@ -564,4 +585,77 @@ message WeekDefinitionItem
int32 persian_year = 9; int32 persian_year = 9;
bool is_active = 10; bool is_active = 10;
bool is_current_week = 11; bool is_current_week = 11;
string start_date_persian = 12; // Frontend expects Persian date string
string end_date_persian = 13; // Frontend expects Persian date string
}
// ============ Customer APIs ============
// GetMyCommissionPayouts - for frontend customer display
message GetMyCommissionPayoutsRequest
{
int32 page_number = 1;
int32 page_size = 2;
google.protobuf.Int64Value week_definition_id = 3;
google.protobuf.Int32Value status = 4; // 0=Pending, 1=Calculated, 2=Paid, 3=Withdrawn
}
message GetMyCommissionPayoutsResponse
{
CustomerMetaData meta_data = 1;
repeated CustomerCommissionPayoutModel payouts = 2;
}
message CustomerMetaData
{
int64 total_count = 1;
}
message CustomerCommissionPayoutModel
{
int64 id = 1;
int64 week_definition_id = 2;
string week_display_name = 3;
int32 balances_earned = 4;
int64 total_amount = 5;
string amount_formatted = 6;
int32 status = 7; // 0=Pending, 1=Paid, 2=WithdrawRequested, 3=Withdrawn, 4=PaymentFailed, 5=Cancelled
google.protobuf.Timestamp calculated_date = 8;
string date_persian = 9;
}
// GetMyWeeklyBalances - for frontend customer display
message GetMyWeeklyBalancesRequest
{
int32 page_number = 1;
int32 page_size = 2;
google.protobuf.Int64Value week_definition_id = 3;
bool only_active = 4;
}
message GetMyWeeklyBalancesResponse
{
CustomerMetaData meta_data = 1;
repeated CustomerWeeklyBalanceModel balances = 2;
int32 total_left_balances = 3;
int32 total_right_balances = 4;
string weaker_leg = 5;
}
message CustomerWeeklyBalanceModel
{
int64 id = 1;
int64 week_definition_id = 2;
string week_display_name = 3;
int32 left_leg_balances = 4;
int32 right_leg_balances = 5;
int32 total_balances = 6;
int64 weekly_pool_contribution = 7;
bool is_expired = 8;
google.protobuf.Timestamp calculated_at = 9;
string date_persian = 10;
int32 left_leg_carryover = 11;
int32 right_leg_carryover = 12;
int32 left_leg_new_members = 13;
int32 right_leg_new_members = 14;
} }
@@ -39,6 +39,19 @@ service ConfigurationContract
get: "/Configuration/GetHistory" get: "/Configuration/GetHistory"
}; };
}; };
// Customer-facing APIs
rpc GetClubConfiguration(google.protobuf.Empty) returns (GetClubConfigurationResponse){
option (google.api.http) = {
get: "/Configuration/Customer/Club"
};
};
rpc GetClubFeatures(google.protobuf.Empty) returns (GetClubFeaturesResponse){
option (google.api.http) = {
get: "/Configuration/Customer/ClubFeatures"
};
};
} }
// CreateOrUpdate Command // CreateOrUpdate Command
@@ -138,3 +151,30 @@ message ConfigurationHistoryModel
string reason = 11; string reason = 11;
google.protobuf.Timestamp created = 12; google.protobuf.Timestamp created = 12;
} }
// ============ Customer APIs ============
// GetClubConfiguration - for frontend customer display
message GetClubConfigurationResponse
{
int64 activation_fee = 1;
int64 membership_gift_value = 2;
}
// GetClubFeatures - for frontend customer display
message GetClubFeaturesResponse
{
repeated ClubFeatureModel features = 1;
}
message ClubFeatureModel
{
int64 id = 1;
string title = 2;
string description = 3;
bool is_enabled = 4;
int32 display_order = 5;
google.protobuf.Timestamp granted_at = 6;
google.protobuf.Timestamp created_at = 7;
string notes = 8;
}
@@ -50,6 +50,25 @@ service NetworkMembershipContract
get: "/NetworkMembership/GetStatistics" get: "/NetworkMembership/GetStatistics"
}; };
}; };
// Customer-facing APIs
rpc GetMyNetworkTree(GetMyNetworkTreeRequest) returns (GetMyNetworkTreeResponse){
option (google.api.http) = {
get: "/NetworkMembership/Customer/MyTree"
};
};
rpc GetSubordinateTree(GetSubordinateTreeRequest) returns (GetMyNetworkTreeResponse){
option (google.api.http) = {
get: "/NetworkMembership/Customer/SubordinateTree/{target_user_id}"
};
};
rpc GetMyNetworkStatistics(google.protobuf.Empty) returns (GetMyNetworkStatisticsResponse){
option (google.api.http) = {
get: "/NetworkMembership/Customer/MyStats"
};
};
} }
// JoinNetwork Command // JoinNetwork Command
@@ -168,9 +187,11 @@ message NetworkTreeNodeModel
{ {
int64 user_id = 1; int64 user_id = 1;
string user_name = 2; string user_name = 2;
string full_name = 20; // Alias for frontend compatibility
google.protobuf.Int64Value parent_id = 3; google.protobuf.Int64Value parent_id = 3;
int32 network_leg = 4; int32 network_leg = 4;
int32 network_level = 5; int32 network_level = 5;
int32 level = 21; // Alias for frontend compatibility
bool is_active = 6; bool is_active = 6;
google.protobuf.Timestamp joined_at = 7; google.protobuf.Timestamp joined_at = 7;
google.protobuf.Timestamp club_activated_at = 8; // تاریخ فعال‌سازی در باشگاه google.protobuf.Timestamp club_activated_at = 8; // تاریخ فعال‌سازی در باشگاه
@@ -179,6 +200,11 @@ message NetworkTreeNodeModel
bool is_activated_in_target_week = 11; // آیا در هفته هدف فعال شده bool is_activated_in_target_week = 11; // آیا در هفته هدف فعال شده
google.protobuf.Timestamp user_created = 12; // تاریخ ایجاد کاربر google.protobuf.Timestamp user_created = 12; // تاریخ ایجاد کاربر
string referral_code = 13; // کد معرف کاربر string referral_code = 13; // کد معرف کاربر
string mobile = 14; // Mobile number for display
google.protobuf.StringValue avatar = 15; // Avatar path
string position = 16; // Root/Left/Right position indicator
NetworkTreeNodeModel left_child = 17; // Left child node
NetworkTreeNodeModel right_child = 18; // Right child node
} }
// GetHistory Query // GetHistory Query
@@ -254,3 +280,51 @@ message TopNetworkUser
int32 left_count = 5; int32 left_count = 5;
int32 right_count = 6; int32 right_count = 6;
} }
// ============ Customer APIs ============
// GetMyNetworkTree - for frontend customer display
message GetMyNetworkTreeRequest
{
int32 max_depth = 1; // Default: 3
}
// GetSubordinateTree - for frontend customer display
message GetSubordinateTreeRequest
{
int64 target_user_id = 1;
int32 max_depth = 2; // Default: 3
}
message GetMyNetworkTreeResponse
{
NetworkTreeNodeModel root_node = 1;
int32 total_members = 2;
int32 current_depth = 3;
}
// GetMyNetworkStatistics - for frontend customer display
message GetMyNetworkStatisticsResponse
{
int32 total_members = 1;
int32 active_members = 2;
int32 left_leg_count = 3;
int32 right_leg_count = 4;
double left_percentage = 5;
double right_percentage = 6;
double average_depth = 7;
int32 max_depth = 8;
string weaker_leg = 9;
int32 my_network_level = 10;
string my_network_leg = 11;
string my_referral_code = 12;
CustomerLastMemberModel last_member = 13;
}
message CustomerLastMemberModel
{
int64 user_id = 1;
string full_name = 2;
string position = 3;
int32 total_children = 4;
}
@@ -226,6 +226,7 @@ message GetUserPackageStatusResponse
message InitiateBasePackagePaymentRequest message InitiateBasePackagePaymentRequest
{ {
int64 user_id = 1; int64 user_id = 1;
string callback_url = 2; // Payment gateway callback URL
} }
message InitiateBasePackagePaymentResponse message InitiateBasePackagePaymentResponse
@@ -235,6 +236,7 @@ message InitiateBasePackagePaymentResponse
int64 order_id = 3; int64 order_id = 3;
int64 transaction_id = 4; int64 transaction_id = 4;
int64 amount = 5; int64 amount = 5;
string payment_gateway_url = 6;
} }
message VerifyBasePackagePaymentRequest message VerifyBasePackagePaymentRequest
@@ -267,7 +269,7 @@ message GetCustomerPackagesRequest
message GetCustomerPackagesResponse message GetCustomerPackagesResponse
{ {
repeated CustomerPackageModel packages = 1; repeated CustomerPackageModel models = 1;
} }
message GetCustomerPackageDetailsRequest message GetCustomerPackageDetailsRequest
@@ -277,9 +279,13 @@ message GetCustomerPackageDetailsRequest
message GetCustomerPackageDetailsResponse message GetCustomerPackageDetailsResponse
{ {
CustomerPackageModel package = 1; int64 id = 1;
repeated PackageFeature features = 2; string title = 2;
PurchaseRequirements requirements = 3; string description = 3;
int64 price = 4;
google.protobuf.StringValue image_path = 5;
repeated PackageFeature features = 6;
PurchaseRequirements requirements = 7;
} }
message CustomerPurchasePackageRequest message CustomerPurchasePackageRequest
@@ -342,6 +348,8 @@ message CustomerPackageModel
int32 validity_days = 9; int32 validity_days = 9;
bool is_popular = 10; bool is_popular = 10;
string short_description = 11; string short_description = 11;
string title = 12; // Alias for frontend compatibility (uses name)
string image_path = 13; // Alias for frontend compatibility (uses image_url)
} }
message PackageFeature message PackageFeature
@@ -331,6 +331,7 @@ message GetUserForCustomerResponse
bool sms_notifications = 13; bool sms_notifications = 13;
bool push_notifications = 14; bool push_notifications = 14;
google.protobuf.Timestamp birth_date = 15; google.protobuf.Timestamp birth_date = 15;
string token = 16; // JWT token for authentication refresh
} }
// ============= Customer Profile Messages ============= // ============= Customer Profile Messages =============
@@ -85,6 +85,7 @@ message AddNewUserCartResponse
message UpdateUserCartRequest message UpdateUserCartRequest
{ {
int64 id = 1; int64 id = 1;
int64 user_cart_id = 11; // Alias for frontend compatibility
int32 count = 2; int32 count = 2;
} }
message DeleteUserCartRequest message DeleteUserCartRequest
@@ -145,7 +146,7 @@ message GetUserCartForCustomerRequest
} }
message GetUserCartForCustomerResponse message GetUserCartForCustomerResponse
{ {
repeated UserCartItem items = 1; repeated UserCartItem models = 1;
int64 total_price = 2; int64 total_price = 2;
int32 total_items_count = 3; int32 total_items_count = 3;
string message = 4; string message = 4;
@@ -156,11 +157,13 @@ message UserCartItem
int64 product_id = 2; int64 product_id = 2;
string product_title = 3; string product_title = 3;
string product_short_information = 4; string product_short_information = 4;
string product_short_infomation = 14; // Alias for typo compatibility
int64 product_price = 5; int64 product_price = 5;
int32 product_discount = 6; int32 product_discount = 6;
string product_thumbnail_path = 7; string product_thumbnail_path = 7;
int32 count = 8; int32 count = 8;
int64 total_item_price = 9; int64 total_item_price = 9;
google.protobuf.Timestamp created = 10; // Creation timestamp for frontend
} }
message GetAllUserCartsByFilterRequest message GetAllUserCartsByFilterRequest
{ {
@@ -128,6 +128,12 @@ service UserOrderContract
body: "*" body: "*"
}; };
}; };
rpc GetVATRate(google.protobuf.Empty) returns (GetVATRateResponse){
option (google.api.http) = {
get: "/Customer/GetVATRate"
};
};
} }
message CreateNewUserOrderRequest message CreateNewUserOrderRequest
{ {
@@ -526,3 +532,11 @@ message ProductPVDto
int64 unit_pv = 4; int64 unit_pv = 4;
int64 total_pv = 5; int64 total_pv = 5;
} }
// GetVATRate - for frontend customer display
message GetVATRateResponse
{
double vat_rate = 1;
int32 vat_percentage = 2;
bool is_enabled = 3;
}
@@ -81,12 +81,14 @@ public class PackageService : PackageContract.PackageContractBase
{ {
Id = 1, Id = 1,
Name = "پکیج طلایی", Name = "پکیج طلایی",
Title = "پکیج طلایی", // Populate alias field
Description = "پکیج کامل با امکانات ویژه برای کاربران فعال", Description = "پکیج کامل با امکانات ویژه برای کاربران فعال",
Price = 5600000, Price = 5600000,
Currency = "IRR", Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypeGolden, PackageType = PackageTypeEnum.PackageTypeGolden,
IsAvailable = true, IsAvailable = true,
ImageUrl = "/images/packages/golden.jpg", ImageUrl = "/images/packages/golden.jpg",
ImagePath = "/images/packages/golden.jpg", // Populate alias field
ValidityDays = 365, ValidityDays = 365,
IsPopular = true, IsPopular = true,
ShortDescription = "بهترین انتخاب برای درآمد بیشتر" ShortDescription = "بهترین انتخاب برای درآمد بیشتر"
@@ -95,12 +97,14 @@ public class PackageService : PackageContract.PackageContractBase
{ {
Id = 2, Id = 2,
Name = "پکیج پریمیوم", Name = "پکیج پریمیوم",
Title = "پکیج پریمیوم", // Populate alias field
Description = "پکیج پیشرفته با امکانات حرفه‌ای", Description = "پکیج پیشرفته با امکانات حرفه‌ای",
Price = 3200000, Price = 3200000,
Currency = "IRR", Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypePremium, PackageType = PackageTypeEnum.PackageTypePremium,
IsAvailable = true, IsAvailable = true,
ImageUrl = "/images/packages/premium.jpg", ImageUrl = "/images/packages/premium.jpg",
ImagePath = "/images/packages/premium.jpg", // Populate alias field
ValidityDays = 180, ValidityDays = 180,
IsPopular = false, IsPopular = false,
ShortDescription = "برای کسب و کارهای متوسط" ShortDescription = "برای کسب و کارهای متوسط"
@@ -109,12 +113,14 @@ public class PackageService : PackageContract.PackageContractBase
{ {
Id = 3, Id = 3,
Name = "پکیج ابتدایی", Name = "پکیج ابتدایی",
Title = "پکیج ابتدایی", // Populate alias field
Description = "پکیج مقدماتی برای شروع کار", Description = "پکیج مقدماتی برای شروع کار",
Price = 1500000, Price = 1500000,
Currency = "IRR", Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypeBasic, PackageType = PackageTypeEnum.PackageTypeBasic,
IsAvailable = true, IsAvailable = true,
ImageUrl = "/images/packages/basic.jpg", ImageUrl = "/images/packages/basic.jpg",
ImagePath = "/images/packages/basic.jpg", // Populate alias field
ValidityDays = 90, ValidityDays = 90,
IsPopular = false, IsPopular = false,
ShortDescription = "مناسب برای شروع کننده‌ها" ShortDescription = "مناسب برای شروع کننده‌ها"
@@ -161,12 +167,14 @@ public class PackageService : PackageContract.PackageContractBase
{ {
Id = request.PackageId, Id = request.PackageId,
Name = "پکیج طلایی", Name = "پکیج طلایی",
Title = "پکیج طلایی", // Populate alias field
Description = "پکیج کامل با تمام امکانات برای کاربران حرفه‌ای", Description = "پکیج کامل با تمام امکانات برای کاربران حرفه‌ای",
Price = 5600000, Price = 5600000,
Currency = "IRR", Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypeGolden, PackageType = PackageTypeEnum.PackageTypeGolden,
IsAvailable = true, IsAvailable = true,
ImageUrl = "/images/packages/golden-detail.jpg", ImageUrl = "/images/packages/golden-detail.jpg",
ImagePath = "/images/packages/golden-detail.jpg", // Populate alias field
ValidityDays = 365, ValidityDays = 365,
IsPopular = true, IsPopular = true,
ShortDescription = "بهترین انتخاب برای کسب درآمد حداکثری" ShortDescription = "بهترین انتخاب برای کسب درآمد حداکثری"
+5
View File
@@ -4,11 +4,16 @@
<clear /> <clear />
<!-- Nexus (hosts FourSat packages + proxies nuget.org) --> <!-- Nexus (hosts FourSat packages + proxies nuget.org) -->
<add key="Nexus" value="http://194.5.195.53:32081/repository/nuget-all/index.json" allowInsecureConnections="true" /> <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> </packageSources>
<packageSourceCredentials> <packageSourceCredentials>
<Nexus> <Nexus>
<add key="Username" value="admin" /> <add key="Username" value="admin" />
<add key="ClearTextPassword" value="87zH26nbqT" /> <add key="ClearTextPassword" value="87zH26nbqT" />
</Nexus> </Nexus>
<foursat-hosted>
<add key="Username" value="admin" />
<add key="ClearTextPassword" value="87zH26nbqT" />
</foursat-hosted>
</packageSourceCredentials> </packageSourceCredentials>
</configuration> </configuration>