313 lines
13 KiB
Go
313 lines
13 KiB
Go
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/lib/pq"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Contest représente un concours musical
|
|
type Contest struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
Title string `json:"title" gorm:"not null"`
|
|
Description string `json:"description" gorm:"not null"`
|
|
Type string `json:"type" gorm:"not null;index"` // remix, production, sound_design, collaboration
|
|
Status string `json:"status" gorm:"not null;default:'draft'"` // draft, active, voting, completed, cancelled
|
|
CreatorID uuid.UUID `json:"creator_id" gorm:"type:uuid;not null;index"`
|
|
OriginalTrackID *uuid.UUID `json:"original_track_id,omitempty" gorm:"type:uuid"`
|
|
Genre sql.NullString `json:"genre,omitempty"`
|
|
BPM sql.NullInt32 `json:"bpm,omitempty"`
|
|
Key sql.NullString `json:"key,omitempty"`
|
|
Requirements pq.StringArray `json:"requirements" gorm:"type:jsonb"`
|
|
Rules pq.StringArray `json:"rules" gorm:"type:jsonb"`
|
|
Timeline ContestTimeline `json:"timeline" gorm:"type:jsonb"`
|
|
Prizes []ContestPrize `json:"prizes" gorm:"type:jsonb"`
|
|
JudgingCriteria []JudgingCriterion `json:"judging_criteria" gorm:"type:jsonb"`
|
|
Settings map[string]interface{} `json:"settings" gorm:"type:jsonb"`
|
|
CoverImage sql.NullString `json:"cover_image,omitempty"`
|
|
IsPublic bool `json:"is_public" gorm:"not null;default:true"`
|
|
IsFeatured bool `json:"is_featured" gorm:"not null;default:false"`
|
|
MaxParticipants sql.NullInt32 `json:"max_participants,omitempty"`
|
|
EntryCount int64 `json:"entry_count" gorm:"not null;default:0"`
|
|
ViewCount int64 `json:"view_count" gorm:"not null;default:0"`
|
|
VoteCount int64 `json:"vote_count" gorm:"not null;default:0"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
|
|
// Relations
|
|
Creator *User `json:"creator,omitempty"`
|
|
OriginalTrack *SellableContent `json:"original_track,omitempty"`
|
|
Entries []ContestEntry `json:"entries,omitempty"`
|
|
Judges []ContestJudge `json:"judges,omitempty"`
|
|
Sponsors []ContestSponsor `json:"sponsors,omitempty"`
|
|
}
|
|
|
|
// ContestTimeline représente la timeline d'un concours
|
|
type ContestTimeline struct {
|
|
StartDate time.Time `json:"start_date"`
|
|
SubmissionDeadline time.Time `json:"submission_deadline"`
|
|
VotingStart time.Time `json:"voting_start"`
|
|
VotingEnd time.Time `json:"voting_end"`
|
|
ResultsAnnouncement time.Time `json:"results_announcement"`
|
|
}
|
|
|
|
// ContestPrize représente un prix dans un concours
|
|
type ContestPrize struct {
|
|
Position int `json:"position"`
|
|
Prize string `json:"prize"`
|
|
Description string `json:"description"`
|
|
CashAmount float64 `json:"cash_amount,omitempty"`
|
|
Currency string `json:"currency,omitempty"`
|
|
Badge string `json:"badge,omitempty"`
|
|
Distribution string `json:"distribution,omitempty"`
|
|
}
|
|
|
|
// JudgingCriterion représente un critère de jugement
|
|
type JudgingCriterion struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Weight float64 `json:"weight"`
|
|
MaxScore int `json:"max_score"`
|
|
}
|
|
|
|
// ContestEntry représente une participation à un concours
|
|
type ContestEntry struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;index"`
|
|
UserID uuid.UUID `json:"user_id" gorm:"type:uuid;not null;index"`
|
|
Title string `json:"title" gorm:"not null"`
|
|
Description string `json:"description"`
|
|
AudioFile string `json:"audio_file" gorm:"not null"`
|
|
Metadata map[string]interface{} `json:"metadata" gorm:"type:jsonb"`
|
|
Status string `json:"status" gorm:"not null;default:'submitted'"` // submitted, approved, disqualified, winner
|
|
Position sql.NullInt32 `json:"position,omitempty"`
|
|
Score sql.NullFloat64 `json:"score,omitempty"`
|
|
VoteCount int64 `json:"vote_count" gorm:"not null;default:0"`
|
|
ViewCount int64 `json:"view_count" gorm:"not null;default:0"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
User *User `json:"user,omitempty"`
|
|
Votes []ContestVote `json:"votes,omitempty"`
|
|
}
|
|
|
|
// ContestJudge représente un juge dans un concours
|
|
type ContestJudge struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;index"`
|
|
UserID uuid.UUID `json:"user_id" gorm:"type:uuid;not null;index"`
|
|
Role string `json:"role" gorm:"not null"` // head_judge, expert_judge, community_judge
|
|
Weight float64 `json:"weight" gorm:"not null;default:1.0"`
|
|
Credentials sql.NullString `json:"credentials,omitempty"`
|
|
IsActive bool `json:"is_active" gorm:"not null;default:true"`
|
|
JoinedAt time.Time `json:"joined_at" gorm:"autoCreateTime"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
User *User `json:"user,omitempty"`
|
|
}
|
|
|
|
// ContestVote représente un vote dans un concours
|
|
type ContestVote struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;index"`
|
|
EntryID uuid.UUID `json:"entry_id" gorm:"type:uuid;not null;index"`
|
|
UserID uuid.UUID `json:"user_id" gorm:"type:uuid;not null;index"`
|
|
JudgeID *uuid.UUID `json:"judge_id,omitempty" gorm:"type:uuid"`
|
|
VoteType string `json:"vote_type" gorm:"not null"` // expert, community
|
|
Score float64 `json:"score" gorm:"not null"`
|
|
Criteria map[string]float64 `json:"criteria" gorm:"type:jsonb"`
|
|
Comment sql.NullString `json:"comment,omitempty"`
|
|
IsValid bool `json:"is_valid" gorm:"not null;default:true"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
Entry *ContestEntry `json:"entry,omitempty"`
|
|
User *User `json:"user,omitempty"`
|
|
Judge *ContestJudge `json:"judge,omitempty"`
|
|
}
|
|
|
|
// ContestSponsor représente un sponsor d'un concours
|
|
type ContestSponsor struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;index"`
|
|
Name string `json:"name" gorm:"not null"`
|
|
Description sql.NullString `json:"description,omitempty"`
|
|
Logo sql.NullString `json:"logo,omitempty"`
|
|
Website sql.NullString `json:"website,omitempty"`
|
|
Contribution float64 `json:"contribution" gorm:"not null"`
|
|
Currency string `json:"currency" gorm:"not null;default:'EUR'"`
|
|
Benefits pq.StringArray `json:"benefits" gorm:"type:jsonb"`
|
|
IsActive bool `json:"is_active" gorm:"not null;default:true"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
}
|
|
|
|
// ContestStems représente les stems d'un concours (pour remix contests)
|
|
type ContestStems struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;uniqueIndex"`
|
|
VocalsPath string `json:"vocals_path" gorm:"not null"`
|
|
DrumsPath string `json:"drums_path" gorm:"not null"`
|
|
BassPath string `json:"bass_path" gorm:"not null"`
|
|
OtherPath string `json:"other_path" gorm:"not null"`
|
|
DownloadURL string `json:"download_url" gorm:"not null"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
}
|
|
|
|
// ContestAnalytics représente les analytics d'un concours
|
|
type ContestAnalytics struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;uniqueIndex"`
|
|
TotalEntries int64 `json:"total_entries" gorm:"not null;default:0"`
|
|
UniqueParticipants int64 `json:"unique_participants" gorm:"not null;default:0"`
|
|
TotalVotes int64 `json:"total_votes" gorm:"not null;default:0"`
|
|
UniqueVoters int64 `json:"unique_voters" gorm:"not null;default:0"`
|
|
AverageScore float64 `json:"average_score" gorm:"not null;default:0"`
|
|
CompletionRate float64 `json:"completion_rate" gorm:"not null;default:0"`
|
|
EngagementRate float64 `json:"engagement_rate" gorm:"not null;default:0"`
|
|
SocialShares int64 `json:"social_shares" gorm:"not null;default:0"`
|
|
Comments int64 `json:"comments" gorm:"not null;default:0"`
|
|
Countries int64 `json:"countries" gorm:"not null;default:0"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
}
|
|
|
|
// ContestBadge représente un badge de concours
|
|
type ContestBadge struct {
|
|
ID uuid.UUID `json:"id" gorm:"type:uuid;primaryKey"`
|
|
ContestID uuid.UUID `json:"contest_id" gorm:"type:uuid;not null;index"`
|
|
UserID uuid.UUID `json:"user_id" gorm:"type:uuid;not null;index"`
|
|
BadgeType string `json:"badge_type" gorm:"not null"` // winner, participant, judge, sponsor
|
|
Position sql.NullInt32 `json:"position,omitempty"`
|
|
Description string `json:"description" gorm:"not null"`
|
|
Icon string `json:"icon" gorm:"not null"`
|
|
Rarity string `json:"rarity" gorm:"not null;default:'common'"` // common, rare, epic, legendary
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
|
|
|
// Relations
|
|
Contest *Contest `json:"contest,omitempty"`
|
|
User *User `json:"user,omitempty"`
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour Contest
|
|
func (Contest) TableName() string {
|
|
return "contests"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestEntry
|
|
func (ContestEntry) TableName() string {
|
|
return "contest_entries"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestJudge
|
|
func (ContestJudge) TableName() string {
|
|
return "contest_judges"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestVote
|
|
func (ContestVote) TableName() string {
|
|
return "contest_votes"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestSponsor
|
|
func (ContestSponsor) TableName() string {
|
|
return "contest_sponsors"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestStems
|
|
func (ContestStems) TableName() string {
|
|
return "contest_stems"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestAnalytics
|
|
func (ContestAnalytics) TableName() string {
|
|
return "contest_analytics"
|
|
}
|
|
|
|
// TableName spécifie le nom de la table pour ContestBadge
|
|
func (ContestBadge) TableName() string {
|
|
return "contest_badges"
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *Contest) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestEntry) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestJudge) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestVote) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestSponsor) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestStems) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestAnalytics) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BeforeCreate hook GORM pour générer UUID si non défini
|
|
func (m *ContestBadge) BeforeCreate(tx *gorm.DB) error {
|
|
if m.ID == uuid.Nil {
|
|
m.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|