2025-09-06 17:25:10 +03:30

102 lines
2.2 KiB
Go

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()
}