refactor: rename UserWalletChangeLog→UserWalletHistory, add History interceptor & migration
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m11s

- Rename UserWalletChangeLog to UserWalletHistory across 54+ files (entities, configs, DTOs, commands, queries, protos, services)
- Rename 34 files and 11 directories accordingly
- Rename proto file userwalletchangelog.proto → userwallethistory.proto
- Add IHasHistory<T> generic interface for history auto-tracking
- Implement IHasHistory<PackageHistory> on Package entity
- Add HistoryTrackingSaveChangesInterceptor (reflection-based, auto-fills Old* values from OriginalValues)
- Wire interceptor in DI and ApplicationDbContext
- Add EF migration Q27_HistoryTables_And_RenameWalletHistory:
  * RenameTable UserWalletChangeLogs → UserWalletHistories (preserves data)
  * Rename PK, FK constraints and indexes via sp_rename
  * CreateTable ClubMembershipCycleHistories + PackageHistories
This commit is contained in:
masoodafar-web
2026-02-27 06:22:15 +03:30
parent fdbb91d2e1
commit 10d2ca20d1
86 changed files with 6255 additions and 472 deletions
@@ -29,7 +29,7 @@
<Protobuf Include="Protos\user.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\useraddress.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\userwallet.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\userwalletchangelog.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\userwallethistory.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\usercarts.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\productgalleries.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\factordetails.proto" ProtoRoot="Protos\" GrpcServices="Both" />
@@ -51,9 +51,9 @@ service UserWalletContract
get: "/Customer/GetWallet"
};
};
rpc GetCustomerWalletChangeLog(GetCustomerWalletChangeLogRequest) returns (GetCustomerWalletChangeLogResponse){
rpc GetCustomerWalletHistory(GetCustomerWalletHistoryRequest) returns (GetCustomerWalletHistoryResponse){
option (google.api.http) = {
post: "/Customer/GetWalletChangeLog"
post: "/Customer/GetWalletHistory"
body: "*"
};
};
@@ -167,19 +167,19 @@ message GetCustomerWalletResponse
int32 wallet_mode = 4; // 0=Normal, 1=Magic
}
message GetCustomerWalletChangeLogRequest
message GetCustomerWalletHistoryRequest
{
google.protobuf.Int64Value reference_id = 1;
google.protobuf.BoolValue is_increase = 2;
}
message GetCustomerWalletChangeLogResponse
message GetCustomerWalletHistoryResponse
{
messages.MetaData meta_data = 1;
repeated CustomerWalletChangeLogModel models = 2;
repeated CustomerWalletHistoryModel models = 2;
}
message CustomerWalletChangeLogModel
message CustomerWalletHistoryModel
{
int64 current_balance = 1;
int64 change_value = 2;
@@ -1,6 +1,6 @@
syntax = "proto3";
package userwalletchangelog;
package userwallethistory;
import "public_messages.proto";
import "google/protobuf/empty.proto";
@@ -9,42 +9,42 @@ import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";
option csharp_namespace = "CMSMicroservice.Protobuf.Protos.UserWalletChangeLog";
option csharp_namespace = "CMSMicroservice.Protobuf.Protos.UserWalletHistory";
service UserWalletChangeLogContract
service UserWalletHistoryContract
{
rpc CreateNewUserWalletChangeLog(CreateNewUserWalletChangeLogRequest) returns (CreateNewUserWalletChangeLogResponse){
rpc CreateNewUserWalletHistory(CreateNewUserWalletHistoryRequest) returns (CreateNewUserWalletHistoryResponse){
option (google.api.http) = {
post: "/CreateNewUserWalletChangeLog"
post: "/CreateNewUserWalletHistory"
body: "*"
};
};
rpc UpdateUserWalletChangeLog(UpdateUserWalletChangeLogRequest) returns (google.protobuf.Empty){
rpc UpdateUserWalletHistory(UpdateUserWalletHistoryRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
put: "/UpdateUserWalletChangeLog"
put: "/UpdateUserWalletHistory"
body: "*"
};
};
rpc DeleteUserWalletChangeLog(DeleteUserWalletChangeLogRequest) returns (google.protobuf.Empty){
rpc DeleteUserWalletHistory(DeleteUserWalletHistoryRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
delete: "/DeleteUserWalletChangeLog"
delete: "/DeleteUserWalletHistory"
body: "*"
};
};
rpc GetUserWalletChangeLog(GetUserWalletChangeLogRequest) returns (GetUserWalletChangeLogResponse){
rpc GetUserWalletHistory(GetUserWalletHistoryRequest) returns (GetUserWalletHistoryResponse){
option (google.api.http) = {
get: "/GetUserWalletChangeLog"
get: "/GetUserWalletHistory"
};
};
rpc GetAllUserWalletChangeLogByFilter(GetAllUserWalletChangeLogByFilterRequest) returns (GetAllUserWalletChangeLogByFilterResponse){
rpc GetAllUserWalletHistoryByFilter(GetAllUserWalletHistoryByFilterRequest) returns (GetAllUserWalletHistoryByFilterResponse){
option (google.api.http) = {
get: "/GetAllUserWalletChangeLogByFilter"
get: "/GetAllUserWalletHistoryByFilter"
};
};
}
message CreateNewUserWalletChangeLogRequest
message CreateNewUserWalletHistoryRequest
{
int64 wallet_id = 1;
int64 current_balance = 2;
@@ -54,11 +54,11 @@ message CreateNewUserWalletChangeLogRequest
bool is_increase = 6;
google.protobuf.Int64Value refrence_id = 7;
}
message CreateNewUserWalletChangeLogResponse
message CreateNewUserWalletHistoryResponse
{
int64 id = 1;
}
message UpdateUserWalletChangeLogRequest
message UpdateUserWalletHistoryRequest
{
int64 id = 1;
int64 wallet_id = 2;
@@ -69,15 +69,15 @@ message UpdateUserWalletChangeLogRequest
bool is_increase = 7;
google.protobuf.Int64Value refrence_id = 8;
}
message DeleteUserWalletChangeLogRequest
message DeleteUserWalletHistoryRequest
{
int64 id = 1;
}
message GetUserWalletChangeLogRequest
message GetUserWalletHistoryRequest
{
int64 id = 1;
}
message GetUserWalletChangeLogResponse
message GetUserWalletHistoryResponse
{
int64 id = 1;
int64 wallet_id = 2;
@@ -89,13 +89,13 @@ message GetUserWalletChangeLogResponse
google.protobuf.Int64Value refrence_id = 8;
google.protobuf.Timestamp created_at = 9;
}
message GetAllUserWalletChangeLogByFilterRequest
message GetAllUserWalletHistoryByFilterRequest
{
messages.PaginationState pagination_state = 1;
google.protobuf.StringValue sort_by = 2;
GetAllUserWalletChangeLogByFilterFilter filter = 3;
GetAllUserWalletHistoryByFilterFilter filter = 3;
}
message GetAllUserWalletChangeLogByFilterFilter
message GetAllUserWalletHistoryByFilterFilter
{
google.protobuf.Int64Value id = 1;
google.protobuf.Int64Value wallet_id = 2;
@@ -105,12 +105,12 @@ message GetAllUserWalletChangeLogByFilterFilter
google.protobuf.Int64Value refrence_id = 6;
google.protobuf.Int64Value user_id = 7;
}
message GetAllUserWalletChangeLogByFilterResponse
message GetAllUserWalletHistoryByFilterResponse
{
messages.MetaData meta_data = 1;
repeated GetAllUserWalletChangeLogByFilterResponseModel models = 2;
repeated GetAllUserWalletHistoryByFilterResponseModel models = 2;
}
message GetAllUserWalletChangeLogByFilterResponseModel
message GetAllUserWalletHistoryByFilterResponseModel
{
int64 id = 1;
int64 wallet_id = 2;
@@ -1,19 +0,0 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
public class DeleteUserWalletChangeLogRequestValidator : AbstractValidator<DeleteUserWalletChangeLogRequest>
{
public DeleteUserWalletChangeLogRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserWalletChangeLogRequest>.CreateWithOptions((DeleteUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,17 +0,0 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
public class GetAllUserWalletChangeLogByFilterRequestValidator : AbstractValidator<GetAllUserWalletChangeLogByFilterRequest>
{
public GetAllUserWalletChangeLogByFilterRequestValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserWalletChangeLogByFilterRequest>.CreateWithOptions((GetAllUserWalletChangeLogByFilterRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,10 +1,10 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class CreateNewUserWalletChangeLogRequestValidator : AbstractValidator<CreateNewUserWalletChangeLogRequest>
public class CreateNewUserWalletHistoryRequestValidator : AbstractValidator<CreateNewUserWalletHistoryRequest>
{
public CreateNewUserWalletChangeLogRequestValidator()
public CreateNewUserWalletHistoryRequestValidator()
{
RuleFor(model => model.WalletId)
.NotNull();
@@ -21,7 +21,7 @@ public class CreateNewUserWalletChangeLogRequestValidator : AbstractValidator<Cr
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<CreateNewUserWalletChangeLogRequest>.CreateWithOptions((CreateNewUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName)));
var result = await ValidateAsync(ValidationContext<CreateNewUserWalletHistoryRequest>.CreateWithOptions((CreateNewUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
@@ -0,0 +1,19 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class DeleteUserWalletHistoryRequestValidator : AbstractValidator<DeleteUserWalletHistoryRequest>
{
public DeleteUserWalletHistoryRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserWalletHistoryRequest>.CreateWithOptions((DeleteUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -0,0 +1,17 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class GetAllUserWalletHistoryByFilterRequestValidator : AbstractValidator<GetAllUserWalletHistoryByFilterRequest>
{
public GetAllUserWalletHistoryByFilterRequestValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserWalletHistoryByFilterRequest>.CreateWithOptions((GetAllUserWalletHistoryByFilterRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,17 +1,17 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class GetUserWalletChangeLogRequestValidator : AbstractValidator<GetUserWalletChangeLogRequest>
public class GetUserWalletHistoryRequestValidator : AbstractValidator<GetUserWalletHistoryRequest>
{
public GetUserWalletChangeLogRequestValidator()
public GetUserWalletHistoryRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetUserWalletChangeLogRequest>.CreateWithOptions((GetUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName)));
var result = await ValidateAsync(ValidationContext<GetUserWalletHistoryRequest>.CreateWithOptions((GetUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
@@ -1,10 +1,10 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class UpdateUserWalletChangeLogRequestValidator : AbstractValidator<UpdateUserWalletChangeLogRequest>
public class UpdateUserWalletHistoryRequestValidator : AbstractValidator<UpdateUserWalletHistoryRequest>
{
public UpdateUserWalletChangeLogRequestValidator()
public UpdateUserWalletHistoryRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
@@ -23,7 +23,7 @@ public class UpdateUserWalletChangeLogRequestValidator : AbstractValidator<Updat
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<UpdateUserWalletChangeLogRequest>.CreateWithOptions((UpdateUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName)));
var result = await ValidateAsync(ValidationContext<UpdateUserWalletHistoryRequest>.CreateWithOptions((UpdateUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);