package models import "time" // Sweepstake represents a lottery/cup style competition with prizes // Visible from start until end+3 days. Winners are selected at end. type Sweepstake struct { BaseModel Title string `json:"title" gorm:"size:255;not null"` Description string `json:"description" gorm:"type:text"` ImageURL string `json:"image_url" gorm:"size:500"` RulesURL string `json:"rules_url" gorm:"size:500"` StartAt time.Time `json:"start_at" gorm:"not null;index"` EndAt time.Time `json:"end_at" gorm:"not null;index"` Status string `json:"status" gorm:"size:16;not null;default:'draft';index"` // draft|scheduled|active|locked|finalized|archived PickerStyle string `json:"picker_style" gorm:"size:16;not null;default:'wheel'"` // wheel|cycler TotalPrizes int `json:"total_prizes" gorm:"not null;default:1"` PrizeSummary string `json:"prize_summary" gorm:"type:text"` WinnersSelectedAt *time.Time `json:"winners_selected_at"` VisibilityUntil *time.Time `json:"visibility_until"` DrawSeed string `json:"draw_seed" gorm:"size:64"` MaxEntriesPerUser int `json:"max_entries_per_user" gorm:"not null;default:1"` Prizes []SweepstakePrize `json:"prizes" gorm:"foreignKey:SweepstakeID;constraint:OnDelete:CASCADE"` Entries []SweepstakeEntry `json:"-" gorm:"foreignKey:SweepstakeID;constraint:OnDelete:CASCADE"` Winners []SweepstakeWinner `json:"-" gorm:"foreignKey:SweepstakeID;constraint:OnDelete:CASCADE"` } func (Sweepstake) TableName() string { return "sweepstakes" } // SweepstakePrize defines a prize tier and quantity type SweepstakePrize struct { BaseModel SweepstakeID uint `json:"sweepstake_id" gorm:"index;not null"` Name string `json:"name" gorm:"size:255;not null"` Description string `json:"description" gorm:"type:text"` ImageURL string `json:"image_url" gorm:"size:500"` Value string `json:"value" gorm:"size:255"` Quantity int `json:"quantity" gorm:"not null;default:1"` DisplayOrder int `json:"display_order" gorm:"not null;default:0"` Kind string `json:"kind" gorm:"size:16;not null;default:'physical'"` // physical|points|xp|points_xp Points int64 `json:"points" gorm:"not null;default:0"` XP int64 `json:"xp" gorm:"not null;default:0"` } func (SweepstakePrize) TableName() string { return "sweepstake_prizes" } // SweepstakeEntry is a user's participation record type SweepstakeEntry struct { BaseModel SweepstakeID uint `json:"sweepstake_id" gorm:"index;not null"` UserID uint `json:"user_id" gorm:"index;not null"` Status string `json:"status" gorm:"size:16;not null;default:'valid';index"` // valid|invalid|withdrawn IPHash string `json:"ip_hash" gorm:"size:64"` VisualPlayedAt *time.Time `json:"visual_played_at"` ViewCount int `json:"view_count" gorm:"not null;default:0"` } func (SweepstakeEntry) TableName() string { return "sweepstake_entries" } // SweepstakeWinner stores selected winners mapped to prizes type SweepstakeWinner struct { BaseModel SweepstakeID uint `json:"sweepstake_id" gorm:"index;not null"` EntryID uint `json:"entry_id" gorm:"index;not null"` UserID uint `json:"user_id" gorm:"index;not null"` PrizeID *uint `json:"prize_id" gorm:"index"` PrizeName string `json:"prize_name" gorm:"size:255"` AnnouncedAt *time.Time `json:"announced_at"` NotifiedUserAt *time.Time `json:"notified_user_at"` NotifiedAdminAt *time.Time `json:"notified_admin_at"` ClaimStatus string `json:"claim_status" gorm:"size:16;not null;default:'pending';index"` // pending|claimed|delivered ClaimNote string `json:"claim_note" gorm:"type:text"` AwardedAt *time.Time `json:"awarded_at"` } func (SweepstakeWinner) TableName() string { return "sweepstake_winners" }