tercul-backend/internal/domain/work/entity.go
google-labs-jules[bot] 06e6e2be85 refactor(domain): Isolate Work aggregate
This commit isolates the `Work` aggregate into its own package at `internal/domain/work`, following the first step of the refactoring plan in `refactor.md`.

- The `Work` struct, related types, and the `WorkRepository` interface have been moved to the new package.
- A circular dependency between `domain` and `work` was resolved by moving the `AnalyticsRepository` to the `app` layer.
- All references to the moved types have been updated across the entire codebase to fix compilation errors.
- Test files, including mocks and integration tests, have been updated to reflect the new structure.
2025-10-03 16:15:09 +00:00

116 lines
3.8 KiB
Go

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" }