package translation import ( "context" "tercul/internal/domain" "github.com/google/uuid" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" ) // TranslationQueries contains the query handlers for the translation aggregate. type TranslationQueries struct { repo domain.TranslationRepository tracer trace.Tracer } // NewTranslationQueries creates a new TranslationQueries handler. func NewTranslationQueries(repo domain.TranslationRepository) *TranslationQueries { return &TranslationQueries{ repo: repo, tracer: otel.Tracer("translation.queries"), } } // Translation returns a translation by ID. func (q *TranslationQueries) Translation(ctx context.Context, id uuid.UUID) (*TranslationDTO, error) { ctx, span := q.tracer.Start(ctx, "Translation") defer span.End() translation, err := q.repo.GetByID(ctx, id) if err != nil { return nil, err } if translation == nil { return nil, nil } return &TranslationDTO{ ID: translation.ID, Title: translation.Title, Language: translation.Language, Content: translation.Content, TranslatableID: translation.TranslatableID, }, nil } // TranslationsByWorkID returns all translations for a work. func (q *TranslationQueries) TranslationsByWorkID(ctx context.Context, workID uuid.UUID) ([]domain.Translation, error) { ctx, span := q.tracer.Start(ctx, "TranslationsByWorkID") defer span.End() return q.repo.ListByWorkID(ctx, workID) } // TranslationsByEntity returns all translations for an entity. func (q *TranslationQueries) TranslationsByEntity(ctx context.Context, entityType string, entityID uuid.UUID) ([]domain.Translation, error) { ctx, span := q.tracer.Start(ctx, "TranslationsByEntity") defer span.End() return q.repo.ListByEntity(ctx, entityType, entityID) } // TranslationsByTranslatorID returns all translations for a translator. func (q *TranslationQueries) TranslationsByTranslatorID(ctx context.Context, translatorID uuid.UUID) ([]domain.Translation, error) { ctx, span := q.tracer.Start(ctx, "TranslationsByTranslatorID") defer span.End() return q.repo.ListByTranslatorID(ctx, translatorID) } // TranslationsByStatus returns all translations for a status. func (q *TranslationQueries) TranslationsByStatus(ctx context.Context, status domain.TranslationStatus) ([]domain.Translation, error) { ctx, span := q.tracer.Start(ctx, "TranslationsByStatus") defer span.End() return q.repo.ListByStatus(ctx, status) } // Translations returns all translations. func (q *TranslationQueries) Translations(ctx context.Context) ([]domain.Translation, error) { ctx, span := q.tracer.Start(ctx, "Translations") defer span.End() return q.repo.ListAll(ctx) } // ListTranslations returns a paginated list of translations for a work, with optional language filtering. func (q *TranslationQueries) ListTranslations(ctx context.Context, workID uuid.UUID, language *string, page, pageSize int) (*domain.PaginatedResult[TranslationDTO], error) { ctx, span := q.tracer.Start(ctx, "ListTranslations") defer span.End() paginatedTranslations, err := q.repo.ListByWorkIDPaginated(ctx, workID, language, page, pageSize) if err != nil { return nil, err } translationDTOs := make([]TranslationDTO, len(paginatedTranslations.Items)) for i, t := range paginatedTranslations.Items { translationDTOs[i] = TranslationDTO{ ID: t.ID, Title: t.Title, Language: t.Language, Content: t.Content, TranslatableID: t.TranslatableID, } } return &domain.PaginatedResult[TranslationDTO]{ Items: translationDTOs, TotalCount: paginatedTranslations.TotalCount, Page: paginatedTranslations.Page, PageSize: paginatedTranslations.PageSize, TotalPages: paginatedTranslations.TotalPages, }, nil }