package domain import ( "context" "gorm.io/gorm" ) // PaginatedResult represents a paginated result set type PaginatedResult[T any] struct { Items []T `json:"items"` TotalCount int64 `json:"totalCount"` Page int `json:"page"` PageSize int `json:"pageSize"` TotalPages int `json:"totalPages"` HasNext bool `json:"hasNext"` HasPrev bool `json:"hasPrev"` } // QueryOptions provides options for repository queries type QueryOptions struct { Preloads []string OrderBy string Where map[string]interface{} Limit int Offset int } // BaseRepository defines common CRUD operations that all repositories should implement type BaseRepository[T any] interface { Create(ctx context.Context, entity *T) error CreateInTx(ctx context.Context, tx *gorm.DB, entity *T) error GetByID(ctx context.Context, id uint) (*T, error) GetByIDWithOptions(ctx context.Context, id uint, options *QueryOptions) (*T, error) Update(ctx context.Context, entity *T) error UpdateInTx(ctx context.Context, tx *gorm.DB, entity *T) error Delete(ctx context.Context, id uint) error DeleteInTx(ctx context.Context, tx *gorm.DB, id uint) error List(ctx context.Context, page, pageSize int) (*PaginatedResult[T], error) ListWithOptions(ctx context.Context, options *QueryOptions) ([]T, error) ListAll(ctx context.Context) ([]T, error) Count(ctx context.Context) (int64, error) CountWithOptions(ctx context.Context, options *QueryOptions) (int64, error) FindWithPreload(ctx context.Context, preloads []string, id uint) (*T, error) GetAllForSync(ctx context.Context, batchSize, offset int) ([]T, error) Exists(ctx context.Context, id uint) (bool, error) BeginTx(ctx context.Context) (*gorm.DB, error) WithTx(ctx context.Context, fn func(tx *gorm.DB) error) error } // WorkRepository defines methods specific to Work. type WorkRepository interface { BaseRepository[Work] FindByTitle(ctx context.Context, title string) ([]Work, error) FindByAuthor(ctx context.Context, authorID uint) ([]Work, error) FindByCategory(ctx context.Context, categoryID uint) ([]Work, error) FindByLanguage(ctx context.Context, language string, page, pageSize int) (*PaginatedResult[Work], error) GetWithTranslations(ctx context.Context, id uint) (*Work, error) ListWithTranslations(ctx context.Context, page, pageSize int) (*PaginatedResult[Work], error) } // AuthorRepository defines CRUD methods specific to Author. type AuthorRepository interface { BaseRepository[Author] ListByWorkID(ctx context.Context, workID uint) ([]Author, error) ListByBookID(ctx context.Context, bookID uint) ([]Author, error) ListByCountryID(ctx context.Context, countryID uint) ([]Author, error) } // BookRepository defines CRUD methods specific to Book. type BookRepository interface { BaseRepository[Book] ListByAuthorID(ctx context.Context, authorID uint) ([]Book, error) ListByPublisherID(ctx context.Context, publisherID uint) ([]Book, error) ListByWorkID(ctx context.Context, workID uint) ([]Book, error) FindByISBN(ctx context.Context, isbn string) (*Book, error) } // UserRepository defines CRUD methods specific to User. type UserRepository interface { BaseRepository[User] FindByUsername(ctx context.Context, username string) (*User, error) FindByEmail(ctx context.Context, email string) (*User, error) ListByRole(ctx context.Context, role UserRole) ([]User, error) } // TranslationRepository defines CRUD methods specific to Translation. type TranslationRepository interface { BaseRepository[Translation] ListByWorkID(ctx context.Context, workID uint) ([]Translation, error) ListByEntity(ctx context.Context, entityType string, entityID uint) ([]Translation, error) ListByTranslatorID(ctx context.Context, translatorID uint) ([]Translation, error) ListByStatus(ctx context.Context, status TranslationStatus) ([]Translation, error) } // CommentRepository defines CRUD methods specific to Comment. type CommentRepository interface { BaseRepository[Comment] ListByUserID(ctx context.Context, userID uint) ([]Comment, error) ListByWorkID(ctx context.Context, workID uint) ([]Comment, error) ListByTranslationID(ctx context.Context, translationID uint) ([]Comment, error) ListByParentID(ctx context.Context, parentID uint) ([]Comment, error) } // LikeRepository defines CRUD methods specific to Like. type LikeRepository interface { BaseRepository[Like] ListByUserID(ctx context.Context, userID uint) ([]Like, error) ListByWorkID(ctx context.Context, workID uint) ([]Like, error) ListByTranslationID(ctx context.Context, translationID uint) ([]Like, error) ListByCommentID(ctx context.Context, commentID uint) ([]Like, error) } // BookmarkRepository defines CRUD methods specific to Bookmark. type BookmarkRepository interface { BaseRepository[Bookmark] ListByUserID(ctx context.Context, userID uint) ([]Bookmark, error) ListByWorkID(ctx context.Context, workID uint) ([]Bookmark, error) } // CollectionRepository defines CRUD methods specific to Collection. type CollectionRepository interface { BaseRepository[Collection] ListByUserID(ctx context.Context, userID uint) ([]Collection, error) ListPublic(ctx context.Context) ([]Collection, error) ListByWorkID(ctx context.Context, workID uint) ([]Collection, error) } // TagRepository defines CRUD methods specific to Tag. type TagRepository interface { BaseRepository[Tag] FindByName(ctx context.Context, name string) (*Tag, error) ListByWorkID(ctx context.Context, workID uint) ([]Tag, error) } // CategoryRepository defines CRUD methods specific to Category. type CategoryRepository interface { BaseRepository[Category] FindByName(ctx context.Context, name string) (*Category, error) ListByWorkID(ctx context.Context, workID uint) ([]Category, error) ListByParentID(ctx context.Context, parentID *uint) ([]Category, error) } // CopyrightRepository defines CRUD methods specific to Copyright. type CopyrightRepository interface { BaseRepository[Copyright] AttachToEntity(ctx context.Context, copyrightID uint, entityID uint, entityType string) error DetachFromEntity(ctx context.Context, copyrightID uint, entityID uint, entityType string) error GetByEntity(ctx context.Context, entityID uint, entityType string) ([]Copyright, error) GetEntitiesByCopyright(ctx context.Context, copyrightID uint) ([]Copyrightable, error) AddTranslation(ctx context.Context, translation *CopyrightTranslation) error GetTranslations(ctx context.Context, copyrightID uint) ([]CopyrightTranslation, error) GetTranslationByLanguage(ctx context.Context, copyrightID uint, languageCode string) (*CopyrightTranslation, error) }