From ead0cf423554744d622a29df69528a0c6224162d Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Thu, 18 Dec 2025 00:43:55 +0330 Subject: [PATCH] feat: add geography entities with countries, states and cities --- .../CMSMicroservice.Application.csproj | 1 + .../GetAllCitiesByFilterQuery.cs | 42 + .../GetAllCitiesByFilterQueryHandler.cs | 43 + .../GetAllCitiesByFilterQueryValidator.cs | 20 + .../GetAllCitiesByFilterResponseDto.cs | 62 + .../AcceptClubMembershipContractCommand.cs | 48 + ...eptClubMembershipContractCommandHandler.cs | 196 + ...tClubMembershipContractCommandValidator.cs | 25 + .../Interfaces/IApplicationDbContext.cs | 6 + .../Interfaces/ITokenNotificationService.cs | 26 + .../Profiles/CityProfile.cs | 22 + .../RefreshToken/RefreshTokenCommand.cs | 14 + .../RefreshTokenCommandHandler.cs | 82 + .../RefreshToken/RefreshTokenResponseDto.cs | 22 + .../UpdateUserEventHandler.cs | 16 +- .../Entities/Geography/City.cs | 49 + .../Entities/Geography/Country.cs | 109 + .../Entities/Geography/State.cs | 64 + .../Enums/ContractType.cs | 4 +- .../Persistence/ApplicationDbContext.cs | 7 +- .../Geography/CityConfiguration.cs | 55 + .../Geography/CountryConfiguration.cs | 99 + .../Geography/StateConfiguration.cs | 68 + ...216190010_AddGeographyEntities.Designer.cs | 3523 +++++++++++++++++ .../20251216190010_AddGeographyEntities.cs | 146 + .../ApplicationDbContextModelSnapshot.cs | 282 ++ .../CMSMicroservice.Protobuf.csproj | 2 + .../Protos/city.proto | 54 + .../Protos/clubmembership.proto | 24 + .../Protos/user.proto | 16 + .../CMSMicroservice.WebApi.csproj | 1 + .../Common/Mappings/CityProfile.cs | 40 + .../Common/Mappings/ClubFeatureProfile.cs | 14 + .../Services/TokenNotificationService.cs | 115 + .../ConfigureServices.cs | 5 + .../Hubs/TokenNotificationHub.cs | 50 + src/CMSMicroservice.WebApi/Program.cs | 5 + .../Services/CityService.cs | 25 + .../Services/ClubMembershipService.cs | 6 + .../Services/UserService.cs | 5 + 40 files changed, 5386 insertions(+), 7 deletions(-) create mode 100644 src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQuery.cs create mode 100644 src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryHandler.cs create mode 100644 src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryValidator.cs create mode 100644 src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterResponseDto.cs create mode 100644 src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommand.cs create mode 100644 src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandHandler.cs create mode 100644 src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandValidator.cs create mode 100644 src/CMSMicroservice.Application/Common/Interfaces/ITokenNotificationService.cs create mode 100644 src/CMSMicroservice.Application/Profiles/CityProfile.cs create mode 100644 src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommand.cs create mode 100644 src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommandHandler.cs create mode 100644 src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenResponseDto.cs create mode 100644 src/CMSMicroservice.Domain/Entities/Geography/City.cs create mode 100644 src/CMSMicroservice.Domain/Entities/Geography/Country.cs create mode 100644 src/CMSMicroservice.Domain/Entities/Geography/State.cs create mode 100644 src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CityConfiguration.cs create mode 100644 src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CountryConfiguration.cs create mode 100644 src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/StateConfiguration.cs create mode 100644 src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.Designer.cs create mode 100644 src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.cs create mode 100644 src/CMSMicroservice.Protobuf/Protos/city.proto create mode 100644 src/CMSMicroservice.WebApi/Common/Mappings/CityProfile.cs create mode 100644 src/CMSMicroservice.WebApi/Common/Services/TokenNotificationService.cs create mode 100644 src/CMSMicroservice.WebApi/Hubs/TokenNotificationHub.cs create mode 100644 src/CMSMicroservice.WebApi/Services/CityService.cs diff --git a/src/CMSMicroservice.Application/CMSMicroservice.Application.csproj b/src/CMSMicroservice.Application/CMSMicroservice.Application.csproj index c335a84..af74491 100644 --- a/src/CMSMicroservice.Application/CMSMicroservice.Application.csproj +++ b/src/CMSMicroservice.Application/CMSMicroservice.Application.csproj @@ -12,6 +12,7 @@ + diff --git a/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQuery.cs b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQuery.cs new file mode 100644 index 0000000..ebfe8e4 --- /dev/null +++ b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQuery.cs @@ -0,0 +1,42 @@ +namespace CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; + +public record GetAllCitiesByFilterQuery : IRequest +{ + /// + /// موقعیت صفحه بندی + /// + public PaginationState? PaginationState { get; init; } + + /// + /// مرتب سازی بر اساس + /// + public string? SortBy { get; init; } + + /// + /// فیلتر + /// + public GetAllCitiesByFilterFilter? Filter { get; init; } +} + +public class GetAllCitiesByFilterFilter +{ + /// + /// شناسه + /// + public long? Id { get; set; } + + /// + /// نام شهر (Contains) + /// + public string? Name { get; set; } + + /// + /// نام بومی شهر (Contains) + /// + public string? Native { get; set; } + + /// + /// شناسه استان + /// + public long? StateId { get; set; } +} diff --git a/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryHandler.cs b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryHandler.cs new file mode 100644 index 0000000..cd677f1 --- /dev/null +++ b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryHandler.cs @@ -0,0 +1,43 @@ +using CMSMicroservice.Application.Common.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; + +public class GetAllCitiesByFilterQueryHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + + public GetAllCitiesByFilterQueryHandler(IApplicationDbContext context) + { + _context = context; + } + + public async Task Handle( + GetAllCitiesByFilterQuery request, + CancellationToken cancellationToken) + { + var query = _context.Cities + .Include(c => c.State) + .ApplyOrder(sortBy: request.SortBy) + .AsNoTracking() + .AsQueryable(); + + if (request.Filter is not null) + { + query = query + .Where(x => request.Filter.Id == null || x.Id == request.Filter.Id) + .Where(x => request.Filter.Name == null || x.Name.Contains(request.Filter.Name)) + .Where(x => request.Filter.Native == null || x.Native.Contains(request.Filter.Native)) + .Where(x => request.Filter.StateId == null || x.StateId == request.Filter.StateId); + } + + return new GetAllCitiesByFilterResponseDto + { + MetaData = await query.GetMetaData(request.PaginationState, cancellationToken), + Models = await query + .PaginatedListAsync(paginationState: request.PaginationState) + .ProjectToType() + .ToListAsync(cancellationToken) + }; + } +} diff --git a/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryValidator.cs b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryValidator.cs new file mode 100644 index 0000000..b2ed06a --- /dev/null +++ b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterQueryValidator.cs @@ -0,0 +1,20 @@ +using FluentValidation; + +namespace CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; + +public class GetAllCitiesByFilterQueryValidator : AbstractValidator +{ + public GetAllCitiesByFilterQueryValidator() + { + // Validation rules اگر نیاز باشد + } + + public async Task Validate(object model, string propertyName) + { + var result = await ValidateAsync( + ValidationContext.CreateWithOptions( + (GetAllCitiesByFilterQuery)model, + x => x.IncludeProperties(propertyName))); + return result.IsValid; + } +} diff --git a/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterResponseDto.cs b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterResponseDto.cs new file mode 100644 index 0000000..ba2b553 --- /dev/null +++ b/src/CMSMicroservice.Application/CityCQ/Queries/GetAllCitiesByFilter/GetAllCitiesByFilterResponseDto.cs @@ -0,0 +1,62 @@ +namespace CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; + +public class GetAllCitiesByFilterResponseDto +{ + /// + /// متادیتا + /// + public MetaData MetaData { get; set; } = null!; + + /// + /// مدل خروجی + /// + public List? Models { get; set; } +} + +public class GetAllCitiesByFilterResponseModel +{ + /// + /// شناسه + /// + public long Id { get; set; } + + /// + /// شناسه خارجی + /// + public long ExternalId { get; set; } + + /// + /// نام شهر + /// + public string Name { get; set; } = null!; + + /// + /// نام بومی شهر (فارسی) + /// + public string Native { get; set; } = null!; + + /// + /// عرض جغرافیایی + /// + public string Latitude { get; set; } = null!; + + /// + /// طول جغرافیایی + /// + public string Longitude { get; set; } = null!; + + /// + /// شناسه استان + /// + public long StateId { get; set; } + + /// + /// نام استان + /// + public string StateName { get; set; } = null!; + + /// + /// نام بومی استان + /// + public string StateNative { get; set; } = null!; +} diff --git a/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommand.cs b/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommand.cs new file mode 100644 index 0000000..2187728 --- /dev/null +++ b/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommand.cs @@ -0,0 +1,48 @@ +namespace CMSMicroservice.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract; + +/// +/// Command برای پذیرش قرارداد باشگاه مشتریان +/// +public record AcceptClubMembershipContractCommand : IRequest +{ + /// + /// شناسه کاربر + /// + public long UserId { get; init; } + + /// + /// کد OTP برای تایید + /// + public string OtpCode { get; init; } + + /// + /// شناسه یکتای امضا (GUID) + /// + public string SignGuid { get; init; } + + /// + /// محتوای HTML قرارداد + /// + public string ContractHtml { get; init; } +} + +/// +/// DTO پاسخ پذیرش قرارداد باشگاه مشتریان +/// +public class AcceptClubMembershipContractResponseDto +{ + /// + /// آیا عملیات موفق بود؟ + /// + public bool Success { get; set; } + + /// + /// پیام نتیجه + /// + public string Message { get; set; } + + /// + /// شناسه قرارداد ثبت شده + /// + public long ContractId { get; set; } +} diff --git a/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandHandler.cs b/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandHandler.cs new file mode 100644 index 0000000..16f0f1e --- /dev/null +++ b/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandHandler.cs @@ -0,0 +1,196 @@ +using CMSMicroservice.Application.Common.Exceptions; +using CMSMicroservice.Domain.Entities; +using CMSMicroservice.Domain.Enums; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace CMSMicroservice.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract; + +/// +/// Handler برای پذیرش قرارداد باشگاه مشتریان +/// این handler: +/// 1. کد OTP را تایید می‌کند +/// 2. قرارداد را در جدول UserContract ثبت می‌کند +/// 3. باشگاه مشتری را فعال می‌کند (IsActive = true) +/// +public class AcceptClubMembershipContractCommandHandler + : IRequestHandler +{ + private readonly IApplicationDbContext _context; + private readonly IConfiguration _cfg; + private readonly IHashService _hashService; + private readonly ILogger _logger; + + private const int MaxAttempts = 5; + private const string OtpPurpose = "signClubContract"; + + public AcceptClubMembershipContractCommandHandler( + IApplicationDbContext context, + IConfiguration cfg, + IHashService hashService, + ILogger logger) + { + _context = context; + _cfg = cfg; + _hashService = hashService; + _logger = logger; + } + + public async Task Handle( + AcceptClubMembershipContractCommand request, + CancellationToken cancellationToken) + { + _logger.LogInformation( + "Processing club membership contract for UserId: {UserId}", + request.UserId + ); + + // 1. دریافت کاربر + var user = await _context.Users + .Include(u => u.ClubMembership) + .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken); + + if (user == null) + { + _logger.LogWarning("User not found: {UserId}", request.UserId); + throw new NotFoundException(nameof(User), request.UserId); + } + + // 2. بررسی خرید پکیج + if (user.PackagePurchaseMethod == PackagePurchaseMethod.None) + { + return new AcceptClubMembershipContractResponseDto + { + Success = false, + Message = "برای امضای قرارداد باشگاه مشتریان ابتدا باید پکیج پایه را خریداری کنید" + }; + } + + // 3. بررسی عدم فعال بودن قبلی باشگاه + if (user.ClubMembership?.IsActive == true) + { + return new AcceptClubMembershipContractResponseDto + { + Success = false, + Message = "شما قبلاً عضو باشگاه مشتریان شده‌اید" + }; + } + + // 4. تایید OTP + var otpResult = await VerifyOtpAsync(user.Mobile, request.OtpCode, cancellationToken); + if (!otpResult.Success) + { + return new AcceptClubMembershipContractResponseDto + { + Success = false, + Message = otpResult.Message + }; + } + + // 5. ثبت قرارداد در جدول UserContract + var contract = await _context.Contracts + .FirstOrDefaultAsync(c => c.Type == ContractType.ClubMembership, cancellationToken); + + if (contract == null) + { + // اگر قرارداد وجود ندارد، یک قرارداد پیش‌فرض ایجاد کنید + contract = new Contract + { + Title = "قرارداد باشگاه مشتریان", + Description = "قوانین و مقررات باشگاه مشتریان کارابازار", + HtmlContent = request.ContractHtml, + Type = ContractType.ClubMembership + }; + await _context.Contracts.AddAsync(contract, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + } + + var userContract = new UserContract + { + UserId = user.Id, + ContractId = contract.Id, + SignGuid = request.SignGuid, + SignedPdfFile = request.ContractHtml + }; + await _context.UserContracts.AddAsync(userContract, cancellationToken); + + // 6. فعال‌سازی باشگاه مشتریان + if (user.ClubMembership == null) + { + user.ClubMembership = new Domain.Entities.Club.ClubMembership + { + UserId = user.Id, + IsActive = true, + ActivatedAt = DateTime.Now, + InitialContribution = 56_000_000, + GiftValue = 25_200_000, + PurchaseMethod = user.PackagePurchaseMethod + }; + await _context.ClubMemberships.AddAsync(user.ClubMembership, cancellationToken); + } + else + { + user.ClubMembership.IsActive = true; + user.ClubMembership.ActivatedAt = DateTime.Now; + _context.ClubMemberships.Update(user.ClubMembership); + } + + await _context.SaveChangesAsync(cancellationToken); + + _logger.LogInformation( + "Club membership contract accepted and activated for UserId: {UserId}, ContractId: {ContractId}", + request.UserId, + userContract.Id + ); + + return new AcceptClubMembershipContractResponseDto + { + Success = true, + Message = "قرارداد باشگاه مشتریان با موفقیت ثبت شد و عضویت شما فعال گردید", + ContractId = userContract.Id + }; + } + + private async Task<(bool Success, string Message)> VerifyOtpAsync( + string mobile, + string code, + CancellationToken cancellationToken) + { + var normalizedMobile = mobile.NormalizeIranMobile(); + var now = DateTime.Now; + + var otp = await _context.OtpTokens + .Where(o => o.Mobile == normalizedMobile + && o.Purpose == OtpPurpose + && !o.IsUsed + && o.ExpiresAt > now) + .OrderByDescending(o => o.Created) + .FirstOrDefaultAsync(cancellationToken); + + if (otp == null) + { + return (false, "کد تایید پیدا نشد یا منقضی شده است"); + } + + if (otp.Attempts >= MaxAttempts) + { + return (false, "تعداد تلاش‌ها بیش از حد مجاز است. لطفاً کد جدید دریافت کنید"); + } + + otp.Attempts++; + + var secret = _cfg["Otp:Secret"] ?? throw new InvalidOperationException("Otp:Secret not configured"); + + if (!_hashService.VerifyHmacSha256Hex(code, otp.CodeHash, secret)) + { + await _context.SaveChangesAsync(cancellationToken); + return (false, "کد تایید نادرست است"); + } + + // کد صحیح است - علامت‌گذاری به عنوان استفاده شده + otp.IsUsed = true; + await _context.SaveChangesAsync(cancellationToken); + + return (true, "کد تایید صحیح است"); + } +} diff --git a/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandValidator.cs b/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandValidator.cs new file mode 100644 index 0000000..8c5f308 --- /dev/null +++ b/src/CMSMicroservice.Application/ClubMembershipCQ/Commands/AcceptClubMembershipContract/AcceptClubMembershipContractCommandValidator.cs @@ -0,0 +1,25 @@ +namespace CMSMicroservice.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract; + +public class AcceptClubMembershipContractCommandValidator : AbstractValidator +{ + public AcceptClubMembershipContractCommandValidator() + { + RuleFor(x => x.UserId) + .GreaterThan(0) + .WithMessage("شناسه کاربر الزامی است"); + + RuleFor(x => x.OtpCode) + .NotEmpty() + .WithMessage("کد تایید الزامی است") + .Length(6) + .WithMessage("کد تایید باید ۶ رقم باشد"); + + RuleFor(x => x.SignGuid) + .NotEmpty() + .WithMessage("شناسه امضا الزامی است"); + + RuleFor(x => x.ContractHtml) + .NotEmpty() + .WithMessage("محتوای قرارداد الزامی است"); + } +} diff --git a/src/CMSMicroservice.Application/Common/Interfaces/IApplicationDbContext.cs b/src/CMSMicroservice.Application/Common/Interfaces/IApplicationDbContext.cs index 0677b7d..7b85fa8 100644 --- a/src/CMSMicroservice.Application/Common/Interfaces/IApplicationDbContext.cs +++ b/src/CMSMicroservice.Application/Common/Interfaces/IApplicationDbContext.cs @@ -1,6 +1,7 @@ using CMSMicroservice.Domain.Entities.Payment; using CMSMicroservice.Domain.Entities.Order; using CMSMicroservice.Domain.Entities.DiscountShop; +using CMSMicroservice.Domain.Entities.Geography; namespace CMSMicroservice.Application.Common.Interfaces; @@ -53,5 +54,10 @@ public interface IApplicationDbContext DbSet DiscountOrders { get; } DbSet DiscountOrderDetails { get; } + // ============= Geography ============= + DbSet Countries { get; } + DbSet States { get; } + DbSet Cities { get; } + Task SaveChangesAsync(CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/CMSMicroservice.Application/Common/Interfaces/ITokenNotificationService.cs b/src/CMSMicroservice.Application/Common/Interfaces/ITokenNotificationService.cs new file mode 100644 index 0000000..08770e0 --- /dev/null +++ b/src/CMSMicroservice.Application/Common/Interfaces/ITokenNotificationService.cs @@ -0,0 +1,26 @@ +namespace CMSMicroservice.Application.Common.Interfaces; + +/// +/// Interface for sending token-related notifications via SignalR +/// +public interface ITokenNotificationService +{ + /// + /// Notify that a user's token has been revoked and they should refresh their token + /// + /// The user ID whose token was revoked + /// The reason for revocation + Task NotifyTokenRevokedAsync(long userId, string reason); + + /// + /// Notify that a user should refresh their token due to profile changes + /// + /// The user ID whose profile changed + Task NotifyForceRefreshAsync(long userId); + + /// + /// Broadcast a message to all connected clients + /// + /// The message to broadcast + Task BroadcastMessageAsync(string message); +} diff --git a/src/CMSMicroservice.Application/Profiles/CityProfile.cs b/src/CMSMicroservice.Application/Profiles/CityProfile.cs new file mode 100644 index 0000000..92cf0a0 --- /dev/null +++ b/src/CMSMicroservice.Application/Profiles/CityProfile.cs @@ -0,0 +1,22 @@ +using CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; +using CMSMicroservice.Domain.Entities.Geography; +using Mapster; + +namespace CMSMicroservice.Application.Profiles; + +public class CityProfile : IRegister +{ + public void Register(TypeAdapterConfig config) + { + config.NewConfig() + .Map(dest => dest.Id, src => src.Id) + .Map(dest => dest.ExternalId, src => src.ExternalId) + .Map(dest => dest.Name, src => src.Name) + .Map(dest => dest.Native, src => src.Native) + .Map(dest => dest.Latitude, src => src.Latitude) + .Map(dest => dest.Longitude, src => src.Longitude) + .Map(dest => dest.StateId, src => src.StateId) + .Map(dest => dest.StateName, src => src.State.Name) + .Map(dest => dest.StateNative, src => src.State.Native); + } +} diff --git a/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommand.cs b/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommand.cs new file mode 100644 index 0000000..af4d0f2 --- /dev/null +++ b/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommand.cs @@ -0,0 +1,14 @@ +using MediatR; + +namespace CMSMicroservice.Application.UserCQ.Commands.RefreshToken; + +/// +/// درخواست رفرش توکن JWT +/// +public sealed record RefreshTokenCommand : IRequest +{ + /// + /// توکن فعلی کاربر + /// + public string CurrentToken { get; init; } = null!; +} diff --git a/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommandHandler.cs b/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommandHandler.cs new file mode 100644 index 0000000..57191e8 --- /dev/null +++ b/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenCommandHandler.cs @@ -0,0 +1,82 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using CMSMicroservice.Application.Common.Interfaces; +using CMSMicroservice.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace CMSMicroservice.Application.UserCQ.Commands.RefreshToken; + +/// +/// هندلر رفرش توکن - توکن جدید با آخرین اطلاعات کاربر تولید می‌کند +/// +public class RefreshTokenCommandHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + private readonly IGenerateJwtToken _generateJwt; + + public RefreshTokenCommandHandler(IApplicationDbContext context, IGenerateJwtToken generateJwt) + { + _context = context; + _generateJwt = generateJwt; + } + + public async Task Handle(RefreshTokenCommand request, CancellationToken cancellationToken) + { + try + { + // Extract user id from current token + var handler = new JwtSecurityTokenHandler(); + var jwtToken = handler.ReadJwtToken(request.CurrentToken); + + var userIdClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier); + if (userIdClaim == null || !long.TryParse(userIdClaim.Value, out var userId)) + { + return new RefreshTokenResponseDto + { + Success = false, + Message = "توکن نامعتبر است", + Token = string.Empty + }; + } + + // Get user with all required relations + var user = await _context.Users + .Include(u => u.UserContracts) + .ThenInclude(u => u.Contract) + .Include(u => u.UserRoles) + .ThenInclude(ur => ur.Role) + .Include(u => u.ClubMembership) + .FirstOrDefaultAsync(x => x.Id == userId, cancellationToken); + + if (user == null) + { + return new RefreshTokenResponseDto + { + Success = false, + Message = "کاربر یافت نشد", + Token = string.Empty + }; + } + + // Generate new token + var newToken = await _generateJwt.GenerateJwtToken(user); + + return new RefreshTokenResponseDto + { + Success = true, + Message = "توکن با موفقیت رفرش شد", + Token = newToken + }; + } + catch (Exception ex) + { + return new RefreshTokenResponseDto + { + Success = false, + Message = $"خطا در رفرش توکن: {ex.Message}", + Token = string.Empty + }; + } + } +} diff --git a/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenResponseDto.cs b/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenResponseDto.cs new file mode 100644 index 0000000..a868eae --- /dev/null +++ b/src/CMSMicroservice.Application/UserCQ/Commands/RefreshToken/RefreshTokenResponseDto.cs @@ -0,0 +1,22 @@ +namespace CMSMicroservice.Application.UserCQ.Commands.RefreshToken; + +/// +/// پاسخ رفرش توکن +/// +public class RefreshTokenResponseDto +{ + /// + /// توکن جدید + /// + public string Token { get; set; } = null!; + + /// + /// آیا عملیات موفق بود؟ + /// + public bool Success { get; set; } + + /// + /// پیام + /// + public string Message { get; set; } = null!; +} diff --git a/src/CMSMicroservice.Application/UserCQ/EventHandlers/UpdateUserEventHandlers/UpdateUserEventHandler.cs b/src/CMSMicroservice.Application/UserCQ/EventHandlers/UpdateUserEventHandlers/UpdateUserEventHandler.cs index 45714ae..cdefea6 100644 --- a/src/CMSMicroservice.Application/UserCQ/EventHandlers/UpdateUserEventHandlers/UpdateUserEventHandler.cs +++ b/src/CMSMicroservice.Application/UserCQ/EventHandlers/UpdateUserEventHandlers/UpdateUserEventHandler.cs @@ -1,3 +1,4 @@ +using CMSMicroservice.Application.Common.Interfaces; using CMSMicroservice.Domain.Events; using Microsoft.Extensions.Logging; @@ -6,16 +7,23 @@ namespace CMSMicroservice.Application.UserCQ.EventHandlers; public class UpdateUserEventHandler : INotificationHandler { private readonly ILogger _logger; + private readonly ITokenNotificationService _tokenNotificationService; - public UpdateUserEventHandler(ILogger logger) + public UpdateUserEventHandler( + ILogger logger, + ITokenNotificationService tokenNotificationService) { _logger = logger; + _tokenNotificationService = tokenNotificationService; } - public Task Handle(UpdateUserEvent notification, CancellationToken cancellationToken) + public async Task Handle(UpdateUserEvent notification, CancellationToken cancellationToken) { - _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name); + _logger.LogInformation("Domain Event: {DomainEvent} for User {UserId}", + notification.GetType().Name, + notification.Item.Id); - return Task.CompletedTask; + // Notify connected clients that user profile has changed and token should be refreshed + await _tokenNotificationService.NotifyForceRefreshAsync(notification.Item.Id); } } diff --git a/src/CMSMicroservice.Domain/Entities/Geography/City.cs b/src/CMSMicroservice.Domain/Entities/Geography/City.cs new file mode 100644 index 0000000..386dbd5 --- /dev/null +++ b/src/CMSMicroservice.Domain/Entities/Geography/City.cs @@ -0,0 +1,49 @@ +using CMSMicroservice.Domain.Common; + +namespace CMSMicroservice.Domain.Entities.Geography; + +/// +/// شهر - City +/// +public class City : BaseAuditableEntity +{ + /// + /// شناسه یکتا + /// + public long Id { get; set; } + + /// + /// شناسه خارجی (External ID) + /// + public long ExternalId { get; set; } + + /// + /// نام شهر + /// + public required string Name { get; set; } + + /// + /// عرض جغرافیایی + /// + public required string Latitude { get; set; } + + /// + /// طول جغرافیایی + /// + public required string Longitude { get; set; } + + /// + /// نام بومی شهر (فارسی یا زبان محلی) + /// + public required string Native { get; set; } + + /// + /// شناسه استان متعلق + /// + public long StateId { get; set; } + + /// + /// استان متعلق + /// + public virtual State State { get; set; } = null!; +} diff --git a/src/CMSMicroservice.Domain/Entities/Geography/Country.cs b/src/CMSMicroservice.Domain/Entities/Geography/Country.cs new file mode 100644 index 0000000..7393371 --- /dev/null +++ b/src/CMSMicroservice.Domain/Entities/Geography/Country.cs @@ -0,0 +1,109 @@ +using CMSMicroservice.Domain.Common; + +namespace CMSMicroservice.Domain.Entities.Geography; + +/// +/// کشور - Country +/// +public class Country : BaseAuditableEntity +{ + /// + /// شناسه یکتا + /// + public long Id { get; set; } + + /// + /// شناسه خارجی (External ID) + /// + public long ExternalId { get; set; } + + /// + /// نام کشور (انگلیسی) + /// + public required string Name { get; set; } + + /// + /// کد ISO3 (3 حرفی) + /// + public required string Iso3 { get; set; } + + /// + /// کد ISO2 (2 حرفی) + /// + public required string Iso2 { get; set; } + + /// + /// کد عددی کشور + /// + public required string NumericCode { get; set; } + + /// + /// کد تلفن کشور (مثلاً 98 برای ایران) + /// + public required string PhoneCode { get; set; } + + /// + /// پایتخت + /// + public required string Capital { get; set; } + + /// + /// واحد پول (کد ارز) + /// + public required string Currency { get; set; } + + /// + /// نام واحد پول + /// + public required string CurrencyName { get; set; } + + /// + /// نماد واحد پول + /// + public required string CurrencySymbol { get; set; } + + /// + /// Top-Level Domain (مثلاً .ir) + /// + public required string Tld { get; set; } + + /// + /// نام بومی کشور (فارسی یا زبان محلی) + /// + public required string Native { get; set; } + + /// + /// منطقه جغرافیایی (مثلاً Asia) + /// + public required string Region { get; set; } + + /// + /// زیرمنطقه (مثلاً Southern Asia) + /// + public required string Subregion { get; set; } + + /// + /// عرض جغرافیایی + /// + public required string Latitude { get; set; } + + /// + /// طول جغرافیایی + /// + public required string Longitude { get; set; } + + /// + /// ایموجی پرچم کشور + /// + public required string Emoji { get; set; } + + /// + /// کد یونیکد ایموجی + /// + public required string EmojiU { get; set; } + + /// + /// استان‌های این کشور + /// + public virtual ICollection States { get; set; } = new List(); +} diff --git a/src/CMSMicroservice.Domain/Entities/Geography/State.cs b/src/CMSMicroservice.Domain/Entities/Geography/State.cs new file mode 100644 index 0000000..ba6cf44 --- /dev/null +++ b/src/CMSMicroservice.Domain/Entities/Geography/State.cs @@ -0,0 +1,64 @@ +using CMSMicroservice.Domain.Common; + +namespace CMSMicroservice.Domain.Entities.Geography; + +/// +/// استان - State/Province +/// +public class State : BaseAuditableEntity +{ + /// + /// شناسه یکتا + /// + public long Id { get; set; } + + /// + /// شناسه خارجی (External ID) + /// + public long ExternalId { get; set; } + + /// + /// نام استان + /// + public required string Name { get; set; } + + /// + /// کد استان + /// + public required string StateCode { get; set; } + + /// + /// عرض جغرافیایی + /// + public required string Latitude { get; set; } + + /// + /// طول جغرافیایی + /// + public required string Longitude { get; set; } + + /// + /// نوع استان (province, state, etc.) + /// + public required string Type { get; set; } + + /// + /// نام بومی استان (فارسی یا زبان محلی) + /// + public required string Native { get; set; } + + /// + /// شناسه کشور متعلق + /// + public long CountryId { get; set; } + + /// + /// کشور متعلق + /// + public virtual Country Country { get; set; } = null!; + + /// + /// شهرهای این استان + /// + public virtual ICollection Cities { get; set; } = new List(); +} diff --git a/src/CMSMicroservice.Domain/Enums/ContractType.cs b/src/CMSMicroservice.Domain/Enums/ContractType.cs index 401dadd..4a239c8 100644 --- a/src/CMSMicroservice.Domain/Enums/ContractType.cs +++ b/src/CMSMicroservice.Domain/Enums/ContractType.cs @@ -2,6 +2,6 @@ namespace CMSMicroservice.Domain.Enums; //قراردادها public enum ContractType { - Main = 0, - CMS = 1, + Main = 0, // قرارداد ثبت‌نام اولیه + ClubMembership = 1, // قرارداد باشگاه مشتریان } diff --git a/src/CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs b/src/CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs index 9f42582..1bf1274 100644 --- a/src/CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs +++ b/src/CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs @@ -3,7 +3,7 @@ using CMSMicroservice.Application.Common.Interfaces; using Microsoft.EntityFrameworkCore.Diagnostics; using CMSMicroservice.Domain.Entities; using CMSMicroservice.Domain.Entities.Payment; - +using CMSMicroservice.Domain.Entities.Geography; using CMSMicroservice.Domain.Entities.Order; using CMSMicroservice.Domain.Entities.DiscountShop; using CMSMicroservice.Infrastructure.Persistence.Interceptors; @@ -111,4 +111,9 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext public DbSet DiscountShoppingCarts => Set(); public DbSet DiscountOrders => Set(); public DbSet DiscountOrderDetails => Set(); + + // ============= Geography DbSets ============= + public DbSet Countries => Set(); + public DbSet States => Set(); + public DbSet Cities => Set(); } diff --git a/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CityConfiguration.cs b/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CityConfiguration.cs new file mode 100644 index 0000000..8a2fa7f --- /dev/null +++ b/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CityConfiguration.cs @@ -0,0 +1,55 @@ +using CMSMicroservice.Domain.Entities.Geography; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace CMSMicroservice.Infrastructure.Persistence.Configurations.Geography; + +public class CityConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Cities", "GMS"); + + builder.HasKey(c => c.Id); + + builder.Property(c => c.Id) + .ValueGeneratedOnAdd(); + + builder.Property(c => c.ExternalId) + .IsRequired(); + + builder.Property(c => c.Name) + .IsRequired() + .HasMaxLength(500); + + builder.Property(c => c.Latitude) + .IsRequired() + .HasMaxLength(50); + + builder.Property(c => c.Longitude) + .IsRequired() + .HasMaxLength(50); + + builder.Property(c => c.Native) + .IsRequired() + .HasMaxLength(500) + .HasDefaultValue(""); + + builder.Property(c => c.IsDeleted) + .IsRequired() + .HasDefaultValue(false); + + builder.Property(c => c.StateId) + .IsRequired(); + + // Index + builder.HasIndex(c => c.StateId) + .HasDatabaseName("IX_Cities_StateId"); + + // Relationships + builder.HasOne(c => c.State) + .WithMany(s => s.Cities) + .HasForeignKey(c => c.StateId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CountryConfiguration.cs b/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CountryConfiguration.cs new file mode 100644 index 0000000..3f63178 --- /dev/null +++ b/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/CountryConfiguration.cs @@ -0,0 +1,99 @@ +using CMSMicroservice.Domain.Entities.Geography; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace CMSMicroservice.Infrastructure.Persistence.Configurations.Geography; + +public class CountryConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Countries", "GMS"); + + builder.HasKey(c => c.Id); + + builder.Property(c => c.Id) + .ValueGeneratedOnAdd(); + + builder.Property(c => c.ExternalId) + .IsRequired(); + + builder.Property(c => c.Name) + .IsRequired() + .HasMaxLength(500); + + builder.Property(c => c.Iso3) + .IsRequired() + .HasMaxLength(3); + + builder.Property(c => c.Iso2) + .IsRequired() + .HasMaxLength(2); + + builder.Property(c => c.NumericCode) + .IsRequired() + .HasMaxLength(10); + + builder.Property(c => c.PhoneCode) + .IsRequired() + .HasMaxLength(10); + + builder.Property(c => c.Capital) + .IsRequired() + .HasMaxLength(500); + + builder.Property(c => c.Currency) + .IsRequired() + .HasMaxLength(10); + + builder.Property(c => c.CurrencyName) + .IsRequired() + .HasMaxLength(100); + + builder.Property(c => c.CurrencySymbol) + .IsRequired() + .HasMaxLength(10); + + builder.Property(c => c.Tld) + .IsRequired() + .HasMaxLength(10); + + builder.Property(c => c.Native) + .IsRequired() + .HasMaxLength(500); + + builder.Property(c => c.Region) + .IsRequired() + .HasMaxLength(100); + + builder.Property(c => c.Subregion) + .IsRequired() + .HasMaxLength(100); + + builder.Property(c => c.Latitude) + .IsRequired() + .HasMaxLength(50); + + builder.Property(c => c.Longitude) + .IsRequired() + .HasMaxLength(50); + + builder.Property(c => c.Emoji) + .IsRequired() + .HasMaxLength(10); + + builder.Property(c => c.EmojiU) + .IsRequired() + .HasMaxLength(50); + + builder.Property(c => c.IsDeleted) + .IsRequired() + .HasDefaultValue(false); + + // Relationships + builder.HasMany(c => c.States) + .WithOne(s => s.Country) + .HasForeignKey(s => s.CountryId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/StateConfiguration.cs b/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/StateConfiguration.cs new file mode 100644 index 0000000..ab15efe --- /dev/null +++ b/src/CMSMicroservice.Infrastructure/Persistence/Configurations/Geography/StateConfiguration.cs @@ -0,0 +1,68 @@ +using CMSMicroservice.Domain.Entities.Geography; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace CMSMicroservice.Infrastructure.Persistence.Configurations.Geography; + +public class StateConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("States", "GMS"); + + builder.HasKey(s => s.Id); + + builder.Property(s => s.Id) + .ValueGeneratedOnAdd(); + + builder.Property(s => s.ExternalId) + .IsRequired(); + + builder.Property(s => s.Name) + .IsRequired() + .HasMaxLength(500); + + builder.Property(s => s.StateCode) + .IsRequired() + .HasMaxLength(10); + + builder.Property(s => s.Latitude) + .IsRequired() + .HasMaxLength(50); + + builder.Property(s => s.Longitude) + .IsRequired() + .HasMaxLength(50); + + builder.Property(s => s.Type) + .IsRequired() + .HasMaxLength(100); + + builder.Property(s => s.Native) + .IsRequired() + .HasMaxLength(500) + .HasDefaultValue(""); + + builder.Property(s => s.IsDeleted) + .IsRequired() + .HasDefaultValue(false); + + builder.Property(s => s.CountryId) + .IsRequired(); + + // Index + builder.HasIndex(s => s.CountryId) + .HasDatabaseName("IX_States_CountryId"); + + // Relationships + builder.HasOne(s => s.Country) + .WithMany(c => c.States) + .HasForeignKey(s => s.CountryId) + .OnDelete(DeleteBehavior.Cascade); + + builder.HasMany(s => s.Cities) + .WithOne(c => c.State) + .HasForeignKey(c => c.StateId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.Designer.cs b/src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.Designer.cs new file mode 100644 index 0000000..293cb6b --- /dev/null +++ b/src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.Designer.cs @@ -0,0 +1,3523 @@ +// +using System; +using CMSMicroservice.Infrastructure.Persistence; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace CMSMicroservice.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251216190010_AddGeographyEntities")] + partial class AddGeographyEntities + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("CMS") + .HasAnnotation("ProductVersion", "9.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("ImagePath") + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("SortOrder") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("Categories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubFeature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("RequiredPoints") + .HasColumnType("int"); + + b.Property("SortOrder") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("IsActive", "SortOrder") + .HasDatabaseName("IX_ClubFeature_IsActive_SortOrder"); + + b.ToTable("ClubFeatures", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubMembership", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ActivatedAt") + .HasColumnType("datetime2"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("GiftValue") + .HasColumnType("bigint"); + + b.Property("InitialContribution") + .HasColumnType("bigint"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("PurchaseMethod") + .HasColumnType("int"); + + b.Property("TotalEarned") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("IsActive") + .HasDatabaseName("IX_ClubMembership_IsActive"); + + b.HasIndex("UserId") + .IsUnique() + .HasDatabaseName("IX_ClubMembership_UserId"); + + b.ToTable("ClubMemberships", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.UserClubFeature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClubFeatureId") + .HasColumnType("bigint"); + + b.Property("ClubMembershipId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("GrantedAt") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(true); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ClubFeatureId"); + + b.HasIndex("ClubMembershipId") + .HasDatabaseName("IX_UserClubFeature_ClubMembershipId"); + + b.HasIndex("UserId", "ClubFeatureId") + .IsUnique() + .HasDatabaseName("IX_UserClubFeature_UserId_ClubFeatureId"); + + b.ToTable("UserClubFeatures", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BalancesEarned") + .HasColumnType("int"); + + b.Property("BankReferenceId") + .HasColumnType("nvarchar(max)"); + + b.Property("BankTrackingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IbanNumber") + .HasMaxLength(26) + .HasColumnType("nvarchar(26)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("PaidAt") + .HasColumnType("datetime2"); + + b.Property("PaymentFailureReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ProcessedAt") + .HasColumnType("datetime2"); + + b.Property("ProcessedBy") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("RejectionReason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TotalAmount") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("ValuePerBalance") + .HasColumnType("bigint"); + + b.Property("WeekNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("WeeklyPoolId") + .HasColumnType("bigint"); + + b.Property("WithdrawalMethod") + .HasColumnType("int"); + + b.Property("WithdrawnAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("Status") + .HasDatabaseName("IX_UserCommissionPayout_Status"); + + b.HasIndex("WeekNumber") + .HasDatabaseName("IX_UserCommissionPayout_WeekNumber"); + + b.HasIndex("WeeklyPoolId") + .HasDatabaseName("IX_UserCommissionPayout_WeeklyPoolId"); + + b.HasIndex("UserId", "WeekNumber") + .IsUnique() + .HasDatabaseName("IX_UserCommissionPayout_UserId_WeekNumber"); + + b.ToTable("UserCommissionPayouts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.WeeklyCommissionPool", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CalculatedAt") + .HasColumnType("datetime2"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsCalculated") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalBalances") + .HasColumnType("int"); + + b.Property("TotalPoolAmount") + .HasColumnType("bigint"); + + b.Property("ValuePerBalance") + .HasColumnType("bigint"); + + b.Property("WeekNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.HasKey("Id"); + + b.HasIndex("IsCalculated") + .HasDatabaseName("IX_WeeklyCommissionPool_IsCalculated"); + + b.HasIndex("WeekNumber") + .IsUnique() + .HasDatabaseName("IX_WeeklyCommissionPool_WeekNumber"); + + b.ToTable("WeeklyCommissionPools", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.WorkerExecutionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompletedAt") + .HasColumnType("datetime2"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Details") + .HasColumnType("nvarchar(max)"); + + b.Property("DurationMs") + .HasColumnType("bigint"); + + b.Property("ErrorCount") + .HasColumnType("int"); + + b.Property("ErrorMessage") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ErrorStackTrace") + .HasColumnType("nvarchar(max)"); + + b.Property("ExecutionId") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProcessedCount") + .HasColumnType("int"); + + b.Property("StartedAt") + .HasColumnType("datetime2"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("WeekNumber") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.HasIndex("StartedAt"); + + b.HasIndex("Status"); + + b.HasIndex("WeekNumber"); + + b.ToTable("WorkerExecutionLogs", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Configuration.SystemConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("DataType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Scope") + .HasColumnType("int"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("IsActive") + .HasDatabaseName("IX_SystemConfiguration_IsActive"); + + b.HasIndex("Scope", "Key") + .IsUnique() + .HasDatabaseName("IX_SystemConfiguration_Scope_Key"); + + b.ToTable("SystemConfigurations", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Contract", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlContent") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Contracts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DayaLoanContract", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ContractNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsProcessed") + .HasColumnType("bit"); + + b.Property("LastCheckDate") + .HasColumnType("datetime2"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("NationalCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProcessedDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("TransactionId"); + + b.HasIndex("UserId"); + + b.ToTable("DayaLoanContracts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ImagePath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(true); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ParentCategoryId") + .HasColumnType("bigint"); + + b.Property("SortOrder") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("ParentCategoryId"); + + b.ToTable("DiscountCategories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("DeliveryStatus") + .HasColumnType("int"); + + b.Property("DiscountBalanceUsed") + .HasColumnType("bigint"); + + b.Property("GatewayAmountPaid") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDate") + .HasColumnType("datetime2"); + + b.Property("PaymentStatus") + .HasColumnType("int"); + + b.Property("TotalAmount") + .HasColumnType("bigint"); + + b.Property("TrackingCode") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("UserAddressId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("VatAmount") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("TransactionId"); + + b.HasIndex("UserAddressId"); + + b.HasIndex("UserId"); + + b.ToTable("DiscountOrders", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountOrderDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscountAmount") + .HasColumnType("bigint"); + + b.Property("DiscountOrderId") + .HasColumnType("bigint"); + + b.Property("DiscountPercentUsed") + .HasColumnType("int"); + + b.Property("FinalPrice") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("UnitPrice") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("DiscountOrderId"); + + b.HasIndex("ProductId"); + + b.ToTable("DiscountOrderDetails", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("FullInformation") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ImagePath") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(true); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("MaxDiscountPercent") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("bigint"); + + b.Property("Rate") + .HasColumnType("int"); + + b.Property("RemainingCount") + .HasColumnType("int"); + + b.Property("SaleCount") + .HasColumnType("int"); + + b.Property("ShortInfomation") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ThumbnailPath") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ViewCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("DiscountProducts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.HasIndex("ProductId", "CategoryId") + .IsUnique(); + + b.ToTable("DiscountProductCategories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountShoppingCart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("UserId", "ProductId") + .IsUnique(); + + b.ToTable("DiscountShoppingCarts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.FactorDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsChangePrice") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("UnitDiscount") + .HasColumnType("int"); + + b.Property("UnitDiscountPrice") + .HasColumnType("bigint"); + + b.Property("UnitPrice") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.HasIndex("ProductId"); + + b.ToTable("FactorDetails", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.City", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalId") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Latitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Native") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)") + .HasDefaultValue(""); + + b.Property("StateId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("StateId") + .HasDatabaseName("IX_Cities_StateId"); + + b.ToTable("Cities", "GMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Capital") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Currency") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CurrencyName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CurrencySymbol") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Emoji") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("EmojiU") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ExternalId") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Iso2") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("Iso3") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("nvarchar(3)"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Latitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Native") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NumericCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("PhoneCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Region") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Subregion") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Tld") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Countries", "GMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.State", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CountryId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalId") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Latitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Native") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)") + .HasDefaultValue(""); + + b.Property("StateCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.HasIndex("CountryId") + .HasDatabaseName("IX_States_CountryId"); + + b.ToTable("States", "GMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("ClubMembershipId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("NewInitialContribution") + .HasColumnType("bigint"); + + b.Property("NewIsActive") + .HasColumnType("bit"); + + b.Property("OldInitialContribution") + .HasColumnType("bigint"); + + b.Property("OldIsActive") + .HasColumnType("bit"); + + b.Property("PerformedBy") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Action") + .HasDatabaseName("IX_ClubMembershipHistory_Action"); + + b.HasIndex("ClubMembershipId") + .HasDatabaseName("IX_ClubMembershipHistory_ClubMembershipId"); + + b.HasIndex("UserId", "Created") + .HasDatabaseName("IX_ClubMembershipHistory_UserId_Created"); + + b.ToTable("ClubMembershipHistories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.CommissionPayoutHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("AmountAfter") + .HasColumnType("bigint"); + + b.Property("AmountBefore") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("NewStatus") + .HasColumnType("int"); + + b.Property("OldStatus") + .HasColumnType("int"); + + b.Property("PerformedBy") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserCommissionPayoutId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("WeekNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.HasKey("Id"); + + b.HasIndex("Action") + .HasDatabaseName("IX_CommissionPayoutHistory_Action"); + + b.HasIndex("UserCommissionPayoutId") + .HasDatabaseName("IX_CommissionPayoutHistory_PayoutId"); + + b.HasIndex("WeekNumber") + .HasDatabaseName("IX_CommissionPayoutHistory_WeekNumber"); + + b.HasIndex("UserId", "Created") + .HasDatabaseName("IX_CommissionPayoutHistory_UserId_Created"); + + b.ToTable("CommissionPayoutHistories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.NetworkMembershipHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("NewLegPosition") + .HasColumnType("int"); + + b.Property("NewParentId") + .HasColumnType("bigint"); + + b.Property("OldLegPosition") + .HasColumnType("int"); + + b.Property("OldParentId") + .HasColumnType("bigint"); + + b.Property("PerformedBy") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Action") + .HasDatabaseName("IX_NetworkMembershipHistory_Action"); + + b.HasIndex("UserId", "Created") + .HasDatabaseName("IX_NetworkMembershipHistory_UserId_Created"); + + b.ToTable("NetworkMembershipHistories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.SystemConfigurationHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConfigurationId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("NewValue") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("OldValue") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("PerformedBy") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Scope") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ConfigurationId", "Created") + .HasDatabaseName("IX_SystemConfigurationHistory_ConfigId_Created"); + + b.HasIndex("Scope", "Key") + .HasDatabaseName("IX_SystemConfigurationHistory_Scope_Key"); + + b.ToTable("SystemConfigurationHistories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Network.NetworkWeeklyBalance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CalculatedAt") + .HasColumnType("datetime2"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("FlushedPerSide") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsExpired") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LeftLegBalances") + .HasColumnType("int"); + + b.Property("LeftLegCarryover") + .HasColumnType("int"); + + b.Property("LeftLegNewMembers") + .HasColumnType("int"); + + b.Property("LeftLegRemainder") + .HasColumnType("int"); + + b.Property("LeftLegTotal") + .HasColumnType("int"); + + b.Property("RightLegBalances") + .HasColumnType("int"); + + b.Property("RightLegCarryover") + .HasColumnType("int"); + + b.Property("RightLegNewMembers") + .HasColumnType("int"); + + b.Property("RightLegRemainder") + .HasColumnType("int"); + + b.Property("RightLegTotal") + .HasColumnType("int"); + + b.Property("SubordinateBalances") + .HasColumnType("int"); + + b.Property("TotalBalances") + .HasColumnType("int"); + + b.Property("TotalFlushed") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("WeekNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("WeeklyPoolContribution") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("IsExpired") + .HasDatabaseName("IX_NetworkWeeklyBalance_IsExpired"); + + b.HasIndex("WeekNumber") + .HasDatabaseName("IX_NetworkWeeklyBalance_WeekNumber"); + + b.HasIndex("UserId", "WeekNumber") + .IsUnique() + .HasDatabaseName("IX_NetworkWeeklyBalance_UserId_WeekNumber"); + + b.ToTable("NetworkWeeklyBalances", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Order.OrderVAT", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BaseAmount") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsPaid") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Note") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("PaidAt") + .HasColumnType("datetime2"); + + b.Property("TotalAmount") + .HasColumnType("bigint"); + + b.Property("VATAmount") + .HasColumnType("bigint"); + + b.Property("VATRate") + .HasColumnType("decimal(5,4)"); + + b.HasKey("Id"); + + b.HasIndex("Created") + .HasDatabaseName("IX_OrderVATs_Created"); + + b.HasIndex("IsPaid") + .HasDatabaseName("IX_OrderVATs_IsPaid"); + + b.HasIndex("OrderId") + .IsUnique() + .HasDatabaseName("IX_OrderVATs_OrderId"); + + b.ToTable("OrderVATs", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.OtpToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Attempts") + .HasColumnType("int"); + + b.Property("CodeHash") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsUsed") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Mobile") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("OtpTokens", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Package", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImagePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Packages", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Payment.ManualPayment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("ApprovedAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedBy") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ReferenceNumber") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("RejectionReason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("RequestedBy") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedBy"); + + b.HasIndex("Created"); + + b.HasIndex("RequestedBy"); + + b.HasIndex("Status"); + + b.HasIndex("TransactionId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "Status"); + + b.ToTable("ManualPayments", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClubDiscountPercent") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Discount") + .HasColumnType("int"); + + b.Property("FullInformation") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImagePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsClubExclusive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("bigint"); + + b.Property("Rate") + .HasColumnType("int"); + + b.Property("RemainingCount") + .HasColumnType("int"); + + b.Property("SaleCount") + .HasColumnType("int"); + + b.Property("ShortInfomation") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ThumbnailPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ViewCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IsClubExclusive") + .HasDatabaseName("IX_Products_IsClubExclusive"); + + b.ToTable("Products", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.HasIndex("ProductId"); + + b.ToTable("ProductCategories", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductGallery", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("ProductImageId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("ProductImageId"); + + b.ToTable("ProductGalleries", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ImagePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImageThumbnailPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ProductImages", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductTag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("TagId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("TagId"); + + b.ToTable("ProductTags", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.PublicMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchivedAt") + .HasColumnType("datetime2"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedByUserId") + .HasColumnType("bigint"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(true); + + b.Property("IsArchived") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LinkText") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("LinkUrl") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("PublishedAt") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("StartsAt") + .HasColumnType("datetime2"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.HasKey("Id"); + + b.HasIndex("CreatedByUserId") + .HasDatabaseName("IX_PublicMessages_CreatedByUserId"); + + b.HasIndex("ExpiresAt") + .HasDatabaseName("IX_PublicMessages_ExpiresAt"); + + b.HasIndex("IsActive") + .HasDatabaseName("IX_PublicMessages_IsActive"); + + b.HasIndex("Priority") + .HasDatabaseName("IX_PublicMessages_Priority"); + + b.HasIndex("StartsAt") + .HasDatabaseName("IX_PublicMessages_StartsAt"); + + b.HasIndex("Type") + .HasDatabaseName("IX_PublicMessages_Type"); + + b.HasIndex("IsActive", "ExpiresAt") + .HasDatabaseName("IX_PublicMessages_IsActive_ExpiresAt"); + + b.ToTable("PublicMessages", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Roles", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SortOrder") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Tags", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDate") + .HasColumnType("datetime2"); + + b.Property("PaymentStatus") + .HasColumnType("int"); + + b.Property("RefId") + .HasColumnType("nvarchar(max)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Transactions", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AvatarPath") + .HasColumnType("nvarchar(max)"); + + b.Property("BirthDate") + .HasColumnType("datetime2"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("DayaCreditReceivedAt") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailNotifications") + .HasColumnType("bit"); + + b.Property("FirstName") + .HasColumnType("nvarchar(max)"); + + b.Property("HasReceivedDayaCredit") + .HasColumnType("bit"); + + b.Property("HashPassword") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsMobileVerified") + .HasColumnType("bit"); + + b.Property("IsRulesAccepted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .HasColumnType("nvarchar(max)"); + + b.Property("LegPosition") + .HasColumnType("int"); + + b.Property("Mobile") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MobileVerifiedAt") + .HasColumnType("datetime2"); + + b.Property("NationalCode") + .HasColumnType("nvarchar(max)"); + + b.Property("NetworkParentId") + .HasColumnType("bigint"); + + b.Property("PackagePurchaseMethod") + .HasColumnType("int"); + + b.Property("PushNotifications") + .HasColumnType("bit"); + + b.Property("ReferralCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RulesAcceptedAt") + .HasColumnType("datetime2"); + + b.Property("SmsNotifications") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("LegPosition") + .HasDatabaseName("IX_User_LegPosition"); + + b.HasIndex("NetworkParentId") + .HasDatabaseName("IX_User_NetworkParentId"); + + b.ToTable("Users", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CityId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDefault") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("PostalCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserAddresses", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserCart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("UserId"); + + b.ToTable("UserCarts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserContract", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ContractId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("SignGuid") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SignedPdfFile") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ContractId"); + + b.HasIndex("UserId"); + + b.ToTable("UserContracts", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("DeliveryStatus") + .HasColumnType("int"); + + b.Property("HasVAT") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderVATId") + .HasColumnType("bigint"); + + b.Property("PackageId") + .HasColumnType("bigint"); + + b.Property("PaymentDate") + .HasColumnType("datetime2"); + + b.Property("PaymentMethod") + .HasColumnType("int"); + + b.Property("PaymentStatus") + .HasColumnType("int"); + + b.Property("TrackingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("UserAddressId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("OrderVATId"); + + b.HasIndex("PackageId"); + + b.HasIndex("TransactionId"); + + b.HasIndex("UserAddressId"); + + b.HasIndex("UserId"); + + b.ToTable("UserOrders", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserPackagePurchase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderId") + .HasColumnType("bigint"); + + b.Property("PackageId") + .HasColumnType("bigint"); + + b.Property("PurchaseMethod") + .HasColumnType("int"); + + b.Property("PurchasedAt") + .HasColumnType("datetime2"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.HasIndex("PackageId") + .HasDatabaseName("IX_UserPackagePurchase_PackageId"); + + b.HasIndex("PurchasedAt") + .HasDatabaseName("IX_UserPackagePurchase_PurchasedAt"); + + b.HasIndex("TransactionId"); + + b.HasIndex("UserId") + .HasDatabaseName("IX_UserPackagePurchase_UserId"); + + b.HasIndex("UserId", "PurchasedAt") + .HasDatabaseName("IX_UserPackagePurchase_UserId_PurchasedAt"); + + b.ToTable("UserPackagePurchases", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.HasIndex("UserId"); + + b.ToTable("UserRoles", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWallet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Balance") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscountBalance") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("NetworkBalance") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserWallets", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletChangeLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangeDiscountValue") + .HasColumnType("bigint"); + + b.Property("ChangeNerworkValue") + .HasColumnType("bigint"); + + b.Property("ChangeValue") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("CurrentBalance") + .HasColumnType("bigint"); + + b.Property("CurrentDiscountBalance") + .HasColumnType("bigint"); + + b.Property("CurrentNetworkBalance") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsIncrease") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("RefrenceId") + .HasColumnType("bigint"); + + b.Property("WalletId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("WalletId"); + + b.ToTable("UserWalletChangeLogs", "CMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Category", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Category", "Parent") + .WithMany("Categories") + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubMembership", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithOne("ClubMembership") + .HasForeignKey("CMSMicroservice.Domain.Entities.Club.ClubMembership", "UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.UserClubFeature", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubFeature", "ClubFeature") + .WithMany("UserClubFeatures") + .HasForeignKey("ClubFeatureId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembership", "ClubMembership") + .WithMany("UserClubFeatures") + .HasForeignKey("ClubMembershipId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserClubFeatures") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ClubFeature"); + + b.Navigation("ClubMembership"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("CommissionPayouts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.Commission.WeeklyCommissionPool", "WeeklyPool") + .WithMany("UserCommissionPayouts") + .HasForeignKey("WeeklyPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("WeeklyPool"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DayaLoanContract", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Transaction", "Transaction") + .WithMany() + .HasForeignKey("TransactionId"); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("DayaLoanContracts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Transaction"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountCategory", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountCategory", "ParentCategory") + .WithMany("ChildCategories") + .HasForeignKey("ParentCategoryId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ParentCategory"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountOrder", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Transaction", "Transaction") + .WithMany() + .HasForeignKey("TransactionId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("CMSMicroservice.Domain.Entities.UserAddress", "UserAddress") + .WithMany() + .HasForeignKey("UserAddressId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("DiscountOrders") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Transaction"); + + b.Navigation("User"); + + b.Navigation("UserAddress"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountOrderDetail", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountOrder", "DiscountOrder") + .WithMany("OrderDetails") + .HasForeignKey("DiscountOrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", "Product") + .WithMany("OrderDetails") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("DiscountOrder"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProductCategory", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountCategory", "Category") + .WithMany("ProductCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", "Product") + .WithMany("ProductCategories") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountShoppingCart", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", "Product") + .WithMany("ShoppingCarts") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("DiscountShoppingCarts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.FactorDetails", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.UserOrder", "Order") + .WithMany("FactorDetails") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.Product", "Product") + .WithMany("FactorDetails") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.City", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Geography.State", "State") + .WithMany("Cities") + .HasForeignKey("StateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("State"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.State", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Geography.Country", "Country") + .WithMany("States") + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Country"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembership", "ClubMembership") + .WithMany("ClubMembershipHistories") + .HasForeignKey("ClubMembershipId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ClubMembership"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.CommissionPayoutHistory", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", "UserCommissionPayout") + .WithMany("CommissionPayoutHistories") + .HasForeignKey("UserCommissionPayoutId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("UserCommissionPayout"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.SystemConfigurationHistory", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Configuration.SystemConfiguration", "Configuration") + .WithMany("SystemConfigurationHistories") + .HasForeignKey("ConfigurationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Configuration"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Network.NetworkWeeklyBalance", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("NetworkWeeklyBalances") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Order.OrderVAT", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.UserOrder", "Order") + .WithOne() + .HasForeignKey("CMSMicroservice.Domain.Entities.Order.OrderVAT", "OrderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Payment.ManualPayment", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Transaction", "Transaction") + .WithMany() + .HasForeignKey("TransactionId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Transaction"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductCategory", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Category", "Category") + .WithMany("ProductCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.Product", "Product") + .WithMany("ProductCategories") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductGallery", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Product", "Product") + .WithMany("ProductGalleries") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.ProductImage", "ProductImage") + .WithMany("ProductGalleries") + .HasForeignKey("ProductImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("ProductImage"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductTag", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Product", "Product") + .WithMany("ProductTags") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.Tag", "Tag") + .WithMany("ProductTags") + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("Tag"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.User", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.User", "NetworkParent") + .WithMany("NetworkChildren") + .HasForeignKey("NetworkParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("NetworkParent"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserAddress", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserAddresses") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserCart", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Product", "Product") + .WithMany("UserCarts") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserCarts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserContract", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Contract", "Contract") + .WithMany("UserContracts") + .HasForeignKey("ContractId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserContracts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Contract"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserOrder", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Order.OrderVAT", "OrderVAT") + .WithMany() + .HasForeignKey("OrderVATId"); + + b.HasOne("CMSMicroservice.Domain.Entities.Package", "Package") + .WithMany("UserOrders") + .HasForeignKey("PackageId"); + + b.HasOne("CMSMicroservice.Domain.Entities.Transaction", "Transaction") + .WithMany("UserOrders") + .HasForeignKey("TransactionId"); + + b.HasOne("CMSMicroservice.Domain.Entities.UserAddress", "UserAddress") + .WithMany("UserOrders") + .HasForeignKey("UserAddressId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserOrders") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OrderVAT"); + + b.Navigation("Package"); + + b.Navigation("Transaction"); + + b.Navigation("User"); + + b.Navigation("UserAddress"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserPackagePurchase", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.UserOrder", "Order") + .WithMany() + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("CMSMicroservice.Domain.Entities.Package", "Package") + .WithMany() + .HasForeignKey("PackageId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.Transaction", "Transaction") + .WithMany() + .HasForeignKey("TransactionId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Order"); + + b.Navigation("Package"); + + b.Navigation("Transaction"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserRole", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Role", "Role") + .WithMany("UserRoles") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserRoles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWallet", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.User", "User") + .WithMany("UserWallets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletChangeLog", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.UserWallet", "Wallet") + .WithMany("UserWalletChangeLogs") + .HasForeignKey("WalletId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Wallet"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Category", b => + { + b.Navigation("Categories"); + + b.Navigation("ProductCategories"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubFeature", b => + { + b.Navigation("UserClubFeatures"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubMembership", b => + { + b.Navigation("ClubMembershipHistories"); + + b.Navigation("UserClubFeatures"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", b => + { + b.Navigation("CommissionPayoutHistories"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.WeeklyCommissionPool", b => + { + b.Navigation("UserCommissionPayouts"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Configuration.SystemConfiguration", b => + { + b.Navigation("SystemConfigurationHistories"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Contract", b => + { + b.Navigation("UserContracts"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountCategory", b => + { + b.Navigation("ChildCategories"); + + b.Navigation("ProductCategories"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountOrder", b => + { + b.Navigation("OrderDetails"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", b => + { + b.Navigation("OrderDetails"); + + b.Navigation("ProductCategories"); + + b.Navigation("ShoppingCarts"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.Country", b => + { + b.Navigation("States"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.State", b => + { + b.Navigation("Cities"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Package", b => + { + b.Navigation("UserOrders"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Product", b => + { + b.Navigation("FactorDetails"); + + b.Navigation("ProductCategories"); + + b.Navigation("ProductGalleries"); + + b.Navigation("ProductTags"); + + b.Navigation("UserCarts"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.ProductImage", b => + { + b.Navigation("ProductGalleries"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Role", b => + { + b.Navigation("UserRoles"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Tag", b => + { + b.Navigation("ProductTags"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Transaction", b => + { + b.Navigation("UserOrders"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.User", b => + { + b.Navigation("ClubMembership"); + + b.Navigation("CommissionPayouts"); + + b.Navigation("DayaLoanContracts"); + + b.Navigation("DiscountOrders"); + + b.Navigation("DiscountShoppingCarts"); + + b.Navigation("NetworkChildren"); + + b.Navigation("NetworkWeeklyBalances"); + + b.Navigation("UserAddresses"); + + b.Navigation("UserCarts"); + + b.Navigation("UserClubFeatures"); + + b.Navigation("UserContracts"); + + b.Navigation("UserOrders"); + + b.Navigation("UserRoles"); + + b.Navigation("UserWallets"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserAddress", b => + { + b.Navigation("UserOrders"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserOrder", b => + { + b.Navigation("FactorDetails"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWallet", b => + { + b.Navigation("UserWalletChangeLogs"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.cs b/src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.cs new file mode 100644 index 0000000..52bd656 --- /dev/null +++ b/src/CMSMicroservice.Infrastructure/Persistence/Migrations/20251216190010_AddGeographyEntities.cs @@ -0,0 +1,146 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace CMSMicroservice.Infrastructure.Persistence.Migrations +{ + /// + public partial class AddGeographyEntities : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "GMS"); + + migrationBuilder.CreateTable( + name: "Countries", + schema: "GMS", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ExternalId = table.Column(type: "bigint", nullable: false), + Name = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + Iso3 = table.Column(type: "nvarchar(3)", maxLength: 3, nullable: false), + Iso2 = table.Column(type: "nvarchar(2)", maxLength: 2, nullable: false), + NumericCode = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + PhoneCode = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + Capital = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + Currency = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + CurrencyName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + CurrencySymbol = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + Tld = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + Native = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + Region = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Subregion = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Latitude = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Longitude = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Emoji = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + EmojiU = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Created = table.Column(type: "datetime2", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: true), + LastModified = table.Column(type: "datetime2", nullable: true), + LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Countries", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "States", + schema: "GMS", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ExternalId = table.Column(type: "bigint", nullable: false), + Name = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + StateCode = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + Latitude = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Longitude = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Type = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Native = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false, defaultValue: ""), + CountryId = table.Column(type: "bigint", nullable: false), + Created = table.Column(type: "datetime2", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: true), + LastModified = table.Column(type: "datetime2", nullable: true), + LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false) + }, + constraints: table => + { + table.PrimaryKey("PK_States", x => x.Id); + table.ForeignKey( + name: "FK_States_Countries_CountryId", + column: x => x.CountryId, + principalSchema: "GMS", + principalTable: "Countries", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Cities", + schema: "GMS", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ExternalId = table.Column(type: "bigint", nullable: false), + Name = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + Latitude = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Longitude = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Native = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false, defaultValue: ""), + StateId = table.Column(type: "bigint", nullable: false), + Created = table.Column(type: "datetime2", nullable: false), + CreatedBy = table.Column(type: "nvarchar(max)", nullable: true), + LastModified = table.Column(type: "datetime2", nullable: true), + LastModifiedBy = table.Column(type: "nvarchar(max)", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Cities", x => x.Id); + table.ForeignKey( + name: "FK_Cities_States_StateId", + column: x => x.StateId, + principalSchema: "GMS", + principalTable: "States", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Cities_StateId", + schema: "GMS", + table: "Cities", + column: "StateId"); + + migrationBuilder.CreateIndex( + name: "IX_States_CountryId", + schema: "GMS", + table: "States", + column: "CountryId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Cities", + schema: "GMS"); + + migrationBuilder.DropTable( + name: "States", + schema: "GMS"); + + migrationBuilder.DropTable( + name: "Countries", + schema: "GMS"); + } + } +} diff --git a/src/CMSMicroservice.Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs b/src/CMSMicroservice.Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs index a359194..1124ab6 100644 --- a/src/CMSMicroservice.Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/CMSMicroservice.Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs @@ -1014,6 +1014,256 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations b.ToTable("FactorDetails", "CMS"); }); + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.City", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalId") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Latitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Native") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)") + .HasDefaultValue(""); + + b.Property("StateId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("StateId") + .HasDatabaseName("IX_Cities_StateId"); + + b.ToTable("Cities", "GMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Capital") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Currency") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CurrencyName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CurrencySymbol") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Emoji") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("EmojiU") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ExternalId") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Iso2") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("Iso3") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("nvarchar(3)"); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Latitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Native") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NumericCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("PhoneCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Region") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Subregion") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Tld") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Countries", "GMS"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.State", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CountryId") + .HasColumnType("bigint"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalId") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModified") + .HasColumnType("datetime2"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Latitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Native") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)") + .HasDefaultValue(""); + + b.Property("StateCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.HasIndex("CountryId") + .HasDatabaseName("IX_States_CountryId"); + + b.ToTable("States", "GMS"); + }); + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b => { b.Property("Id") @@ -2789,6 +3039,28 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations b.Navigation("Product"); }); + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.City", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Geography.State", "State") + .WithMany("Cities") + .HasForeignKey("StateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("State"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.State", b => + { + b.HasOne("CMSMicroservice.Domain.Entities.Geography.Country", "Country") + .WithMany("States") + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Country"); + }); + modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b => { b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembership", "ClubMembership") @@ -3149,6 +3421,16 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations b.Navigation("ShoppingCarts"); }); + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.Country", b => + { + b.Navigation("States"); + }); + + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Geography.State", b => + { + b.Navigation("Cities"); + }); + modelBuilder.Entity("CMSMicroservice.Domain.Entities.Package", b => { b.Navigation("UserOrders"); diff --git a/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj b/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj index 177884e..f53fc43 100644 --- a/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj +++ b/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj @@ -55,6 +55,8 @@ + + diff --git a/src/CMSMicroservice.Protobuf/Protos/city.proto b/src/CMSMicroservice.Protobuf/Protos/city.proto new file mode 100644 index 0000000..e653004 --- /dev/null +++ b/src/CMSMicroservice.Protobuf/Protos/city.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +package city; + +import "public_messages.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "CMSMicroservice.Protobuf.Protos.City"; + +service CityContract +{ + rpc GetAllCitiesByFilter(GetAllCitiesByFilterRequest) returns (GetAllCitiesByFilterResponse){ + option (google.api.http) = { + get: "/GetAllCitiesByFilter" + }; + }; +} + +message GetAllCitiesByFilterRequest +{ + messages.PaginationState pagination_state = 1; + google.protobuf.StringValue sort_by = 2; + GetAllCitiesByFilterFilter filter = 3; +} + +message GetAllCitiesByFilterFilter +{ + google.protobuf.Int64Value id = 1; + google.protobuf.StringValue name = 2; + google.protobuf.StringValue native = 3; + google.protobuf.Int64Value state_id = 4; +} + +message GetAllCitiesByFilterResponse +{ + messages.MetaData meta_data = 1; + repeated GetAllCitiesByFilterResponseModel models = 2; +} + +message GetAllCitiesByFilterResponseModel +{ + int64 id = 1; + int64 external_id = 2; + string name = 3; + string native = 4; + string latitude = 5; + string longitude = 6; + int64 state_id = 7; + string state_name = 8; + string state_native = 9; +} diff --git a/src/CMSMicroservice.Protobuf/Protos/clubmembership.proto b/src/CMSMicroservice.Protobuf/Protos/clubmembership.proto index e979470..e646237 100644 --- a/src/CMSMicroservice.Protobuf/Protos/clubmembership.proto +++ b/src/CMSMicroservice.Protobuf/Protos/clubmembership.proto @@ -63,6 +63,14 @@ service ClubMembershipContract body: "*" }; }; + + // امضای قرارداد باشگاه مشتریان + rpc AcceptClubMembershipContract(AcceptClubMembershipContractRequest) returns (AcceptClubMembershipContractResponse){ + option (google.api.http) = { + post: "/ClubMembership/AcceptContract" + body: "*" + }; + }; } // Activate Command @@ -258,3 +266,19 @@ message ToggleUserClubFeatureResponse google.protobuf.Int64Value user_club_feature_id = 3; google.protobuf.BoolValue is_active = 4; } + +// AcceptClubMembershipContract Command - امضای قرارداد باشگاه مشتریان +message AcceptClubMembershipContractRequest +{ + int64 user_id = 1; + string otp_code = 2; + string sign_guid = 3; + string contract_html = 4; +} + +message AcceptClubMembershipContractResponse +{ + bool success = 1; + string message = 2; + int64 contract_id = 3; +} diff --git a/src/CMSMicroservice.Protobuf/Protos/user.proto b/src/CMSMicroservice.Protobuf/Protos/user.proto index 93878d3..ad410c6 100644 --- a/src/CMSMicroservice.Protobuf/Protos/user.proto +++ b/src/CMSMicroservice.Protobuf/Protos/user.proto @@ -61,6 +61,12 @@ service UserContract body: "*" }; }; + rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse){ + option (google.api.http) = { + post: "/RefreshToken" + body: "*" + }; + }; } message CreateNewUserRequest { @@ -191,3 +197,13 @@ message SetPasswordForUserRequest string new_password = 3; string confirm_password = 4; } +message RefreshTokenRequest +{ + string current_token = 1; +} +message RefreshTokenResponse +{ + string token = 1; + bool success = 2; + string message = 3; +} diff --git a/src/CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj b/src/CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj index a9f4cc3..6399589 100644 --- a/src/CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj +++ b/src/CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj @@ -28,6 +28,7 @@ + diff --git a/src/CMSMicroservice.WebApi/Common/Mappings/CityProfile.cs b/src/CMSMicroservice.WebApi/Common/Mappings/CityProfile.cs new file mode 100644 index 0000000..bdea9b9 --- /dev/null +++ b/src/CMSMicroservice.WebApi/Common/Mappings/CityProfile.cs @@ -0,0 +1,40 @@ +using CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; +using Mapster; +using ProtoCity = CMSMicroservice.Protobuf.Protos.City; +using AppCity = CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; + +namespace CMSMicroservice.WebApi.Common.Mappings; + +public class CityProfile : IRegister +{ + void IRegister.Register(TypeAdapterConfig config) + { + // Request: Proto → Application + config.NewConfig() + .Map(dest => dest.PaginationState, src => src.PaginationState) + .Map(dest => dest.SortBy, src => src.SortBy) + .Map(dest => dest.Filter, src => src.Filter); + + config.NewConfig() + .Map(dest => dest.Id, src => src.Id) + .Map(dest => dest.Name, src => src.Name) + .Map(dest => dest.Native, src => src.Native) + .Map(dest => dest.StateId, src => src.StateId); + + // Response: Application → Proto + config.NewConfig() + .Map(dest => dest.MetaData, src => src.MetaData) + .Map(dest => dest.Models, src => src.Models); + + config.NewConfig() + .Map(dest => dest.Id, src => src.Id) + .Map(dest => dest.ExternalId, src => src.ExternalId) + .Map(dest => dest.Name, src => src.Name) + .Map(dest => dest.Native, src => src.Native) + .Map(dest => dest.Latitude, src => src.Latitude) + .Map(dest => dest.Longitude, src => src.Longitude) + .Map(dest => dest.StateId, src => src.StateId) + .Map(dest => dest.StateName, src => src.StateName) + .Map(dest => dest.StateNative, src => src.StateNative); + } +} diff --git a/src/CMSMicroservice.WebApi/Common/Mappings/ClubFeatureProfile.cs b/src/CMSMicroservice.WebApi/Common/Mappings/ClubFeatureProfile.cs index 4095291..dc02a19 100644 --- a/src/CMSMicroservice.WebApi/Common/Mappings/ClubFeatureProfile.cs +++ b/src/CMSMicroservice.WebApi/Common/Mappings/ClubFeatureProfile.cs @@ -1,5 +1,6 @@ using CMSMicroservice.Application.ClubFeatureCQ.Commands.ToggleUserClubFeature; using CMSMicroservice.Application.ClubFeatureCQ.Queries.GetUserClubFeatures; +using CMSMicroservice.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract; using CMSMicroservice.Protobuf.Protos.ClubMembership; using Google.Protobuf.WellKnownTypes; using System; @@ -43,5 +44,18 @@ public class ClubFeatureProfile : IRegister .Map(dest => dest.Message, src => src.Message) .Map(dest => dest.UserClubFeatureId, src => src.UserClubFeatureId.HasValue ? (long?)src.UserClubFeatureId.Value : null) .Map(dest => dest.IsActive, src => src.IsActive.HasValue ? (bool?)src.IsActive.Value : null); + + // AcceptClubMembershipContractRequest → AcceptClubMembershipContractCommand + config.NewConfig() + .Map(dest => dest.UserId, src => src.UserId) + .Map(dest => dest.OtpCode, src => src.OtpCode) + .Map(dest => dest.SignGuid, src => src.SignGuid) + .Map(dest => dest.ContractHtml, src => src.ContractHtml); + + // AcceptClubMembershipContractResponseDto → AcceptClubMembershipContractResponse + config.NewConfig() + .Map(dest => dest.Success, src => src.Success) + .Map(dest => dest.Message, src => src.Message) + .Map(dest => dest.ContractId, src => src.ContractId); } } diff --git a/src/CMSMicroservice.WebApi/Common/Services/TokenNotificationService.cs b/src/CMSMicroservice.WebApi/Common/Services/TokenNotificationService.cs new file mode 100644 index 0000000..48dd477 --- /dev/null +++ b/src/CMSMicroservice.WebApi/Common/Services/TokenNotificationService.cs @@ -0,0 +1,115 @@ +using CMSMicroservice.Application.Common.Interfaces; +using CMSMicroservice.WebApi.Hubs; +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Logging; + +namespace CMSMicroservice.WebApi.Common.Services; + +/// +/// Service for sending token-related notifications via SignalR +/// +public class TokenNotificationService : ITokenNotificationService +{ + private readonly IHubContext _hubContext; + private readonly ILogger _logger; + + public TokenNotificationService( + IHubContext hubContext, + ILogger logger) + { + _hubContext = hubContext; + _logger = logger; + } + + /// + public async Task NotifyTokenRevokedAsync(long userId, string reason) + { + try + { + _logger.LogInformation("Notifying token revoked for user {UserId}. Reason: {Reason}", userId, reason); + + await _hubContext.Clients.Group($"user_{userId}") + .SendAsync("TokenRevoked", new TokenRevokedNotification + { + UserId = userId, + Reason = reason, + Timestamp = DateTime.UtcNow + }); + + _logger.LogInformation("Token revoked notification sent for user {UserId}", userId); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to send token revoked notification for user {UserId}", userId); + } + } + + /// + public async Task NotifyForceRefreshAsync(long userId) + { + try + { + _logger.LogInformation("Notifying force refresh for user {UserId}", userId); + + await _hubContext.Clients.Group($"user_{userId}") + .SendAsync("ForceRefreshToken", new ForceRefreshNotification + { + UserId = userId, + Timestamp = DateTime.UtcNow + }); + + _logger.LogInformation("Force refresh notification sent for user {UserId}", userId); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to send force refresh notification for user {UserId}", userId); + } + } + + /// + public async Task BroadcastMessageAsync(string message) + { + try + { + _logger.LogInformation("Broadcasting message to all clients: {Message}", message); + + await _hubContext.Clients.All.SendAsync("BroadcastMessage", new BroadcastNotification + { + Message = message, + Timestamp = DateTime.UtcNow + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to broadcast message"); + } + } +} + +/// +/// Notification payload for token revoked event +/// +public class TokenRevokedNotification +{ + public long UserId { get; set; } + public string Reason { get; set; } = string.Empty; + public DateTime Timestamp { get; set; } +} + +/// +/// Notification payload for force refresh event +/// +public class ForceRefreshNotification +{ + public long UserId { get; set; } + public DateTime Timestamp { get; set; } +} + +/// +/// Notification payload for broadcast message +/// +public class BroadcastNotification +{ + public string Message { get; set; } = string.Empty; + public DateTime Timestamp { get; set; } +} diff --git a/src/CMSMicroservice.WebApi/ConfigureServices.cs b/src/CMSMicroservice.WebApi/ConfigureServices.cs index 9c2c50c..cdc66ba 100644 --- a/src/CMSMicroservice.WebApi/ConfigureServices.cs +++ b/src/CMSMicroservice.WebApi/ConfigureServices.cs @@ -1,6 +1,7 @@ using CMSMicroservice.Application.Common.Interfaces; using CMSMicroservice.Infrastructure.Persistence; using CMSMicroservice.WebApi.Common.Services; +using CMSMicroservice.WebApi.Hubs; using MapsterMapper; using System.Reflection; using CMSMicroservice.WebApi.Services; @@ -21,6 +22,10 @@ public static class ConfigureServices services.AddScoped(); services.AddScoped(); + + // Add SignalR services + services.AddSignalR(); + services.AddScoped(); services.AddHttpContextAccessor(); diff --git a/src/CMSMicroservice.WebApi/Hubs/TokenNotificationHub.cs b/src/CMSMicroservice.WebApi/Hubs/TokenNotificationHub.cs new file mode 100644 index 0000000..04568f6 --- /dev/null +++ b/src/CMSMicroservice.WebApi/Hubs/TokenNotificationHub.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Logging; + +namespace CMSMicroservice.WebApi.Hubs; + +/// +/// SignalR Hub for broadcasting token-related notifications to connected BFF clients. +/// This hub is used internally between CMS and BFF services. +/// +public class TokenNotificationHub : Hub +{ + private readonly ILogger _logger; + + public TokenNotificationHub(ILogger logger) + { + _logger = logger; + } + + public override async Task OnConnectedAsync() + { + _logger.LogInformation("Client connected to TokenNotificationHub: {ConnectionId}", Context.ConnectionId); + await base.OnConnectedAsync(); + } + + public override async Task OnDisconnectedAsync(Exception? exception) + { + _logger.LogInformation("Client disconnected from TokenNotificationHub: {ConnectionId}, Exception: {Exception}", + Context.ConnectionId, exception?.Message); + await base.OnDisconnectedAsync(exception); + } + + /// + /// Subscribe to notifications for a specific user + /// + public async Task SubscribeToUser(long userId) + { + await Groups.AddToGroupAsync(Context.ConnectionId, $"user_{userId}"); + _logger.LogInformation("Client {ConnectionId} subscribed to user_{UserId}", Context.ConnectionId, userId); + } + + /// + /// Unsubscribe from notifications for a specific user + /// + public async Task UnsubscribeFromUser(long userId) + { + await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"user_{userId}"); + _logger.LogInformation("Client {ConnectionId} unsubscribed from user_{UserId}", Context.ConnectionId, userId); + } +} diff --git a/src/CMSMicroservice.WebApi/Program.cs b/src/CMSMicroservice.WebApi/Program.cs index d168d00..f9bac0d 100644 --- a/src/CMSMicroservice.WebApi/Program.cs +++ b/src/CMSMicroservice.WebApi/Program.cs @@ -1,5 +1,6 @@ using CMSMicroservice.Infrastructure.Persistence; using CMSMicroservice.Infrastructure.Data.Seeding; +using CMSMicroservice.WebApi.Hubs; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -169,6 +170,10 @@ app.MapHealthChecks("/health/live", new Microsoft.AspNetCore.Diagnostics.HealthC }); app.MapControllers(); app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true }); // Configure the HTTP request pipeline. + +// Map SignalR Hub for token notifications +app.MapHub("/hubs/token-notification"); + app.ConfigureGrpcEndpoints(Assembly.GetExecutingAssembly(), endpoints => { // endpoints.MapGrpcService(); diff --git a/src/CMSMicroservice.WebApi/Services/CityService.cs b/src/CMSMicroservice.WebApi/Services/CityService.cs new file mode 100644 index 0000000..132dd3d --- /dev/null +++ b/src/CMSMicroservice.WebApi/Services/CityService.cs @@ -0,0 +1,25 @@ +using CMSMicroservice.Protobuf.Protos.City; +using CMSMicroservice.WebApi.Common.Services; +using CMSMicroservice.Application.CityCQ.Queries.GetAllCitiesByFilter; + +namespace CMSMicroservice.WebApi.Services; + +public class CityService : CityContract.CityContractBase +{ + private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; + + public CityService(IDispatchRequestToCQRS dispatchRequestToCQRS) + { + _dispatchRequestToCQRS = dispatchRequestToCQRS; + } + + public override async Task GetAllCitiesByFilter( + GetAllCitiesByFilterRequest request, + ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle< + GetAllCitiesByFilterRequest, + GetAllCitiesByFilterQuery, + GetAllCitiesByFilterResponse>(request, context); + } +} diff --git a/src/CMSMicroservice.WebApi/Services/ClubMembershipService.cs b/src/CMSMicroservice.WebApi/Services/ClubMembershipService.cs index af62c32..0b8cfa5 100644 --- a/src/CMSMicroservice.WebApi/Services/ClubMembershipService.cs +++ b/src/CMSMicroservice.WebApi/Services/ClubMembershipService.cs @@ -3,6 +3,7 @@ using CMSMicroservice.WebApi.Common.Services; using CMSMicroservice.Application.ClubMembershipCQ.Commands.ActivateClubMembership; using CMSMicroservice.Application.ClubMembershipCQ.Commands.DeactivateClubMembership; using CMSMicroservice.Application.ClubMembershipCQ.Commands.AssignClubFeature; +using CMSMicroservice.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract; using CMSMicroservice.Application.ClubMembershipCQ.Queries.GetClubMembership; using CMSMicroservice.Application.ClubMembershipCQ.Queries.GetAllClubMemberships; using CMSMicroservice.Application.ClubMembershipCQ.Queries.GetClubMembershipHistory; @@ -65,4 +66,9 @@ public class ClubMembershipService : ClubMembershipContract.ClubMembershipContra { return await _dispatchRequestToCQRS.Handle(request, context); } + + public override async Task AcceptClubMembershipContract(AcceptClubMembershipContractRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } } diff --git a/src/CMSMicroservice.WebApi/Services/UserService.cs b/src/CMSMicroservice.WebApi/Services/UserService.cs index 13abc6b..f6a0b68 100644 --- a/src/CMSMicroservice.WebApi/Services/UserService.cs +++ b/src/CMSMicroservice.WebApi/Services/UserService.cs @@ -8,6 +8,7 @@ using CMSMicroservice.Application.UserCQ.Queries.GetAllUserByFilter; using CMSMicroservice.Application.UserCQ.Queries.GetJwtToken; using CMSMicroservice.Application.UserCQ.Queries.AdminGetJwtToken; using CMSMicroservice.Application.UserCQ.Commands.SetPasswordForUser; +using CMSMicroservice.Application.UserCQ.Commands.RefreshToken; namespace CMSMicroservice.WebApi.Services; public class UserService : UserContract.UserContractBase { @@ -49,4 +50,8 @@ public class UserService : UserContract.UserContractBase { return await _dispatchRequestToCQRS.Handle(request, context); } + public override async Task RefreshToken(RefreshTokenRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } }