feat(user): add user invitation functionality and enhance OTP verification
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m27s

- Introduced UserInvitation entity and updated IApplicationDbContext to include UserInvitations DbSet.
- Enhanced VerifyOtpTokenCommand and its handler to support optional inviter mobile number for user registration.
- Added new Protobuf definitions for GetMyInvitees and GetInvitationsByFilter RPCs to manage user invitations.
- Updated UserService to implement methods for retrieving invitees and invitations based on filters.
- Bumped Protobuf project version to reflect the addition of new features.
This commit is contained in:
masoodafar-web
2026-09-20 23:33:03 +03:30
parent f31fb5ee39
commit 2b958bd214
17 changed files with 6019 additions and 3 deletions
@@ -115,6 +115,16 @@ service UserContract
};
};
rpc GetMyInvitees(GetMyInviteesRequest) returns (GetMyInviteesResponse){
option (google.api.http) = {
get: "/Customer/GetMyInvitees"
};
};
rpc GetInvitationsByFilter(GetInvitationsByFilterRequest) returns (GetInvitationsByFilterResponse){
option (google.api.http) = {
get: "/GetInvitationsByFilter"
};
};
rpc UploadCustomerAvatar(UploadCustomerAvatarRequest) returns (UploadCustomerAvatarResponse){
option (google.api.http) = {
post: "/Customer/UploadAvatar"
@@ -294,6 +304,8 @@ message VerifyOtpTokenRequest
string purpose = 2;
string code = 3;
google.protobuf.StringValue parent_referral_code = 4;
// شماره موبایل دعوت‌کننده (اختیاری؛ فقط برای ثبت‌نام جدید)
google.protobuf.StringValue inviter_mobile = 5;
}
message VerifyOtpTokenResponse
{
@@ -466,3 +478,78 @@ message UpdateCustomerSettingsRequest
google.protobuf.StringValue time_zone = 6;
google.protobuf.BoolValue two_factor_auth_enabled = 7;
}
// ============= Inviter (دعوت‌کننده) — جدا از معرف شبکه =============
message GetMyInviteesRequest
{
city.PaginationState pagination_state = 1;
// ALL | ACTIVE | INACTIVE — بر اساس ClubMembership.IsActive
google.protobuf.StringValue club_status_filter = 2;
}
message GetMyInviteesResponse
{
city.MetaData meta_data = 1;
repeated InviteeModel invitees = 2;
InviteeStats stats = 3;
}
message InviteeModel
{
int64 user_id = 1;
google.protobuf.StringValue first_name = 2;
google.protobuf.StringValue last_name = 3;
string mobile = 4;
google.protobuf.Timestamp registered_at = 5;
bool is_club_active = 6;
}
message InviteeStats
{
int32 total_invitees = 1;
int32 club_active_count = 2;
int32 club_inactive_count = 3;
}
message GetInvitationsByFilterRequest
{
city.PaginationState pagination_state = 1;
google.protobuf.StringValue sort_by = 2;
GetInvitationsByFilterFilter filter = 3;
}
message GetInvitationsByFilterFilter
{
google.protobuf.StringValue inviter_mobile = 1;
google.protobuf.StringValue inviter_first_name = 2;
google.protobuf.StringValue inviter_last_name = 3;
google.protobuf.StringValue invitee_mobile = 4;
google.protobuf.StringValue invitee_first_name = 5;
google.protobuf.StringValue invitee_last_name = 6;
google.protobuf.BoolValue invitee_club_active = 7;
google.protobuf.Timestamp created_from = 8;
google.protobuf.Timestamp created_to = 9;
}
message GetInvitationsByFilterResponse
{
city.MetaData meta_data = 1;
repeated InvitationReportModel models = 2;
}
message InvitationReportModel
{
int64 id = 1;
int64 inviter_user_id = 2;
google.protobuf.StringValue inviter_first_name = 3;
google.protobuf.StringValue inviter_last_name = 4;
string inviter_mobile = 5;
int64 invitee_user_id = 6;
google.protobuf.StringValue invitee_first_name = 7;
google.protobuf.StringValue invitee_last_name = 8;
string invitee_mobile = 9;
google.protobuf.Timestamp invitee_registered_at = 10;
bool invitee_club_active = 11;
google.protobuf.Timestamp invited_at = 12;
}