From d917e76f1b7e4052d2c41d3f847b7fcbe480775b Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Wed, 6 May 2026 22:34:08 +0300 Subject: [PATCH] implement SearchUsers use case --- backend/app/User/EloquentUserRepository.php | 19 ++++++++++++ .../User/UseCases/SearchUsers/SearchUsers.php | 29 ++++++++++++++++++ .../SearchUsers/SearchUsersRequest.php | 10 +++++++ backend/app/User/UserRepository.php | 5 ++++ backend/tests/Fakes/FakeUserRepository.php | 30 +++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 backend/app/User/UseCases/SearchUsers/SearchUsers.php create mode 100644 backend/app/User/UseCases/SearchUsers/SearchUsersRequest.php diff --git a/backend/app/User/EloquentUserRepository.php b/backend/app/User/EloquentUserRepository.php index a4fdc67..5824a6c 100644 --- a/backend/app/User/EloquentUserRepository.php +++ b/backend/app/User/EloquentUserRepository.php @@ -43,6 +43,25 @@ class EloquentUserRepository implements UserRepository return $model === null ? null : $this->toDomain($model); } + /** + * @return User[] + */ + public function search(string $query): array + { + $like = strtolower($query).'%'; + $models = UserModel::query() + ->whereRaw('LOWER(display_name) LIKE ?', [$like]) + ->orWhereRaw('LOWER(email) LIKE ?', [$like]) + ->orderBy('display_name') + ->get(); + + return $models->map( + function (UserModel $model) { + return $this->toDomain($model); + }, + )->all(); + } + /** * @throws RuntimeException */ diff --git a/backend/app/User/UseCases/SearchUsers/SearchUsers.php b/backend/app/User/UseCases/SearchUsers/SearchUsers.php new file mode 100644 index 0000000..ea64e79 --- /dev/null +++ b/backend/app/User/UseCases/SearchUsers/SearchUsers.php @@ -0,0 +1,29 @@ +query); + if ($query === '') { + throw new BadRequestException('query is required'); + } + + return $this->userRepo->search($query); + } +} diff --git a/backend/app/User/UseCases/SearchUsers/SearchUsersRequest.php b/backend/app/User/UseCases/SearchUsers/SearchUsersRequest.php new file mode 100644 index 0000000..a6be688 --- /dev/null +++ b/backend/app/User/UseCases/SearchUsers/SearchUsersRequest.php @@ -0,0 +1,10 @@ +existingUsers as $user) { + $displayName = strtolower($user->getDisplayName()); + $email = strtolower($user->getEmail()->value()); + if ( + str_starts_with($displayName, $needle) + || str_starts_with($email, $needle) + ) { + $results[] = $this->copy($user); + } + } + usort( + $results, + function (User $left, User $right) { + return strcmp( + $left->getDisplayName(), + $right->getDisplayName(), + ); + }, + ); + + return $results; + } + /** * @throws RuntimeException */