From 8239f03592fa6bcff454a2d4e933f7c56cd9dc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 5 Mar 2026 16:51:00 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[approval]=20=EC=98=81=EA=B5=AC=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=8B=9C=20=EC=B2=A8=EB=B6=80=ED=8C=8C=EC=9D=BC/?= =?UTF-8?q?=ED=95=98=EC=9C=84=EB=AC=B8=EC=84=9C=20=EC=A0=95=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EC=97=90=EB=9F=AC=20=EB=A1=9C=EA=B9=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 첨부파일(files 테이블) soft delete 처리 - 하위 문서(parent_doc_id) 참조 해제 - DB 트랜잭션으로 원자성 보장 - catch 블록에 report() 추가로 에러 로깅 --- .../Api/Admin/ApprovalApiController.php | 3 ++ app/Services/ApprovalService.php | 29 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Api/Admin/ApprovalApiController.php b/app/Http/Controllers/Api/Admin/ApprovalApiController.php index 91b783e6..cdb31ce9 100644 --- a/app/Http/Controllers/Api/Admin/ApprovalApiController.php +++ b/app/Http/Controllers/Api/Admin/ApprovalApiController.php @@ -200,9 +200,12 @@ public function forceDestroy(int $id): JsonResponse 'message' => '결재 문서가 영구삭제되었습니다.', ]); } catch (\Throwable $e) { + report($e); + return response()->json([ 'success' => false, 'message' => '영구삭제에 실패했습니다.', + 'error' => config('app.debug') ? $e->getMessage() : null, ], 500); } } diff --git a/app/Services/ApprovalService.php b/app/Services/ApprovalService.php index f9cabe36..eec5f6ba 100644 --- a/app/Services/ApprovalService.php +++ b/app/Services/ApprovalService.php @@ -231,16 +231,29 @@ public function forceDeleteApproval(int $id): bool { $approval = Approval::withTrashed()->with('form')->findOrFail($id); - // 연동 Leave 정리 - $leave = \App\Models\HR\Leave::where('approval_id', $approval->id)->first(); - if ($leave) { - $leave->update(['deleted_by' => auth()->id()]); - $leave->delete(); - } + return DB::transaction(function () use ($approval) { + // 연동 Leave 정리 + $leave = \App\Models\HR\Leave::where('approval_id', $approval->id)->first(); + if ($leave) { + $leave->update(['deleted_by' => auth()->id()]); + $leave->delete(); + } - $approval->steps()->withTrashed()->forceDelete(); + // 첨부파일 정리 (files 테이블) + \App\Models\File::where('document_id', $approval->id) + ->where('document_type', 'approval') + ->update(['deleted_by' => auth()->id(), 'deleted_at' => now()]); - return $approval->forceDelete(); + // 하위 문서 참조 해제 + Approval::withTrashed() + ->where('parent_doc_id', $approval->id) + ->update(['parent_doc_id' => null]); + + // 결재 단계 삭제 + $approval->steps()->forceDelete(); + + return $approval->forceDelete(); + }); } // =========================================================================