gcx/backend/services/translate-service/internal/application/service/translate_service.go

80 lines
2.7 KiB
Go

package service
import (
"context"
"fmt"
"sync/atomic"
"github.com/genex/translate-service/internal/domain/entity"
"github.com/genex/translate-service/internal/domain/repository"
)
// TranslateService is the application service that orchestrates address mapping
// operations. It depends on the domain repository interface, not a concrete
// implementation — following the Dependency Inversion Principle.
type TranslateService struct {
repo repository.AddressMappingRepository
idCounter atomic.Int64
}
// NewTranslateService creates a new TranslateService with the injected repository.
func NewTranslateService(repo repository.AddressMappingRepository) *TranslateService {
return &TranslateService{
repo: repo,
}
}
// CreateMapping validates inputs via the domain entity factory, persists the
// mapping through the repository, and returns the created entity.
func (s *TranslateService) CreateMapping(ctx context.Context, userID, internalAddr, chainAddr, chainType string) (*entity.AddressMapping, error) {
id := fmt.Sprintf("map-%d", s.idCounter.Add(1))
mapping, err := entity.NewAddressMapping(id, userID, internalAddr, chainAddr, chainType)
if err != nil {
return nil, fmt.Errorf("domain validation failed: %w", err)
}
if err := s.repo.Save(ctx, mapping); err != nil {
return nil, fmt.Errorf("failed to save mapping: %w", err)
}
return mapping, nil
}
// InternalToChain resolves an internal platform address to the corresponding
// on-chain mapping.
func (s *TranslateService) InternalToChain(ctx context.Context, internalAddr string) (*entity.AddressMapping, error) {
mapping, err := s.repo.FindByInternalAddress(ctx, internalAddr)
if err != nil {
return nil, fmt.Errorf("repository lookup failed: %w", err)
}
return mapping, nil
}
// ChainToInternal resolves an on-chain address (with chain type) to the
// corresponding internal platform mapping.
func (s *TranslateService) ChainToInternal(ctx context.Context, chain, chainAddr string) (*entity.AddressMapping, error) {
mapping, err := s.repo.FindByChainAddress(ctx, chain, chainAddr)
if err != nil {
return nil, fmt.Errorf("repository lookup failed: %w", err)
}
return mapping, nil
}
// GetByUserID returns all address mappings belonging to the specified user.
func (s *TranslateService) GetByUserID(ctx context.Context, userID string) ([]*entity.AddressMapping, error) {
mappings, err := s.repo.FindByUserID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("repository lookup failed: %w", err)
}
return mappings, nil
}
// DeleteMapping removes an address mapping by its ID.
func (s *TranslateService) DeleteMapping(ctx context.Context, id string) error {
if err := s.repo.Delete(ctx, id); err != nil {
return fmt.Errorf("failed to delete mapping: %w", err)
}
return nil
}