From 94612e3b50eef3307314a34a6b833c491061a984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Wed, 28 Jan 2026 21:09:53 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20Attendance=20store()=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A5=BC=20Upsert=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=EC=9C=BC=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 - 같은 날 같은 사용자의 기록이 있으면 업데이트, 없으면 생성 - 기존 Create Only 패턴에서 Upsert 패턴으로 변경 - Swagger 문서 업데이트 (409 응답 제거, 설명 변경) Co-Authored-By: Claude --- app/Services/AttendanceService.php | 23 +++++++++++++++++------ app/Swagger/v1/AttendanceApi.php | 9 ++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/Services/AttendanceService.php b/app/Services/AttendanceService.php index f4b444d..4c26c6a 100644 --- a/app/Services/AttendanceService.php +++ b/app/Services/AttendanceService.php @@ -88,7 +88,9 @@ public function show(int $id): Attendance } /** - * 근태 등록 + * 근태 등록 (Upsert) + * - 같은 날 같은 사용자의 기록이 있으면 업데이트 + * - 없으면 새로 생성 */ public function store(array $data): Attendance { @@ -103,16 +105,25 @@ public function store(array $data): Attendance ->whereDate('base_date', $data['base_date']) ->first(); - if ($existing) { - throw new \Exception(__('error.attendance.already_exists')); - } - // json_details 구성 - // json_details 객체가 직접 전달된 경우 그대로 사용, 아니면 개별 필드에서 구성 $jsonDetails = isset($data['json_details']) && is_array($data['json_details']) ? $data['json_details'] : $this->buildJsonDetails($data); + if ($existing) { + // 기존 기록 업데이트 (Upsert) + $existing->status = $data['status'] ?? $existing->status; + $existing->json_details = array_merge($existing->json_details ?? [], $jsonDetails); + if (array_key_exists('remarks', $data)) { + $existing->remarks = $data['remarks']; + } + $existing->updated_by = $userId; + $existing->save(); + + return $existing->fresh(['user:id,name,email']); + } + + // 새 기록 생성 $attendance = Attendance::create([ 'tenant_id' => $tenantId, 'user_id' => $data['user_id'], diff --git a/app/Swagger/v1/AttendanceApi.php b/app/Swagger/v1/AttendanceApi.php index 17ec740..77a53b5 100644 --- a/app/Swagger/v1/AttendanceApi.php +++ b/app/Swagger/v1/AttendanceApi.php @@ -283,8 +283,8 @@ public function show() {} * @OA\Post( * path="/api/v1/attendances", * tags={"Attendances"}, - * summary="근태 등록", - * description="새 근태 기록을 등록합니다.", + * summary="근태 등록 (Upsert)", + * description="근태 기록을 등록합니다. 같은 날 같은 사용자의 기록이 있으면 업데이트, 없으면 새로 생성합니다.", * security={{"ApiKeyAuth":{}},{"BearerAuth":{}}}, * * @OA\RequestBody( @@ -294,8 +294,8 @@ public function show() {} * ), * * @OA\Response( - * response=201, - * description="등록 성공", + * response=200, + * description="등록/수정 성공", * * @OA\JsonContent( * allOf={ @@ -308,7 +308,6 @@ public function show() {} * * @OA\Response(response=400, description="잘못된 요청", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")), * @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")), - * @OA\Response(response=409, description="같은 날 기록이 이미 존재함", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")), * @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")) * ) */