package domain import ( "context" "time" "gorm.io/gorm" "github.com/google/uuid" ) // 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"` } // MonetizationRepository defines CRUD methods specific to Monetization. type MonetizationRepository interface { BaseRepository[Monetization] AddMonetizationToWork(ctx context.Context, workID uuid.UUID, monetizationID uuid.UUID) error RemoveMonetizationFromWork(ctx context.Context, workID uuid.UUID, monetizationID uuid.UUID) error AddMonetizationToAuthor(ctx context.Context, authorID uuid.UUID, monetizationID uuid.UUID) error RemoveMonetizationFromAuthor(ctx context.Context, authorID uuid.UUID, monetizationID uuid.UUID) error AddMonetizationToBook(ctx context.Context, bookID uuid.UUID, monetizationID uuid.UUID) error RemoveMonetizationFromBook(ctx context.Context, bookID uuid.UUID, monetizationID uuid.UUID) error AddMonetizationToPublisher(ctx context.Context, publisherID uuid.UUID, monetizationID uuid.UUID) error RemoveMonetizationFromPublisher(ctx context.Context, publisherID uuid.UUID, monetizationID uuid.UUID) error AddMonetizationToSource(ctx context.Context, sourceID uuid.UUID, monetizationID uuid.UUID) error RemoveMonetizationFromSource(ctx context.Context, sourceID uuid.UUID, monetizationID uuid.UUID) error } // PublisherRepository defines CRUD methods specific to Publisher. type PublisherRepository interface { BaseRepository[Publisher] ListByCountryID(ctx context.Context, countryID uuid.UUID) ([]Publisher, error) } // SourceRepository defines CRUD methods specific to Source. type SourceRepository interface { BaseRepository[Source] ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Source, error) FindByURL(ctx context.Context, url string) (*Source, error) } // BookRepository defines CRUD methods specific to Book. type BookRepository interface { BaseRepository[Book] ListByAuthorID(ctx context.Context, authorID uuid.UUID) ([]Book, error) ListByPublisherID(ctx context.Context, publisherID uuid.UUID) ([]Book, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Book, error) FindByISBN(ctx context.Context, isbn string) (*Book, error) } // BookmarkRepository defines CRUD methods specific to Bookmark. type BookmarkRepository interface { BaseRepository[Bookmark] ListByUserID(ctx context.Context, userID uuid.UUID) ([]Bookmark, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Bookmark, 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 uuid.UUID) ([]Category, error) ListByParentID(ctx context.Context, parentID *uuid.UUID) ([]Category, error) } // CityRepository defines CRUD methods specific to City. type CityRepository interface { BaseRepository[City] ListByCountryID(ctx context.Context, countryID uuid.UUID) ([]City, error) } // CollectionRepository defines CRUD methods specific to Collection. type CollectionRepository interface { BaseRepository[Collection] ListByUserID(ctx context.Context, userID uuid.UUID) ([]Collection, error) ListPublic(ctx context.Context) ([]Collection, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Collection, error) AddWorkToCollection(ctx context.Context, collectionID uuid.UUID, workID uuid.UUID) error RemoveWorkFromCollection(ctx context.Context, collectionID uuid.UUID, workID uuid.UUID) error } // CommentRepository defines CRUD methods specific to Comment. type CommentRepository interface { BaseRepository[Comment] ListByUserID(ctx context.Context, userID uuid.UUID) ([]Comment, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Comment, error) ListByTranslationID(ctx context.Context, translationID uuid.UUID) ([]Comment, error) ListByParentID(ctx context.Context, parentID uuid.UUID) ([]Comment, error) } // ContributionRepository defines CRUD methods specific to Contribution. type ContributionRepository interface { BaseRepository[Contribution] ListByUserID(ctx context.Context, userID uuid.UUID) ([]Contribution, error) ListByReviewerID(ctx context.Context, reviewerID uuid.UUID) ([]Contribution, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Contribution, error) ListByTranslationID(ctx context.Context, translationID uuid.UUID) ([]Contribution, error) ListByStatus(ctx context.Context, status string) ([]Contribution, error) } // CopyrightClaimRepository defines CRUD methods specific to CopyrightClaim. type CopyrightClaimRepository interface { BaseRepository[CopyrightClaim] ListByWorkID(ctx context.Context, workID uuid.UUID) ([]CopyrightClaim, error) ListByUserID(ctx context.Context, userID uuid.UUID) ([]CopyrightClaim, error) } // CountryRepository defines CRUD methods specific to Country. type CountryRepository interface { BaseRepository[Country] GetByCode(ctx context.Context, code string) (*Country, error) ListByContinent(ctx context.Context, continent string) ([]Country, error) } // EdgeRepository defines CRUD methods specific to Edge. type EdgeRepository interface { BaseRepository[Edge] ListBySource(ctx context.Context, sourceTable string, sourceID uuid.UUID) ([]Edge, error) } // EditionRepository defines CRUD methods specific to Edition. type EditionRepository interface { BaseRepository[Edition] ListByBookID(ctx context.Context, bookID uuid.UUID) ([]Edition, error) FindByISBN(ctx context.Context, isbn string) (*Edition, error) } // EmailVerificationRepository defines CRUD methods specific to EmailVerification. type EmailVerificationRepository interface { BaseRepository[EmailVerification] GetByToken(ctx context.Context, token string) (*EmailVerification, error) GetByUserID(ctx context.Context, userID uuid.UUID) ([]EmailVerification, error) DeleteExpired(ctx context.Context) error MarkAsUsed(ctx context.Context, id uuid.UUID) error } // LikeRepository defines CRUD methods specific to Like. type LikeRepository interface { BaseRepository[Like] ListByUserID(ctx context.Context, userID uuid.UUID) ([]Like, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Like, error) ListByTranslationID(ctx context.Context, translationID uuid.UUID) ([]Like, error) ListByCommentID(ctx context.Context, commentID uuid.UUID) ([]Like, error) } // PasswordResetRepository defines CRUD methods specific to PasswordReset. type PasswordResetRepository interface { BaseRepository[PasswordReset] GetByToken(ctx context.Context, token string) (*PasswordReset, error) GetByUserID(ctx context.Context, userID uuid.UUID) ([]PasswordReset, error) DeleteExpired(ctx context.Context) error MarkAsUsed(ctx context.Context, id uuid.UUID) error } // PlaceRepository defines CRUD methods specific to Place. type PlaceRepository interface { BaseRepository[Place] ListByCountryID(ctx context.Context, countryID uuid.UUID) ([]Place, error) ListByCityID(ctx context.Context, cityID uuid.UUID) ([]Place, error) FindNearby(ctx context.Context, latitude, longitude float64, radiusKm float64) ([]Place, 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 uuid.UUID) ([]Tag, error) } // TranslationRepository defines CRUD methods specific to Translation. type TranslationRepository interface { BaseRepository[Translation] ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Translation, error) ListByWorkIDPaginated(ctx context.Context, workID uuid.UUID, language *string, page, pageSize int) (*PaginatedResult[Translation], error) ListByEntity(ctx context.Context, entityType string, entityID uuid.UUID) ([]Translation, error) ListByTranslatorID(ctx context.Context, translatorID uuid.UUID) ([]Translation, error) ListByStatus(ctx context.Context, status TranslationStatus) ([]Translation, error) Upsert(ctx context.Context, translation *Translation) 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) } // UserProfileRepository defines CRUD methods specific to UserProfile. type UserProfileRepository interface { BaseRepository[UserProfile] GetByUserID(ctx context.Context, userID uuid.UUID) (*UserProfile, error) } // UserSessionRepository defines CRUD methods specific to UserSession. type UserSessionRepository interface { BaseRepository[UserSession] GetByToken(ctx context.Context, token string) (*UserSession, error) GetByUserID(ctx context.Context, userID uuid.UUID) ([]UserSession, error) DeleteExpired(ctx context.Context) error } // 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 uuid.UUID) (*T, error) GetByIDWithOptions(ctx context.Context, id uuid.UUID, 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 uuid.UUID) error DeleteInTx(ctx context.Context, tx *gorm.DB, id uuid.UUID) 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 uuid.UUID) (*T, error) GetAllForSync(ctx context.Context, batchSize, offset int) ([]T, error) Exists(ctx context.Context, id uuid.UUID) (bool, error) BeginTx(ctx context.Context) (*gorm.DB, error) WithTx(ctx context.Context, fn func(tx *gorm.DB) error) error } // AuthorRepository defines CRUD methods specific to Author. type AuthorRepository interface { BaseRepository[Author] FindByName(ctx context.Context, name string) (*Author, error) ListByWorkID(ctx context.Context, workID uuid.UUID) ([]Author, error) ListByBookID(ctx context.Context, bookID uuid.UUID) ([]Author, error) ListByCountryID(ctx context.Context, countryID uuid.UUID) ([]Author, error) GetWithTranslations(ctx context.Context, id uuid.UUID) (*Author, error) } // CopyrightRepository defines CRUD methods specific to Copyright. type CopyrightRepository interface { BaseRepository[Copyright] AddCopyrightToWork(ctx context.Context, workID uuid.UUID, copyrightID uuid.UUID) error RemoveCopyrightFromWork(ctx context.Context, workID uuid.UUID, copyrightID uuid.UUID) error AddCopyrightToAuthor(ctx context.Context, authorID uuid.UUID, copyrightID uuid.UUID) error RemoveCopyrightFromAuthor(ctx context.Context, authorID uuid.UUID, copyrightID uuid.UUID) error AddCopyrightToBook(ctx context.Context, bookID uuid.UUID, copyrightID uuid.UUID) error RemoveCopyrightFromBook(ctx context.Context, bookID uuid.UUID, copyrightID uuid.UUID) error AddCopyrightToPublisher(ctx context.Context, publisherID uuid.UUID, copyrightID uuid.UUID) error RemoveCopyrightFromPublisher(ctx context.Context, publisherID uuid.UUID, copyrightID uuid.UUID) error AddCopyrightToSource(ctx context.Context, sourceID uuid.UUID, copyrightID uuid.UUID) error RemoveCopyrightFromSource(ctx context.Context, sourceID uuid.UUID, copyrightID uuid.UUID) error AddTranslation(ctx context.Context, translation *CopyrightTranslation) error GetTranslations(ctx context.Context, copyrightID uuid.UUID) ([]CopyrightTranslation, error) GetTranslationByLanguage(ctx context.Context, copyrightID uuid.UUID, languageCode string) (*CopyrightTranslation, 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 uuid.UUID) ([]Work, error) FindByCategory(ctx context.Context, categoryID uuid.UUID) ([]Work, error) FindByLanguage(ctx context.Context, language string, page, pageSize int) (*PaginatedResult[Work], error) GetWithTranslations(ctx context.Context, id uuid.UUID) (*Work, error) GetWithAssociations(ctx context.Context, id uuid.UUID) (*Work, error) GetWithAssociationsInTx(ctx context.Context, tx *gorm.DB, id uuid.UUID) (*Work, error) ListWithTranslations(ctx context.Context, page, pageSize int) (*PaginatedResult[Work], error) IsAuthor(ctx context.Context, workID uuid.UUID, authorID uuid.UUID) (bool, error) ListByCollectionID(ctx context.Context, collectionID uuid.UUID) ([]Work, error) } // AuthRepository defines the interface for authentication data access. type AuthRepository interface { StoreToken(ctx context.Context, userID uuid.UUID, token string, expiresAt time.Time) error DeleteToken(ctx context.Context, token string) error } // LocalizationRepository defines the interface for localization data access. type LocalizationRepository interface { GetTranslation(ctx context.Context, key string, language string) (string, error) GetTranslations(ctx context.Context, keys []string, language string) (map[string]string, error) GetAuthorBiography(ctx context.Context, authorID uuid.UUID, language string) (string, error) GetWorkContent(ctx context.Context, workID uuid.UUID, language string) (string, error) }