66 lines
2.5 KiB
Go
66 lines
2.5 KiB
Go
// Package logic is the user application use-case layer, split by function (profile, login, email code).
|
|
package logic
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
smsentity "spark-server/internal/module/sms/entity"
|
|
"spark-server/internal/module/user/entity"
|
|
)
|
|
|
|
// Repository is user persistence. Model implements it; do not split this by table.
|
|
type Repository interface {
|
|
GetByID(ctx context.Context, id int64) (*entity.User, error)
|
|
GetByEmail(ctx context.Context, email string) (*entity.User, error)
|
|
GetBySparkID(ctx context.Context, sparkID string) (*entity.User, error)
|
|
GetByQRCode(ctx context.Context, qrcode string) (*entity.User, error)
|
|
CreateWithEmail(ctx context.Context, u *entity.User, email string) error
|
|
UpdateSparkID(ctx context.Context, userID int64, sparkID string) error
|
|
UpdateQRCode(ctx context.Context, userID int64, qrcode string) error
|
|
UpdateProfile(ctx context.Context, u *entity.User) error
|
|
TouchLogin(ctx context.Context, userID int64, at time.Time) error
|
|
UpsertDevice(ctx context.Context, d *entity.UserDeviceLink) error
|
|
GetDevice(ctx context.Context, userID int64, deviceID uint64) (*entity.UserDeviceLink, error)
|
|
TouchDeviceActive(ctx context.Context, userID int64, deviceID uint64, at time.Time) error
|
|
InsertLoginLog(ctx context.Context, log *entity.LoginLog) error
|
|
GetEmail(ctx context.Context, userID int64) (string, error)
|
|
GetDeleted(ctx context.Context, id int64) (*entity.Deleted, error)
|
|
ArchiveAndDelete(ctx context.Context, d *entity.Deleted) error
|
|
}
|
|
|
|
// IDGen issues time-ordered Snowflake IDs (user PK).
|
|
type IDGen interface {
|
|
NextID() (int64, error)
|
|
}
|
|
|
|
// Objects stores the generated default avatar. Nil or Put error keeps an SVG data-URI fallback.
|
|
type Objects interface {
|
|
Put(ctx context.Context, key string, body []byte, contentType string) error
|
|
}
|
|
|
|
// OTP checks and clears verification codes issued by the sms module.
|
|
type OTP interface {
|
|
CheckAndConsume(ctx context.Context, ch smsentity.Channel, purpose smsentity.Purpose, target, code string) error
|
|
ClearTarget(ctx context.Context, ch smsentity.Channel, target string)
|
|
}
|
|
|
|
// Service is the user application use-case (HTTP and TCP share it).
|
|
type Service struct {
|
|
repo Repository
|
|
otp OTP
|
|
ids IDGen
|
|
objects Objects
|
|
tokens TokenRevoker
|
|
sessions SessionDropper
|
|
cleaners []UserDataCleaner
|
|
}
|
|
|
|
func NewService(repo Repository, otp OTP, ids IDGen, objects Objects) *Service {
|
|
return &Service{repo: repo, otp: otp, ids: ids, objects: objects}
|
|
}
|
|
|
|
func (s *Service) ready() bool {
|
|
return s != nil && s.repo != nil && s.ids != nil
|
|
}
|