agency房间列表

This commit is contained in:
zhx 2026-06-30 13:05:13 +08:00
parent ce4f1dc4c1
commit 3af61b2468
38 changed files with 2876 additions and 1162 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1189,6 +1189,18 @@ message ListRoomsRequest {
bool all_visible_regions = 10;
}
// ListRoomsByOwnersRequest active
// owner_user_ids gateway
message ListRoomsByOwnersRequest {
RequestMeta meta = 1;
int64 viewer_user_id = 2;
repeated int64 owner_user_ids = 3;
string tab = 4;
string cursor = 5;
int32 limit = 6;
string query = 7;
}
// ListRoomFeedsRequest Mine visited/friend/following/followed
//
message ListRoomFeedsRequest {
@ -1456,6 +1468,7 @@ service RoomQueryService {
rpc AdminListRobotRooms(AdminListRobotRoomsRequest) returns (AdminListRobotRoomsResponse);
rpc AdminFilterAvailableRoomRobots(AdminFilterAvailableRoomRobotsRequest) returns (AdminFilterAvailableRoomRobotsResponse);
rpc ListRooms(ListRoomsRequest) returns (ListRoomsResponse);
rpc ListRoomsByOwners(ListRoomsByOwnersRequest) returns (ListRoomsResponse);
rpc ListRoomFeeds(ListRoomFeedsRequest) returns (ListRoomsResponse);
rpc ListRoomGiftLeaderboard(ListRoomGiftLeaderboardRequest) returns (ListRoomGiftLeaderboardResponse);
rpc GetMyRoom(GetMyRoomRequest) returns (GetMyRoomResponse);

View File

@ -1570,6 +1570,7 @@ const (
RoomQueryService_AdminListRobotRooms_FullMethodName = "/hyapp.room.v1.RoomQueryService/AdminListRobotRooms"
RoomQueryService_AdminFilterAvailableRoomRobots_FullMethodName = "/hyapp.room.v1.RoomQueryService/AdminFilterAvailableRoomRobots"
RoomQueryService_ListRooms_FullMethodName = "/hyapp.room.v1.RoomQueryService/ListRooms"
RoomQueryService_ListRoomsByOwners_FullMethodName = "/hyapp.room.v1.RoomQueryService/ListRoomsByOwners"
RoomQueryService_ListRoomFeeds_FullMethodName = "/hyapp.room.v1.RoomQueryService/ListRoomFeeds"
RoomQueryService_ListRoomGiftLeaderboard_FullMethodName = "/hyapp.room.v1.RoomQueryService/ListRoomGiftLeaderboard"
RoomQueryService_GetMyRoom_FullMethodName = "/hyapp.room.v1.RoomQueryService/GetMyRoom"
@ -1596,6 +1597,7 @@ type RoomQueryServiceClient interface {
AdminListRobotRooms(ctx context.Context, in *AdminListRobotRoomsRequest, opts ...grpc.CallOption) (*AdminListRobotRoomsResponse, error)
AdminFilterAvailableRoomRobots(ctx context.Context, in *AdminFilterAvailableRoomRobotsRequest, opts ...grpc.CallOption) (*AdminFilterAvailableRoomRobotsResponse, error)
ListRooms(ctx context.Context, in *ListRoomsRequest, opts ...grpc.CallOption) (*ListRoomsResponse, error)
ListRoomsByOwners(ctx context.Context, in *ListRoomsByOwnersRequest, opts ...grpc.CallOption) (*ListRoomsResponse, error)
ListRoomFeeds(ctx context.Context, in *ListRoomFeedsRequest, opts ...grpc.CallOption) (*ListRoomsResponse, error)
ListRoomGiftLeaderboard(ctx context.Context, in *ListRoomGiftLeaderboardRequest, opts ...grpc.CallOption) (*ListRoomGiftLeaderboardResponse, error)
GetMyRoom(ctx context.Context, in *GetMyRoomRequest, opts ...grpc.CallOption) (*GetMyRoomResponse, error)
@ -1705,6 +1707,16 @@ func (c *roomQueryServiceClient) ListRooms(ctx context.Context, in *ListRoomsReq
return out, nil
}
func (c *roomQueryServiceClient) ListRoomsByOwners(ctx context.Context, in *ListRoomsByOwnersRequest, opts ...grpc.CallOption) (*ListRoomsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListRoomsResponse)
err := c.cc.Invoke(ctx, RoomQueryService_ListRoomsByOwners_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *roomQueryServiceClient) ListRoomFeeds(ctx context.Context, in *ListRoomFeedsRequest, opts ...grpc.CallOption) (*ListRoomsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListRoomsResponse)
@ -1810,6 +1822,7 @@ type RoomQueryServiceServer interface {
AdminListRobotRooms(context.Context, *AdminListRobotRoomsRequest) (*AdminListRobotRoomsResponse, error)
AdminFilterAvailableRoomRobots(context.Context, *AdminFilterAvailableRoomRobotsRequest) (*AdminFilterAvailableRoomRobotsResponse, error)
ListRooms(context.Context, *ListRoomsRequest) (*ListRoomsResponse, error)
ListRoomsByOwners(context.Context, *ListRoomsByOwnersRequest) (*ListRoomsResponse, error)
ListRoomFeeds(context.Context, *ListRoomFeedsRequest) (*ListRoomsResponse, error)
ListRoomGiftLeaderboard(context.Context, *ListRoomGiftLeaderboardRequest) (*ListRoomGiftLeaderboardResponse, error)
GetMyRoom(context.Context, *GetMyRoomRequest) (*GetMyRoomResponse, error)
@ -1856,6 +1869,9 @@ func (UnimplementedRoomQueryServiceServer) AdminFilterAvailableRoomRobots(contex
func (UnimplementedRoomQueryServiceServer) ListRooms(context.Context, *ListRoomsRequest) (*ListRoomsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListRooms not implemented")
}
func (UnimplementedRoomQueryServiceServer) ListRoomsByOwners(context.Context, *ListRoomsByOwnersRequest) (*ListRoomsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListRoomsByOwners not implemented")
}
func (UnimplementedRoomQueryServiceServer) ListRoomFeeds(context.Context, *ListRoomFeedsRequest) (*ListRoomsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListRoomFeeds not implemented")
}
@ -2066,6 +2082,24 @@ func _RoomQueryService_ListRooms_Handler(srv interface{}, ctx context.Context, d
return interceptor(ctx, in, info, handler)
}
func _RoomQueryService_ListRoomsByOwners_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListRoomsByOwnersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RoomQueryServiceServer).ListRoomsByOwners(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: RoomQueryService_ListRoomsByOwners_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RoomQueryServiceServer).ListRoomsByOwners(ctx, req.(*ListRoomsByOwnersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _RoomQueryService_ListRoomFeeds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListRoomFeedsRequest)
if err := dec(in); err != nil {
@ -2271,6 +2305,10 @@ var RoomQueryService_ServiceDesc = grpc.ServiceDesc{
MethodName: "ListRooms",
Handler: _RoomQueryService_ListRooms_Handler,
},
{
MethodName: "ListRoomsByOwners",
Handler: _RoomQueryService_ListRoomsByOwners_Handler,
},
{
MethodName: "ListRoomFeeds",
Handler: _RoomQueryService_ListRoomFeeds_Handler,

View File

@ -5120,6 +5120,136 @@ func (x *SetAgencyJoinEnabledResponse) GetAgency() *Agency {
return nil
}
type UpdateAgencyProfileRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Meta *RequestMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"`
CommandId string `protobuf:"bytes,2,opt,name=command_id,json=commandId,proto3" json:"command_id,omitempty"`
OperatorUserId int64 `protobuf:"varint,3,opt,name=operator_user_id,json=operatorUserId,proto3" json:"operator_user_id,omitempty"`
AgencyId int64 `protobuf:"varint,4,opt,name=agency_id,json=agencyId,proto3" json:"agency_id,omitempty"`
Name *string `protobuf:"bytes,5,opt,name=name,proto3,oneof" json:"name,omitempty"`
Avatar *string `protobuf:"bytes,6,opt,name=avatar,proto3,oneof" json:"avatar,omitempty"`
}
func (x *UpdateAgencyProfileRequest) Reset() {
*x = UpdateAgencyProfileRequest{}
mi := &file_proto_user_v1_host_proto_msgTypes[75]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateAgencyProfileRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateAgencyProfileRequest) ProtoMessage() {}
func (x *UpdateAgencyProfileRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_user_v1_host_proto_msgTypes[75]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateAgencyProfileRequest.ProtoReflect.Descriptor instead.
func (*UpdateAgencyProfileRequest) Descriptor() ([]byte, []int) {
return file_proto_user_v1_host_proto_rawDescGZIP(), []int{75}
}
func (x *UpdateAgencyProfileRequest) GetMeta() *RequestMeta {
if x != nil {
return x.Meta
}
return nil
}
func (x *UpdateAgencyProfileRequest) GetCommandId() string {
if x != nil {
return x.CommandId
}
return ""
}
func (x *UpdateAgencyProfileRequest) GetOperatorUserId() int64 {
if x != nil {
return x.OperatorUserId
}
return 0
}
func (x *UpdateAgencyProfileRequest) GetAgencyId() int64 {
if x != nil {
return x.AgencyId
}
return 0
}
func (x *UpdateAgencyProfileRequest) GetName() string {
if x != nil && x.Name != nil {
return *x.Name
}
return ""
}
func (x *UpdateAgencyProfileRequest) GetAvatar() string {
if x != nil && x.Avatar != nil {
return *x.Avatar
}
return ""
}
type UpdateAgencyProfileResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Agency *Agency `protobuf:"bytes,1,opt,name=agency,proto3" json:"agency,omitempty"`
}
func (x *UpdateAgencyProfileResponse) Reset() {
*x = UpdateAgencyProfileResponse{}
mi := &file_proto_user_v1_host_proto_msgTypes[76]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpdateAgencyProfileResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateAgencyProfileResponse) ProtoMessage() {}
func (x *UpdateAgencyProfileResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_user_v1_host_proto_msgTypes[76]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateAgencyProfileResponse.ProtoReflect.Descriptor instead.
func (*UpdateAgencyProfileResponse) Descriptor() ([]byte, []int) {
return file_proto_user_v1_host_proto_rawDescGZIP(), []int{76}
}
func (x *UpdateAgencyProfileResponse) GetAgency() *Agency {
if x != nil {
return x.Agency
}
return nil
}
var File_proto_user_v1_host_proto protoreflect.FileDescriptor
var file_proto_user_v1_host_proto_rawDesc = []byte{
@ -5954,220 +6084,248 @@ var file_proto_user_v1_host_proto_rawDesc = []byte{
0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x61, 0x67,
0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63,
0x79, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x32, 0xd5, 0x12, 0x0a, 0x0f, 0x55, 0x73,
0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a,
0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12,
0x79, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xfc, 0x01, 0x0a, 0x1a, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65,
0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61,
0x74, 0x6f, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49,
0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04,
0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x49, 0x64, 0x12, 0x17,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61,
0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61,
0x72, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x09, 0x0a,
0x07, 0x5f, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x4c, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x06,
0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x32, 0xc3, 0x13, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x48,
0x6f, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x53, 0x65,
0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61,
0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0d, 0x41, 0x70, 0x70,
0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79,
0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0d,
0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x2e,
0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70,
0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x17, 0x52, 0x65, 0x76, 0x69,
0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79,
0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41,
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79,
0x48, 0x6f, 0x73, 0x74, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48,
0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41,
0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x57, 0x0a, 0x0c, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63,
0x79, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x49, 0x6e,
0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x12, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74,
0x65, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f,
0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x0f, 0x4c, 0x69,
0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x12, 0x25, 0x2e,
0x41, 0x70, 0x70, 0x6c, 0x79, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x17, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41,
0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c,
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x5d, 0x0a, 0x0e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73,
0x74, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x73, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x69, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57,
0x0a, 0x0c, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22,
0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49,
0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x49, 0x6e, 0x76, 0x69, 0x74,
0x65, 0x42, 0x44, 0x12, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f,
0x73, 0x74, 0x12, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42,
0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42,
0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x4c, 0x69, 0x73,
0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65,
0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67,
0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e,
0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x44, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65,
0x72, 0x42, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14,
0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65,
0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65,
0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a,
0x0e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12,
0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a,
0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x11, 0x47, 0x65,
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65,
0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c,
0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63,
0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x73, 0x74, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69,
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x4c, 0x69,
0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x44, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x6f,
0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76,
0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x72, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e,
0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73,
0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74,
0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25,
0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65,
0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x2e,
0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61,
0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70,
0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47,
0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50,
0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66,
0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44,
0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x6f, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72,
0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53,
0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65,
0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x90, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43,
0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65,
0x67, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43,
0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65,
0x67, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72,
0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f,
0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70,
0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53,
0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e,
0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x2e, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41,
0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78,
0x0a, 0x17, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43,
0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70,
0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42,
0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75,
0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41,
0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x26, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65,
0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a,
0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79,
0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x6c,
0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72,
0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f,
0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48,
0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x48, 0x6f,
0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68,
0x47, 0x65, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x48,
0x6f, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66,
0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x44, 0x50, 0x72, 0x6f,
0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14,
0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72, 0x6f,
0x66, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c,
0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x72,
0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x90, 0x01,
0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e,
0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f,
0x6e, 0x12, 0x35, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e,
0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74,
0x69, 0x76, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x49, 0x6e,
0x4d, 0x79, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x69, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53,
0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x28, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f,
0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d,
0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x47,
0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x68, 0x79, 0x61, 0x70,
0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65,
0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x17, 0x43,
0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61,
0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75,
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69,
0x6e, 0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x42, 0x75, 0x73, 0x69, 0x6e,
0x65, 0x73, 0x73, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70,
0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65,
0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x47, 0x65,
0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x32, 0xc6, 0x07, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x41, 0x64,
0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65,
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x42, 0x44, 0x12, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x42, 0x44, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x44, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x44, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x10,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72,
0x12, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65,
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43,
0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x6c, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c,
0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e,
0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x2c, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c,
0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72,
0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x72, 0x6f,
0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc6, 0x07, 0x0a,
0x14, 0x55, 0x73, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42,
0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44,
0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e,
0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44,
0x12, 0x1e, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1f, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x54, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x42, 0x44, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x74, 0x42, 0x44, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x44, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65,
0x6c, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13,
0x53, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x12, 0x29, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65,
0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x57, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12,
0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73,
0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e,
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x41, 0x67, 0x65,
0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65,
0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57,
0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22,
0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x41, 0x67,
0x65, 0x6e, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x67,
0x65, 0x6e, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x26, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x53, 0x65, 0x74,
0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a,
0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53,
0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61,
0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23,
0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x12, 0x21, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63,
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22, 0x2e, 0x68, 0x79, 0x61, 0x70,
0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e,
0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x60, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74,
0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63,
0x79, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x68,
0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74,
0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x64, 0x12, 0x2a, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4a, 0x6f, 0x69, 0x6e, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e,
0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65,
0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c,
0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x26, 0x5a, 0x24, 0x68, 0x79,
0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72,
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x68, 0x79, 0x61, 0x70, 0x70,
0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e,
0x63, 0x79, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x26, 0x5a, 0x24, 0x68, 0x79, 0x61, 0x70, 0x70, 0x2e, 0x6c,
0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x75,
0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -6182,7 +6340,7 @@ func file_proto_user_v1_host_proto_rawDescGZIP() []byte {
return file_proto_user_v1_host_proto_rawDescData
}
var file_proto_user_v1_host_proto_msgTypes = make([]protoimpl.MessageInfo, 76)
var file_proto_user_v1_host_proto_msgTypes = make([]protoimpl.MessageInfo, 78)
var file_proto_user_v1_host_proto_goTypes = []any{
(*HostProfile)(nil), // 0: hyapp.user.v1.HostProfile
(*Agency)(nil), // 1: hyapp.user.v1.Agency
@ -6259,156 +6417,162 @@ var file_proto_user_v1_host_proto_goTypes = []any{
(*SetAgencyStatusResponse)(nil), // 72: hyapp.user.v1.SetAgencyStatusResponse
(*SetAgencyJoinEnabledRequest)(nil), // 73: hyapp.user.v1.SetAgencyJoinEnabledRequest
(*SetAgencyJoinEnabledResponse)(nil), // 74: hyapp.user.v1.SetAgencyJoinEnabledResponse
nil, // 75: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry
(*RequestMeta)(nil), // 76: hyapp.user.v1.RequestMeta
(*UpdateAgencyProfileRequest)(nil), // 75: hyapp.user.v1.UpdateAgencyProfileRequest
(*UpdateAgencyProfileResponse)(nil), // 76: hyapp.user.v1.UpdateAgencyProfileResponse
nil, // 77: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry
(*RequestMeta)(nil), // 78: hyapp.user.v1.RequestMeta
}
var file_proto_user_v1_host_proto_depIdxs = []int32{
76, // 0: hyapp.user.v1.SearchAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 0: hyapp.user.v1.SearchAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 1: hyapp.user.v1.SearchAgenciesResponse.agencies:type_name -> hyapp.user.v1.Agency
76, // 2: hyapp.user.v1.ApplyToAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 2: hyapp.user.v1.ApplyToAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
7, // 3: hyapp.user.v1.ApplyToAgencyResponse.application:type_name -> hyapp.user.v1.AgencyApplication
76, // 4: hyapp.user.v1.ReviewAgencyApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 4: hyapp.user.v1.ReviewAgencyApplicationRequest.meta:type_name -> hyapp.user.v1.RequestMeta
7, // 5: hyapp.user.v1.ReviewAgencyApplicationResponse.application:type_name -> hyapp.user.v1.AgencyApplication
0, // 6: hyapp.user.v1.ReviewAgencyApplicationResponse.host_profile:type_name -> hyapp.user.v1.HostProfile
6, // 7: hyapp.user.v1.ReviewAgencyApplicationResponse.membership:type_name -> hyapp.user.v1.AgencyMembership
76, // 8: hyapp.user.v1.KickAgencyHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 8: hyapp.user.v1.KickAgencyHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta
6, // 9: hyapp.user.v1.KickAgencyHostResponse.membership:type_name -> hyapp.user.v1.AgencyMembership
0, // 10: hyapp.user.v1.KickAgencyHostResponse.host_profile:type_name -> hyapp.user.v1.HostProfile
76, // 11: hyapp.user.v1.InviteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 11: hyapp.user.v1.InviteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
8, // 12: hyapp.user.v1.InviteAgencyResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation
76, // 13: hyapp.user.v1.InviteBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 13: hyapp.user.v1.InviteBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta
8, // 14: hyapp.user.v1.InviteBDResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation
76, // 15: hyapp.user.v1.InviteHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 15: hyapp.user.v1.InviteHostRequest.meta:type_name -> hyapp.user.v1.RequestMeta
8, // 16: hyapp.user.v1.InviteHostResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation
76, // 17: hyapp.user.v1.ListBDLeaderBDsRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 17: hyapp.user.v1.ListBDLeaderBDsRequest.meta:type_name -> hyapp.user.v1.RequestMeta
2, // 18: hyapp.user.v1.ListBDLeaderBDsResponse.bd_profiles:type_name -> hyapp.user.v1.BDProfile
76, // 19: hyapp.user.v1.ListBDLeaderAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 19: hyapp.user.v1.ListBDLeaderAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 20: hyapp.user.v1.ListBDLeaderAgenciesResponse.agencies:type_name -> hyapp.user.v1.Agency
76, // 21: hyapp.user.v1.ListBDAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 21: hyapp.user.v1.ListBDAgenciesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 22: hyapp.user.v1.ListBDAgenciesResponse.agencies:type_name -> hyapp.user.v1.Agency
76, // 23: hyapp.user.v1.ListRoleInvitationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 23: hyapp.user.v1.ListRoleInvitationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta
8, // 24: hyapp.user.v1.ListRoleInvitationsResponse.invitations:type_name -> hyapp.user.v1.RoleInvitation
76, // 25: hyapp.user.v1.GetRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 25: hyapp.user.v1.GetRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta
8, // 26: hyapp.user.v1.GetRoleInvitationResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation
76, // 27: hyapp.user.v1.ProcessRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 27: hyapp.user.v1.ProcessRoleInvitationRequest.meta:type_name -> hyapp.user.v1.RequestMeta
8, // 28: hyapp.user.v1.ProcessRoleInvitationResponse.invitation:type_name -> hyapp.user.v1.RoleInvitation
0, // 29: hyapp.user.v1.ProcessRoleInvitationResponse.host_profile:type_name -> hyapp.user.v1.HostProfile
1, // 30: hyapp.user.v1.ProcessRoleInvitationResponse.agency:type_name -> hyapp.user.v1.Agency
6, // 31: hyapp.user.v1.ProcessRoleInvitationResponse.membership:type_name -> hyapp.user.v1.AgencyMembership
2, // 32: hyapp.user.v1.ProcessRoleInvitationResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile
76, // 33: hyapp.user.v1.GetHostProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 33: hyapp.user.v1.GetHostProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
0, // 34: hyapp.user.v1.GetHostProfileResponse.host_profile:type_name -> hyapp.user.v1.HostProfile
76, // 35: hyapp.user.v1.BatchGetHostProfilesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
75, // 36: hyapp.user.v1.BatchGetHostProfilesResponse.host_profiles:type_name -> hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry
76, // 37: hyapp.user.v1.GetBDProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 35: hyapp.user.v1.BatchGetHostProfilesRequest.meta:type_name -> hyapp.user.v1.RequestMeta
77, // 36: hyapp.user.v1.BatchGetHostProfilesResponse.host_profiles:type_name -> hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry
78, // 37: hyapp.user.v1.GetBDProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
2, // 38: hyapp.user.v1.GetBDProfileResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile
76, // 39: hyapp.user.v1.GetCoinSellerProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 39: hyapp.user.v1.GetCoinSellerProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
3, // 40: hyapp.user.v1.GetCoinSellerProfileResponse.coin_seller_profile:type_name -> hyapp.user.v1.CoinSellerProfile
76, // 41: hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 41: hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest.meta:type_name -> hyapp.user.v1.RequestMeta
4, // 42: hyapp.user.v1.ListActiveCoinSellersInMyRegionResponse.coin_sellers:type_name -> hyapp.user.v1.CoinSellerListItem
76, // 43: hyapp.user.v1.GetUserRoleSummaryRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 43: hyapp.user.v1.GetUserRoleSummaryRequest.meta:type_name -> hyapp.user.v1.RequestMeta
5, // 44: hyapp.user.v1.GetUserRoleSummaryResponse.summary:type_name -> hyapp.user.v1.UserRoleSummary
76, // 45: hyapp.user.v1.GetAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 45: hyapp.user.v1.GetAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 46: hyapp.user.v1.GetAgencyResponse.agency:type_name -> hyapp.user.v1.Agency
76, // 47: hyapp.user.v1.CheckBusinessCapabilityRequest.meta:type_name -> hyapp.user.v1.RequestMeta
76, // 48: hyapp.user.v1.GetAgencyMembersRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 47: hyapp.user.v1.CheckBusinessCapabilityRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 48: hyapp.user.v1.GetAgencyMembersRequest.meta:type_name -> hyapp.user.v1.RequestMeta
6, // 49: hyapp.user.v1.GetAgencyMembersResponse.memberships:type_name -> hyapp.user.v1.AgencyMembership
76, // 50: hyapp.user.v1.GetAgencyApplicationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 50: hyapp.user.v1.GetAgencyApplicationsRequest.meta:type_name -> hyapp.user.v1.RequestMeta
7, // 51: hyapp.user.v1.GetAgencyApplicationsResponse.applications:type_name -> hyapp.user.v1.AgencyApplication
76, // 52: hyapp.user.v1.CreateBDLeaderRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 52: hyapp.user.v1.CreateBDLeaderRequest.meta:type_name -> hyapp.user.v1.RequestMeta
2, // 53: hyapp.user.v1.CreateBDLeaderResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile
76, // 54: hyapp.user.v1.CreateBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 54: hyapp.user.v1.CreateBDRequest.meta:type_name -> hyapp.user.v1.RequestMeta
2, // 55: hyapp.user.v1.CreateBDResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile
76, // 56: hyapp.user.v1.SetBDStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 56: hyapp.user.v1.SetBDStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta
2, // 57: hyapp.user.v1.SetBDStatusResponse.bd_profile:type_name -> hyapp.user.v1.BDProfile
76, // 58: hyapp.user.v1.CreateCoinSellerRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 58: hyapp.user.v1.CreateCoinSellerRequest.meta:type_name -> hyapp.user.v1.RequestMeta
3, // 59: hyapp.user.v1.CreateCoinSellerResponse.coin_seller_profile:type_name -> hyapp.user.v1.CoinSellerProfile
76, // 60: hyapp.user.v1.SetCoinSellerStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 60: hyapp.user.v1.SetCoinSellerStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta
3, // 61: hyapp.user.v1.SetCoinSellerStatusResponse.coin_seller_profile:type_name -> hyapp.user.v1.CoinSellerProfile
76, // 62: hyapp.user.v1.CreateAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 62: hyapp.user.v1.CreateAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 63: hyapp.user.v1.CreateAgencyResponse.agency:type_name -> hyapp.user.v1.Agency
0, // 64: hyapp.user.v1.CreateAgencyResponse.host_profile:type_name -> hyapp.user.v1.HostProfile
6, // 65: hyapp.user.v1.CreateAgencyResponse.membership:type_name -> hyapp.user.v1.AgencyMembership
76, // 66: hyapp.user.v1.CloseAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 66: hyapp.user.v1.CloseAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 67: hyapp.user.v1.CloseAgencyResponse.agency:type_name -> hyapp.user.v1.Agency
76, // 68: hyapp.user.v1.DeleteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 68: hyapp.user.v1.DeleteAgencyRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 69: hyapp.user.v1.DeleteAgencyResponse.agency:type_name -> hyapp.user.v1.Agency
76, // 70: hyapp.user.v1.SetAgencyStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 70: hyapp.user.v1.SetAgencyStatusRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 71: hyapp.user.v1.SetAgencyStatusResponse.agency:type_name -> hyapp.user.v1.Agency
76, // 72: hyapp.user.v1.SetAgencyJoinEnabledRequest.meta:type_name -> hyapp.user.v1.RequestMeta
78, // 72: hyapp.user.v1.SetAgencyJoinEnabledRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 73: hyapp.user.v1.SetAgencyJoinEnabledResponse.agency:type_name -> hyapp.user.v1.Agency
0, // 74: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry.value:type_name -> hyapp.user.v1.HostProfile
9, // 75: hyapp.user.v1.UserHostService.SearchAgencies:input_type -> hyapp.user.v1.SearchAgenciesRequest
11, // 76: hyapp.user.v1.UserHostService.ApplyToAgency:input_type -> hyapp.user.v1.ApplyToAgencyRequest
13, // 77: hyapp.user.v1.UserHostService.ReviewAgencyApplication:input_type -> hyapp.user.v1.ReviewAgencyApplicationRequest
15, // 78: hyapp.user.v1.UserHostService.KickAgencyHost:input_type -> hyapp.user.v1.KickAgencyHostRequest
17, // 79: hyapp.user.v1.UserHostService.InviteAgency:input_type -> hyapp.user.v1.InviteAgencyRequest
19, // 80: hyapp.user.v1.UserHostService.InviteBD:input_type -> hyapp.user.v1.InviteBDRequest
21, // 81: hyapp.user.v1.UserHostService.InviteHost:input_type -> hyapp.user.v1.InviteHostRequest
23, // 82: hyapp.user.v1.UserHostService.ListBDLeaderBDs:input_type -> hyapp.user.v1.ListBDLeaderBDsRequest
25, // 83: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:input_type -> hyapp.user.v1.ListBDLeaderAgenciesRequest
27, // 84: hyapp.user.v1.UserHostService.ListBDAgencies:input_type -> hyapp.user.v1.ListBDAgenciesRequest
29, // 85: hyapp.user.v1.UserHostService.ListRoleInvitations:input_type -> hyapp.user.v1.ListRoleInvitationsRequest
31, // 86: hyapp.user.v1.UserHostService.GetRoleInvitation:input_type -> hyapp.user.v1.GetRoleInvitationRequest
33, // 87: hyapp.user.v1.UserHostService.ProcessRoleInvitation:input_type -> hyapp.user.v1.ProcessRoleInvitationRequest
35, // 88: hyapp.user.v1.UserHostService.GetHostProfile:input_type -> hyapp.user.v1.GetHostProfileRequest
37, // 89: hyapp.user.v1.UserHostService.BatchGetHostProfiles:input_type -> hyapp.user.v1.BatchGetHostProfilesRequest
39, // 90: hyapp.user.v1.UserHostService.GetBDProfile:input_type -> hyapp.user.v1.GetBDProfileRequest
41, // 91: hyapp.user.v1.UserHostService.GetCoinSellerProfile:input_type -> hyapp.user.v1.GetCoinSellerProfileRequest
43, // 92: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:input_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest
45, // 93: hyapp.user.v1.UserHostService.GetUserRoleSummary:input_type -> hyapp.user.v1.GetUserRoleSummaryRequest
47, // 94: hyapp.user.v1.UserHostService.GetAgency:input_type -> hyapp.user.v1.GetAgencyRequest
49, // 95: hyapp.user.v1.UserHostService.CheckBusinessCapability:input_type -> hyapp.user.v1.CheckBusinessCapabilityRequest
51, // 96: hyapp.user.v1.UserHostService.GetAgencyMembers:input_type -> hyapp.user.v1.GetAgencyMembersRequest
53, // 97: hyapp.user.v1.UserHostService.GetAgencyApplications:input_type -> hyapp.user.v1.GetAgencyApplicationsRequest
55, // 98: hyapp.user.v1.UserHostAdminService.CreateBDLeader:input_type -> hyapp.user.v1.CreateBDLeaderRequest
57, // 99: hyapp.user.v1.UserHostAdminService.CreateBD:input_type -> hyapp.user.v1.CreateBDRequest
59, // 100: hyapp.user.v1.UserHostAdminService.SetBDStatus:input_type -> hyapp.user.v1.SetBDStatusRequest
61, // 101: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:input_type -> hyapp.user.v1.CreateCoinSellerRequest
63, // 102: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:input_type -> hyapp.user.v1.SetCoinSellerStatusRequest
65, // 103: hyapp.user.v1.UserHostAdminService.CreateAgency:input_type -> hyapp.user.v1.CreateAgencyRequest
67, // 104: hyapp.user.v1.UserHostAdminService.CloseAgency:input_type -> hyapp.user.v1.CloseAgencyRequest
69, // 105: hyapp.user.v1.UserHostAdminService.DeleteAgency:input_type -> hyapp.user.v1.DeleteAgencyRequest
71, // 106: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:input_type -> hyapp.user.v1.SetAgencyStatusRequest
73, // 107: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:input_type -> hyapp.user.v1.SetAgencyJoinEnabledRequest
10, // 108: hyapp.user.v1.UserHostService.SearchAgencies:output_type -> hyapp.user.v1.SearchAgenciesResponse
12, // 109: hyapp.user.v1.UserHostService.ApplyToAgency:output_type -> hyapp.user.v1.ApplyToAgencyResponse
14, // 110: hyapp.user.v1.UserHostService.ReviewAgencyApplication:output_type -> hyapp.user.v1.ReviewAgencyApplicationResponse
16, // 111: hyapp.user.v1.UserHostService.KickAgencyHost:output_type -> hyapp.user.v1.KickAgencyHostResponse
18, // 112: hyapp.user.v1.UserHostService.InviteAgency:output_type -> hyapp.user.v1.InviteAgencyResponse
20, // 113: hyapp.user.v1.UserHostService.InviteBD:output_type -> hyapp.user.v1.InviteBDResponse
22, // 114: hyapp.user.v1.UserHostService.InviteHost:output_type -> hyapp.user.v1.InviteHostResponse
24, // 115: hyapp.user.v1.UserHostService.ListBDLeaderBDs:output_type -> hyapp.user.v1.ListBDLeaderBDsResponse
26, // 116: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:output_type -> hyapp.user.v1.ListBDLeaderAgenciesResponse
28, // 117: hyapp.user.v1.UserHostService.ListBDAgencies:output_type -> hyapp.user.v1.ListBDAgenciesResponse
30, // 118: hyapp.user.v1.UserHostService.ListRoleInvitations:output_type -> hyapp.user.v1.ListRoleInvitationsResponse
32, // 119: hyapp.user.v1.UserHostService.GetRoleInvitation:output_type -> hyapp.user.v1.GetRoleInvitationResponse
34, // 120: hyapp.user.v1.UserHostService.ProcessRoleInvitation:output_type -> hyapp.user.v1.ProcessRoleInvitationResponse
36, // 121: hyapp.user.v1.UserHostService.GetHostProfile:output_type -> hyapp.user.v1.GetHostProfileResponse
38, // 122: hyapp.user.v1.UserHostService.BatchGetHostProfiles:output_type -> hyapp.user.v1.BatchGetHostProfilesResponse
40, // 123: hyapp.user.v1.UserHostService.GetBDProfile:output_type -> hyapp.user.v1.GetBDProfileResponse
42, // 124: hyapp.user.v1.UserHostService.GetCoinSellerProfile:output_type -> hyapp.user.v1.GetCoinSellerProfileResponse
44, // 125: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:output_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionResponse
46, // 126: hyapp.user.v1.UserHostService.GetUserRoleSummary:output_type -> hyapp.user.v1.GetUserRoleSummaryResponse
48, // 127: hyapp.user.v1.UserHostService.GetAgency:output_type -> hyapp.user.v1.GetAgencyResponse
50, // 128: hyapp.user.v1.UserHostService.CheckBusinessCapability:output_type -> hyapp.user.v1.CheckBusinessCapabilityResponse
52, // 129: hyapp.user.v1.UserHostService.GetAgencyMembers:output_type -> hyapp.user.v1.GetAgencyMembersResponse
54, // 130: hyapp.user.v1.UserHostService.GetAgencyApplications:output_type -> hyapp.user.v1.GetAgencyApplicationsResponse
56, // 131: hyapp.user.v1.UserHostAdminService.CreateBDLeader:output_type -> hyapp.user.v1.CreateBDLeaderResponse
58, // 132: hyapp.user.v1.UserHostAdminService.CreateBD:output_type -> hyapp.user.v1.CreateBDResponse
60, // 133: hyapp.user.v1.UserHostAdminService.SetBDStatus:output_type -> hyapp.user.v1.SetBDStatusResponse
62, // 134: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:output_type -> hyapp.user.v1.CreateCoinSellerResponse
64, // 135: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:output_type -> hyapp.user.v1.SetCoinSellerStatusResponse
66, // 136: hyapp.user.v1.UserHostAdminService.CreateAgency:output_type -> hyapp.user.v1.CreateAgencyResponse
68, // 137: hyapp.user.v1.UserHostAdminService.CloseAgency:output_type -> hyapp.user.v1.CloseAgencyResponse
70, // 138: hyapp.user.v1.UserHostAdminService.DeleteAgency:output_type -> hyapp.user.v1.DeleteAgencyResponse
72, // 139: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:output_type -> hyapp.user.v1.SetAgencyStatusResponse
74, // 140: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:output_type -> hyapp.user.v1.SetAgencyJoinEnabledResponse
108, // [108:141] is the sub-list for method output_type
75, // [75:108] is the sub-list for method input_type
75, // [75:75] is the sub-list for extension type_name
75, // [75:75] is the sub-list for extension extendee
0, // [0:75] is the sub-list for field type_name
78, // 74: hyapp.user.v1.UpdateAgencyProfileRequest.meta:type_name -> hyapp.user.v1.RequestMeta
1, // 75: hyapp.user.v1.UpdateAgencyProfileResponse.agency:type_name -> hyapp.user.v1.Agency
0, // 76: hyapp.user.v1.BatchGetHostProfilesResponse.HostProfilesEntry.value:type_name -> hyapp.user.v1.HostProfile
9, // 77: hyapp.user.v1.UserHostService.SearchAgencies:input_type -> hyapp.user.v1.SearchAgenciesRequest
11, // 78: hyapp.user.v1.UserHostService.ApplyToAgency:input_type -> hyapp.user.v1.ApplyToAgencyRequest
13, // 79: hyapp.user.v1.UserHostService.ReviewAgencyApplication:input_type -> hyapp.user.v1.ReviewAgencyApplicationRequest
15, // 80: hyapp.user.v1.UserHostService.KickAgencyHost:input_type -> hyapp.user.v1.KickAgencyHostRequest
17, // 81: hyapp.user.v1.UserHostService.InviteAgency:input_type -> hyapp.user.v1.InviteAgencyRequest
19, // 82: hyapp.user.v1.UserHostService.InviteBD:input_type -> hyapp.user.v1.InviteBDRequest
21, // 83: hyapp.user.v1.UserHostService.InviteHost:input_type -> hyapp.user.v1.InviteHostRequest
23, // 84: hyapp.user.v1.UserHostService.ListBDLeaderBDs:input_type -> hyapp.user.v1.ListBDLeaderBDsRequest
25, // 85: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:input_type -> hyapp.user.v1.ListBDLeaderAgenciesRequest
27, // 86: hyapp.user.v1.UserHostService.ListBDAgencies:input_type -> hyapp.user.v1.ListBDAgenciesRequest
29, // 87: hyapp.user.v1.UserHostService.ListRoleInvitations:input_type -> hyapp.user.v1.ListRoleInvitationsRequest
31, // 88: hyapp.user.v1.UserHostService.GetRoleInvitation:input_type -> hyapp.user.v1.GetRoleInvitationRequest
33, // 89: hyapp.user.v1.UserHostService.ProcessRoleInvitation:input_type -> hyapp.user.v1.ProcessRoleInvitationRequest
35, // 90: hyapp.user.v1.UserHostService.GetHostProfile:input_type -> hyapp.user.v1.GetHostProfileRequest
37, // 91: hyapp.user.v1.UserHostService.BatchGetHostProfiles:input_type -> hyapp.user.v1.BatchGetHostProfilesRequest
39, // 92: hyapp.user.v1.UserHostService.GetBDProfile:input_type -> hyapp.user.v1.GetBDProfileRequest
41, // 93: hyapp.user.v1.UserHostService.GetCoinSellerProfile:input_type -> hyapp.user.v1.GetCoinSellerProfileRequest
43, // 94: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:input_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionRequest
45, // 95: hyapp.user.v1.UserHostService.GetUserRoleSummary:input_type -> hyapp.user.v1.GetUserRoleSummaryRequest
47, // 96: hyapp.user.v1.UserHostService.GetAgency:input_type -> hyapp.user.v1.GetAgencyRequest
49, // 97: hyapp.user.v1.UserHostService.CheckBusinessCapability:input_type -> hyapp.user.v1.CheckBusinessCapabilityRequest
51, // 98: hyapp.user.v1.UserHostService.GetAgencyMembers:input_type -> hyapp.user.v1.GetAgencyMembersRequest
53, // 99: hyapp.user.v1.UserHostService.GetAgencyApplications:input_type -> hyapp.user.v1.GetAgencyApplicationsRequest
75, // 100: hyapp.user.v1.UserHostService.UpdateAgencyProfile:input_type -> hyapp.user.v1.UpdateAgencyProfileRequest
55, // 101: hyapp.user.v1.UserHostAdminService.CreateBDLeader:input_type -> hyapp.user.v1.CreateBDLeaderRequest
57, // 102: hyapp.user.v1.UserHostAdminService.CreateBD:input_type -> hyapp.user.v1.CreateBDRequest
59, // 103: hyapp.user.v1.UserHostAdminService.SetBDStatus:input_type -> hyapp.user.v1.SetBDStatusRequest
61, // 104: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:input_type -> hyapp.user.v1.CreateCoinSellerRequest
63, // 105: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:input_type -> hyapp.user.v1.SetCoinSellerStatusRequest
65, // 106: hyapp.user.v1.UserHostAdminService.CreateAgency:input_type -> hyapp.user.v1.CreateAgencyRequest
67, // 107: hyapp.user.v1.UserHostAdminService.CloseAgency:input_type -> hyapp.user.v1.CloseAgencyRequest
69, // 108: hyapp.user.v1.UserHostAdminService.DeleteAgency:input_type -> hyapp.user.v1.DeleteAgencyRequest
71, // 109: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:input_type -> hyapp.user.v1.SetAgencyStatusRequest
73, // 110: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:input_type -> hyapp.user.v1.SetAgencyJoinEnabledRequest
10, // 111: hyapp.user.v1.UserHostService.SearchAgencies:output_type -> hyapp.user.v1.SearchAgenciesResponse
12, // 112: hyapp.user.v1.UserHostService.ApplyToAgency:output_type -> hyapp.user.v1.ApplyToAgencyResponse
14, // 113: hyapp.user.v1.UserHostService.ReviewAgencyApplication:output_type -> hyapp.user.v1.ReviewAgencyApplicationResponse
16, // 114: hyapp.user.v1.UserHostService.KickAgencyHost:output_type -> hyapp.user.v1.KickAgencyHostResponse
18, // 115: hyapp.user.v1.UserHostService.InviteAgency:output_type -> hyapp.user.v1.InviteAgencyResponse
20, // 116: hyapp.user.v1.UserHostService.InviteBD:output_type -> hyapp.user.v1.InviteBDResponse
22, // 117: hyapp.user.v1.UserHostService.InviteHost:output_type -> hyapp.user.v1.InviteHostResponse
24, // 118: hyapp.user.v1.UserHostService.ListBDLeaderBDs:output_type -> hyapp.user.v1.ListBDLeaderBDsResponse
26, // 119: hyapp.user.v1.UserHostService.ListBDLeaderAgencies:output_type -> hyapp.user.v1.ListBDLeaderAgenciesResponse
28, // 120: hyapp.user.v1.UserHostService.ListBDAgencies:output_type -> hyapp.user.v1.ListBDAgenciesResponse
30, // 121: hyapp.user.v1.UserHostService.ListRoleInvitations:output_type -> hyapp.user.v1.ListRoleInvitationsResponse
32, // 122: hyapp.user.v1.UserHostService.GetRoleInvitation:output_type -> hyapp.user.v1.GetRoleInvitationResponse
34, // 123: hyapp.user.v1.UserHostService.ProcessRoleInvitation:output_type -> hyapp.user.v1.ProcessRoleInvitationResponse
36, // 124: hyapp.user.v1.UserHostService.GetHostProfile:output_type -> hyapp.user.v1.GetHostProfileResponse
38, // 125: hyapp.user.v1.UserHostService.BatchGetHostProfiles:output_type -> hyapp.user.v1.BatchGetHostProfilesResponse
40, // 126: hyapp.user.v1.UserHostService.GetBDProfile:output_type -> hyapp.user.v1.GetBDProfileResponse
42, // 127: hyapp.user.v1.UserHostService.GetCoinSellerProfile:output_type -> hyapp.user.v1.GetCoinSellerProfileResponse
44, // 128: hyapp.user.v1.UserHostService.ListActiveCoinSellersInMyRegion:output_type -> hyapp.user.v1.ListActiveCoinSellersInMyRegionResponse
46, // 129: hyapp.user.v1.UserHostService.GetUserRoleSummary:output_type -> hyapp.user.v1.GetUserRoleSummaryResponse
48, // 130: hyapp.user.v1.UserHostService.GetAgency:output_type -> hyapp.user.v1.GetAgencyResponse
50, // 131: hyapp.user.v1.UserHostService.CheckBusinessCapability:output_type -> hyapp.user.v1.CheckBusinessCapabilityResponse
52, // 132: hyapp.user.v1.UserHostService.GetAgencyMembers:output_type -> hyapp.user.v1.GetAgencyMembersResponse
54, // 133: hyapp.user.v1.UserHostService.GetAgencyApplications:output_type -> hyapp.user.v1.GetAgencyApplicationsResponse
76, // 134: hyapp.user.v1.UserHostService.UpdateAgencyProfile:output_type -> hyapp.user.v1.UpdateAgencyProfileResponse
56, // 135: hyapp.user.v1.UserHostAdminService.CreateBDLeader:output_type -> hyapp.user.v1.CreateBDLeaderResponse
58, // 136: hyapp.user.v1.UserHostAdminService.CreateBD:output_type -> hyapp.user.v1.CreateBDResponse
60, // 137: hyapp.user.v1.UserHostAdminService.SetBDStatus:output_type -> hyapp.user.v1.SetBDStatusResponse
62, // 138: hyapp.user.v1.UserHostAdminService.CreateCoinSeller:output_type -> hyapp.user.v1.CreateCoinSellerResponse
64, // 139: hyapp.user.v1.UserHostAdminService.SetCoinSellerStatus:output_type -> hyapp.user.v1.SetCoinSellerStatusResponse
66, // 140: hyapp.user.v1.UserHostAdminService.CreateAgency:output_type -> hyapp.user.v1.CreateAgencyResponse
68, // 141: hyapp.user.v1.UserHostAdminService.CloseAgency:output_type -> hyapp.user.v1.CloseAgencyResponse
70, // 142: hyapp.user.v1.UserHostAdminService.DeleteAgency:output_type -> hyapp.user.v1.DeleteAgencyResponse
72, // 143: hyapp.user.v1.UserHostAdminService.SetAgencyStatus:output_type -> hyapp.user.v1.SetAgencyStatusResponse
74, // 144: hyapp.user.v1.UserHostAdminService.SetAgencyJoinEnabled:output_type -> hyapp.user.v1.SetAgencyJoinEnabledResponse
111, // [111:145] is the sub-list for method output_type
77, // [77:111] is the sub-list for method input_type
77, // [77:77] is the sub-list for extension type_name
77, // [77:77] is the sub-list for extension extendee
0, // [0:77] is the sub-list for field type_name
}
func init() { file_proto_user_v1_host_proto_init() }
@ -6417,13 +6581,14 @@ func file_proto_user_v1_host_proto_init() {
return
}
file_proto_user_v1_user_proto_init()
file_proto_user_v1_host_proto_msgTypes[75].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_user_v1_host_proto_rawDesc,
NumEnums: 0,
NumMessages: 76,
NumMessages: 78,
NumExtensions: 0,
NumServices: 2,
},

View File

@ -533,6 +533,19 @@ message SetAgencyJoinEnabledResponse {
Agency agency = 1;
}
message UpdateAgencyProfileRequest {
RequestMeta meta = 1;
string command_id = 2;
int64 operator_user_id = 3;
int64 agency_id = 4;
optional string name = 5;
optional string avatar = 6;
}
message UpdateAgencyProfileResponse {
Agency agency = 1;
}
// UserHostService user-service host domain gRPC
service UserHostService {
rpc SearchAgencies(SearchAgenciesRequest) returns (SearchAgenciesResponse);
@ -558,6 +571,7 @@ service UserHostService {
rpc CheckBusinessCapability(CheckBusinessCapabilityRequest) returns (CheckBusinessCapabilityResponse);
rpc GetAgencyMembers(GetAgencyMembersRequest) returns (GetAgencyMembersResponse);
rpc GetAgencyApplications(GetAgencyApplicationsRequest) returns (GetAgencyApplicationsResponse);
rpc UpdateAgencyProfile(UpdateAgencyProfileRequest) returns (UpdateAgencyProfileResponse);
}
// UserHostAdminService admin admin-server

View File

@ -42,6 +42,7 @@ const (
UserHostService_CheckBusinessCapability_FullMethodName = "/hyapp.user.v1.UserHostService/CheckBusinessCapability"
UserHostService_GetAgencyMembers_FullMethodName = "/hyapp.user.v1.UserHostService/GetAgencyMembers"
UserHostService_GetAgencyApplications_FullMethodName = "/hyapp.user.v1.UserHostService/GetAgencyApplications"
UserHostService_UpdateAgencyProfile_FullMethodName = "/hyapp.user.v1.UserHostService/UpdateAgencyProfile"
)
// UserHostServiceClient is the client API for UserHostService service.
@ -73,6 +74,7 @@ type UserHostServiceClient interface {
CheckBusinessCapability(ctx context.Context, in *CheckBusinessCapabilityRequest, opts ...grpc.CallOption) (*CheckBusinessCapabilityResponse, error)
GetAgencyMembers(ctx context.Context, in *GetAgencyMembersRequest, opts ...grpc.CallOption) (*GetAgencyMembersResponse, error)
GetAgencyApplications(ctx context.Context, in *GetAgencyApplicationsRequest, opts ...grpc.CallOption) (*GetAgencyApplicationsResponse, error)
UpdateAgencyProfile(ctx context.Context, in *UpdateAgencyProfileRequest, opts ...grpc.CallOption) (*UpdateAgencyProfileResponse, error)
}
type userHostServiceClient struct {
@ -313,6 +315,16 @@ func (c *userHostServiceClient) GetAgencyApplications(ctx context.Context, in *G
return out, nil
}
func (c *userHostServiceClient) UpdateAgencyProfile(ctx context.Context, in *UpdateAgencyProfileRequest, opts ...grpc.CallOption) (*UpdateAgencyProfileResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(UpdateAgencyProfileResponse)
err := c.cc.Invoke(ctx, UserHostService_UpdateAgencyProfile_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// UserHostServiceServer is the server API for UserHostService service.
// All implementations must embed UnimplementedUserHostServiceServer
// for forward compatibility.
@ -342,6 +354,7 @@ type UserHostServiceServer interface {
CheckBusinessCapability(context.Context, *CheckBusinessCapabilityRequest) (*CheckBusinessCapabilityResponse, error)
GetAgencyMembers(context.Context, *GetAgencyMembersRequest) (*GetAgencyMembersResponse, error)
GetAgencyApplications(context.Context, *GetAgencyApplicationsRequest) (*GetAgencyApplicationsResponse, error)
UpdateAgencyProfile(context.Context, *UpdateAgencyProfileRequest) (*UpdateAgencyProfileResponse, error)
mustEmbedUnimplementedUserHostServiceServer()
}
@ -421,6 +434,9 @@ func (UnimplementedUserHostServiceServer) GetAgencyMembers(context.Context, *Get
func (UnimplementedUserHostServiceServer) GetAgencyApplications(context.Context, *GetAgencyApplicationsRequest) (*GetAgencyApplicationsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAgencyApplications not implemented")
}
func (UnimplementedUserHostServiceServer) UpdateAgencyProfile(context.Context, *UpdateAgencyProfileRequest) (*UpdateAgencyProfileResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateAgencyProfile not implemented")
}
func (UnimplementedUserHostServiceServer) mustEmbedUnimplementedUserHostServiceServer() {}
func (UnimplementedUserHostServiceServer) testEmbeddedByValue() {}
@ -856,6 +872,24 @@ func _UserHostService_GetAgencyApplications_Handler(srv interface{}, ctx context
return interceptor(ctx, in, info, handler)
}
func _UserHostService_UpdateAgencyProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateAgencyProfileRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserHostServiceServer).UpdateAgencyProfile(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserHostService_UpdateAgencyProfile_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserHostServiceServer).UpdateAgencyProfile(ctx, req.(*UpdateAgencyProfileRequest))
}
return interceptor(ctx, in, info, handler)
}
// UserHostService_ServiceDesc is the grpc.ServiceDesc for UserHostService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -955,6 +989,10 @@ var UserHostService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetAgencyApplications",
Handler: _UserHostService_GetAgencyApplications_Handler,
},
{
MethodName: "UpdateAgencyProfile",
Handler: _UserHostService_UpdateAgencyProfile_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/user/v1/host.proto",

View File

@ -0,0 +1,296 @@
# Agency 资料与房间 Flutter 对接
## 基础约定
本地开发地址:
```text
http://127.0.0.1:13000
```
所有接口都是登录接口,需要带登录 token。
请求头:
| Header | 必填 | 说明 |
| --- | --- | --- |
| `Authorization` | 是 | `Bearer <access_token>`。 |
| `X-App-Code` | 否 | App 编码,默认 `lalu`;登录态接口最终以 token 内 app_code 为准。 |
成功和失败都使用统一 envelope
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_xxx",
"data": {}
}
```
客户端分支只判断 `code`,排查问题记录 `request_id`
## 1. 查询用户所属 Agency 资料
地址:
```http
GET /api/v1/agencies/profile
```
参数:
| 参数 | 位置 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- | --- |
| `user_id` | query | 是 | string/int64 | 被查看的 host 用户 ID。 |
示例:
```http
GET /api/v1/agencies/profile?user_id=10001
Authorization: Bearer <access_token>
X-App-Code: lalu
```
返回值:
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_abc",
"data": {
"agency": {
"agency_id": "7001",
"owner_user_id": "99",
"region_id": 30,
"parent_bd_user_id": "501",
"name": "Yumi Star Agency",
"avatar": "https://cdn.example/agency.png",
"host_count": 20,
"status": "active",
"join_enabled": true,
"created_by_user_id": "1",
"created_at_ms": 1710000000000,
"updated_at_ms": 1710000001000
}
}
}
```
没有 active host 身份,或没有 active agency 归属时:
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_abc",
"data": {
"agency": null
}
}
```
字段说明:
| 字段 | 说明 |
| --- | --- |
| `agency_id` | Agency ID字符串。 |
| `owner_user_id` | Agency 会长用户 ID字符串。 |
| `name` | Agency 自己的名称,不再读 owner 用户昵称。 |
| `avatar` | Agency 自己的头像,不再读 owner 用户头像。 |
| `host_count` | 当前 active host 数量。 |
| `status` | 当前只展示 `active`。 |
| `join_enabled` | 是否允许用户申请加入。 |
| `created_at_ms` / `updated_at_ms` | Unix epoch milliseconds。 |
## 2. 查询 Agency 下所有 host 的房间
地址:
```http
GET /api/v1/agencies/rooms
```
参数:
| 参数 | 位置 | 必填 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `user_id` | query | 是 | string/int64 | 无 | 被查看的 host 用户 ID。 |
| `limit` | query | 否 | int | 20 | 每页数量,最大 50。 |
| `cursor` | query | 否 | string | 空 | 下一页 cursor。 |
| `tab` | query | 否 | string | `hot` | `hot``new`。 |
| `query` | query | 否 | string | 空 | 搜索房间标题、房间 ID 或短号。 |
示例:
```http
GET /api/v1/agencies/rooms?user_id=10001&tab=hot&limit=20
Authorization: Bearer <access_token>
X-App-Code: lalu
```
返回值:
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_abc",
"data": {
"agency_id": "7001",
"rooms": [
{
"room_id": "room_101",
"im_group_id": "room_101",
"owner_user_id": "101",
"title": "Agency Room",
"cover_url": "https://cdn.example/room.png",
"mode": "voice",
"status": "active",
"locked": false,
"heat": 88,
"online_count": 12,
"seat_count": 8,
"occupied_seat_count": 3,
"visible_region_id": 30,
"app_code": "lalu",
"room_short_id": "M20",
"country_code": "AE",
"country_flag": "🇦🇪"
}
],
"next_cursor": "cursor_xxx"
}
}
```
没有 active host 身份,或没有 active agency 归属时:
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_abc",
"data": {
"agency_id": "",
"rooms": [],
"next_cursor": ""
}
}
```
字段说明:
| 字段 | 说明 |
| --- | --- |
| `agency_id` | 当前查询到的 Agency ID无归属时为空字符串。 |
| `rooms` | Agency 下所有 active host 的 active 房间。 |
| `next_cursor` | 下一页 cursor为空表示没有下一页。 |
| `room_id` | 房间 ID。 |
| `im_group_id` | 腾讯云 IM 房间群 ID进群使用这个字段。 |
| `owner_user_id` | 房主用户 ID字符串。 |
| `title` | 房间名。 |
| `cover_url` | 房间封面。 |
| `locked` | 是否锁房。 |
| `heat` | 房间热度。 |
| `online_count` | 在线人数。 |
| `seat_count` | 麦位数量。 |
| `occupied_seat_count` | 已占用麦位数量。 |
| `room_short_id` | 房间短号。 |
| `country_code` / `country_flag` | 房主国家展示字段。 |
## 3. 修改 Agency 资料
地址:
```http
POST /api/v1/agencies/profile/update
```
权限:
只有当前登录用户是 active Agency owner 时可以修改。普通 host、Agency 成员、BD、非 active owner 都不能修改。
参数:
| 参数 | 位置 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- | --- |
| `command_id` | body | 是 | string | 客户端生成的幂等 ID。 |
| `name` | body | 否 | string | 新 Agency 名称。 |
| `avatar` | body | 否 | string | 新 Agency 头像 URL。 |
`name``avatar` 至少传一个;传了就不能是空字符串。修改 Agency 资料不会修改 owner 用户昵称和头像。
示例:
```http
POST /api/v1/agencies/profile/update
Authorization: Bearer <access_token>
X-App-Code: lalu
Content-Type: application/json
{
"command_id": "cmd_agency_profile_001",
"name": "New Agency Name",
"avatar": "https://cdn.example/new-agency.png"
}
```
返回值:
```json
{
"code": "OK",
"message": "ok",
"request_id": "req_abc",
"data": {
"agency": {
"agency_id": "7001",
"owner_user_id": "42",
"region_id": 30,
"name": "New Agency Name",
"avatar": "https://cdn.example/new-agency.png",
"host_count": 20,
"status": "active",
"join_enabled": true,
"created_at_ms": 1710000000000,
"updated_at_ms": 1710000005000
}
}
}
```
## 错误处理
失败返回:
```json
{
"code": "INVALID_ARGUMENT",
"message": "invalid argument",
"request_id": "req_abc"
}
```
| HTTP 状态码 | `code` | 处理方式 |
| --- | --- | --- |
| `400` | `INVALID_ARGUMENT` | 参数错误,例如 `user_id` 非法、`tab` 非法、`limit` 非法、缺少 `command_id``name/avatar` 都没传或传空。 |
| `401` | `UNAUTHORIZED` | token 缺失、无效或过期,重新登录。 |
| `403` | `PROFILE_REQUIRED` | 用户资料未完成,跳转资料补全。 |
| `403` | `PERMISSION_DENIED` | 修改接口中当前用户不是 active Agency owner不允许修改。 |
| `404` | `NOT_FOUND` | 修改接口中 Agency 事实不存在;刷新当前用户身份后再进入页面。 |
| `409` | `CONFLICT` | `command_id` 与已有不同命令冲突;重新生成新的 `command_id` 再提交。 |
| `502` | `UPSTREAM_ERROR` | 服务暂不可用,可以提示稍后重试。 |
客户端处理规则:
1. 查询资料时,`agency == null` 是正常空状态,不弹错误。
2. 查询房间时,`rooms == []` 是正常空列表,不弹错误。
3. 修改资料成功后,用返回的 `data.agency` 刷新页面,不要用 owner 用户资料覆盖。
4. 修改失败时保留本地未保存状态,让用户可以重试。
5. 所有失败日志记录 `request_id`
## 相关 IM
无。Agency 资料修改和 Agency 房间列表不会下发新的 IM房间卡片里的 `im_group_id` 只用于进入房间时加入腾讯云 IM 房间群。

View File

@ -615,6 +615,7 @@ type Agency struct {
RegionID int64 `json:"regionId"`
ParentBDUserID int64 `json:"parentBdUserId,string"`
Name string `json:"name"`
Avatar string `json:"avatar"`
Status string `json:"status"`
JoinEnabled bool `json:"joinEnabled"`
MaxHosts int32 `json:"maxHosts"`
@ -895,6 +896,7 @@ func fromProtoAgency(agency *userv1.Agency) *Agency {
RegionID: agency.GetRegionId(),
ParentBDUserID: agency.GetParentBdUserId(),
Name: agency.GetName(),
Avatar: agency.GetAvatar(),
Status: agency.GetStatus(),
JoinEnabled: agency.GetJoinEnabled(),
MaxHosts: agency.GetMaxHosts(),

View File

@ -213,7 +213,7 @@ type createAgencyRequest struct {
CommandID string `json:"commandId" binding:"required"`
OwnerUserID flexibleInt64 `json:"ownerUserId" binding:"required"`
ParentBDUserID flexibleInt64 `json:"parentBdUserId"`
Name string `json:"name" binding:"required"`
Name string `json:"name"`
JoinEnabled *bool `json:"joinEnabled" binding:"required"`
Reason string `json:"reason"`
}

View File

@ -45,6 +45,7 @@ type RoomGuardClient interface {
// RoomQueryClient 抽象 gateway 对 room-service 读模型查询的依赖。
type RoomQueryClient interface {
ListRooms(ctx context.Context, req *roomv1.ListRoomsRequest) (*roomv1.ListRoomsResponse, error)
ListRoomsByOwners(ctx context.Context, req *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error)
ListRoomFeeds(ctx context.Context, req *roomv1.ListRoomFeedsRequest) (*roomv1.ListRoomsResponse, error)
ListRoomGiftLeaderboard(ctx context.Context, req *roomv1.ListRoomGiftLeaderboardRequest) (*roomv1.ListRoomGiftLeaderboardResponse, error)
GetMyRoom(ctx context.Context, req *roomv1.GetMyRoomRequest) (*roomv1.GetMyRoomResponse, error)
@ -197,6 +198,10 @@ func (c *grpcRoomQueryClient) ListRooms(ctx context.Context, req *roomv1.ListRoo
return c.client.ListRooms(ctx, req)
}
func (c *grpcRoomQueryClient) ListRoomsByOwners(ctx context.Context, req *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error) {
return c.client.ListRoomsByOwners(ctx, req)
}
func (c *grpcRoomQueryClient) ListRoomFeeds(ctx context.Context, req *roomv1.ListRoomFeedsRequest) (*roomv1.ListRoomsResponse, error) {
return c.client.ListRoomFeeds(ctx, req)
}

View File

@ -119,6 +119,7 @@ type UserHostClient interface {
ListActiveCoinSellersInMyRegion(ctx context.Context, req *userv1.ListActiveCoinSellersInMyRegionRequest) (*userv1.ListActiveCoinSellersInMyRegionResponse, error)
GetUserRoleSummary(ctx context.Context, req *userv1.GetUserRoleSummaryRequest) (*userv1.GetUserRoleSummaryResponse, error)
GetAgency(ctx context.Context, req *userv1.GetAgencyRequest) (*userv1.GetAgencyResponse, error)
UpdateAgencyProfile(ctx context.Context, req *userv1.UpdateAgencyProfileRequest) (*userv1.UpdateAgencyProfileResponse, error)
CheckBusinessCapability(ctx context.Context, req *userv1.CheckBusinessCapabilityRequest) (*userv1.CheckBusinessCapabilityResponse, error)
GetAgencyMembers(ctx context.Context, req *userv1.GetAgencyMembersRequest) (*userv1.GetAgencyMembersResponse, error)
GetAgencyApplications(ctx context.Context, req *userv1.GetAgencyApplicationsRequest) (*userv1.GetAgencyApplicationsResponse, error)
@ -560,6 +561,10 @@ func (c *grpcUserHostClient) GetAgency(ctx context.Context, req *userv1.GetAgenc
return c.client.GetAgency(ctx, req)
}
func (c *grpcUserHostClient) UpdateAgencyProfile(ctx context.Context, req *userv1.UpdateAgencyProfileRequest) (*userv1.UpdateAgencyProfileResponse, error) {
return c.client.UpdateAgencyProfile(ctx, req)
}
func (c *grpcUserHostClient) CheckBusinessCapability(ctx context.Context, req *userv1.CheckBusinessCapabilityRequest) (*userv1.CheckBusinessCapabilityResponse, error) {
return c.client.CheckBusinessCapability(ctx, req)
}

View File

@ -183,6 +183,10 @@ func (f *fakeUserLeaderboardRoomQueryClient) ListRooms(context.Context, *roomv1.
return &roomv1.ListRoomsResponse{}, nil
}
func (f *fakeUserLeaderboardRoomQueryClient) ListRoomsByOwners(context.Context, *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error) {
return &roomv1.ListRoomsResponse{}, nil
}
func (f *fakeUserLeaderboardRoomQueryClient) ListRoomFeeds(context.Context, *roomv1.ListRoomFeedsRequest) (*roomv1.ListRoomsResponse, error) {
return &roomv1.ListRoomsResponse{}, nil
}

View File

@ -81,6 +81,9 @@ type UserHandlers struct {
GetMyRoleSummary http.HandlerFunc
SearchHostAgencies http.HandlerFunc
ApplyToHostAgency http.HandlerFunc
GetAgencyProfile http.HandlerFunc
ListAgencyRooms http.HandlerFunc
UpdateAgencyProfile http.HandlerFunc
GetHostCenterAgency http.HandlerFunc
GetHostCenterPlatformPolicy http.HandlerFunc
GetAgencyCenterOverview http.HandlerFunc
@ -430,6 +433,9 @@ func (r routes) registerUserRoutes() {
r.profile("/users/me/role-summary", "", h.GetMyRoleSummary)
r.profile("/host/agencies/search", http.MethodGet, h.SearchHostAgencies)
r.profile("/host/agency-applications", http.MethodPost, h.ApplyToHostAgency)
r.profile("/agencies/profile", http.MethodGet, h.GetAgencyProfile)
r.profile("/agencies/rooms", http.MethodGet, h.ListAgencyRooms)
r.profile("/agencies/profile/update", http.MethodPost, h.UpdateAgencyProfile)
r.profile("/host-center/agency", http.MethodGet, h.GetHostCenterAgency)
r.profile("/host-center/platform-policy", http.MethodGet, h.GetHostCenterPlatformPolicy)
r.profile("/agency-center/overview", http.MethodGet, h.GetAgencyCenterOverview)

View File

@ -375,6 +375,7 @@ type fakeUserIdentityClient struct {
type fakeRoomQueryClient struct {
lastList *roomv1.ListRoomsRequest
lastListOwners *roomv1.ListRoomsByOwnersRequest
lastFeeds *roomv1.ListRoomFeedsRequest
lastMyRoom *roomv1.GetMyRoomRequest
lastCurrent *roomv1.GetCurrentRoomRequest
@ -384,6 +385,7 @@ type fakeRoomQueryClient struct {
lastOnline *roomv1.ListRoomOnlineUsersRequest
lastBannedUsers *roomv1.ListRoomBannedUsersRequest
resp *roomv1.ListRoomsResponse
ownersResp *roomv1.ListRoomsResponse
feedsResp *roomv1.ListRoomsResponse
myRoomResp *roomv1.GetMyRoomResponse
currentResp *roomv1.GetCurrentRoomResponse
@ -393,6 +395,7 @@ type fakeRoomQueryClient struct {
onlineResp *roomv1.ListRoomOnlineUsersResponse
bannedUsersResp *roomv1.ListRoomBannedUsersResponse
err error
ownersErr error
feedsErr error
myRoomErr error
currentErr error
@ -479,6 +482,9 @@ type fakeUserHostClient struct {
lastGetAgency *userv1.GetAgencyRequest
getAgencyResp *userv1.GetAgencyResponse
getAgencyErr error
lastUpdateAgency *userv1.UpdateAgencyProfileRequest
updateAgencyResp *userv1.UpdateAgencyProfileResponse
updateAgencyErr error
lastMembers *userv1.GetAgencyMembersRequest
membersResp *userv1.GetAgencyMembersResponse
membersErr error
@ -1107,6 +1113,17 @@ func (f *fakeRoomQueryClient) ListRooms(_ context.Context, req *roomv1.ListRooms
return &roomv1.ListRoomsResponse{}, nil
}
func (f *fakeRoomQueryClient) ListRoomsByOwners(_ context.Context, req *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error) {
f.lastListOwners = req
if f.ownersErr != nil {
return nil, f.ownersErr
}
if f.ownersResp != nil {
return f.ownersResp, nil
}
return &roomv1.ListRoomsResponse{}, nil
}
func (f *fakeRoomQueryClient) ListRoomFeeds(_ context.Context, req *roomv1.ListRoomFeedsRequest) (*roomv1.ListRoomsResponse, error) {
f.lastFeeds = req
if f.feedsErr != nil {
@ -1653,6 +1670,23 @@ func (f *fakeUserHostClient) GetAgency(_ context.Context, req *userv1.GetAgencyR
return &userv1.GetAgencyResponse{}, nil
}
func (f *fakeUserHostClient) UpdateAgencyProfile(_ context.Context, req *userv1.UpdateAgencyProfileRequest) (*userv1.UpdateAgencyProfileResponse, error) {
f.lastUpdateAgency = req
if f.updateAgencyErr != nil {
return nil, f.updateAgencyErr
}
if f.updateAgencyResp != nil {
return f.updateAgencyResp, nil
}
return &userv1.UpdateAgencyProfileResponse{Agency: &userv1.Agency{
AgencyId: req.GetAgencyId(),
OwnerUserId: req.GetOperatorUserId(),
Name: req.GetName(),
Avatar: req.GetAvatar(),
Status: "active",
}}, nil
}
func (f *fakeUserHostClient) CheckBusinessCapability(_ context.Context, req *userv1.CheckBusinessCapabilityRequest) (*userv1.CheckBusinessCapabilityResponse, error) {
f.lastCapability = req
f.capabilities = append(f.capabilities, req.GetCapability())
@ -5013,6 +5047,7 @@ func TestHostCenterAgencyUsesCurrentHostAgencyAndOwnerProfile(t *testing.T) {
OwnerUserId: 99,
RegionId: 30,
Name: "Yumi Star Agency",
Avatar: "https://cdn.example/agency.png",
Status: "active",
}},
}
@ -5047,11 +5082,198 @@ func TestHostCenterAgencyUsesCurrentHostAgencyAndOwnerProfile(t *testing.T) {
}
data := response.Data.(map[string]any)
agency := data["agency"].(map[string]any)
if agency["agency_id"] != "7001" || agency["short_id"] != "163003" || agency["avatar"] != "https://cdn.example/agency-owner.png" || agency["name"] != "Yumi Star Agency" {
if agency["agency_id"] != "7001" || agency["short_id"] != "163003" || agency["avatar"] != "https://cdn.example/agency.png" || agency["name"] != "Yumi Star Agency" {
t.Fatalf("host center agency response mismatch: %+v", agency)
}
}
func TestGetAgencyProfileReturnsIndependentAgencyAvatar(t *testing.T) {
hostClient := &fakeUserHostClient{
hostProfile: &userv1.HostProfile{UserId: 88, Status: "active", RegionId: 30, CurrentAgencyId: 7001},
getAgencyResp: &userv1.GetAgencyResponse{Agency: &userv1.Agency{
AgencyId: 7001,
OwnerUserId: 99,
RegionId: 30,
Name: "Independent Agency",
Avatar: "https://cdn.example/agency-avatar.png",
HostCount: 3,
Status: "active",
JoinEnabled: true,
}},
}
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
handler.SetUserHostClient(hostClient)
router := handler.Routes(auth.NewVerifier("secret"))
request := httptest.NewRequest(http.MethodGet, "/api/v1/agencies/profile?user_id=88", nil)
request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42))
request.Header.Set("X-Request-ID", "req-agency-profile")
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
}
if hostClient.lastHost == nil || hostClient.lastHost.GetUserId() != 88 || hostClient.lastGetAgency == nil || hostClient.lastGetAgency.GetAgencyId() != 7001 {
t.Fatalf("agency profile upstream requests mismatch: host=%+v agency=%+v", hostClient.lastHost, hostClient.lastGetAgency)
}
var response httpkit.ResponseEnvelope
if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil {
t.Fatalf("decode response failed: %v", err)
}
data := response.Data.(map[string]any)
agency := data["agency"].(map[string]any)
if agency["agency_id"] != "7001" || agency["owner_user_id"] != "99" || agency["name"] != "Independent Agency" || agency["avatar"] != "https://cdn.example/agency-avatar.png" || agency["host_count"] != float64(3) {
t.Fatalf("agency profile response mismatch: %+v", agency)
}
}
func TestGetAgencyProfileReturnsNullWhenTargetNotActiveHost(t *testing.T) {
hostClient := &fakeUserHostClient{hostProfile: &userv1.HostProfile{UserId: 88, Status: "inactive", RegionId: 30, CurrentAgencyId: 7001}}
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
handler.SetUserHostClient(hostClient)
router := handler.Routes(auth.NewVerifier("secret"))
request := httptest.NewRequest(http.MethodGet, "/api/v1/agencies/profile?user_id=88", nil)
request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42))
request.Header.Set("X-Request-ID", "req-agency-profile-empty")
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
}
if hostClient.lastGetAgency != nil {
t.Fatalf("inactive host must not fetch agency: %+v", hostClient.lastGetAgency)
}
var response httpkit.ResponseEnvelope
if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil {
t.Fatalf("decode response failed: %v", err)
}
data := response.Data.(map[string]any)
if data["agency"] != nil {
t.Fatalf("inactive host must return null agency: %+v", data)
}
}
func TestListAgencyRoomsUsesActiveAgencyHosts(t *testing.T) {
hostClient := &fakeUserHostClient{
hostProfile: &userv1.HostProfile{UserId: 88, Status: "active", RegionId: 30, CurrentAgencyId: 7001},
getAgencyResp: &userv1.GetAgencyResponse{Agency: &userv1.Agency{
AgencyId: 7001,
OwnerUserId: 99,
RegionId: 30,
Name: "Independent Agency",
Avatar: "https://cdn.example/agency-avatar.png",
Status: "active",
}},
membersResp: &userv1.GetAgencyMembersResponse{Memberships: []*userv1.AgencyMembership{
{MembershipId: 1, AgencyId: 7001, HostUserId: 101, Status: "active"},
{MembershipId: 2, AgencyId: 7001, HostUserId: 102, Status: "inactive"},
{MembershipId: 3, AgencyId: 7001, HostUserId: 99, Status: "active"},
}},
}
roomClient := &fakeRoomQueryClient{ownersResp: &roomv1.ListRoomsResponse{
Rooms: []*roomv1.RoomListItem{{
RoomId: "room-101",
OwnerUserId: 101,
Title: "Agency Room",
CoverUrl: "https://cdn.example/room.png",
Mode: "voice",
Status: "active",
Heat: 88,
OnlineCount: 12,
SeatCount: 8,
OccupiedSeatCount: 3,
RoomShortId: "M20",
CountryCode: "AE",
}},
NextCursor: "next-owner-room",
}}
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
handler.SetUserHostClient(hostClient)
handler.SetRoomQueryClient(roomClient)
router := handler.Routes(auth.NewVerifier("secret"))
request := httptest.NewRequest(http.MethodGet, "/api/v1/agencies/rooms?user_id=88&tab=new&limit=120&cursor=cursor-1&query=karaoke", nil)
request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42))
request.Header.Set("X-Request-ID", "req-agency-rooms")
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
}
if hostClient.lastMembers == nil || hostClient.lastMembers.GetAgencyId() != 7001 || hostClient.lastMembers.GetStatus() != "active" {
t.Fatalf("agency members request mismatch: %+v", hostClient.lastMembers)
}
if roomClient.lastListOwners == nil {
t.Fatal("agency rooms must call ListRoomsByOwners")
}
ownerIDs := roomClient.lastListOwners.GetOwnerUserIds()
if len(ownerIDs) != 2 || ownerIDs[0] != 99 || ownerIDs[1] != 101 {
t.Fatalf("owner ids mismatch: got %v request=%+v", roomClient.lastListOwners.GetOwnerUserIds(), roomClient.lastListOwners)
}
if roomClient.lastListOwners.GetViewerUserId() != 42 || roomClient.lastListOwners.GetTab() != "new" || roomClient.lastListOwners.GetLimit() != 50 || roomClient.lastListOwners.GetCursor() != "cursor-1" || roomClient.lastListOwners.GetQuery() != "karaoke" {
t.Fatalf("agency rooms request mismatch: %+v", roomClient.lastListOwners)
}
var response httpkit.ResponseEnvelope
if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil {
t.Fatalf("decode response failed: %v", err)
}
data := response.Data.(map[string]any)
rooms := data["rooms"].([]any)
first := rooms[0].(map[string]any)
if data["agency_id"] != "7001" || data["next_cursor"] != "next-owner-room" || first["room_id"] != "room-101" || first["owner_user_id"] != "101" || first["country_flag"] != "🇦🇪" {
t.Fatalf("agency rooms response mismatch: %+v", response)
}
}
func TestUpdateAgencyProfileForwardsOwnerCommand(t *testing.T) {
hostClient := &fakeUserHostClient{
roleSummary: &userv1.UserRoleSummary{UserId: 42, IsAgency: true, AgencyId: 7001},
getAgencyResp: &userv1.GetAgencyResponse{Agency: &userv1.Agency{AgencyId: 7001, OwnerUserId: 42, RegionId: 30, Name: "Old Agency", Avatar: "https://cdn.example/old.png", Status: "active"}},
updateAgencyResp: &userv1.UpdateAgencyProfileResponse{Agency: &userv1.Agency{
AgencyId: 7001,
OwnerUserId: 42,
RegionId: 30,
Name: "New Agency",
Avatar: "https://cdn.example/new.png",
Status: "active",
}},
}
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
handler.SetUserHostClient(hostClient)
router := handler.Routes(auth.NewVerifier("secret"))
request := httptest.NewRequest(http.MethodPost, "/api/v1/agencies/profile/update", bytes.NewReader([]byte(`{"command_id":"cmd-agency-profile","name":" New Agency ","avatar":" https://cdn.example/new.png "}`)))
request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42))
request.Header.Set("X-Request-ID", "req-agency-profile-update")
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
}
if hostClient.lastUpdateAgency == nil ||
hostClient.lastUpdateAgency.GetCommandId() != "cmd-agency-profile" ||
hostClient.lastUpdateAgency.GetOperatorUserId() != 42 ||
hostClient.lastUpdateAgency.GetAgencyId() != 7001 ||
hostClient.lastUpdateAgency.GetName() != "New Agency" ||
hostClient.lastUpdateAgency.GetAvatar() != "https://cdn.example/new.png" {
t.Fatalf("update agency profile request mismatch: %+v", hostClient.lastUpdateAgency)
}
var response httpkit.ResponseEnvelope
if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil {
t.Fatalf("decode response failed: %v", err)
}
data := response.Data.(map[string]any)
agency := data["agency"].(map[string]any)
if agency["agency_id"] != "7001" || agency["name"] != "New Agency" || agency["avatar"] != "https://cdn.example/new.png" {
t.Fatalf("update agency profile response mismatch: %+v", agency)
}
}
func TestHostCenterPlatformPolicyUsesCurrentHostRegion(t *testing.T) {
hostClient := &fakeUserHostClient{hostProfile: &userv1.HostProfile{
UserId: 42,

View File

@ -273,6 +273,10 @@ func (c *shareRoomQueryClient) ListRooms(context.Context, *roomv1.ListRoomsReque
return &roomv1.ListRoomsResponse{}, nil
}
func (c *shareRoomQueryClient) ListRoomsByOwners(context.Context, *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error) {
return &roomv1.ListRoomsResponse{}, nil
}
func (c *shareRoomQueryClient) ListRoomFeeds(context.Context, *roomv1.ListRoomFeedsRequest) (*roomv1.ListRoomsResponse, error) {
return &roomv1.ListRoomsResponse{}, nil
}

View File

@ -64,6 +64,7 @@ func (h *Handler) Routes(jwtVerifier *auth.Verifier) http.Handler {
UserCPClient: h.userCPClient,
UserCountryClient: h.userCountryClient,
UserHostClient: h.userHostClient,
RoomQueryClient: h.roomQueryClient,
WalletClient: h.walletClient,
GrowthLevelClient: h.growthLevelClient,
AchievementClient: h.achievementClient,

View File

@ -0,0 +1,348 @@
package userapi
import (
"net/http"
"strconv"
"strings"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"hyapp/pkg/imgroup"
"hyapp/services/gateway-service/internal/auth"
"hyapp/services/gateway-service/internal/transport/http/httpkit"
roomv1 "hyapp.local/api/proto/room/v1"
userv1 "hyapp.local/api/proto/user/v1"
)
const maxAgencyRoomListLimit = 50
type agencyRoomsData struct {
AgencyID string `json:"agency_id"`
Rooms []agencyRoomItemData `json:"rooms"`
NextCursor string `json:"next_cursor"`
}
type agencyRoomItemData struct {
RoomID string `json:"room_id"`
IMGroupID string `json:"im_group_id"`
OwnerUserID string `json:"owner_user_id,omitempty"`
Title string `json:"title,omitempty"`
CoverURL string `json:"cover_url,omitempty"`
Mode string `json:"mode,omitempty"`
Status string `json:"status,omitempty"`
Locked bool `json:"locked"`
Heat int64 `json:"heat"`
OnlineCount int32 `json:"online_count"`
SeatCount int32 `json:"seat_count"`
OccupiedSeatCount int32 `json:"occupied_seat_count"`
VisibleRegionID int64 `json:"visible_region_id,omitempty"`
AppCode string `json:"app_code,omitempty"`
RoomShortID string `json:"room_short_id,omitempty"`
CountryCode string `json:"country_code,omitempty"`
CountryFlag string `json:"country_flag,omitempty"`
}
func (h *Handler) getAgencyProfile(writer http.ResponseWriter, request *http.Request) {
targetUserID, ok := positiveInt64Query(request, "user_id")
if !ok {
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
return
}
agency, found, err := h.resolveAgencyForTargetHost(request, targetUserID)
if err != nil {
httpkit.WriteRPCError(writer, request, err)
return
}
if !found {
httpkit.WriteOK(writer, request, map[string]any{"agency": nil})
return
}
httpkit.WriteOK(writer, request, map[string]any{"agency": hostAgencyFromProto(agency)})
}
func (h *Handler) listAgencyRooms(writer http.ResponseWriter, request *http.Request) {
targetUserID, ok := positiveInt64Query(request, "user_id")
if !ok {
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
return
}
limit, ok := parseAgencyRoomListLimit(request.URL.Query().Get("limit"))
if !ok {
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
return
}
tab, ok := parseAgencyRoomListTab(request.URL.Query().Get("tab"))
if !ok {
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
return
}
if h.roomQueryClient == nil {
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
return
}
agency, found, err := h.resolveAgencyForTargetHost(request, targetUserID)
if err != nil {
httpkit.WriteRPCError(writer, request, err)
return
}
if !found {
httpkit.WriteOK(writer, request, agencyRoomsData{Rooms: []agencyRoomItemData{}})
return
}
ownerUserIDs, err := h.activeAgencyHostUserIDs(request, agency)
if err != nil {
httpkit.WriteRPCError(writer, request, err)
return
}
if len(ownerUserIDs) == 0 {
httpkit.WriteOK(writer, request, agencyRoomsData{AgencyID: int64String(agency.GetAgencyId()), Rooms: []agencyRoomItemData{}})
return
}
resp, err := h.roomQueryClient.ListRoomsByOwners(request.Context(), &roomv1.ListRoomsByOwnersRequest{
Meta: httpkit.RoomMeta(request, "", ""),
ViewerUserId: auth.UserIDFromContext(request.Context()),
OwnerUserIds: ownerUserIDs,
Tab: tab,
Cursor: strings.TrimSpace(request.URL.Query().Get("cursor")),
Limit: limit,
Query: agencyRoomListQuery(request),
})
if err != nil {
httpkit.WriteRPCError(writer, request, err)
return
}
httpkit.WriteOK(writer, request, agencyRoomsData{
AgencyID: int64String(agency.GetAgencyId()),
Rooms: agencyRoomItemsFromProto(resp.GetRooms()),
NextCursor: resp.GetNextCursor(),
})
}
func (h *Handler) updateAgencyProfile(writer http.ResponseWriter, request *http.Request) {
agency, ok := h.resolveCurrentOwnerAgency(writer, request)
if !ok {
return
}
var body struct {
CommandID string `json:"command_id"`
CommandIDAlt string `json:"commandId"`
Name *string `json:"name"`
Avatar *string `json:"avatar"`
}
if !httpkit.Decode(writer, request, &body) {
return
}
commandID := strings.TrimSpace(body.CommandID)
if commandID == "" {
commandID = strings.TrimSpace(body.CommandIDAlt)
}
name := trimmedOptionalString(body.Name)
avatar := trimmedOptionalString(body.Avatar)
if commandID == "" || (name == nil && avatar == nil) || optionalStringIsEmpty(name) || optionalStringIsEmpty(avatar) {
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
return
}
resp, err := h.userHostClient.UpdateAgencyProfile(request.Context(), &userv1.UpdateAgencyProfileRequest{
Meta: httpkit.UserMeta(request, ""),
CommandId: commandID,
OperatorUserId: auth.UserIDFromContext(request.Context()),
AgencyId: agency.GetAgencyId(),
Name: name,
Avatar: avatar,
})
if err != nil {
httpkit.WriteRPCError(writer, request, err)
return
}
httpkit.WriteOK(writer, request, map[string]any{"agency": hostAgencyFromProto(resp.GetAgency())})
}
func (h *Handler) resolveAgencyForTargetHost(request *http.Request, targetUserID int64) (*userv1.Agency, bool, error) {
if h.userHostClient == nil {
return nil, false, status.Error(codes.Unavailable, "user host client unavailable")
}
profileResp, err := h.userHostClient.GetHostProfile(request.Context(), &userv1.GetHostProfileRequest{
Meta: httpkit.UserMeta(request, ""),
UserId: targetUserID,
})
if status.Code(err) == codes.NotFound {
return nil, false, nil
}
if err != nil {
return nil, false, err
}
profile := profileResp.GetHostProfile()
// 这两个公开查询看的是“被查询用户作为 active host 当前所属 agency”。非 host、停用 host、
// 或没有 active agency 归属都按空结果处理,避免向客户端暴露中间态/历史关系。
if profile == nil || profile.GetStatus() != agencyStatusActive || profile.GetCurrentAgencyId() <= 0 {
return nil, false, nil
}
agencyResp, err := h.userHostClient.GetAgency(request.Context(), &userv1.GetAgencyRequest{
Meta: httpkit.UserMeta(request, ""),
AgencyId: profile.GetCurrentAgencyId(),
})
if status.Code(err) == codes.NotFound {
return nil, false, nil
}
if err != nil {
return nil, false, err
}
agency := agencyResp.GetAgency()
if agency == nil || agency.GetAgencyId() != profile.GetCurrentAgencyId() || agency.GetStatus() != agencyStatusActive {
return nil, false, nil
}
return agency, true, nil
}
func (h *Handler) activeAgencyHostUserIDs(request *http.Request, agency *userv1.Agency) ([]int64, error) {
resp, err := h.userHostClient.GetAgencyMembers(request.Context(), &userv1.GetAgencyMembersRequest{
Meta: httpkit.UserMeta(request, ""),
AgencyId: agency.GetAgencyId(),
Status: membershipStatusActive,
})
if err != nil {
return nil, err
}
seen := make(map[int64]struct{}, len(resp.GetMemberships())+1)
ownerUserIDs := make([]int64, 0, len(resp.GetMemberships())+1)
appendOwner := func(userID int64) {
if userID <= 0 {
return
}
if _, exists := seen[userID]; exists {
return
}
seen[userID] = struct{}{}
ownerUserIDs = append(ownerUserIDs, userID)
}
// Agency owner 自动拥有 owner membership即使历史数据缺 owner membership也要把 owner 的 active 房间纳入组织房间列表。
appendOwner(agency.GetOwnerUserId())
for _, membership := range resp.GetMemberships() {
if membership.GetStatus() == membershipStatusActive {
appendOwner(membership.GetHostUserId())
}
}
return ownerUserIDs, nil
}
func agencyRoomItemsFromProto(rooms []*roomv1.RoomListItem) []agencyRoomItemData {
items := make([]agencyRoomItemData, 0, len(rooms))
for _, room := range rooms {
items = append(items, agencyRoomItemFromProto(room))
}
return items
}
func agencyRoomItemFromProto(room *roomv1.RoomListItem) agencyRoomItemData {
if room == nil {
return agencyRoomItemData{}
}
roomID := room.GetRoomId()
return agencyRoomItemData{
RoomID: roomID,
IMGroupID: agencyRoomIMGroupID(roomID),
OwnerUserID: int64String(room.GetOwnerUserId()),
Title: room.GetTitle(),
CoverURL: room.GetCoverUrl(),
Mode: room.GetMode(),
Status: room.GetStatus(),
Locked: room.GetLocked(),
Heat: room.GetHeat(),
OnlineCount: room.GetOnlineCount(),
SeatCount: room.GetSeatCount(),
OccupiedSeatCount: room.GetOccupiedSeatCount(),
VisibleRegionID: room.GetVisibleRegionId(),
AppCode: room.GetAppCode(),
RoomShortID: room.GetRoomShortId(),
CountryCode: room.GetCountryCode(),
CountryFlag: agencyRoomCountryFlag(room.GetCountryCode()),
}
}
func positiveInt64Query(request *http.Request, name string) (int64, bool) {
raw := strings.TrimSpace(request.URL.Query().Get(name))
value, err := strconv.ParseInt(raw, 10, 64)
return value, err == nil && value > 0
}
func parseAgencyRoomListLimit(raw string) (int32, bool) {
raw = strings.TrimSpace(raw)
if raw == "" {
return 0, true
}
value, err := strconv.ParseInt(raw, 10, 32)
if err != nil || value <= 0 {
return 0, false
}
if value > maxAgencyRoomListLimit {
value = maxAgencyRoomListLimit
}
return int32(value), true
}
func parseAgencyRoomListTab(raw string) (string, bool) {
switch strings.ToLower(strings.TrimSpace(raw)) {
case "", "hot":
return "hot", true
case "new":
return "new", true
default:
return "", false
}
}
func agencyRoomListQuery(request *http.Request) string {
if query := strings.TrimSpace(request.URL.Query().Get("query")); query != "" {
return query
}
return strings.TrimSpace(request.URL.Query().Get("q"))
}
func trimmedOptionalString(value *string) *string {
if value == nil {
return nil
}
trimmed := strings.TrimSpace(*value)
return &trimmed
}
func optionalStringIsEmpty(value *string) bool {
return value != nil && *value == ""
}
func agencyRoomIMGroupID(roomID string) string {
groupID, err := imgroup.RoomGroupID(roomID)
if err != nil {
return roomID
}
return groupID
}
func agencyRoomCountryFlag(country string) string {
country = strings.ToUpper(strings.TrimSpace(country))
if len(country) != 2 {
return ""
}
runes := []rune(country)
for _, value := range runes {
if value < 'A' || value > 'Z' {
return ""
}
}
const regionalIndicatorA = 0x1F1E6
return string([]rune{
regionalIndicatorA + (runes[0] - 'A'),
regionalIndicatorA + (runes[1] - 'A'),
})
}

View File

@ -17,6 +17,7 @@ type Handler struct {
userCPClient client.UserCPClient
userCountryClient client.UserCountryQueryClient
userHostClient client.UserHostClient
roomQueryClient client.RoomQueryClient
walletClient client.WalletClient
growthLevelClient client.GrowthLevelClient
achievementClient client.AchievementClient
@ -31,6 +32,7 @@ type Config struct {
UserCPClient client.UserCPClient
UserCountryClient client.UserCountryQueryClient
UserHostClient client.UserHostClient
RoomQueryClient client.RoomQueryClient
WalletClient client.WalletClient
GrowthLevelClient client.GrowthLevelClient
AchievementClient client.AchievementClient
@ -46,6 +48,7 @@ func New(config Config) *Handler {
userCPClient: config.UserCPClient,
userCountryClient: config.UserCountryClient,
userHostClient: config.UserHostClient,
roomQueryClient: config.RoomQueryClient,
walletClient: config.WalletClient,
growthLevelClient: config.GrowthLevelClient,
achievementClient: config.AchievementClient,
@ -65,6 +68,9 @@ func (h *Handler) UserHandlers() httproutes.UserHandlers {
GetMyRoleSummary: h.getMyRoleSummary,
SearchHostAgencies: h.searchHostAgencies,
ApplyToHostAgency: h.applyToHostAgency,
GetAgencyProfile: h.getAgencyProfile,
ListAgencyRooms: h.listAgencyRooms,
UpdateAgencyProfile: h.updateAgencyProfile,
GetHostCenterAgency: h.getHostCenterAgency,
GetHostCenterPlatformPolicy: h.getHostCenterPlatformPolicy,
GetAgencyCenterOverview: h.getAgencyCenterOverview,

View File

@ -59,9 +59,6 @@ func (h *Handler) getHostCenterAgency(writer http.ResponseWriter, request *http.
if owner.DisplayUserID != "" {
data.ShortID = owner.DisplayUserID
}
if owner.Avatar != "" {
data.Avatar = owner.Avatar
}
}
}

View File

@ -24,6 +24,7 @@ const (
defaultRoomListLimit = 20
maxRoomListLimit = 50
maxRoomListQueryRunes = 64
maxRoomOwnerIDFilters = 500
roomHotHeatWeight = 650000
roomHotOnlineWeight = 300000
roomHotMicWeight = 50000
@ -102,6 +103,45 @@ func (s *Service) ListRooms(ctx context.Context, req *roomv1.ListRoomsRequest) (
return roomListResponseFromEntries(tab, query, countryCode, viewerCountryCode, allVisibleRegions, entries, limit), nil
}
func (s *Service) ListRoomsByOwners(ctx context.Context, req *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
if req.GetViewerUserId() <= 0 {
// owner 集合必须由 gateway 在鉴权后根据业务归属注入room-service 不接受匿名组织页查询。
return nil, xerr.New(xerr.InvalidArgument, "viewer_user_id is required")
}
tab := normalizeRoomListTab(req.GetTab())
if tab == "" {
return nil, xerr.New(xerr.InvalidArgument, "tab is invalid")
}
ownerUserIDs := normalizeRoomOwnerFilters(req.GetOwnerUserIds())
if len(ownerUserIDs) == 0 {
return roomListResponseFromEntries(tab, "", "", "", false, nil, normalizeRoomListLimit(req.GetLimit())), nil
}
limit := normalizeRoomListLimit(req.GetLimit())
query, err := normalizeRoomListQuery(req.GetQuery())
if err != nil {
return nil, err
}
cursor, err := decodeRoomListCursor(tab, query, "", "", false, req.GetCursor())
if err != nil {
return nil, err
}
entries, err := s.repository.ListRoomListEntries(ctx, RoomListQuery{
AppCode: appcode.FromContext(ctx),
Tab: tab,
OwnerUserIDs: ownerUserIDs,
Query: query,
Limit: limit + 1,
CursorSortScore: cursor.SortScore,
CursorCreatedAtMS: cursor.CreatedAtMS,
CursorRoomID: cursor.RoomID,
})
if err != nil {
return nil, err
}
return roomListResponseFromEntries(tab, query, "", "", false, entries, limit), nil
}
func (s *Service) listRoomListEntries(ctx context.Context, query RoomListQuery) ([]RoomListEntry, error) {
if s != nil && s.roomListCache != nil && roomListCacheEligible(query) {
entries, ok, err := s.roomListCache.ListRoomListEntries(ctx, query)
@ -118,7 +158,7 @@ func (s *Service) listRoomListEntries(ctx context.Context, query RoomListQuery)
func roomListCacheEligible(query RoomListQuery) bool {
// 搜索、全区白名单和内部定向查询仍走 MySQL避免为了低频条件维护过宽的 Redis 索引。
if strings.TrimSpace(query.Query) != "" || query.AllVisibleRegions || query.OwnerUserID > 0 {
if strings.TrimSpace(query.Query) != "" || query.AllVisibleRegions || query.OwnerUserID > 0 || len(query.OwnerUserIDs) > 0 {
return false
}
return query.Tab == roomListTabHot || query.Tab == roomListTabNew
@ -439,6 +479,25 @@ func normalizeRoomListLimit(limit int32) int {
return int(limit)
}
func normalizeRoomOwnerFilters(ownerUserIDs []int64) []int64 {
seen := make(map[int64]struct{}, len(ownerUserIDs))
ids := make([]int64, 0, len(ownerUserIDs))
for _, userID := range ownerUserIDs {
if userID <= 0 {
continue
}
if _, exists := seen[userID]; exists {
continue
}
seen[userID] = struct{}{}
ids = append(ids, userID)
if len(ids) >= maxRoomOwnerIDFilters {
break
}
}
return ids
}
// normalizeVisibleRegionID 把负数区域收敛到 GLOBAL 桶,避免非法区域影响 SQL 查询边界。
func normalizeVisibleRegionID(regionID int64) int64 {
if regionID < 0 {

View File

@ -84,6 +84,48 @@ func TestListRoomsFallsBackToMySQLWhenCacheMisses(t *testing.T) {
}
}
func TestListRoomsByOwnersReturnsActiveRoomsForAgencyHosts(t *testing.T) {
ctx := context.Background()
repository := mysqltest.NewRepository(t)
svc := roomservice.New(roomservice.Config{
NodeID: "node-list-by-owners-test",
LeaseTTL: 10 * time.Second,
RankLimit: 20,
SnapshotEveryN: 1,
}, router.NewMemoryDirectory(), repository, followTestWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher())
createPinnedListRoom(t, ctx, svc, "room-agency-owner", "agency-owner", 6201, 7101, "US")
createPinnedListRoom(t, ctx, svc, "room-agency-member", "agency-member", 6202, 7202, "AE")
createPinnedListRoom(t, ctx, svc, "room-outside-agency", "outside-agency", 6203, 7101, "US")
createPinnedListRoom(t, ctx, svc, "room-agency-closed", "agency-closed", 6202, 7202, "AE")
if _, err := svc.CloseRoom(ctx, &roomv1.CloseRoomRequest{
Meta: roomservice.NewRequestMeta("room-agency-closed", 6202),
Reason: "closed fixture",
}); err != nil {
t.Fatalf("close agency room fixture failed: %v", err)
}
resp, err := svc.ListRoomsByOwners(ctx, &roomv1.ListRoomsByOwnersRequest{
Meta: &roomv1.RequestMeta{AppCode: appcode.Default},
ViewerUserId: 4001,
OwnerUserIds: []int64{6201, 6202},
Tab: "new",
Limit: 10,
})
if err != nil {
t.Fatalf("list rooms by owners failed: %v", err)
}
got := roomIDs(resp.GetRooms())
want := map[string]bool{"room-agency-owner": true, "room-agency-member": true}
if len(got) != len(want) {
t.Fatalf("owner-filtered room count mismatch: got=%v", got)
}
for _, roomID := range got {
if !want[roomID] {
t.Fatalf("owner-filtered rooms must include only active agency host rooms, got=%v", got)
}
}
}
type fakeRoomListCache struct {
entries []roomservice.RoomListEntry
ok bool

View File

@ -497,6 +497,8 @@ type RoomListQuery struct {
Tab string
// OwnerUserID 保留给内部定向读模型;公开 Mine 顶部卡片走 GetMyRoom。
OwnerUserID int64
// OwnerUserIDs 是业务方预先解析出的房主集合,用于 Agency 等组织页批量取房间卡片。
OwnerUserIDs []int64
// Query 非空时按 room_id 或 title 做包含匹配。
Query string
// CountryCode 非空时只返回房主国家命中的房间gateway 必须先校验它属于当前用户区域。

View File

@ -572,6 +572,9 @@ const roomFollowSelectColumns = `
JOIN room_list_entries r ON r.app_code = f.app_code AND r.room_id = f.room_id`
func buildRoomListQuerySQL(query roomservice.RoomListQuery) (string, []any) {
if len(query.OwnerUserIDs) > 0 {
return buildRoomListByOwnersQuerySQL(query)
}
regionID := query.VisibleRegionID
if regionID < 0 {
regionID = 0
@ -674,6 +677,40 @@ func buildRoomListQuerySQL(query roomservice.RoomListQuery) (string, []any) {
return selectSQL + "\n\tWHERE " + strings.Join(where, " AND ") + "\n\tORDER BY " + pinRankExpr + " ASC, " + pinWeightExpr + " DESC, " + pinExpiresExpr + " DESC, r.sort_score DESC, r.room_id ASC\n\tLIMIT ?", args
}
func buildRoomListByOwnersQuerySQL(query roomservice.RoomListQuery) (string, []any) {
where := []string{"app_code = ?", "status = ?"}
args := []any{appcode.Normalize(query.AppCode), "active"}
placeholders := make([]string, 0, len(query.OwnerUserIDs))
for _, ownerUserID := range query.OwnerUserIDs {
placeholders = append(placeholders, "?")
args = append(args, ownerUserID)
}
where = append(where, "owner_user_id IN ("+strings.Join(placeholders, ",")+")")
if strings.TrimSpace(query.Query) != "" {
where = append(where, "(room_id LIKE ? ESCAPE '\\\\' OR room_short_id LIKE ? ESCAPE '\\\\' OR title LIKE ? ESCAPE '\\\\')")
like := "%" + escapeRoomListLike(query.Query) + "%"
args = append(args, like, like, like)
}
if query.Tab == "new" {
if query.CursorRoomID != "" {
where = append(where, "(created_at_ms < ? OR (created_at_ms = ? AND room_id > ?))")
args = append(args, query.CursorCreatedAtMS, query.CursorCreatedAtMS, query.CursorRoomID)
}
args = append(args, query.Limit)
return roomListSelectColumns + "\n\tWHERE " + strings.Join(where, " AND ") + "\n\tORDER BY created_at_ms DESC, room_id ASC\n\tLIMIT ?", args
}
if query.CursorRoomID != "" {
where = append(where, "(sort_score < ? OR (sort_score = ? AND room_id > ?))")
args = append(args, query.CursorSortScore, query.CursorSortScore, query.CursorRoomID)
}
args = append(args, query.Limit)
return roomListSelectColumns + "\n\tWHERE " + strings.Join(where, " AND ") + "\n\tORDER BY sort_score DESC, room_id ASC\n\tLIMIT ?", args
}
func normalizeRoomListSQLCountryCode(countryCode string) string {
countryCode = strings.ToUpper(strings.TrimSpace(countryCode))
if len(countryCode) < 2 || len(countryCode) > 3 {

View File

@ -485,6 +485,13 @@ func (s *Server) ListRooms(ctx context.Context, req *roomv1.ListRoomsRequest) (*
return mapServiceResult(s.svc.ListRooms(ctx, req))
}
// ListRoomsByOwners 代理到 owner 批量房间卡片读模型。
func (s *Server) ListRoomsByOwners(ctx context.Context, req *roomv1.ListRoomsByOwnersRequest) (*roomv1.ListRoomsResponse, error) {
// owner 集合由上游业务归属解析后注入room-service 只按房间 owner 投影批量读取卡片。
ctx = contextWithMetaApp(ctx, req.GetMeta())
return mapServiceResult(s.svc.ListRoomsByOwners(ctx, req))
}
// ListRoomFeeds 代理到 Mine 页用户房间流读模型。
func (s *Server) ListRoomFeeds(ctx context.Context, req *roomv1.ListRoomFeedsRequest) (*roomv1.ListRoomsResponse, error) {
// feed 查询只读用户到房间索引,并 join 房间卡片投影,不扫描 Room Cell 内存集合。

View File

@ -820,6 +820,7 @@ CREATE TABLE IF NOT EXISTS agencies (
owner_user_id BIGINT NOT NULL COMMENT '房主用户 ID',
parent_bd_user_id BIGINT NOT NULL COMMENT '父级BD用户 ID',
name VARCHAR(128) NOT NULL COMMENT '名称',
avatar VARCHAR(512) NOT NULL DEFAULT '' COMMENT '公会头像',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
join_enabled BOOLEAN NOT NULL COMMENT '加入是否启用',
max_hosts INT NOT NULL COMMENT '最大主播',

View File

@ -0,0 +1,8 @@
ALTER TABLE agencies
ADD COLUMN avatar VARCHAR(512) NOT NULL DEFAULT '' COMMENT '公会头像' AFTER name;
UPDATE agencies a
JOIN users u
ON u.app_code = a.app_code AND u.user_id = a.owner_user_id
SET a.avatar = COALESCE(u.avatar, '')
WHERE a.avatar = '';

View File

@ -126,6 +126,8 @@ const (
CommandTypeDeleteAgency = "admin_delete_agency"
// CommandTypeSetAgencyJoinEnabled 记录后台设置 Agency 入会开关命令。
CommandTypeSetAgencyJoinEnabled = "admin_set_agency_join_enabled"
// CommandTypeUpdateAgencyProfile 记录 Agency owner 修改独立资料的命令。
CommandTypeUpdateAgencyProfile = "update_agency_profile"
// CommandTypeCreateCoinSeller 记录后台创建币商身份命令。
CommandTypeCreateCoinSeller = "admin_create_coin_seller"
// CommandTypeSetCoinSellerStatus 记录后台启用或停用币商身份命令。
@ -167,7 +169,7 @@ type Agency struct {
RegionID int64
ParentBDUserID int64
Name string
OwnerAvatar string
Avatar string
ActiveHostCount int32
Status string
JoinEnabled bool

View File

@ -389,3 +389,25 @@ type SetAgencyJoinEnabledCommand struct {
EventID int64
NowMs int64
}
// UpdateAgencyProfileInput 是 Agency owner 修改独立组织资料的外部输入。
type UpdateAgencyProfileInput struct {
CommandID string
OperatorUserID int64
AgencyID int64
Name *string
Avatar *string
RequestID string
}
// UpdateAgencyProfileCommand 是修改 Agency 独立资料事务需要的完整命令。
type UpdateAgencyProfileCommand struct {
CommandID string
OperatorUserID int64
AgencyID int64
Name *string
Avatar *string
RequestID string
EventID int64
NowMs int64
}

View File

@ -44,6 +44,7 @@ type Repository interface {
ListActiveCoinSellersInMyRegion(ctx context.Context, userID int64) ([]hostdomain.CoinSellerListItem, error)
GetUserRoleSummary(ctx context.Context, userID int64) (hostdomain.UserRoleSummary, error)
GetAgency(ctx context.Context, agencyID int64) (hostdomain.Agency, error)
UpdateAgencyProfile(ctx context.Context, command UpdateAgencyProfileCommand) (hostdomain.Agency, error)
HasActiveAgencyOwner(ctx context.Context, userID int64) (int64, bool, error)
HasActiveManagerProfile(ctx context.Context, userID int64) (bool, error)
HasActiveManagerCapability(ctx context.Context, userID int64, capability string) (bool, error)
@ -207,15 +208,55 @@ func (s *Service) GetAgency(ctx context.Context, agencyID int64) (hostdomain.Age
return s.repository.GetAgency(ctx, agencyID)
}
// UpdateAgencyProfile 只修改 Agency 独立组织资料,不回写 owner 用户昵称或头像。
func (s *Service) UpdateAgencyProfile(ctx context.Context, command UpdateAgencyProfileInput) (hostdomain.Agency, error) {
if err := s.requireWriteDependencies(); err != nil {
return hostdomain.Agency{}, err
}
if strings.TrimSpace(command.CommandID) == "" || command.OperatorUserID <= 0 || command.AgencyID <= 0 {
return hostdomain.Agency{}, xerr.New(xerr.InvalidArgument, "command_id, operator_user_id and agency_id are required")
}
if command.Name == nil && command.Avatar == nil {
return hostdomain.Agency{}, xerr.New(xerr.InvalidArgument, "name or avatar is required")
}
var name *string
if command.Name != nil {
trimmed := strings.TrimSpace(*command.Name)
if trimmed == "" {
return hostdomain.Agency{}, xerr.New(xerr.InvalidArgument, "agency name is required")
}
name = &trimmed
}
var avatar *string
if command.Avatar != nil {
trimmed := strings.TrimSpace(*command.Avatar)
if trimmed == "" {
return hostdomain.Agency{}, xerr.New(xerr.InvalidArgument, "agency avatar is required")
}
avatar = &trimmed
}
return s.repository.UpdateAgencyProfile(ctx, UpdateAgencyProfileCommand{
CommandID: strings.TrimSpace(command.CommandID),
OperatorUserID: command.OperatorUserID,
AgencyID: command.AgencyID,
Name: name,
Avatar: avatar,
RequestID: strings.TrimSpace(command.RequestID),
EventID: s.nextEventIDRange(1),
NowMs: s.now().UnixMilli(),
})
}
// InviteAgency 由 BD 或 BD Leader 创建 Agency owner 邀请;目标用户接受前不创建 Agency 身份。
func (s *Service) InviteAgency(ctx context.Context, command InviteAgencyInput) (hostdomain.RoleInvitation, error) {
if err := s.requireWriteDependencies(); err != nil {
return hostdomain.RoleInvitation{}, err
}
// Agency 名称在邀请动作里固化,接受时按这份快照创建 Agency避免目标确认后前端再传入不同名称。
// Agency 名称允许邀请方显式覆盖;为空时在目标接受并真正创建 Agency 时复制 owner 当前昵称/短 ID
agencyName := strings.TrimSpace(command.AgencyName)
if strings.TrimSpace(command.CommandID) == "" || command.InviterUserID <= 0 || command.TargetUserID <= 0 || agencyName == "" {
return hostdomain.RoleInvitation{}, xerr.New(xerr.InvalidArgument, "command_id, inviter_user_id, target_user_id and agency_name are required")
if strings.TrimSpace(command.CommandID) == "" || command.InviterUserID <= 0 || command.TargetUserID <= 0 {
return hostdomain.RoleInvitation{}, xerr.New(xerr.InvalidArgument, "command_id, inviter_user_id and target_user_id are required")
}
nowMs := s.now().UnixMilli()
@ -500,8 +541,8 @@ func (s *Service) CreateAgency(ctx context.Context, command CreateAgencyInput) (
return hostdomain.CreateAgencyResult{}, err
}
name := strings.TrimSpace(command.Name)
if strings.TrimSpace(command.CommandID) == "" || command.AdminUserID <= 0 || command.OwnerUserID <= 0 || name == "" {
return hostdomain.CreateAgencyResult{}, xerr.New(xerr.InvalidArgument, "command_id, admin_user_id, owner_user_id and name are required")
if strings.TrimSpace(command.CommandID) == "" || command.AdminUserID <= 0 || command.OwnerUserID <= 0 {
return hostdomain.CreateAgencyResult{}, xerr.New(xerr.InvalidArgument, "command_id, admin_user_id and owner_user_id are required")
}
if command.ParentBDUserID < 0 {
return hostdomain.CreateAgencyResult{}, xerr.New(xerr.InvalidArgument, "parent_bd_user_id must not be negative")

View File

@ -847,7 +847,7 @@ func TestAdminCreateAgencyControlsAppSearch(t *testing.T) {
if err != nil {
t.Fatalf("SearchAgencies list failed: %v", err)
}
if len(agencies) != 1 || agencies[0].AgencyID != created.Agency.AgencyID || agencies[0].OwnerAvatar != "https://cdn.example/owner-901.png" || agencies[0].ActiveHostCount != 1 {
if len(agencies) != 1 || agencies[0].AgencyID != created.Agency.AgencyID || agencies[0].Avatar != "https://cdn.example/owner-901.png" || agencies[0].ActiveHostCount != 1 {
t.Fatalf("created agency list should be scoped by country with display fields: %+v", agencies)
}
if agencies[0].RegionID != 30 {
@ -972,6 +972,96 @@ func TestAdminCreateAgencyControlsAppSearch(t *testing.T) {
}
}
func TestAgencyProfileDefaultsAndStaysIndependent(t *testing.T) {
ctx := context.Background()
repository := mysqltest.NewRepository(t)
repository.PutUser(userdomain.User{
UserID: 921,
DefaultDisplayUserID: displayID(921),
CurrentDisplayUserID: displayID(921),
Username: "Owner Nick",
Avatar: "https://cdn.example/owner-old.png",
Country: "CN",
RegionID: 30,
ProfileCompleted: true,
ProfileCompletedAtMs: 1,
OnboardingStatus: userdomain.OnboardingStatusCompleted,
Status: userdomain.StatusActive,
})
seedActiveUser(t, repository, 922, 30)
svc := newHostService(repository, 5200, 6200)
created, err := svc.CreateAgency(ctx, hostservice.CreateAgencyInput{
CommandID: "admin-create-agency-default-profile",
AdminUserID: 1,
OwnerUserID: 921,
JoinEnabled: true,
RequestID: "req-agency-default-profile",
})
if err != nil {
t.Fatalf("CreateAgency with default profile failed: %v", err)
}
if created.Agency.Name != "Owner Nick" || created.Agency.Avatar != "https://cdn.example/owner-old.png" {
t.Fatalf("agency must copy owner profile once on create: %+v", created.Agency)
}
newName := "Agency New"
newAvatar := "https://cdn.example/agency-new.png"
updated, err := svc.UpdateAgencyProfile(ctx, hostservice.UpdateAgencyProfileInput{
CommandID: "agency-profile-update-owner",
OperatorUserID: 921,
AgencyID: created.Agency.AgencyID,
Name: &newName,
Avatar: &newAvatar,
RequestID: "req-agency-profile-update-owner",
})
if err != nil {
t.Fatalf("UpdateAgencyProfile by owner failed: %v", err)
}
if updated.Name != newName || updated.Avatar != newAvatar {
t.Fatalf("agency profile update mismatch: %+v", updated)
}
owner, err := repository.GetUser(ctx, 921)
if err != nil {
t.Fatalf("GetUser after agency update failed: %v", err)
}
if owner.Username != "Owner Nick" || owner.Avatar != "https://cdn.example/owner-old.png" {
t.Fatalf("agency profile update must not modify owner user: %+v", owner)
}
repository.PutUser(userdomain.User{
UserID: 921,
DefaultDisplayUserID: displayID(921),
CurrentDisplayUserID: displayID(921),
Username: "Owner New",
Avatar: "https://cdn.example/owner-new.png",
Country: "CN",
RegionID: 30,
ProfileCompleted: true,
ProfileCompletedAtMs: 1,
OnboardingStatus: userdomain.OnboardingStatusCompleted,
Status: userdomain.StatusActive,
})
afterUserChange, err := svc.GetAgency(ctx, created.Agency.AgencyID)
if err != nil {
t.Fatalf("GetAgency after owner profile change failed: %v", err)
}
if afterUserChange.Name != newName || afterUserChange.Avatar != newAvatar {
t.Fatalf("owner profile change must not sync back to agency: %+v", afterUserChange)
}
_, err = svc.UpdateAgencyProfile(ctx, hostservice.UpdateAgencyProfileInput{
CommandID: "agency-profile-update-non-owner",
OperatorUserID: 922,
AgencyID: created.Agency.AgencyID,
Name: &newName,
RequestID: "req-agency-profile-update-non-owner",
})
if got := xerr.CodeOf(err); got != xerr.PermissionDenied {
t.Fatalf("non owner agency update must be denied: got %s err=%v", got, err)
}
}
func TestAdminCreateAgencyWithoutParentBD(t *testing.T) {
ctx := context.Background()
repository := mysqltest.NewRepository(t)

View File

@ -315,8 +315,12 @@ func (r *Repository) CreateAgency(ctx context.Context, command hostservice.Creat
return hostdomain.CreateAgencyResult{}, err
}
agencyName, agencyAvatar, err := defaultAgencyProfileFromOwner(ctx, tx, command.OwnerUserID, command.Name)
if err != nil {
return hostdomain.CreateAgencyResult{}, err
}
// max_hosts 是历史兼容字段,当前业务不再限制主播数量,新建 Agency 固化为 0。
agency := hostdomain.Agency{AgencyID: command.AgencyID, OwnerUserID: command.OwnerUserID, RegionID: regionID, ParentBDUserID: command.ParentBDUserID, Name: command.Name, Status: hostdomain.AgencyStatusActive, JoinEnabled: command.JoinEnabled, MaxHosts: 0, CreatedByUserID: command.AdminUserID, CreatedAtMs: command.NowMs, UpdatedAtMs: command.NowMs}
agency := hostdomain.Agency{AgencyID: command.AgencyID, OwnerUserID: command.OwnerUserID, RegionID: regionID, ParentBDUserID: command.ParentBDUserID, Name: agencyName, Avatar: agencyAvatar, Status: hostdomain.AgencyStatusActive, JoinEnabled: command.JoinEnabled, MaxHosts: 0, CreatedByUserID: command.AdminUserID, CreatedAtMs: command.NowMs, UpdatedAtMs: command.NowMs}
if err := insertAgency(ctx, tx, agency); err != nil {
return hostdomain.CreateAgencyResult{}, mapHostDuplicateError(err)
}
@ -510,6 +514,53 @@ func (r *Repository) SetAgencyJoinEnabled(ctx context.Context, command hostservi
})
}
// UpdateAgencyProfile 只允许 active Agency owner 修改组织独立资料。
func (r *Repository) UpdateAgencyProfile(ctx context.Context, command hostservice.UpdateAgencyProfileCommand) (hostdomain.Agency, error) {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return hostdomain.Agency{}, err
}
defer tx.Rollback()
if existing, ok, err := commandResult(ctx, tx, command.CommandID); err != nil {
return hostdomain.Agency{}, err
} else if ok {
if err := requireCommandResult(existing, hostdomain.CommandTypeUpdateAgencyProfile, hostdomain.ResultTypeAgency); err != nil {
return hostdomain.Agency{}, err
}
return queryAgency(ctx, tx, "WHERE agency_id = ?", existing.ResultID)
}
agency, err := queryAgency(ctx, tx, "WHERE agency_id = ? FOR UPDATE", command.AgencyID)
if err != nil {
return hostdomain.Agency{}, err
}
if agency.Status != hostdomain.AgencyStatusActive || agency.OwnerUserID != command.OperatorUserID {
// Agency 资料的写权限只属于当前 active owner普通成员、关闭团队和历史 owner 都不能改。
return hostdomain.Agency{}, xerr.New(xerr.PermissionDenied, "permission denied")
}
if command.Name != nil {
agency.Name = *command.Name
}
if command.Avatar != nil {
agency.Avatar = *command.Avatar
}
agency.UpdatedAtMs = command.NowMs
if err := updateAgencyProfile(ctx, tx, agency); err != nil {
return hostdomain.Agency{}, err
}
if err := insertCommandResult(ctx, tx, hostdomain.CommandResult{CommandID: command.CommandID, CommandType: hostdomain.CommandTypeUpdateAgencyProfile, ResultType: hostdomain.ResultTypeAgency, ResultID: agency.AgencyID, CreatedAtMs: command.NowMs}); err != nil {
return hostdomain.Agency{}, mapHostDuplicateError(err)
}
if err := insertHostOutbox(ctx, tx, command.EventID, "AgencyChanged", "agency", agency.AgencyID, command.NowMs); err != nil {
return hostdomain.Agency{}, err
}
if err := tx.Commit(); err != nil {
return hostdomain.Agency{}, err
}
return agency, nil
}
func (r *Repository) updateAgencyAdmin(ctx context.Context, commandID string, commandType string, agencyID int64, eventID int64, nowMs int64, mutate func(hostdomain.Agency) hostdomain.Agency) (hostdomain.Agency, error) {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {

View File

@ -50,8 +50,15 @@ var (
), 0),
source, first_became_host_at_ms, created_at_ms, updated_at_ms`, userRegionProjection("host_profiles", "user_id"))
agencyColumns = fmt.Sprintf(`
agency_id, owner_user_id, %s, parent_bd_user_id, name, status,
join_enabled, max_hosts, created_by_user_id, created_at_ms, updated_at_ms`, userRegionProjection("agencies", "owner_user_id"))
agency_id, owner_user_id, %s, parent_bd_user_id, name, avatar, status,
join_enabled, max_hosts, created_by_user_id, created_at_ms, updated_at_ms,
COALESCE((
SELECT COUNT(*)
FROM agency_memberships active_member
WHERE active_member.app_code = agencies.app_code
AND active_member.agency_id = agencies.agency_id
AND active_member.status = '%s'
), 0)`, userRegionProjection("agencies", "owner_user_id"), hostdomain.MembershipStatusActive)
bdProfileColumns = fmt.Sprintf(`
user_id, role, %s, COALESCE(parent_leader_user_id, 0), status,
created_by_user_id, created_at_ms, updated_at_ms`, userRegionProjection("bd_profiles", "user_id"))
@ -118,6 +125,29 @@ func userRegionValue(ctx context.Context, q sqlQueryer, userID int64, lockClause
return regionID, err
}
func defaultAgencyProfileFromOwner(ctx context.Context, tx *sql.Tx, ownerUserID int64, explicitName string) (string, string, error) {
snapshot, err := roleInvitationUserSnapshotByID(ctx, tx, ownerUserID)
if err != nil {
return "", "", err
}
name := strings.TrimSpace(explicitName)
if name == "" {
// Agency 的默认资料只在创建身份这一刻从 owner 用户资料复制一次;
// 后续用户资料和 Agency 资料完全分离,不能再在查询层动态兜底。
name = firstNonBlank(snapshot.Username, snapshot.DisplayUserID, fmt.Sprintf("%d", ownerUserID))
}
return name, strings.TrimSpace(snapshot.Avatar), nil
}
func firstNonBlank(values ...string) string {
for _, value := range values {
if trimmed := strings.TrimSpace(value); trimmed != "" {
return trimmed
}
}
return ""
}
func currentUserRegion(ctx context.Context, q sqlQueryer, userID int64, lockClause string) (int64, error) {
// Host 领域不拥有 users 表,但所有角色流转都依赖用户当前有效区域。
// 调用方需要串行化用户身份变化时传入 FOR UPDATE 来锁住 users 行。

View File

@ -512,12 +512,17 @@ func (r *Repository) acceptAgencyInvitation(ctx context.Context, tx *sql.Tx, com
// Agency、拥有者 host_profile、拥有者成员关系是同一业务事实的三张表投影
// 必须全部创建成功后邀请才能进入已接受状态。
agencyName, agencyAvatar, err := defaultAgencyProfileFromOwner(ctx, tx, invitation.TargetUserID, invitation.AgencyName)
if err != nil {
return false, false, err
}
agency := hostdomain.Agency{
AgencyID: command.AgencyID,
OwnerUserID: invitation.TargetUserID,
RegionID: targetRegionID,
ParentBDUserID: invitation.ParentBDUserID,
Name: invitation.AgencyName,
Name: agencyName,
Avatar: agencyAvatar,
Status: hostdomain.AgencyStatusActive,
JoinEnabled: true,
// max_hosts 是历史兼容字段,当前业务不再限制主播数量。

View File

@ -31,13 +31,13 @@ func (r *Repository) SearchAgencies(ctx context.Context, command hostservice.Sea
COALESCE(owner.region_id, 0),
a.parent_bd_user_id,
a.name,
a.avatar,
a.status,
a.join_enabled,
a.max_hosts,
a.created_by_user_id,
a.created_at_ms,
a.updated_at_ms,
COALESCE(owner.avatar, ''),
COUNT(active_member.membership_id)
FROM agencies a
INNER JOIN users owner
@ -65,13 +65,13 @@ func (r *Repository) SearchAgencies(ctx context.Context, command hostservice.Sea
owner.region_id,
a.parent_bd_user_id,
a.name,
a.avatar,
a.status,
a.join_enabled,
a.max_hosts,
a.created_by_user_id,
a.created_at_ms,
a.updated_at_ms,
owner.avatar
a.updated_at_ms
ORDER BY a.created_at_ms DESC, a.agency_id DESC
LIMIT ?
`
@ -618,12 +618,14 @@ func scanAgency(scanner rowScanner) (hostdomain.Agency, error) {
&agency.RegionID,
&agency.ParentBDUserID,
&agency.Name,
&agency.Avatar,
&agency.Status,
&agency.JoinEnabled,
&agency.MaxHosts,
&agency.CreatedByUserID,
&agency.CreatedAtMs,
&agency.UpdatedAtMs,
&agency.ActiveHostCount,
)
return agency, err
}
@ -636,13 +638,13 @@ func scanSearchAgency(scanner rowScanner) (hostdomain.Agency, error) {
&agency.RegionID,
&agency.ParentBDUserID,
&agency.Name,
&agency.Avatar,
&agency.Status,
&agency.JoinEnabled,
&agency.MaxHosts,
&agency.CreatedByUserID,
&agency.CreatedAtMs,
&agency.UpdatedAtMs,
&agency.OwnerAvatar,
&agency.ActiveHostCount,
)
return agency, err

View File

@ -181,10 +181,10 @@ func insertAgency(ctx context.Context, tx *sql.Tx, agency hostdomain.Agency) err
// 第一阶段只有接受 Agency 邀请时会创建 Agency。
_, err := tx.ExecContext(ctx, `
INSERT INTO agencies (
app_code, agency_id, owner_user_id, parent_bd_user_id, name, status,
app_code, agency_id, owner_user_id, parent_bd_user_id, name, avatar, status,
join_enabled, max_hosts, created_by_user_id, created_at_ms, updated_at_ms
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`, appcode.FromContext(ctx), agency.AgencyID, agency.OwnerUserID, agency.ParentBDUserID, agency.Name, agency.Status, agency.JoinEnabled, agency.MaxHosts, agency.CreatedByUserID, agency.CreatedAtMs, agency.UpdatedAtMs)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`, appcode.FromContext(ctx), agency.AgencyID, agency.OwnerUserID, agency.ParentBDUserID, agency.Name, agency.Avatar, agency.Status, agency.JoinEnabled, agency.MaxHosts, agency.CreatedByUserID, agency.CreatedAtMs, agency.UpdatedAtMs)
return err
}
@ -198,6 +198,16 @@ func updateAgencyAdminState(ctx context.Context, tx *sql.Tx, agency hostdomain.A
return err
}
func updateAgencyProfile(ctx context.Context, tx *sql.Tx, agency hostdomain.Agency) error {
// Agency 资料是独立组织资料;这里绝不更新 users 表,也不从 owner 用户资料重新派生。
_, err := tx.ExecContext(ctx, `
UPDATE agencies
SET name = ?, avatar = ?, updated_at_ms = ?
WHERE app_code = ? AND agency_id = ?
`, agency.Name, agency.Avatar, agency.UpdatedAtMs, appcode.FromContext(ctx), agency.AgencyID)
return err
}
func insertBDProfile(ctx context.Context, tx *sql.Tx, profile hostdomain.BDProfile) error {
// 普通 BD 身份行和 host_profile 相互独立BD 用户不会自动成为 Host也不会隐式拥有 BD Leader 权限。
_, err := tx.ExecContext(ctx, `

View File

@ -855,18 +855,19 @@ func (r *Repository) PutAgency(agency hostdomain.Agency) {
_, err := r.schema.DB.ExecContext(context.Background(), `
INSERT INTO agencies (
agency_id, owner_user_id, parent_bd_user_id, name, status,
agency_id, owner_user_id, parent_bd_user_id, name, avatar, status,
join_enabled, max_hosts, created_by_user_id, created_at_ms, updated_at_ms
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
owner_user_id = VALUES(owner_user_id),
parent_bd_user_id = VALUES(parent_bd_user_id),
name = VALUES(name),
avatar = VALUES(avatar),
status = VALUES(status),
join_enabled = VALUES(join_enabled),
max_hosts = VALUES(max_hosts),
updated_at_ms = VALUES(updated_at_ms)
`, agency.AgencyID, agency.OwnerUserID, agency.ParentBDUserID, agency.Name, agency.Status, agency.JoinEnabled, agency.MaxHosts, agency.CreatedByUserID, agency.CreatedAtMs, agency.UpdatedAtMs)
`, agency.AgencyID, agency.OwnerUserID, agency.ParentBDUserID, agency.Name, agency.Avatar, agency.Status, agency.JoinEnabled, agency.MaxHosts, agency.CreatedByUserID, agency.CreatedAtMs, agency.UpdatedAtMs)
if err != nil {
r.t.Fatalf("seed agency %d failed: %v", agency.AgencyID, err)
}

View File

@ -434,7 +434,7 @@ func toProtoAgency(agency hostdomain.Agency) *userv1.Agency {
CreatedByUserId: agency.CreatedByUserID,
CreatedAtMs: agency.CreatedAtMs,
UpdatedAtMs: agency.UpdatedAtMs,
Avatar: agency.OwnerAvatar,
Avatar: agency.Avatar,
HostCount: agency.ActiveHostCount,
}
}

View File

@ -393,6 +393,26 @@ func (s *Server) GetAgency(ctx context.Context, req *userv1.GetAgencyRequest) (*
return &userv1.GetAgencyResponse{Agency: toProtoAgency(agency)}, nil
}
// UpdateAgencyProfile 修改 Agency 独立资料;用户资料和 Agency 资料不会互相回写。
func (s *Server) UpdateAgencyProfile(ctx context.Context, req *userv1.UpdateAgencyProfileRequest) (*userv1.UpdateAgencyProfileResponse, error) {
if s.hostSvc == nil {
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
}
ctx = contextWithApp(ctx, req.GetMeta())
agency, err := s.hostSvc.UpdateAgencyProfile(ctx, hostservice.UpdateAgencyProfileInput{
CommandID: req.GetCommandId(),
OperatorUserID: req.GetOperatorUserId(),
AgencyID: req.GetAgencyId(),
Name: req.Name,
Avatar: req.Avatar,
RequestID: req.GetMeta().GetRequestId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &userv1.UpdateAgencyProfileResponse{Agency: toProtoAgency(agency)}, nil
}
// CheckBusinessCapability 返回 H5/App 业务入口可用性,具体身份规则由 host service 统一判断。
func (s *Server) CheckBusinessCapability(ctx context.Context, req *userv1.CheckBusinessCapabilityRequest) (*userv1.CheckBusinessCapabilityResponse, error) {
if s.hostSvc == nil {