diff --git a/internal/transformer/customer_transformer.go b/internal/transformer/customer_transformer.go index 72812af..69b9618 100644 --- a/internal/transformer/customer_transformer.go +++ b/internal/transformer/customer_transformer.go @@ -45,6 +45,10 @@ func SetDefaultCustomerRequestToModel(req *contract.SetDefaultCustomerRequest) * // Model to Contract conversions func CustomerModelToResponse(customer *models.CustomerResponse) *contract.CustomerResponse { + if customer == nil { + return nil + } + return &contract.CustomerResponse{ ID: customer.ID, OrganizationID: customer.OrganizationID, diff --git a/internal/transformer/gamification_transformer.go b/internal/transformer/gamification_transformer.go index a178466..4b2d035 100644 --- a/internal/transformer/gamification_transformer.go +++ b/internal/transformer/gamification_transformer.go @@ -30,11 +30,20 @@ func ListCustomerPointsRequestToModel(req *contract.ListCustomerPointsRequest) * } func CustomerPointsModelToResponse(model *models.CustomerPointsResponse) *contract.CustomerPointsResponse { + if model == nil { + return nil + } + + var customer *contract.CustomerResponse + if model.Customer != nil { + customer = CustomerModelToResponse(model.Customer) + } + return &contract.CustomerPointsResponse{ ID: model.ID, CustomerID: model.CustomerID, Balance: model.Balance, - Customer: CustomerModelToResponse(model.Customer), + Customer: customer, CreatedAt: model.CreatedAt, UpdatedAt: model.UpdatedAt, } @@ -82,12 +91,21 @@ func ListCustomerTokensRequestToModel(req *contract.ListCustomerTokensRequest) * } func CustomerTokensModelToResponse(model *models.CustomerTokensResponse) *contract.CustomerTokensResponse { + if model == nil { + return nil + } + + var customer *contract.CustomerResponse + if model.Customer != nil { + customer = CustomerModelToResponse(model.Customer) + } + return &contract.CustomerTokensResponse{ ID: model.ID, CustomerID: model.CustomerID, TokenType: model.TokenType, Balance: model.Balance, - Customer: CustomerModelToResponse(model.Customer), + Customer: customer, CreatedAt: model.CreatedAt, UpdatedAt: model.UpdatedAt, } @@ -193,6 +211,10 @@ func ListGamesRequestToModel(req *contract.ListGamesRequest) *models.ListGamesQu } func GameModelToResponse(model *models.GameResponse) *contract.GameResponse { + if model == nil { + return nil + } + return &contract.GameResponse{ ID: model.ID, Name: model.Name, @@ -265,6 +287,20 @@ func ListGamePrizesRequestToModel(req *contract.ListGamePrizesRequest) *models.L } func GamePrizeModelToResponse(model *models.GamePrizeResponse) *contract.GamePrizeResponse { + if model == nil { + return nil + } + + var game *contract.GameResponse + if model.Game != nil { + game = GameModelToResponse(model.Game) + } + + var fallbackPrize *contract.GamePrizeResponse + if model.FallbackPrize != nil { + fallbackPrize = GamePrizeModelToResponse(model.FallbackPrize) + } + return &contract.GamePrizeResponse{ ID: model.ID, GameID: model.GameID, @@ -275,8 +311,8 @@ func GamePrizeModelToResponse(model *models.GamePrizeResponse) *contract.GamePri Threshold: model.Threshold, FallbackPrizeID: model.FallbackPrizeID, Metadata: model.Metadata, - Game: GameModelToResponse(model.Game), - FallbackPrize: GamePrizeModelToResponse(model.FallbackPrize), + Game: game, + FallbackPrize: fallbackPrize, CreatedAt: model.CreatedAt, UpdatedAt: model.UpdatedAt, } @@ -337,6 +373,25 @@ func ListGamePlaysRequestToModel(req *contract.ListGamePlaysRequest) *models.Lis } func GamePlayModelToResponse(model *models.GamePlayResponse) *contract.GamePlayResponse { + if model == nil { + return nil + } + + var game *contract.GameResponse + if model.Game != nil { + game = GameModelToResponse(model.Game) + } + + var customer *contract.CustomerResponse + if model.Customer != nil { + customer = CustomerModelToResponse(model.Customer) + } + + var prize *contract.GamePrizeResponse + if model.Prize != nil { + prize = GamePrizeModelToResponse(model.Prize) + } + return &contract.GamePlayResponse{ ID: model.ID, GameID: model.GameID, @@ -345,16 +400,35 @@ func GamePlayModelToResponse(model *models.GamePlayResponse) *contract.GamePlayR TokenUsed: model.TokenUsed, RandomSeed: model.RandomSeed, CreatedAt: model.CreatedAt, - Game: GameModelToResponse(model.Game), - Customer: CustomerModelToResponse(model.Customer), - Prize: GamePrizeModelToResponse(model.Prize), + Game: game, + Customer: customer, + Prize: prize, } } func PlayGameModelToResponse(model *models.PlayGameResponse) *contract.PlayGameResponse { + if model == nil { + return nil + } + + var gamePlay *contract.GamePlayResponse + if &model.GamePlay != nil { + gamePlay = GamePlayModelToResponse(&model.GamePlay) + } + + var prizeWon *contract.GamePrizeResponse + if model.PrizeWon != nil { + prizeWon = GamePrizeModelToResponse(model.PrizeWon) + } + + var gamePlayValue contract.GamePlayResponse + if gamePlay != nil { + gamePlayValue = *gamePlay + } + return &contract.PlayGameResponse{ - GamePlay: *GamePlayModelToResponse(&model.GamePlay), - PrizeWon: GamePrizeModelToResponse(model.PrizeWon), + GamePlay: gamePlayValue, + PrizeWon: prizeWon, TokensRemaining: model.TokensRemaining, } } @@ -410,6 +484,15 @@ func ListOmsetTrackerRequestToModel(req *contract.ListOmsetTrackerRequest) *mode } func OmsetTrackerModelToResponse(model *models.OmsetTrackerResponse) *contract.OmsetTrackerResponse { + if model == nil { + return nil + } + + var game *contract.GameResponse + if model.Game != nil { + game = GameModelToResponse(model.Game) + } + return &contract.OmsetTrackerResponse{ ID: model.ID, PeriodType: model.PeriodType, @@ -417,7 +500,7 @@ func OmsetTrackerModelToResponse(model *models.OmsetTrackerResponse) *contract.O PeriodEnd: model.PeriodEnd, Total: model.Total, GameID: model.GameID, - Game: GameModelToResponse(model.Game), + Game: game, CreatedAt: model.CreatedAt, UpdatedAt: model.UpdatedAt, } diff --git a/migrations/000057_add_customer_password_field.up.sql b/migrations/000057_add_customer_password_field.up.sql new file mode 100644 index 0000000..af613c2 --- /dev/null +++ b/migrations/000057_add_customer_password_field.up.sql @@ -0,0 +1,17 @@ +-- Add password field to customers table for authentication +ALTER TABLE customers ADD COLUMN password_hash VARCHAR(255); + +-- Add phone number field if not exists (for registration) +ALTER TABLE customers ADD COLUMN phone_number VARCHAR(20) UNIQUE; + +-- Add birth_date field for customer registration +ALTER TABLE customers ADD COLUMN birth_date DATE; + +-- Add indexes for better performance +CREATE INDEX idx_customers_phone_number ON customers(phone_number); +CREATE INDEX idx_customers_password_hash ON customers(password_hash) WHERE password_hash IS NOT NULL; + +-- Add comments +COMMENT ON COLUMN customers.password_hash IS 'Hashed password for customer authentication'; +COMMENT ON COLUMN customers.phone_number IS 'Unique phone number for customer login'; +COMMENT ON COLUMN customers.birth_date IS 'Customer birth date for registration';