mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 05:11:34 +00:00
- Core Go application with GraphQL API using gqlgen - Comprehensive data models for literary works, authors, translations - Repository pattern with caching layer - Authentication and authorization system - Linguistics analysis capabilities with multiple adapters - Vector search integration with Weaviate - Docker containerization support - Python data migration and analysis scripts - Clean architecture with proper separation of concerns - Production-ready configuration and middleware - Proper .gitignore excluding vendor/, database files, and build artifacts
214 lines
6.6 KiB
Go
214 lines
6.6 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"tercul/models"
|
|
"tercul/repositories"
|
|
)
|
|
|
|
// CopyrightService defines business logic for copyright operations
|
|
type CopyrightService interface {
|
|
CreateCopyright(ctx context.Context, copyright *models.Copyright) error
|
|
GetCopyrightByID(ctx context.Context, id uint) (*models.Copyright, error)
|
|
UpdateCopyright(ctx context.Context, copyright *models.Copyright) error
|
|
DeleteCopyright(ctx context.Context, id uint) error
|
|
ListCopyrights(ctx context.Context) ([]models.Copyright, error)
|
|
AttachCopyrightToEntity(ctx context.Context, copyrightID uint, entityID uint, entityType string) error
|
|
DetachCopyrightFromEntity(ctx context.Context, copyrightID uint, entityID uint, entityType string) error
|
|
GetCopyrightsForEntity(ctx context.Context, entityID uint, entityType string) ([]models.Copyright, error)
|
|
GetEntitiesByCopyright(ctx context.Context, copyrightID uint) ([]models.Copyrightable, error)
|
|
AddTranslation(ctx context.Context, translation *models.CopyrightTranslation) error
|
|
GetTranslations(ctx context.Context, copyrightID uint) ([]models.CopyrightTranslation, error)
|
|
GetTranslationByLanguage(ctx context.Context, copyrightID uint, languageCode string) (*models.CopyrightTranslation, error)
|
|
}
|
|
|
|
type copyrightService struct {
|
|
copyrightRepo repositories.CopyrightRepository
|
|
}
|
|
|
|
// NewCopyrightService creates a new CopyrightService
|
|
func NewCopyrightService(copyrightRepo repositories.CopyrightRepository) CopyrightService {
|
|
return ©rightService{
|
|
copyrightRepo: copyrightRepo,
|
|
}
|
|
}
|
|
|
|
// ValidateCopyright validates copyright data
|
|
func (s *copyrightService) ValidateCopyright(copyright *models.Copyright) error {
|
|
if copyright == nil {
|
|
return errors.New("copyright cannot be nil")
|
|
}
|
|
|
|
if copyright.Name == "" {
|
|
return errors.New("copyright name cannot be empty")
|
|
}
|
|
|
|
if copyright.Identificator == "" {
|
|
return errors.New("copyright identificator cannot be empty")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CreateCopyright creates a new copyright
|
|
func (s *copyrightService) CreateCopyright(ctx context.Context, copyright *models.Copyright) error {
|
|
if copyright == nil {
|
|
return errors.New("copyright cannot be nil")
|
|
}
|
|
|
|
if err := s.ValidateCopyright(copyright); err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.copyrightRepo.Create(ctx, copyright)
|
|
}
|
|
|
|
// GetCopyrightByID retrieves a copyright by ID
|
|
func (s *copyrightService) GetCopyrightByID(ctx context.Context, id uint) (*models.Copyright, error) {
|
|
if id == 0 {
|
|
return nil, errors.New("invalid copyright ID")
|
|
}
|
|
|
|
return s.copyrightRepo.GetByID(ctx, id)
|
|
}
|
|
|
|
// UpdateCopyright updates an existing copyright
|
|
func (s *copyrightService) UpdateCopyright(ctx context.Context, copyright *models.Copyright) error {
|
|
if copyright == nil {
|
|
return errors.New("copyright cannot be nil")
|
|
}
|
|
|
|
if copyright.ID == 0 {
|
|
return errors.New("copyright ID cannot be zero")
|
|
}
|
|
|
|
if err := s.ValidateCopyright(copyright); err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.copyrightRepo.Update(ctx, copyright)
|
|
}
|
|
|
|
// DeleteCopyright deletes a copyright
|
|
func (s *copyrightService) DeleteCopyright(ctx context.Context, id uint) error {
|
|
if id == 0 {
|
|
return errors.New("invalid copyright ID")
|
|
}
|
|
|
|
return s.copyrightRepo.Delete(ctx, id)
|
|
}
|
|
|
|
// ListCopyrights retrieves all copyrights
|
|
func (s *copyrightService) ListCopyrights(ctx context.Context) ([]models.Copyright, error) {
|
|
result, err := s.copyrightRepo.List(ctx, 1, 1000)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return result.Items, nil
|
|
}
|
|
|
|
// AttachCopyrightToEntity attaches a copyright to any entity type
|
|
func (s *copyrightService) AttachCopyrightToEntity(ctx context.Context, copyrightID uint, entityID uint, entityType string) error {
|
|
if copyrightID == 0 || entityID == 0 {
|
|
return errors.New("invalid copyright ID or entity ID")
|
|
}
|
|
|
|
if entityType == "" {
|
|
return errors.New("entity type cannot be empty")
|
|
}
|
|
|
|
// Validate entity type
|
|
validTypes := []string{"Work", "Translation", "Book", "Author", "Collection"}
|
|
isValid := false
|
|
for _, t := range validTypes {
|
|
if t == entityType {
|
|
isValid = true
|
|
break
|
|
}
|
|
}
|
|
if !isValid {
|
|
return errors.New("invalid entity type")
|
|
}
|
|
|
|
return s.copyrightRepo.AttachToEntity(ctx, copyrightID, entityID, entityType)
|
|
}
|
|
|
|
// DetachCopyrightFromEntity removes a copyright from an entity
|
|
func (s *copyrightService) DetachCopyrightFromEntity(ctx context.Context, copyrightID uint, entityID uint, entityType string) error {
|
|
if copyrightID == 0 || entityID == 0 {
|
|
return errors.New("invalid copyright ID or entity ID")
|
|
}
|
|
|
|
if entityType == "" {
|
|
return errors.New("entity type cannot be empty")
|
|
}
|
|
|
|
return s.copyrightRepo.DetachFromEntity(ctx, copyrightID, entityID, entityType)
|
|
}
|
|
|
|
// GetCopyrightsForEntity gets all copyrights for a specific entity
|
|
func (s *copyrightService) GetCopyrightsForEntity(ctx context.Context, entityID uint, entityType string) ([]models.Copyright, error) {
|
|
if entityID == 0 {
|
|
return nil, errors.New("invalid entity ID")
|
|
}
|
|
|
|
if entityType == "" {
|
|
return nil, errors.New("entity type cannot be empty")
|
|
}
|
|
|
|
return s.copyrightRepo.GetByEntity(ctx, entityID, entityType)
|
|
}
|
|
|
|
// GetEntitiesByCopyright gets all entities that have a specific copyright
|
|
func (s *copyrightService) GetEntitiesByCopyright(ctx context.Context, copyrightID uint) ([]models.Copyrightable, error) {
|
|
if copyrightID == 0 {
|
|
return nil, errors.New("invalid copyright ID")
|
|
}
|
|
|
|
return s.copyrightRepo.GetEntitiesByCopyright(ctx, copyrightID)
|
|
}
|
|
|
|
// AddTranslation adds a translation to a copyright
|
|
func (s *copyrightService) AddTranslation(ctx context.Context, translation *models.CopyrightTranslation) error {
|
|
if translation == nil {
|
|
return errors.New("translation cannot be nil")
|
|
}
|
|
|
|
if translation.CopyrightID == 0 {
|
|
return errors.New("copyright ID cannot be zero")
|
|
}
|
|
|
|
if translation.LanguageCode == "" {
|
|
return errors.New("language code cannot be empty")
|
|
}
|
|
|
|
if translation.Message == "" {
|
|
return errors.New("translation message cannot be empty")
|
|
}
|
|
|
|
return s.copyrightRepo.AddTranslation(ctx, translation)
|
|
}
|
|
|
|
// GetTranslations gets all translations for a copyright
|
|
func (s *copyrightService) GetTranslations(ctx context.Context, copyrightID uint) ([]models.CopyrightTranslation, error) {
|
|
if copyrightID == 0 {
|
|
return nil, errors.New("invalid copyright ID")
|
|
}
|
|
|
|
return s.copyrightRepo.GetTranslations(ctx, copyrightID)
|
|
}
|
|
|
|
// GetTranslationByLanguage gets a specific translation by language code
|
|
func (s *copyrightService) GetTranslationByLanguage(ctx context.Context, copyrightID uint, languageCode string) (*models.CopyrightTranslation, error) {
|
|
if copyrightID == 0 {
|
|
return nil, errors.New("invalid copyright ID")
|
|
}
|
|
|
|
if languageCode == "" {
|
|
return nil, errors.New("language code cannot be empty")
|
|
}
|
|
|
|
return s.copyrightRepo.GetTranslationByLanguage(ctx, copyrightID, languageCode)
|
|
}
|