package logic import ( "context" "errors" "fmt" "strings" "time" userentity "spark-server/internal/module/user/entity" "spark-server/internal/pkg/errs" ) func (s *Service) ensureBots(ctx context.Context) ([]*userentity.User, error) { out := make([]*userentity.User, 0, userentity.BotCount) for i := 1; i <= userentity.BotCount; i++ { u, err := s.ensureBot(ctx, i) if err != nil { return nil, fmt.Errorf("bot %d: %w", i, err) } out = append(out, u) } return out, nil } func (s *Service) ensureBot(ctx context.Context, index int) (*userentity.User, error) { email := userentity.BotEmail(index) if u, err := s.users.GetByEmail(ctx, email); err == nil { return u, nil } else if !errors.Is(err, errs.ErrNotFound) { return nil, err } id, err := s.ids.NextID() if err != nil { return nil, err } nick := nicknameForBot(index) qr, err := userentity.NewQRCode() if err != nil { return nil, err } now := time.Now() u := &userentity.User{ ID: id, SparkID: userentity.BotSparkID(index), Nickname: nick, Avatar: userentity.LetterAvatarDataURI(nick), Gender: userentity.GenderUnknown, Status: userentity.StatusActive, QRCode: qr, CreatedAt: now, UpdatedAt: now, LastActiveAt: now, } if err := s.users.CreateWithEmail(ctx, u, email); err != nil { if errors.Is(err, errs.ErrDuplicate) { return s.users.GetByEmail(ctx, email) } return nil, err } return u, nil } func (s *Service) ensureTestUsers(ctx context.Context) error { for i := 1; i <= 10; i++ { email := fmt.Sprintf("test%02d@spark.com", i) if _, err := s.users.GetByEmail(ctx, email); err == nil { continue } else if !errors.Is(err, errs.ErrNotFound) { return err } if _, err := s.createPlainUser(ctx, email); err != nil { return err } } return nil } func (s *Service) createPlainUser(ctx context.Context, email string) (*userentity.User, error) { id, err := s.ids.NextID() if err != nil { return nil, err } qr, err := userentity.NewQRCode() if err != nil { return nil, err } local, _, _ := strings.Cut(email, "@") if local == "" { local = "user" } now := time.Now() u := &userentity.User{ ID: id, SparkID: userentity.DefaultSparkID(id), Nickname: local, Avatar: userentity.LetterAvatarDataURI(local), Gender: userentity.GenderUnknown, Status: userentity.StatusActive, QRCode: qr, CreatedAt: now, UpdatedAt: now, LastActiveAt: now, } if err := s.users.CreateWithEmail(ctx, u, email); err != nil { if errors.Is(err, errs.ErrDuplicate) { return s.users.GetByEmail(ctx, email) } return nil, err } return u, nil }