fix: 사원 등록 시 이메일 중복 체크 및 user_id 충돌 방지
- 이메일 중복 체크 추가 (삭제된 사용자 포함) - generateUniqueUserId() 메서드 추가 (중복 시 최대 10회 재시도) - email_already_exists 에러 메시지 추가 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -98,14 +98,23 @@ public function store(array $data): TenantUserProfile
|
||||
$tenantId = $this->tenantId();
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
return DB::transaction(function () use ($data, $tenantId, $userId) {
|
||||
// 1. 비밀번호 결정: password가 있으면 시스템 계정 생성
|
||||
// 1. 이메일 중복 체크 (전역 유니크)
|
||||
$existingUser = User::withTrashed()->where('email', $data['email'])->first();
|
||||
if ($existingUser) {
|
||||
throw new \InvalidArgumentException(__('error.email_already_exists'));
|
||||
}
|
||||
|
||||
// 2. user_id 중복 체크 및 유니크 ID 생성
|
||||
$userIdValue = $data['user_id'] ?? $this->generateUniqueUserId($data['email']);
|
||||
|
||||
return DB::transaction(function () use ($data, $tenantId, $userId, $userIdValue) {
|
||||
// 3. 비밀번호 결정: password가 있으면 시스템 계정 생성
|
||||
// User 모델에 'password' => 'hashed' 캐스트가 있으므로 Hash::make() 불필요
|
||||
$password = ! empty($data['password']) ? $data['password'] : null;
|
||||
|
||||
// 2. users 테이블에 사용자 생성
|
||||
// 4. users 테이블에 사용자 생성
|
||||
$user = User::create([
|
||||
'user_id' => $data['user_id'] ?? $this->generateUserId($data['email']),
|
||||
'user_id' => $userIdValue,
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'phone' => $data['phone'] ?? null,
|
||||
@@ -377,13 +386,26 @@ public function revokeAccount(int $id): TenantUserProfile
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용자 ID 자동 생성
|
||||
* 유니크한 사용자 ID 자동 생성
|
||||
* 중복 시 최대 10회까지 재시도
|
||||
*/
|
||||
private function generateUserId(string $email): string
|
||||
private function generateUniqueUserId(string $email): string
|
||||
{
|
||||
$prefix = explode('@', $email)[0];
|
||||
$suffix = Str::random(4);
|
||||
$prefix = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $prefix));
|
||||
|
||||
return strtolower($prefix.'_'.$suffix);
|
||||
$maxAttempts = 10;
|
||||
for ($i = 0; $i < $maxAttempts; $i++) {
|
||||
$suffix = Str::random(6); // 4자리 → 6자리로 증가
|
||||
$userId = $prefix.'_'.$suffix;
|
||||
|
||||
// 중복 체크 (삭제된 사용자 포함)
|
||||
if (! User::withTrashed()->where('user_id', $userId)->exists()) {
|
||||
return $userId;
|
||||
}
|
||||
}
|
||||
|
||||
// 최대 시도 후에도 실패 시 타임스탬프 추가
|
||||
return $prefix.'_'.time().'_'.Str::random(4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
// 검증/파라미터
|
||||
'validation_failed' => '요청 데이터 검증에 실패했습니다.', // 422
|
||||
'missing_parameter' => '필수 파라미터가 누락되었습니다.', // 400
|
||||
'email_already_exists' => '이미 사용 중인 이메일 주소입니다.', // 400
|
||||
'business_num_format' => '사업자등록번호 형식이 올바르지 않습니다 (000-00-00000)',
|
||||
'business_num_duplicate_active' => '이미 등록된 사업자등록번호입니다 (정식 서비스 업체)',
|
||||
'user_id_format' => '아이디는 영문, 숫자, _, - 만 사용할 수 있습니다',
|
||||
|
||||
Reference in New Issue
Block a user