From b74297a75b2d92c7b69703b4b1c0f7fc163a47d0 Mon Sep 17 00:00:00 2001 From: kent Date: Sun, 21 Dec 2025 16:32:44 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20client=5Fcode=20=EB=B0=B1=EC=97=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=90=EB=8F=99=20=EC=83=9D=EC=84=B1=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ClientStoreRequest: client_code 필수→nullable 변경 - ClientService.store(): 프론트 코드 무시, generateClientCode() 자동 생성 - ClientService.update(): client_code 변경 불가 처리 - 코드 형식: 8자리 영숫자 (예: A3B7X9K2) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../Requests/Client/ClientStoreRequest.php | 2 +- app/Services/ClientService.php | 50 +++++++++++++------ 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/app/Http/Requests/Client/ClientStoreRequest.php b/app/Http/Requests/Client/ClientStoreRequest.php index aa2db4e..b53e45b 100644 --- a/app/Http/Requests/Client/ClientStoreRequest.php +++ b/app/Http/Requests/Client/ClientStoreRequest.php @@ -53,7 +53,7 @@ public function rules(): array { return [ 'client_group_id' => 'nullable|integer', - 'client_code' => 'required|string|max:50', + 'client_code' => 'nullable|string|max:50', // 프론트에서 보내도 백엔드에서 자동 생성 'name' => 'required|string|max:100', 'client_type' => [ 'nullable', diff --git a/app/Services/ClientService.php b/app/Services/ClientService.php index cbaa79a..e504d04 100644 --- a/app/Services/ClientService.php +++ b/app/Services/ClientService.php @@ -54,13 +54,8 @@ public function store(array $data) { $tenantId = $this->tenantId(); - // client_code 중복 검사 - $exists = Client::where('tenant_id', $tenantId) - ->where('client_code', $data['client_code']) - ->exists(); - if ($exists) { - throw new BadRequestHttpException(__('error.duplicate_code')); - } + // client_code 자동 생성 (프론트에서 보내도 무시) + $data['client_code'] = $this->generateClientCode($tenantId); $data['tenant_id'] = $tenantId; $data['is_active'] = $data['is_active'] ?? true; @@ -68,6 +63,36 @@ public function store(array $data) return Client::create($data); } + /** + * 유니크한 client_code 자동 생성 + * 형식: 8자리 영숫자 (예: A3B7X9K2) + */ + private function generateClientCode(int $tenantId): string + { + $maxAttempts = 10; + $attempt = 0; + + do { + // 8자리 영숫자 코드 생성 (대문자 + 숫자) + $code = strtoupper(substr(bin2hex(random_bytes(4)), 0, 8)); + + // 중복 검사 + $exists = Client::withoutGlobalScopes() + ->where('tenant_id', $tenantId) + ->where('client_code', $code) + ->exists(); + + $attempt++; + } while ($exists && $attempt < $maxAttempts); + + if ($exists) { + // 극히 드문 경우: timestamp 추가하여 유니크성 보장 + $code = strtoupper(substr(bin2hex(random_bytes(2)), 0, 4).dechex(time() % 0xFFFF)); + } + + return $code; + } + /** 수정 */ public function update(int $id, array $data) { @@ -78,15 +103,8 @@ public function update(int $id, array $data) throw new NotFoundHttpException(__('error.not_found')); } - // client_code 변경 시 중복 검사 - if (isset($data['client_code']) && $data['client_code'] !== $client->client_code) { - $exists = Client::where('tenant_id', $tenantId) - ->where('client_code', $data['client_code']) - ->exists(); - if ($exists) { - throw new BadRequestHttpException(__('error.duplicate_code')); - } - } + // client_code 변경 불가 (프론트에서 보내도 무시) + unset($data['client_code']); $client->update($data);