From a0332df10187bb2054362173bbdf4fc0fba6f154 Mon Sep 17 00:00:00 2001 From: b1ek Date: Fri, 30 Aug 2024 14:16:16 +1000 Subject: [PATCH] feat: /api/users/private/trash/* --- app/Http/Controllers/TrashUserController.php | 48 +++++++++++++++++++ app/Http/Requests/TrashGroupRequest.php | 23 +++++++++ app/Models/User.php | 1 + app/Services/UserService.php | 14 ++++++ app/Services/UserTrashService.php | 48 +++++++++++++++++++ ...4_08_30_013415_add_deleted_at_to_users.php | 28 +++++++++++ routes/web.php | 7 +++ 7 files changed, 169 insertions(+) create mode 100644 app/Http/Controllers/TrashUserController.php create mode 100644 app/Http/Requests/TrashGroupRequest.php create mode 100644 app/Services/UserTrashService.php create mode 100644 database/migrations/2024_08_30_013415_add_deleted_at_to_users.php diff --git a/app/Http/Controllers/TrashUserController.php b/app/Http/Controllers/TrashUserController.php new file mode 100644 index 0000000..66678ce --- /dev/null +++ b/app/Http/Controllers/TrashUserController.php @@ -0,0 +1,48 @@ +getValidatedIds(); + $ret = $this->userTrashService->moveUsersToTrash($ids); + if (is_array($ret)) { + return response()->json($ret, 404); + } + } + + public function deleteMultiple(TrashGroupRequest $request) + { + $ids = $request->getValidatedIds(); + $ret = $this->userTrashService->moveUsersFromTrash($ids); + if (is_array($ret)) { + return response()->json($ret, 404); + } + } + + public function cleanMultiple(TrashGroupRequest $request) + { + $ids = $request->getValidatedIds(); + $ret = $this->userTrashService->cleanUsersFromTrash($ids); + if (is_array($ret)) { + return response()->json($ret, 404); + } + } + + public function list(AuthorizedRequest $request) + { + return $this->userTrashService->listUsersInTrash(); + } +} diff --git a/app/Http/Requests/TrashGroupRequest.php b/app/Http/Requests/TrashGroupRequest.php new file mode 100644 index 0000000..1997dc5 --- /dev/null +++ b/app/Http/Requests/TrashGroupRequest.php @@ -0,0 +1,23 @@ +query('ids')); + $validator = validator([ + 'ids' => $ids + ], [ + 'ids' => 'required|array|min:1', + 'ids.*' => 'required|uuid|distinct' + ]); + if ($validator->fails()) { + throw new HttpResponseException(response()->json($validator->errors(), 422)); + } + return $ids; + } +} diff --git a/app/Models/User.php b/app/Models/User.php index b045b5b..d244982 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -48,6 +48,7 @@ class User extends Authenticatable { return [ 'email_verified_at' => 'datetime', + 'deleted_at' => 'datetime', 'password' => 'hashed', ]; } diff --git a/app/Services/UserService.php b/app/Services/UserService.php index 3c2f404..da0f0be 100644 --- a/app/Services/UserService.php +++ b/app/Services/UserService.php @@ -82,4 +82,18 @@ class UserService $user->save(); return $user; } + + public function getUnexistingIds(array $ids): null | array + { + $users = User::whereIn('id', $ids)->get(); + if ($users->count() != count($ids)) { + $existingIds = $users->map( + function($model) { + return $model->id; + } + )->toArray(); + return array_diff($ids, $existingIds); + } + return null; + } } \ No newline at end of file diff --git a/app/Services/UserTrashService.php b/app/Services/UserTrashService.php new file mode 100644 index 0000000..eaff421 --- /dev/null +++ b/app/Services/UserTrashService.php @@ -0,0 +1,48 @@ +userService->getUnexistingIds($ids); + if (is_array($unexisting)) { + return $unexisting; + } + + return User::whereIn('id', $ids)->update([ 'deleted_at' => now()->toDateTimeImmutable() ]); + } + + public function moveUsersFromTrash(array $ids): bool | array + { + $unexisting = $this->userService->getUnexistingIds($ids); + if (is_array($unexisting)) { + return $unexisting; + } + + return User::whereIn('id', $ids)->update([ 'deleted_at' => null ]); + } + + public function cleanUsersFromTrash(array $ids): bool | null | array + { + $unexisting = $this->userService->getUnexistingIds($ids); + if (is_array($unexisting)) { + return $unexisting; + } + + return User::whereIn('id', $ids)->whereNotNull('deleted_at')->delete(); + } + + public function listUsersInTrash(): array + { + return User::whereNotNull('deleted_at')->get()->toArray(); + } +} diff --git a/database/migrations/2024_08_30_013415_add_deleted_at_to_users.php b/database/migrations/2024_08_30_013415_add_deleted_at_to_users.php new file mode 100644 index 0000000..53fe5ef --- /dev/null +++ b/database/migrations/2024_08_30_013415_add_deleted_at_to_users.php @@ -0,0 +1,28 @@ +timestamp('deleted_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('deleted_at'); + }); + } +}; diff --git a/routes/web.php b/routes/web.php index 513faf6..3403999 100644 --- a/routes/web.php +++ b/routes/web.php @@ -2,6 +2,7 @@ use App\Http\Controllers\PrivateUserController; use App\Http\Controllers\PublicUserController; +use App\Http\Controllers\TrashUserController; use Illuminate\Support\Facades\Route; Route::get('/', function() { @@ -19,6 +20,12 @@ Route::prefix('/api')->group(function() { Route::get('/get/{id}', 'get')->whereUuid('id'); Route::put('/edit/{id}', 'edit')->whereUuid('id'); }); + Route::controller(TrashUserController::class)->prefix('/users/private/trash')->group(function () { + Route::put('/group', 'addMultiple'); + Route::delete('/group', 'deleteMultiple'); + Route::delete('/clean', 'cleanMultiple'); + Route::get('/list', 'list'); + }); }); Route::get('/session', function() {