This commit is contained in:
Tomas Dvorak
2025-11-02 21:31:00 +01:00
parent b9cea0cd77
commit 087f30e82c
130 changed files with 20104 additions and 34330 deletions
+1
View File
@@ -90,6 +90,7 @@ func (n *NavigationItem) GetURL() string {
"contacts": "/admin/kontakty",
"newsletter": "/admin/newsletter",
"polls": "/admin/ankety",
"sweepstakes": "/admin/sweepstakes",
"navigation": "/admin/navigace",
"competition_aliases": "/admin/aliasy-soutezi",
"prefetch": "/admin/prefetch",
+77
View File
@@ -0,0 +1,77 @@
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" }
+3
View File
@@ -6,8 +6,11 @@ type UserProfile struct {
Points int64 `json:"points" gorm:"default:0;index"`
Level int `json:"level" gorm:"default:1"`
XP int64 `json:"xp" gorm:"default:0"`
Username string `json:"username" gorm:"size:32;uniqueIndex"`
AvatarURL string `json:"avatar_url" gorm:"type:varchar(500)"`
AnimatedAvatarURL string `json:"animated_avatar_url" gorm:"type:varchar(500)"`
AvatarUploadUnlocked bool `json:"avatar_upload_unlocked" gorm:"default:false"`
AnimatedAvatarUploadUnlocked bool `json:"animated_avatar_upload_unlocked" gorm:"default:false"`
}
func (UserProfile) TableName() string { return "user_profiles" }