feat(ECR-013B): AccountLifecycle Closed;启用 Loop 连续执行

UserStatus 迁移、DeviceAuth 拒绝非 active、admin-h5 CTA;
Reviewer Closed。Human 授权 LOOP_AUTHORIZATION(免逐闸确认)。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-07 17:47:18 +08:00
co-authored by Cursor
parent f75b42397f
commit e25cd94b0c
33 changed files with 799 additions and 56 deletions
@@ -35,6 +35,9 @@ type SessionResult struct {
User Me `json:"user"`
}
// ErrAccountRestricted is returned when UserStatus is not active.
var ErrAccountRestricted = errors.New("账户已受限")
// Register upgrades or opens an account (same open rules as Login).
func (s *Service) Register(ctx context.Context, userID uuid.UUID, deviceKey, phone, password, nickname string) (*SessionResult, error) {
return s.OpenLogin(ctx, userID, deviceKey, phone, password, nickname)
@@ -60,6 +63,9 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK
acc, err := s.Repo.GetByPhone(ctx, phone)
if err == nil {
if acc.Status != "active" {
return nil, ErrAccountRestricted
}
_ = s.Repo.TouchPassword(ctx, acc.ID, hashStr)
if deviceKey != "" {
_ = s.Repo.BindDevice(ctx, deviceKey, acc.ID)
@@ -78,6 +84,9 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK
cur, curErr := s.Repo.GetAccount(ctx, deviceUserID)
uid := deviceUserID
if curErr == nil && cur.Phone == "" {
if cur.Status != "active" {
return nil, ErrAccountRestricted
}
if err := s.Repo.RegisterOnUser(ctx, deviceUserID, phone, hashStr, nickname); err != nil {
return nil, errors.New("登录失败,请重试")
}