97 lines
2.7 KiB
Go
97 lines
2.7 KiB
Go
package entity
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/genex/translate-service/internal/domain/vo"
|
|
)
|
|
|
|
// AddressMapping is the aggregate root that maps an internal platform address
|
|
// to an on-chain address for a given blockchain network.
|
|
type AddressMapping struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"userId"`
|
|
InternalAddress string `json:"internalAddress"`
|
|
ChainAddress string `json:"chainAddress"`
|
|
ChainType string `json:"chainType"`
|
|
IsActive bool `json:"isActive"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
}
|
|
|
|
// NewAddressMapping is the factory method that creates a fully validated AddressMapping.
|
|
// It enforces all domain invariants at creation time.
|
|
func NewAddressMapping(id, userID, internalAddr, chainAddr, chainType string) (*AddressMapping, error) {
|
|
if id == "" {
|
|
return nil, fmt.Errorf("mapping ID must not be empty")
|
|
}
|
|
if userID == "" {
|
|
return nil, fmt.Errorf("user ID must not be empty")
|
|
}
|
|
|
|
// Validate internal address via value object
|
|
if _, err := vo.NewAddress(internalAddr); err != nil {
|
|
return nil, fmt.Errorf("invalid internal address: %w", err)
|
|
}
|
|
|
|
// Validate chain address via value object
|
|
if _, err := vo.NewAddress(chainAddr); err != nil {
|
|
return nil, fmt.Errorf("invalid chain address: %w", err)
|
|
}
|
|
|
|
// Validate chain type via value object
|
|
if _, err := vo.NewChainType(chainType); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
now := time.Now()
|
|
return &AddressMapping{
|
|
ID: id,
|
|
UserID: userID,
|
|
InternalAddress: internalAddr,
|
|
ChainAddress: chainAddr,
|
|
ChainType: chainType,
|
|
IsActive: true,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}, nil
|
|
}
|
|
|
|
// Validate checks all domain invariants on an existing mapping.
|
|
func (m *AddressMapping) Validate() error {
|
|
if m.ID == "" {
|
|
return fmt.Errorf("mapping ID must not be empty")
|
|
}
|
|
if m.UserID == "" {
|
|
return fmt.Errorf("user ID must not be empty")
|
|
}
|
|
if _, err := vo.NewAddress(m.InternalAddress); err != nil {
|
|
return fmt.Errorf("invalid internal address: %w", err)
|
|
}
|
|
if _, err := vo.NewAddress(m.ChainAddress); err != nil {
|
|
return fmt.Errorf("invalid chain address: %w", err)
|
|
}
|
|
if _, err := vo.NewChainType(m.ChainType); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Deactivate marks the mapping as inactive.
|
|
func (m *AddressMapping) Deactivate() {
|
|
m.IsActive = false
|
|
m.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// Activate marks the mapping as active.
|
|
func (m *AddressMapping) Activate() {
|
|
m.IsActive = true
|
|
m.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// BelongsToUser checks whether this mapping belongs to the specified user.
|
|
func (m *AddressMapping) BelongsToUser(userID string) bool {
|
|
return m.UserID == userID
|
|
}
|