package work import ( "gorm.io/gorm" "tercul/internal/domain" "time" ) type WorkStatus string const ( WorkStatusDraft WorkStatus = "draft" WorkStatusPublished WorkStatus = "published" WorkStatusArchived WorkStatus = "archived" WorkStatusDeleted WorkStatus = "deleted" ) type WorkType string const ( WorkTypePoetry WorkType = "poetry" WorkTypeProse WorkType = "prose" WorkTypeDrama WorkType = "drama" WorkTypeEssay WorkType = "essay" WorkTypeNovel WorkType = "novel" WorkTypeShortStory WorkType = "short_story" WorkTypeNovella WorkType = "novella" WorkTypePlay WorkType = "play" WorkTypeScript WorkType = "script" WorkTypeOther WorkType = "other" ) type Work struct { domain.TranslatableModel Title string `gorm:"size:255;not null"` Description string `gorm:"type:text"` Type WorkType `gorm:"size:50;default:'other'"` Status WorkStatus `gorm:"size:50;default:'draft'"` PublishedAt *time.Time Translations []*domain.Translation `gorm:"polymorphic:Translatable"` Authors []*domain.Author `gorm:"many2many:work_authors"` Tags []*domain.Tag `gorm:"many2many:work_tags"` Categories []*domain.Category `gorm:"many2many:work_categories"` Copyrights []*domain.Copyright `gorm:"many2many:work_copyrights;constraint:OnDelete:CASCADE"` Monetizations []*domain.Monetization `gorm:"many2many:work_monetizations;constraint:OnDelete:CASCADE"` } func (w *Work) BeforeSave(tx *gorm.DB) error { if w.Title == "" { w.Title = "Untitled Work" } return nil } func (w *Work) GetID() uint { return w.ID } func (w *Work) GetType() string { return "Work" } func (w *Work) GetDefaultLanguage() string { return w.Language } type WorkStats struct { domain.BaseModel Views int64 `gorm:"default:0"` Likes int64 `gorm:"default:0"` Comments int64 `gorm:"default:0"` Bookmarks int64 `gorm:"default:0"` Shares int64 `gorm:"default:0"` TranslationCount int64 `gorm:"default:0"` ReadingTime int `gorm:"default:0"` Complexity float64 `gorm:"type:decimal(5,2);default:0.0"` Sentiment float64 `gorm:"type:decimal(5,2);default:0.0"` WorkID uint `gorm:"uniqueIndex;index"` Work *Work `gorm:"foreignKey:WorkID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` } type WorkSeries struct { domain.BaseModel WorkID uint `gorm:"index;uniqueIndex:uniq_work_series"` Work *Work `gorm:"foreignKey:WorkID"` SeriesID uint `gorm:"index;uniqueIndex:uniq_work_series"` Series *domain.Series `gorm:"foreignKey:SeriesID"` NumberInSeries int `gorm:"default:0"` } type BookWork struct { domain.BaseModel BookID uint `gorm:"index;uniqueIndex:uniq_book_work"` Book *domain.Book `gorm:"foreignKey:BookID"` WorkID uint `gorm:"index;uniqueIndex:uniq_book_work"` Work *Work `gorm:"foreignKey:WorkID"` Order int `gorm:"default:0"` } type WorkAuthor struct { domain.BaseModel WorkID uint `gorm:"index;uniqueIndex:uniq_work_author_role"` Work *Work `gorm:"foreignKey:WorkID"` AuthorID uint `gorm:"index;uniqueIndex:uniq_work_author_role"` Author *domain.Author `gorm:"foreignKey:AuthorID"` Role string `gorm:"size:50;default:'author';uniqueIndex:uniq_work_author_role"` Ordinal int `gorm:"default:0"` } type WorkCopyright struct { WorkID uint `gorm:"primaryKey;index"` CopyrightID uint `gorm:"primaryKey;index"` CreatedAt time.Time } func (WorkCopyright) TableName() string { return "work_copyrights" } type WorkMonetization struct { WorkID uint `gorm:"primaryKey;index"` MonetizationID uint `gorm:"primaryKey;index"` CreatedAt time.Time } func (WorkMonetization) TableName() string { return "work_monetizations" }