Fix Commit

This commit is contained in:
Aditya Siregar 2025-09-18 17:21:58 +07:00
parent a520d0ed11
commit 9db3dcb472
3 changed files with 163 additions and 159 deletions

View File

@ -3,33 +3,35 @@ package contract
import ( import (
"time" "time"
"apskel-pos-be/internal/entities"
"github.com/google/uuid" "github.com/google/uuid"
) )
// Request Contracts // Request Contracts
type CreateCampaignRequest struct { type CreateCampaignRequest struct {
Name string `json:"name" binding:"required,min=1,max=150"` Name string `json:"name" binding:"required,min=1,max=150"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"` Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"`
StartDate time.Time `json:"start_date" binding:"required"` StartDate time.Time `json:"start_date" binding:"required"`
EndDate time.Time `json:"end_date" binding:"required"` EndDate time.Time `json:"end_date" binding:"required"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
ShowOnApp bool `json:"show_on_app"` ShowOnApp bool `json:"show_on_app"`
Position int `json:"position" binding:"min=0"` Position int `json:"position" binding:"min=0"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }
type UpdateCampaignRequest struct { type UpdateCampaignRequest struct {
ID uuid.UUID `json:"id" binding:"required"` ID uuid.UUID `json:"id" binding:"required"`
Name string `json:"name" binding:"required,min=1,max=150"` Name string `json:"name" binding:"required,min=1,max=150"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"` Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"`
StartDate time.Time `json:"start_date" binding:"required"` StartDate time.Time `json:"start_date" binding:"required"`
EndDate time.Time `json:"end_date" binding:"required"` EndDate time.Time `json:"end_date" binding:"required"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
ShowOnApp bool `json:"show_on_app"` ShowOnApp bool `json:"show_on_app"`
Position int `json:"position" binding:"min=0"` Position int `json:"position" binding:"min=0"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }
type ListCampaignsRequest struct { type ListCampaignsRequest struct {
@ -53,26 +55,26 @@ type DeleteCampaignRequest struct {
// Campaign Rule Request Contracts // Campaign Rule Request Contracts
type CreateCampaignRuleRequest struct { type CreateCampaignRuleRequest struct {
CampaignID uuid.UUID `json:"campaign_id" binding:"required"` CampaignID uuid.UUID `json:"campaign_id" binding:"required"`
RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"` RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"` RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }
type UpdateCampaignRuleRequest struct { type UpdateCampaignRuleRequest struct {
ID uuid.UUID `json:"id" binding:"required"` ID uuid.UUID `json:"id" binding:"required"`
CampaignID uuid.UUID `json:"campaign_id" binding:"required"` CampaignID uuid.UUID `json:"campaign_id" binding:"required"`
RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"` RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"` RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }
type ListCampaignRulesRequest struct { type ListCampaignRulesRequest struct {
@ -93,33 +95,33 @@ type DeleteCampaignRuleRequest struct {
// Response Contracts // Response Contracts
type CampaignResponse struct { type CampaignResponse struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Type string `json:"type"` Type string `json:"type"`
StartDate time.Time `json:"start_date"` StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"` EndDate time.Time `json:"end_date"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
ShowOnApp bool `json:"show_on_app"` ShowOnApp bool `json:"show_on_app"`
Position int `json:"position"` Position int `json:"position"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
Rules []CampaignRuleResponse `json:"rules,omitempty"` Rules []CampaignRuleResponse `json:"rules,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
type CampaignRuleResponse struct { type CampaignRuleResponse struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id"`
CampaignID uuid.UUID `json:"campaign_id"` CampaignID uuid.UUID `json:"campaign_id"`
RuleType string `json:"rule_type"` RuleType string `json:"rule_type"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type"` RewardType string `json:"reward_type"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
type ListCampaignsResponse struct { type ListCampaignsResponse struct {
@ -138,11 +140,11 @@ type ListCampaignRulesResponse struct {
// Helper structs // Helper structs
type CampaignRuleStruct struct { type CampaignRuleStruct struct {
RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"` RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"` RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }

View File

@ -45,18 +45,18 @@ const (
) )
type Campaign struct { type Campaign struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
Name string `gorm:"type:varchar(150);not null" json:"name"` Name string `gorm:"type:varchar(150);not null" json:"name"`
Description *string `gorm:"type:text" json:"description,omitempty"` Description *string `gorm:"type:text" json:"description,omitempty"`
Type CampaignType `gorm:"type:varchar(50);not null" json:"type"` Type CampaignType `gorm:"type:varchar(50);not null" json:"type"`
StartDate time.Time `gorm:"type:timestamp;not null" json:"start_date"` StartDate time.Time `gorm:"type:timestamp;not null" json:"start_date"`
EndDate time.Time `gorm:"type:timestamp;not null" json:"end_date"` EndDate time.Time `gorm:"type:timestamp;not null" json:"end_date"`
IsActive bool `gorm:"type:boolean;default:true" json:"is_active"` IsActive bool `gorm:"type:boolean;default:true" json:"is_active"`
ShowOnApp bool `gorm:"type:boolean;default:true" json:"show_on_app"` ShowOnApp bool `gorm:"type:boolean;default:true" json:"show_on_app"`
Position int `gorm:"type:int;default:0" json:"position"` Position int `gorm:"type:int;default:0" json:"position"`
Metadata *map[string]interface{} `gorm:"type:jsonb" json:"metadata,omitempty"` Metadata *Metadata `gorm:"type:jsonb" json:"metadata,omitempty"`
CreatedAt time.Time `gorm:"type:timestamp;default:now()" json:"created_at"` CreatedAt time.Time `gorm:"type:timestamp;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"type:timestamp;default:now()" json:"updated_at"` UpdatedAt time.Time `gorm:"type:timestamp;default:now()" json:"updated_at"`
// Relations // Relations
Rules []CampaignRule `gorm:"foreignKey:CampaignID;constraint:OnDelete:CASCADE" json:"rules,omitempty"` Rules []CampaignRule `gorm:"foreignKey:CampaignID;constraint:OnDelete:CASCADE" json:"rules,omitempty"`
@ -79,17 +79,17 @@ func (c *Campaign) BeforeUpdate(tx *gorm.DB) error {
} }
type CampaignRule struct { type CampaignRule struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
CampaignID uuid.UUID `gorm:"type:uuid;not null" json:"campaign_id"` CampaignID uuid.UUID `gorm:"type:uuid;not null" json:"campaign_id"`
RuleType RuleType `gorm:"type:varchar(50);not null" json:"rule_type"` RuleType RuleType `gorm:"type:varchar(50);not null" json:"rule_type"`
ConditionValue *string `gorm:"type:varchar(255)" json:"condition_value,omitempty"` ConditionValue *string `gorm:"type:varchar(255)" json:"condition_value,omitempty"`
RewardType CampaignRewardType `gorm:"type:varchar(50);not null" json:"reward_type"` RewardType CampaignRewardType `gorm:"type:varchar(50);not null" json:"reward_type"`
RewardValue *int64 `gorm:"type:bigint" json:"reward_value,omitempty"` RewardValue *int64 `gorm:"type:bigint" json:"reward_value,omitempty"`
RewardSubtype *RewardSubtype `gorm:"type:varchar(50)" json:"reward_subtype,omitempty"` RewardSubtype *RewardSubtype `gorm:"type:varchar(50)" json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `gorm:"type:uuid" json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `gorm:"type:uuid" json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `gorm:"type:jsonb" json:"metadata,omitempty"` Metadata *Metadata `gorm:"type:jsonb" json:"metadata,omitempty"`
CreatedAt time.Time `gorm:"type:timestamp;default:now()" json:"created_at"` CreatedAt time.Time `gorm:"type:timestamp;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"type:timestamp;default:now()" json:"updated_at"` UpdatedAt time.Time `gorm:"type:timestamp;default:now()" json:"updated_at"`
// Relations // Relations
Campaign Campaign `gorm:"foreignKey:CampaignID" json:"campaign,omitempty"` Campaign Campaign `gorm:"foreignKey:CampaignID" json:"campaign,omitempty"`

View File

@ -3,34 +3,36 @@ package models
import ( import (
"time" "time"
"apskel-pos-be/internal/entities"
"github.com/google/uuid" "github.com/google/uuid"
) )
type CreateCampaignRequest struct { type CreateCampaignRequest struct {
Name string `json:"name" binding:"required,min=1,max=150"` Name string `json:"name" binding:"required,min=1,max=150"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"` Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"`
StartDate time.Time `json:"start_date" binding:"required"` StartDate time.Time `json:"start_date" binding:"required"`
EndDate time.Time `json:"end_date" binding:"required"` EndDate time.Time `json:"end_date" binding:"required"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
ShowOnApp bool `json:"show_on_app"` ShowOnApp bool `json:"show_on_app"`
Position int `json:"position" binding:"min=0"` Position int `json:"position" binding:"min=0"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
Rules []CampaignRuleStruct `json:"rules" binding:"required,min=1"` Rules []CampaignRuleStruct `json:"rules" binding:"required,min=1"`
} }
type UpdateCampaignRequest struct { type UpdateCampaignRequest struct {
ID uuid.UUID `json:"id" binding:"required"` ID uuid.UUID `json:"id" binding:"required"`
Name string `json:"name" binding:"required,min=1,max=150"` Name string `json:"name" binding:"required,min=1,max=150"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"` Type string `json:"type" binding:"required,oneof=REWARD POINTS TOKENS MIXED"`
StartDate time.Time `json:"start_date" binding:"required"` StartDate time.Time `json:"start_date" binding:"required"`
EndDate time.Time `json:"end_date" binding:"required"` EndDate time.Time `json:"end_date" binding:"required"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
ShowOnApp bool `json:"show_on_app"` ShowOnApp bool `json:"show_on_app"`
Position int `json:"position" binding:"min=0"` Position int `json:"position" binding:"min=0"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
Rules []CampaignRuleStruct `json:"rules" binding:"required,min=1"` Rules []CampaignRuleStruct `json:"rules" binding:"required,min=1"`
} }
type ListCampaignsRequest struct { type ListCampaignsRequest struct {
@ -45,33 +47,33 @@ type ListCampaignsRequest struct {
} }
type CampaignResponse struct { type CampaignResponse struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Type string `json:"type"` Type string `json:"type"`
StartDate time.Time `json:"start_date"` StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"` EndDate time.Time `json:"end_date"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
ShowOnApp bool `json:"show_on_app"` ShowOnApp bool `json:"show_on_app"`
Position int `json:"position"` Position int `json:"position"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
Rules []CampaignRuleResponse `json:"rules,omitempty"` Rules []CampaignRuleResponse `json:"rules,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
type CampaignRuleResponse struct { type CampaignRuleResponse struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id"`
CampaignID uuid.UUID `json:"campaign_id"` CampaignID uuid.UUID `json:"campaign_id"`
RuleType string `json:"rule_type"` RuleType string `json:"rule_type"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type"` RewardType string `json:"reward_type"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
type ListCampaignsResponse struct { type ListCampaignsResponse struct {
@ -83,26 +85,26 @@ type ListCampaignsResponse struct {
// Campaign Rule Models // Campaign Rule Models
type CreateCampaignRuleRequest struct { type CreateCampaignRuleRequest struct {
CampaignID uuid.UUID `json:"campaign_id" binding:"required"` CampaignID uuid.UUID `json:"campaign_id" binding:"required"`
RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"` RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"` RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }
type UpdateCampaignRuleRequest struct { type UpdateCampaignRuleRequest struct {
ID uuid.UUID `json:"id" binding:"required"` ID uuid.UUID `json:"id" binding:"required"`
CampaignID uuid.UUID `json:"campaign_id" binding:"required"` CampaignID uuid.UUID `json:"campaign_id" binding:"required"`
RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"` RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"` RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }
type ListCampaignRulesRequest struct { type ListCampaignRulesRequest struct {
@ -122,11 +124,11 @@ type ListCampaignRulesResponse struct {
// Helper structs // Helper structs
type CampaignRuleStruct struct { type CampaignRuleStruct struct {
RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"` RuleType string `json:"rule_type" binding:"required,oneof=TIER SPEND PRODUCT CATEGORY DAY LOCATION"`
ConditionValue *string `json:"condition_value,omitempty"` ConditionValue *string `json:"condition_value,omitempty"`
RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"` RewardType string `json:"reward_type" binding:"required,oneof=POINTS TOKENS REWARD"`
RewardValue *int64 `json:"reward_value,omitempty"` RewardValue *int64 `json:"reward_value,omitempty"`
RewardSubtype *string `json:"reward_subtype,omitempty"` RewardSubtype *string `json:"reward_subtype,omitempty"`
RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"` RewardRefID *uuid.UUID `json:"reward_ref_id,omitempty"`
Metadata *map[string]interface{} `json:"metadata,omitempty"` Metadata *entities.Metadata `json:"metadata,omitempty"`
} }