package processor import ( "context" "fmt" "apskel-pos-be/internal/models" "apskel-pos-be/internal/repository" "github.com/google/uuid" ) type CustomerPointsProcessor struct { walletQuery *WalletQueryProcessor gameRepo *repository.GameRepository } func NewCustomerPointsProcessor(walletQuery *WalletQueryProcessor, gameRepo *repository.GameRepository) *CustomerPointsProcessor { return &CustomerPointsProcessor{ walletQuery: walletQuery, gameRepo: gameRepo, } } // The three endpoints below are the customer app's balance screens. They read the // EnakPoint & EnakCoin wallet; customer_points and customer_tokens are no longer used // for balances (docs/prd-point-coin.md ยง9). func (p *CustomerPointsProcessor) GetCustomerTotalPointsAPI(ctx context.Context, customerID string) (*models.GetCustomerPointsResponse, error) { id, err := parseWalletCustomerID(customerID) if err != nil { return nil, err } data, err := p.walletQuery.LegacyPoints(ctx, id) if err != nil { return nil, fmt.Errorf("failed to get customer points: %w", err) } return &models.GetCustomerPointsResponse{ Status: "SUCCESS", Message: "Customer points retrieved successfully.", Data: data, }, nil } func (p *CustomerPointsProcessor) GetCustomerTotalTokensAPI(ctx context.Context, customerID string) (*models.GetCustomerTokensResponse, error) { id, err := parseWalletCustomerID(customerID) if err != nil { return nil, err } data, err := p.walletQuery.LegacyTokens(ctx, id) if err != nil { return nil, fmt.Errorf("failed to get customer tokens: %w", err) } return &models.GetCustomerTokensResponse{ Status: "SUCCESS", Message: "Customer tokens retrieved successfully.", Data: data, }, nil } func (p *CustomerPointsProcessor) GetCustomerWalletAPI(ctx context.Context, customerID string) (*models.GetCustomerWalletResponse, error) { id, err := parseWalletCustomerID(customerID) if err != nil { return nil, err } data, err := p.walletQuery.Summary(ctx, id) if err != nil { return nil, fmt.Errorf("failed to get customer wallet: %w", err) } return &models.GetCustomerWalletResponse{ Status: "SUCCESS", Message: "Customer wallet retrieved successfully.", Data: data, }, nil } func (p *CustomerPointsProcessor) GetCustomerWalletTransactionsAPI(ctx context.Context, customerID string, query models.ListCustomerWalletTransactionsQuery) (*models.PaginatedResponse[models.CustomerWalletTransaction], error) { id, err := parseWalletCustomerID(customerID) if err != nil { return nil, err } return p.walletQuery.Transactions(ctx, id, query) } func parseWalletCustomerID(customerID string) (uuid.UUID, error) { id, err := uuid.Parse(customerID) if err != nil { return uuid.Nil, fmt.Errorf("%w: invalid customer id", ErrInvalidWalletQuery) } return id, nil } // GetCustomerGamesAPI gets active SPIN games for customers func (p *CustomerPointsProcessor) GetCustomerGamesAPI(ctx context.Context) (*models.GetCustomerGamesResponse, error) { // Get active SPIN games games, err := p.gameRepo.GetActiveSpinGames(ctx) if err != nil { return nil, fmt.Errorf("failed to get active SPIN games: %w", err) } // Convert to response format var gameResponses []models.CustomerGameResponse for _, game := range games { var prizeResponses []models.CustomerGamePrizeResponse for _, prize := range game.Prizes { prizeResponses = append(prizeResponses, models.CustomerGamePrizeResponse{ ID: prize.ID, GameID: prize.GameID, Name: prize.Name, Image: prize.Image, Metadata: (*map[string]interface{})(&prize.Metadata), CreatedAt: prize.CreatedAt, UpdatedAt: prize.UpdatedAt, }) } gameResponses = append(gameResponses, models.CustomerGameResponse{ ID: game.ID, Name: game.Name, Type: string(game.Type), IsActive: game.IsActive, Metadata: (*map[string]interface{})(&game.Metadata), Prizes: prizeResponses, CreatedAt: game.CreatedAt, UpdatedAt: game.UpdatedAt, }) } return &models.GetCustomerGamesResponse{ Status: "SUCCESS", Message: "Customer games retrieved successfully.", Data: &models.GetCustomerGamesResponseData{ Games: gameResponses, }, }, nil } // GetFerrisWheelGameAPI gets the Ferris Wheel game for customers func (p *CustomerPointsProcessor) GetFerrisWheelGameAPI(ctx context.Context) (*models.GetFerrisWheelGameResponse, error) { // Get Ferris Wheel game game, err := p.gameRepo.GetFerrisWheelGame(ctx) if err != nil { return nil, fmt.Errorf("failed to get Ferris Wheel game: %w", err) } // Convert prizes to response format var prizeResponses []models.CustomerGamePrizeResponse for _, prize := range game.Prizes { prizeResponses = append(prizeResponses, models.CustomerGamePrizeResponse{ ID: prize.ID, GameID: prize.GameID, Name: prize.Name, Image: prize.Image, Metadata: (*map[string]interface{})(&prize.Metadata), CreatedAt: prize.CreatedAt, UpdatedAt: prize.UpdatedAt, }) } // Convert game to response format gameResponse := models.CustomerGameResponse{ ID: game.ID, Name: game.Name, Type: string(game.Type), IsActive: game.IsActive, Metadata: (*map[string]interface{})(&game.Metadata), Prizes: prizeResponses, CreatedAt: game.CreatedAt, UpdatedAt: game.UpdatedAt, } return &models.GetFerrisWheelGameResponse{ Status: "SUCCESS", Message: "Ferris Wheel game retrieved successfully.", Data: &models.GetFerrisWheelGameResponseData{ Game: gameResponse, }, }, nil } func (p *CustomerPointsProcessor) GetCustomerWalletExpiringAPI(ctx context.Context, customerID string) (*models.CustomerWalletExpiringList, error) { id, err := parseWalletCustomerID(customerID) if err != nil { return nil, err } return p.walletQuery.Expiring(ctx, id) }