From 07a3894231978972233fa93ae3e238688148ced2 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 13 Jan 2026 16:40:32 -0500 Subject: [PATCH 01/10] Create CaseDeleted Event --- ProcessMaker/Events/CaseDeleted.php | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 ProcessMaker/Events/CaseDeleted.php diff --git a/ProcessMaker/Events/CaseDeleted.php b/ProcessMaker/Events/CaseDeleted.php new file mode 100644 index 0000000000..70f88af2eb --- /dev/null +++ b/ProcessMaker/Events/CaseDeleted.php @@ -0,0 +1,65 @@ +caseNumber = $caseNumber; + $this->caseTitle = $caseTitle; + } + + /** + * Get specific data related to the event + * + * @return array + */ + public function getData(): array + { + return [ + 'case_title' => $this->caseTitle, + 'case_number' => $this->caseNumber, + 'deleted_at' => Carbon::now(), + ]; + } + + /** + * Get specific data related to the event + * + * @return array + */ + public function getChanges(): array + { + return [ + 'case_number' => $this->caseNumber, + ]; + } + + /** + * Get the Event name + * + * @return string + */ + public function getEventName(): string + { + return 'CaseDeleted'; + } +} From 826c5026f88f724d79030e32dfaa4e660de70d7d Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 13 Jan 2026 16:41:46 -0500 Subject: [PATCH 02/10] Listen for CaseDeletedEvent in EventServiceProvider --- ProcessMaker/Providers/EventServiceProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ProcessMaker/Providers/EventServiceProvider.php b/ProcessMaker/Providers/EventServiceProvider.php index f2cc0c0832..1ee0c13b57 100644 --- a/ProcessMaker/Providers/EventServiceProvider.php +++ b/ProcessMaker/Providers/EventServiceProvider.php @@ -9,6 +9,7 @@ use ProcessMaker\Events\AuthClientCreated; use ProcessMaker\Events\AuthClientDeleted; use ProcessMaker\Events\AuthClientUpdated; +use ProcessMaker\Events\CaseDeleted; use ProcessMaker\Events\CategoryCreated; use ProcessMaker\Events\CategoryDeleted; use ProcessMaker\Events\CategoryUpdated; @@ -139,6 +140,7 @@ public function boot() $this->app['events']->listen(AuthClientCreated::class, SecurityLogger::class); $this->app['events']->listen(AuthClientDeleted::class, SecurityLogger::class); $this->app['events']->listen(AuthClientUpdated::class, SecurityLogger::class); + $this->app['events']->listen(CaseDeleted::class, SecurityLogger::class); $this->app['events']->listen(CategoryCreated::class, SecurityLogger::class); $this->app['events']->listen(CategoryDeleted::class, SecurityLogger::class); $this->app['events']->listen(CategoryUpdated::class, SecurityLogger::class); From c7b609e26749a66c151aec4c96e1fac269822958 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 13 Jan 2026 16:43:29 -0500 Subject: [PATCH 03/10] Dispatch CaseDeleted; handle record deletion in trait Record deletion moved to trait to resolve sonarqube complexity issue (too many methods in DeleteCase) --- .../Api/Actions/Cases/DeleteCase.php | 217 +++--------------- .../Api/Actions/Cases/DeletesCaseRecords.php | 202 ++++++++++++++++ 2 files changed, 229 insertions(+), 190 deletions(-) create mode 100644 ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php index 4a81bd5d7a..5cd9cc4495 100644 --- a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php @@ -3,23 +3,16 @@ namespace ProcessMaker\Http\Controllers\Api\Actions\Cases; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Schema; -use ProcessMaker\Models\CaseNumber; -use ProcessMaker\Models\CaseParticipated; +use ProcessMaker\Events\CaseDeleted; use ProcessMaker\Models\CaseStarted; -use ProcessMaker\Models\Comment; -use ProcessMaker\Models\InboxRule; -use ProcessMaker\Models\InboxRuleLog; -use ProcessMaker\Models\Media; -use ProcessMaker\Models\ProcessAbeRequestToken; use ProcessMaker\Models\ProcessRequest; -use ProcessMaker\Models\ProcessRequestLock; use ProcessMaker\Models\ProcessRequestToken; -use ProcessMaker\Models\ScheduledTask; use ProcessMaker\Models\TaskDraft; class DeleteCase { + use DeletesCaseRecords; + public function __invoke(string $caseNumber): void { $requestIds = $this->getRequestIds($caseNumber); @@ -28,6 +21,9 @@ public function __invoke(string $caseNumber): void abort(404); } + // Get case title before deletion for event logging + $caseTitle = $this->getCaseTitle($caseNumber); + $tokenIds = $this->getRequestTokenIds($requestIds); DB::transaction(function () use ($caseNumber, $requestIds, $tokenIds) { @@ -49,6 +45,8 @@ public function __invoke(string $caseNumber): void $this->deleteProcessRequests($requestIds); }); + CaseDeleted::dispatch($caseNumber, $caseTitle); + $this->dispatchSavedSearchRecount(); } @@ -60,6 +58,25 @@ private function getRequestIds(string $caseNumber): array ->all(); } + private function getCaseTitle(string $caseNumber): string + { + $caseStarted = CaseStarted::query() + ->where('case_number', $caseNumber) + ->first(); + + if ($caseStarted) { + return $caseStarted->case_title; + } + + // Get case title from the first ProcessRequest if CaseStarted doesn't exist + $firstRequest = ProcessRequest::query() + ->where('case_number', $caseNumber) + ->whereNull('parent_request_id') + ->first(); + + return $firstRequest?->case_title ?? "Case #{$caseNumber}"; + } + private function getRequestTokenIds(array $requestIds): array { if ($requestIds === []) { @@ -84,186 +101,6 @@ private function getTaskDraftIds(array $tokenIds): array ->all(); } - private function deleteCasesStarted(string $caseNumber): void - { - CaseStarted::query() - ->where('case_number', $caseNumber) - ->delete(); - } - - private function deleteCasesParticipated(string $caseNumber): void - { - CaseParticipated::query() - ->where('case_number', $caseNumber) - ->delete(); - } - - private function deleteCaseNumbers(array $requestIds): void - { - if ($requestIds === []) { - return; - } - - CaseNumber::query() - ->whereIn('process_request_id', $requestIds) - ->delete(); - } - - private function deleteProcessRequests(array $requestIds): void - { - if ($requestIds === []) { - return; - } - - ProcessRequest::query() - ->whereIn('id', $requestIds) - ->get() - ->each - ->delete(); - } - - private function deleteProcessRequestTokens(array $requestIds): void - { - if ($requestIds === []) { - return; - } - - ProcessRequestToken::query() - ->whereIn('process_request_id', $requestIds) - ->delete(); - } - - private function deleteProcessRequestLocks(array $requestIds, array $tokenIds): void - { - ProcessRequestLock::query() - ->whereIn('process_request_id', $requestIds) - ->delete(); - - if ($tokenIds !== []) { - ProcessRequestLock::query() - ->whereIn('process_request_token_id', $tokenIds) - ->delete(); - } - } - - private function deleteProcessAbeRequestTokens(array $requestIds, array $tokenIds): void - { - ProcessAbeRequestToken::query() - ->whereIn('process_request_id', $requestIds) - ->delete(); - - if ($tokenIds !== []) { - ProcessAbeRequestToken::query() - ->whereIn('process_request_token_id', $tokenIds) - ->delete(); - } - } - - private function deleteScheduledTasks(array $requestIds, array $tokenIds): void - { - ScheduledTask::query() - ->whereIn('process_request_id', $requestIds) - ->delete(); - - if ($tokenIds !== []) { - ScheduledTask::query() - ->whereIn('process_request_token_id', $tokenIds) - ->delete(); - } - } - - private function deleteInboxRules(array $tokenIds): void - { - if ($tokenIds === []) { - return; - } - - InboxRule::query() - ->whereIn('process_request_token_id', $tokenIds) - ->get() - ->each - ->delete(); - } - - private function deleteInboxRuleLogs(array $tokenIds): void - { - if ($tokenIds === []) { - return; - } - - InboxRuleLog::query() - ->whereIn('process_request_token_id', $tokenIds) - ->delete(); - } - - private function deleteEllucianEthosSyncTasks(array $tokenIds): void - { - if ($tokenIds === [] || !Schema::hasTable('ellucian_ethos_sync_global_task_list')) { - return; - } - - DB::table('ellucian_ethos_sync_global_task_list') - ->whereIn('process_request_token_id', $tokenIds) - ->delete(); - } - - private function deleteTaskDrafts(array $tokenIds): void - { - if ($tokenIds === []) { - return; - } - - TaskDraft::query() - ->whereIn('task_id', $tokenIds) - ->delete(); - } - - private function deleteTaskDraftMedia(array $draftIds): void - { - if ($draftIds === []) { - return; - } - - Media::query() - ->where('model_type', TaskDraft::class) - ->whereIn('model_id', $draftIds) - ->get() - ->each - ->delete(); - } - - private function deleteRequestMedia(array $requestIds): void - { - if ($requestIds === []) { - return; - } - - Media::query() - ->where('model_type', ProcessRequest::class) - ->whereIn('model_id', $requestIds) - ->get() - ->each - ->delete(); - } - - private function deleteComments(string $caseNumber, array $requestIds, array $tokenIds): void - { - Comment::query() - ->where('case_number', $caseNumber) - ->orWhere(function ($query) use ($requestIds, $tokenIds) { - $query->where('commentable_type', ProcessRequest::class) - ->whereIn('commentable_id', $requestIds); - - if ($tokenIds !== []) { - $query->orWhere(function ($nestedQuery) use ($tokenIds) { - $nestedQuery->where('commentable_type', ProcessRequestToken::class) - ->whereIn('commentable_id', $tokenIds); - }); - } - }) - ->delete(); - } - private function dispatchSavedSearchRecount(): void { if (!config('savedsearch.count', false)) { diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php new file mode 100644 index 0000000000..d8b3493ccf --- /dev/null +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeletesCaseRecords.php @@ -0,0 +1,202 @@ +where('case_number', $caseNumber) + ->delete(); + } + + private function deleteCasesParticipated(string $caseNumber): void + { + CaseParticipated::query() + ->where('case_number', $caseNumber) + ->delete(); + } + + private function deleteCaseNumbers(array $requestIds): void + { + if ($requestIds === []) { + return; + } + + CaseNumber::query() + ->whereIn('process_request_id', $requestIds) + ->delete(); + } + + private function deleteProcessRequests(array $requestIds): void + { + if ($requestIds === []) { + return; + } + + ProcessRequest::query() + ->whereIn('id', $requestIds) + ->get() + ->each + ->delete(); + } + + private function deleteProcessRequestTokens(array $requestIds): void + { + if ($requestIds === []) { + return; + } + + ProcessRequestToken::query() + ->whereIn('process_request_id', $requestIds) + ->delete(); + } + + private function deleteProcessRequestLocks(array $requestIds, array $tokenIds): void + { + ProcessRequestLock::query() + ->whereIn('process_request_id', $requestIds) + ->delete(); + + if ($tokenIds !== []) { + ProcessRequestLock::query() + ->whereIn('process_request_token_id', $tokenIds) + ->delete(); + } + } + + private function deleteProcessAbeRequestTokens(array $requestIds, array $tokenIds): void + { + ProcessAbeRequestToken::query() + ->whereIn('process_request_id', $requestIds) + ->delete(); + + if ($tokenIds !== []) { + ProcessAbeRequestToken::query() + ->whereIn('process_request_token_id', $tokenIds) + ->delete(); + } + } + + private function deleteScheduledTasks(array $requestIds, array $tokenIds): void + { + ScheduledTask::query() + ->whereIn('process_request_id', $requestIds) + ->delete(); + + if ($tokenIds !== []) { + ScheduledTask::query() + ->whereIn('process_request_token_id', $tokenIds) + ->delete(); + } + } + + private function deleteInboxRules(array $tokenIds): void + { + if ($tokenIds === []) { + return; + } + + InboxRule::query() + ->whereIn('process_request_token_id', $tokenIds) + ->get() + ->each + ->delete(); + } + + private function deleteInboxRuleLogs(array $tokenIds): void + { + if ($tokenIds === []) { + return; + } + + InboxRuleLog::query() + ->whereIn('process_request_token_id', $tokenIds) + ->delete(); + } + + private function deleteEllucianEthosSyncTasks(array $tokenIds): void + { + if ($tokenIds === [] || !Schema::hasTable('ellucian_ethos_sync_global_task_list')) { + return; + } + + DB::table('ellucian_ethos_sync_global_task_list') + ->whereIn('process_request_token_id', $tokenIds) + ->delete(); + } + + private function deleteTaskDrafts(array $tokenIds): void + { + if ($tokenIds === []) { + return; + } + + TaskDraft::query() + ->whereIn('task_id', $tokenIds) + ->delete(); + } + + private function deleteTaskDraftMedia(array $draftIds): void + { + if ($draftIds === []) { + return; + } + + Media::query() + ->where('model_type', TaskDraft::class) + ->whereIn('model_id', $draftIds) + ->get() + ->each + ->delete(); + } + + private function deleteRequestMedia(array $requestIds): void + { + if ($requestIds === []) { + return; + } + + Media::query() + ->where('model_type', ProcessRequest::class) + ->whereIn('model_id', $requestIds) + ->get() + ->each + ->delete(); + } + + private function deleteComments(string $caseNumber, array $requestIds, array $tokenIds): void + { + Comment::query() + ->where('case_number', $caseNumber) + ->orWhere(function ($query) use ($requestIds, $tokenIds) { + $query->where('commentable_type', ProcessRequest::class) + ->whereIn('commentable_id', $requestIds); + + if ($tokenIds !== []) { + $query->orWhere(function ($nestedQuery) use ($tokenIds) { + $nestedQuery->where('commentable_type', ProcessRequestToken::class) + ->whereIn('commentable_id', $tokenIds); + }); + } + }) + ->delete(); + } +} From a08015979758865d8394bbe68b66c6c8c77cca39 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 13 Jan 2026 16:55:26 -0500 Subject: [PATCH 04/10] Update comments --- .../Http/Controllers/Api/Actions/Cases/DeleteCase.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php index 5cd9cc4495..b4a1dae226 100644 --- a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php @@ -21,9 +21,7 @@ public function __invoke(string $caseNumber): void abort(404); } - // Get case title before deletion for event logging $caseTitle = $this->getCaseTitle($caseNumber); - $tokenIds = $this->getRequestTokenIds($requestIds); DB::transaction(function () use ($caseNumber, $requestIds, $tokenIds) { @@ -68,7 +66,7 @@ private function getCaseTitle(string $caseNumber): string return $caseStarted->case_title; } - // Get case title from the first ProcessRequest if CaseStarted doesn't exist + // If CaseStarted doesn't exist, get case title from the first ProcessRequest $firstRequest = ProcessRequest::query() ->where('case_number', $caseNumber) ->whereNull('parent_request_id') From 5658b8dbbb39906d3e600cc62e4ea256e37427bc Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 13 Jan 2026 17:38:55 -0500 Subject: [PATCH 05/10] Change case_title to name for priority in modal --- ProcessMaker/Events/CaseDeleted.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProcessMaker/Events/CaseDeleted.php b/ProcessMaker/Events/CaseDeleted.php index 70f88af2eb..2eeb6569b9 100644 --- a/ProcessMaker/Events/CaseDeleted.php +++ b/ProcessMaker/Events/CaseDeleted.php @@ -35,7 +35,7 @@ public function __construct(int $caseNumber, string $caseTitle) public function getData(): array { return [ - 'case_title' => $this->caseTitle, + 'name' => $this->caseTitle, 'case_number' => $this->caseNumber, 'deleted_at' => Carbon::now(), ]; From 78dafca0b4ed68d700abcda1739b309620319d11 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 13 Jan 2026 17:40:48 -0500 Subject: [PATCH 06/10] Add testCaseDeleted test to SecurityLogsTest.php --- tests/Feature/Api/SecurityLogsTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/Feature/Api/SecurityLogsTest.php b/tests/Feature/Api/SecurityLogsTest.php index d4fa5b6290..a8d0a8fc71 100644 --- a/tests/Feature/Api/SecurityLogsTest.php +++ b/tests/Feature/Api/SecurityLogsTest.php @@ -43,12 +43,14 @@ use ProcessMaker\Events\UserDeleted; use ProcessMaker\Events\UserRestored; use ProcessMaker\Events\UserUpdated; +use ProcessMaker\Http\Controllers\Api\Actions\Cases\DeleteCase; use ProcessMaker\Managers\SignalManager; use ProcessMaker\Models\EnvironmentVariable; use ProcessMaker\Models\Group; use ProcessMaker\Models\Permission; use ProcessMaker\Models\Process; use ProcessMaker\Models\ProcessCategory; +use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\ProcessTemplates; use ProcessMaker\Models\Screen; use ProcessMaker\Models\Script; @@ -248,6 +250,24 @@ public function checkAssertsSegurityLog(string $event, $date = 'created_at', $to } } + /** + * This tests Case Deleted + */ + public function testCaseDeleted() + { + $caseNumber = 12345; + + // Create a ProcessRequest with a case number + ProcessRequest::factory() + ->withCaseNumber($caseNumber) + ->create(); + + // Use the DeleteCase action to delete the case and dispatch the CaseDeleted event + (new DeleteCase)($caseNumber); + + $this->checkAssertsSegurityLog('CaseDeleted', 'deleted_at'); + } + /** * This test Category Created */ From 26a4700e7b48de7be0410a8e0d9d28a2ad3c51f4 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Wed, 14 Jan 2026 10:46:52 -0500 Subject: [PATCH 07/10] Resolve caseNumber type mismatch --- ProcessMaker/Events/CaseDeleted.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProcessMaker/Events/CaseDeleted.php b/ProcessMaker/Events/CaseDeleted.php index 2eeb6569b9..8c3abb6049 100644 --- a/ProcessMaker/Events/CaseDeleted.php +++ b/ProcessMaker/Events/CaseDeleted.php @@ -12,7 +12,7 @@ class CaseDeleted implements SecurityLogEventInterface use Dispatchable; use FormatSecurityLogChanges; - private int $caseNumber; + private string $caseNumber; private string $caseTitle; @@ -21,7 +21,7 @@ class CaseDeleted implements SecurityLogEventInterface * * @return void */ - public function __construct(int $caseNumber, string $caseTitle) + public function __construct(string $caseNumber, string $caseTitle) { $this->caseNumber = $caseNumber; $this->caseTitle = $caseTitle; From ed4e52f0ea8e20656985fb10bd9519231d1fa81d Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Wed, 14 Jan 2026 11:07:01 -0500 Subject: [PATCH 08/10] Add null fallback in getCaseTitle --- ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php index b4a1dae226..a9317899af 100644 --- a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php @@ -63,7 +63,7 @@ private function getCaseTitle(string $caseNumber): string ->first(); if ($caseStarted) { - return $caseStarted->case_title; + return $caseStarted->case_title ?? "Case #{$caseNumber}"; } // If CaseStarted doesn't exist, get case title from the first ProcessRequest From 9cc9f51c84e2ac848348eaf4b16f099004082ba5 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Wed, 14 Jan 2026 11:19:15 -0500 Subject: [PATCH 09/10] Update getCaseTitle() --- .../Http/Controllers/Api/Actions/Cases/DeleteCase.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php index a9317899af..d98f39e703 100644 --- a/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php +++ b/ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php @@ -64,15 +64,15 @@ private function getCaseTitle(string $caseNumber): string if ($caseStarted) { return $caseStarted->case_title ?? "Case #{$caseNumber}"; - } - - // If CaseStarted doesn't exist, get case title from the first ProcessRequest - $firstRequest = ProcessRequest::query() + } else { + // If CaseStarted doesn't exist, get case title from the first ProcessRequest + $firstRequest = ProcessRequest::query() ->where('case_number', $caseNumber) ->whereNull('parent_request_id') ->first(); - return $firstRequest?->case_title ?? "Case #{$caseNumber}"; + return $firstRequest?->case_title ?? "Case #{$caseNumber}"; + } } private function getRequestTokenIds(array $requestIds): array From 0e8b89f1484fc31c53e664ad0be1c1f034ecda3b Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Wed, 14 Jan 2026 11:25:58 -0500 Subject: [PATCH 10/10] Update testCaseDeleted() in SecurityLogsTest.php --- tests/Feature/Api/SecurityLogsTest.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/Feature/Api/SecurityLogsTest.php b/tests/Feature/Api/SecurityLogsTest.php index a8d0a8fc71..3ba3db3a9f 100644 --- a/tests/Feature/Api/SecurityLogsTest.php +++ b/tests/Feature/Api/SecurityLogsTest.php @@ -43,7 +43,6 @@ use ProcessMaker\Events\UserDeleted; use ProcessMaker\Events\UserRestored; use ProcessMaker\Events\UserUpdated; -use ProcessMaker\Http\Controllers\Api\Actions\Cases\DeleteCase; use ProcessMaker\Managers\SignalManager; use ProcessMaker\Models\EnvironmentVariable; use ProcessMaker\Models\Group; @@ -257,13 +256,13 @@ public function testCaseDeleted() { $caseNumber = 12345; - // Create a ProcessRequest with a case number ProcessRequest::factory() ->withCaseNumber($caseNumber) ->create(); - // Use the DeleteCase action to delete the case and dispatch the CaseDeleted event - (new DeleteCase)($caseNumber); + $response = $this->apiCall('DELETE', route('api.cases.destroy', ['case_number' => $caseNumber])); + + $response->assertStatus(204); $this->checkAssertsSegurityLog('CaseDeleted', 'deleted_at'); }