package domain import ( "backend/pkg/validate/national" "backend/pkg/validate/phone" "context" "errors" "time" "net/mail" "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" ) var ( ErrPhoneInvalid = errors.New("phone number is invalid") ErrUserNotFound = errors.New("user not found") ErrNationalIDInvalid = errors.New("national ID is invalid") ErrWalletInvalid = errors.New("wallet address is invalid") ErrEmailInvalid = errors.New("email is invalid") ) type UserRepo interface { Create(ctx context.Context, user *User) error GetByID(ctx context.Context, id uuid.UUID) (*User, error) GetByPhone(ctx context.Context, phone string) (*User, error) Update(ctx context.Context, user *User) error Delete(ctx context.Context, id uuid.UUID) error } type User struct { ID uuid.UUID PubKey string Name string //TODO: add Kyc Embedded struct //TODO: add NFT Embedded struct LastName string PhoneNumber string Email *string NationalID string BirthDate *time.Time LastLogin *time.Time CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time } // TODO: move to another file? type Challenge struct { Message uuid.UUID TimeStamp time.Time ExpiresAt time.Time } // TODO: check EIP712 in here for challenge validation func (c *Challenge) IsExpired() bool { return time.Now().After(c.ExpiresAt) } func NewUser(pubKey, name, lastName, phoneNumber, email, nationalID string) (*User, error) { _, err := phone.IsValid(phoneNumber) if err != nil { return nil, ErrPhoneInvalid } _, err = national.IsValid(nationalID) if err != nil { return nil, ErrNationalIDInvalid } if !common.IsHexAddress(pubKey) { return nil, ErrWalletInvalid } return &User{ ID: uuid.New(), PubKey: pubKey, Name: name, LastName: lastName, PhoneNumber: phoneNumber, NationalID: nationalID, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), }, nil } func (u *User) UpdateLastLogin() { now := time.Now().UTC() u.LastLogin = &now u.UpdatedAt = now } func (u *User) UpdateInfo(email string) { addr, err := mail.ParseAddress(email) if err == nil { u.Email = &addr.Address } u.UpdatedAt = time.Now().UTC() }