tercul-backend/internal/app/contribution/commands.go
Damir Mukimov d50722dad5
Some checks failed
Test / Integration Tests (push) Successful in 4s
Build / Build Binary (push) Failing after 2m9s
Docker Build / Build Docker Image (push) Failing after 2m32s
Test / Unit Tests (push) Failing after 3m12s
Lint / Go Lint (push) Failing after 1m0s
Refactor ID handling to use UUIDs across the application
- Updated database models and repositories to replace uint IDs with UUIDs.
- Modified test fixtures to generate and use UUIDs for authors, translations, users, and works.
- Adjusted mock implementations to align with the new UUID structure.
- Ensured all relevant functions and methods are updated to handle UUIDs correctly.
- Added necessary imports for UUID handling in various files.
2025-12-27 00:33:34 +01:00

141 lines
3.8 KiB
Go

package contribution
import (
"context"
"tercul/internal/app/authz"
"tercul/internal/domain"
platform_auth "tercul/internal/platform/auth"
"github.com/google/uuid"
)
// Commands contains the command handlers for the contribution aggregate.
type Commands struct {
repo domain.ContributionRepository
authzSvc *authz.Service
}
// NewCommands creates a new Commands handler.
func NewCommands(repo domain.ContributionRepository, authzSvc *authz.Service) *Commands {
return &Commands{
repo: repo,
authzSvc: authzSvc,
}
}
// CreateContributionInput represents the input for creating a new contribution.
type CreateContributionInput struct {
Name string
Status string
WorkID *uuid.UUID
TranslationID *uuid.UUID
}
// CreateContribution creates a new contribution.
func (c *Commands) CreateContribution(ctx context.Context, input CreateContributionInput) (*domain.Contribution, error) {
actorID, ok := platform_auth.GetUserIDFromContext(ctx)
if !ok {
return nil, domain.ErrUnauthorized
}
// TODO: Add authorization check using authzSvc if necessary
contribution := &domain.Contribution{
Name: input.Name,
Status: input.Status,
UserID: actorID,
WorkID: input.WorkID,
TranslationID: input.TranslationID,
}
err := c.repo.Create(ctx, contribution)
if err != nil {
return nil, err
}
return contribution, nil
}
// UpdateContributionInput represents the input for updating a contribution.
type UpdateContributionInput struct {
ID uuid.UUID
UserID uuid.UUID
Name *string
Status *string
}
// UpdateContribution updates an existing contribution.
func (c *Commands) UpdateContribution(ctx context.Context, input UpdateContributionInput) (*domain.Contribution, error) {
contribution, err := c.repo.GetByID(ctx, input.ID)
if err != nil {
return nil, err
}
// Authorization check: only the user who created the contribution can update it.
if contribution.UserID != input.UserID {
return nil, domain.ErrForbidden
}
if input.Name != nil {
contribution.Name = *input.Name
}
if input.Status != nil {
contribution.Status = *input.Status
}
if err := c.repo.Update(ctx, contribution); err != nil {
return nil, err
}
return contribution, nil
}
// DeleteContribution deletes a contribution.
func (c *Commands) DeleteContribution(ctx context.Context, contributionID uuid.UUID, userID uuid.UUID) error {
contribution, err := c.repo.GetByID(ctx, contributionID)
if err != nil {
return err
}
// Authorization check: only the user who created the contribution can delete it.
if contribution.UserID != userID {
return domain.ErrForbidden
}
return c.repo.Delete(ctx, contributionID)
}
// ReviewContributionInput represents the input for reviewing a contribution.
type ReviewContributionInput struct {
ID uuid.UUID
Status string
Feedback *string
}
// ReviewContribution reviews a contribution, updating its status and adding feedback.
func (c *Commands) ReviewContribution(ctx context.Context, input ReviewContributionInput) (*domain.Contribution, error) {
// Authorization check: for now, let's assume only admins/editors/reviewers can review.
claims, ok := platform_auth.GetClaimsFromContext(ctx)
if !ok {
return nil, domain.ErrUnauthorized
}
if claims.Role != string(domain.UserRoleAdmin) && claims.Role != string(domain.UserRoleEditor) && claims.Role != string(domain.UserRoleReviewer) {
return nil, domain.ErrForbidden
}
contribution, err := c.repo.GetByID(ctx, input.ID)
if err != nil {
return nil, err
}
contribution.Status = input.Status
// Note: The feedback handling is not fully implemented.
// In a real application, this might create a new comment associated with the contribution.
if err := c.repo.Update(ctx, contribution); err != nil {
return nil, err
}
return contribution, nil
}