package grpc import ( "context" activityv1 "hyapp.local/api/proto/activity/v1" "hyapp/pkg/appcode" "hyapp/pkg/xerr" domain "hyapp/services/activity-service/internal/domain/wheel" service "hyapp/services/activity-service/internal/service/wheel" ) type WheelServer struct { activityv1.UnimplementedWheelServiceServer svc *service.Service } func NewWheelServer(svc *service.Service) *WheelServer { return &WheelServer{svc: svc} } func (s *WheelServer) ExecuteWheelDraw(ctx context.Context, req *activityv1.ExecuteWheelDrawRequest) (*activityv1.ExecuteWheelDrawResponse, error) { meta := req.GetWheel() ctx = appcode.WithContext(ctx, meta.GetMeta().GetAppCode()) result, err := s.svc.Draw(ctx, domain.DrawCommand{ CommandID: meta.GetCommandId(), WheelID: meta.GetWheelId(), UserID: meta.GetUserId(), DeviceID: meta.GetDeviceId(), DrawCount: meta.GetDrawCount(), CoinSpent: meta.GetCoinSpent(), PaidAtMS: meta.GetPaidAtMs(), VisibleRegionID: meta.GetVisibleRegionId(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.ExecuteWheelDrawResponse{Result: wheelDrawResultToProto(result)}, nil } type AdminWheelServer struct { activityv1.UnimplementedAdminWheelServiceServer svc *service.Service } func NewAdminWheelServer(svc *service.Service) *AdminWheelServer { return &AdminWheelServer{svc: svc} } func (s *AdminWheelServer) GetWheelConfig(ctx context.Context, req *activityv1.GetWheelConfigRequest) (*activityv1.GetWheelConfigResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) config, err := s.svc.GetConfig(ctx, req.GetWheelId()) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.GetWheelConfigResponse{Config: wheelRuleConfigToProto(config)}, nil } func (s *AdminWheelServer) UpsertWheelConfig(ctx context.Context, req *activityv1.UpsertWheelConfigRequest) (*activityv1.UpsertWheelConfigResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) config := wheelRuleConfigFromProto(req.GetConfig()) config.CreatedByAdminID = req.GetOperatorAdminId() updated, err := s.svc.UpsertConfig(ctx, config) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.UpsertWheelConfigResponse{Config: wheelRuleConfigToProto(updated)}, nil } func (s *AdminWheelServer) ListWheelDraws(ctx context.Context, req *activityv1.ListWheelDrawsRequest) (*activityv1.ListWheelDrawsResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) draws, total, err := s.svc.ListDraws(ctx, domain.DrawQuery{ WheelID: req.GetWheelId(), UserID: req.GetUserId(), Status: req.GetStatus(), Page: req.GetPage(), PageSize: req.GetPageSize(), }) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &activityv1.ListWheelDrawsResponse{Draws: make([]*activityv1.WheelDrawResult, 0, len(draws)), Total: total} for _, draw := range draws { resp.Draws = append(resp.Draws, wheelDrawResultToProto(draw)) } return resp, nil } func (s *AdminWheelServer) GetWheelDrawSummary(ctx context.Context, req *activityv1.GetWheelDrawSummaryRequest) (*activityv1.GetWheelDrawSummaryResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) summary, err := s.svc.GetDrawSummary(ctx, domain.DrawQuery{ WheelID: req.GetWheelId(), UserID: req.GetUserId(), Status: req.GetStatus(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.GetWheelDrawSummaryResponse{Summary: wheelDrawSummaryToProto(summary)}, nil } func wheelRuleConfigFromProto(config *activityv1.WheelRuleConfig) domain.RuleConfig { if config == nil { return domain.RuleConfig{} } tiers := make([]domain.Tier, 0, len(config.GetTiers())) for _, tier := range config.GetTiers() { tiers = append(tiers, domain.Tier{ TierID: tier.GetTierId(), DisplayName: tier.GetDisplayName(), RewardType: tier.GetRewardType(), RewardID: tier.GetRewardId(), RewardCount: tier.GetRewardCount(), RewardCoins: tier.GetRewardCoins(), RTPValueCoins: tier.GetRtpValueCoins(), WeightPPM: tier.GetWeightPpm(), Enabled: tier.GetEnabled(), MetadataJSON: tier.GetMetadataJson(), }) } return domain.RuleConfig{ AppCode: config.GetAppCode(), WheelID: config.GetWheelId(), RuleVersion: config.GetRuleVersion(), Enabled: config.GetEnabled(), DrawPriceCoins: config.GetDrawPriceCoins(), TargetRTPPPM: config.GetTargetRtpPpm(), PoolRatePPM: config.GetPoolRatePpm(), SettlementWindowDraws: config.GetSettlementWindowDraws(), InitialPoolCoins: config.GetInitialPoolCoins(), PoolReserveCoins: config.GetPoolReserveCoins(), MaxSingleRTPPayout: config.GetMaxSingleRtpPayout(), EffectiveFromMS: config.GetEffectiveFromMs(), CreatedByAdminID: config.GetCreatedByAdminId(), CreatedAtMS: config.GetCreatedAtMs(), Tiers: tiers, } } func wheelRuleConfigToProto(config domain.RuleConfig) *activityv1.WheelRuleConfig { tiers := make([]*activityv1.WheelPrizeTier, 0, len(config.Tiers)) for _, tier := range config.Tiers { tiers = append(tiers, &activityv1.WheelPrizeTier{ TierId: tier.TierID, DisplayName: tier.DisplayName, RewardType: tier.RewardType, RewardId: tier.RewardID, RewardCount: tier.RewardCount, RewardCoins: tier.RewardCoins, RtpValueCoins: tier.RTPValueCoins, WeightPpm: tier.WeightPPM, Enabled: tier.Enabled, MetadataJson: tier.MetadataJSON, }) } return &activityv1.WheelRuleConfig{ AppCode: config.AppCode, WheelId: config.WheelID, RuleVersion: config.RuleVersion, Enabled: config.Enabled, DrawPriceCoins: config.DrawPriceCoins, TargetRtpPpm: config.TargetRTPPPM, PoolRatePpm: config.PoolRatePPM, SettlementWindowDraws: config.SettlementWindowDraws, InitialPoolCoins: config.InitialPoolCoins, PoolReserveCoins: config.PoolReserveCoins, MaxSingleRtpPayout: config.MaxSingleRTPPayout, EffectiveFromMs: config.EffectiveFromMS, CreatedByAdminId: config.CreatedByAdminID, CreatedAtMs: config.CreatedAtMS, Tiers: tiers, } } func wheelDrawResultToProto(result domain.DrawResult) *activityv1.WheelDrawResult { return &activityv1.WheelDrawResult{ DrawId: result.DrawID, DrawIds: result.DrawIDs, CommandId: result.CommandID, WheelId: result.WheelID, RuleVersion: result.RuleVersion, SelectedTierId: result.SelectedTierID, RewardType: result.RewardType, RewardId: result.RewardID, RewardCount: result.RewardCount, RewardCoins: result.RewardCoins, RtpValueCoins: result.RTPValueCoins, RewardStatus: result.RewardStatus, RtpWindowIndex: result.RTPWindowIndex, ActualRtpPpm: result.ActualRTPPPM, CreatedAtMs: result.CreatedAtMS, WalletTransactionId: result.WalletTransactionID, CoinBalanceAfter: result.CoinBalanceAfter, MetadataJson: result.MetadataJSON, } } func wheelDrawSummaryToProto(summary domain.DrawSummary) *activityv1.WheelDrawSummary { return &activityv1.WheelDrawSummary{ WheelId: summary.WheelID, TotalDraws: summary.TotalDraws, UniqueUsers: summary.UniqueUsers, TotalSpentCoins: summary.TotalSpentCoins, TotalRtpValueCoins: summary.TotalRTPValueCoins, ActualRtpPpm: summary.ActualRTPPPM, PendingDraws: summary.PendingDraws, GrantedDraws: summary.GrantedDraws, FailedDraws: summary.FailedDraws, } }