diff --git a/pom.xml b/pom.xml
index 6890ffc..ff263ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,14 @@
org.springframework.boot
spring-boot-starter
-
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
org.postgresql
postgresql
@@ -45,7 +52,16 @@
spring-boot-starter-test
test
-
+
+ org.projectlombok
+ lombok
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
@@ -53,6 +69,21 @@
org.springframework.boot
spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.15.0
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.42
+
+
+
+
diff --git a/src/main/java/net/hackyourfuture/tickettrackingsystem/controller/UserController.java b/src/main/java/net/hackyourfuture/tickettrackingsystem/controller/UserController.java
new file mode 100644
index 0000000..013246e
--- /dev/null
+++ b/src/main/java/net/hackyourfuture/tickettrackingsystem/controller/UserController.java
@@ -0,0 +1,66 @@
+package net.hackyourfuture.tickettrackingsystem.controller;
+
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import net.hackyourfuture.tickettrackingsystem.dto.request.CreateUserRequest;
+import net.hackyourfuture.tickettrackingsystem.dto.request.UpdateUserRequest;
+import net.hackyourfuture.tickettrackingsystem.dto.response.UserResponse;
+import net.hackyourfuture.tickettrackingsystem.model.User;
+import net.hackyourfuture.tickettrackingsystem.service.UserService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/users")
+@RequiredArgsConstructor
+public class UserController {
+
+ private final UserService userService;
+
+ private UserResponse toUserResponse(User user) {
+ return new UserResponse(
+ user.id(),
+ user.name(),
+ user.email()
+ );
+ }
+ @GetMapping
+ public List getAllUsers() {
+ return userService.getAllUsers()
+ .stream()
+ .map(this::toUserResponse).
+ toList();
+ }
+
+ @GetMapping("/{id}")
+ public UserResponse getUserById(@PathVariable Long id) {
+ return toUserResponse(
+ userService.getUserById(id)
+ );
+ }
+
+ @PostMapping
+ public ResponseEntity createUser( @Valid @RequestBody CreateUserRequest request) {
+ User user = userService.createUser(request);
+
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(toUserResponse(user));
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity updateUser(@PathVariable Long id, @Valid @RequestBody UpdateUserRequest request) {
+ User user = userService.updateUser(id, request);
+
+ return ResponseEntity.ok(toUserResponse(user));
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteUser(@PathVariable Long id) {
+ userService.deleteUser(id);
+
+ return ResponseEntity.noContent().build();
+ }
+}
diff --git a/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/request/CreateUserRequest.java b/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/request/CreateUserRequest.java
new file mode 100644
index 0000000..50a64d0
--- /dev/null
+++ b/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/request/CreateUserRequest.java
@@ -0,0 +1,13 @@
+package net.hackyourfuture.tickettrackingsystem.dto.request;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+
+public record CreateUserRequest(
+ @NotBlank
+ @Size(min = 3)
+ String name,
+ @NotBlank
+ @Email
+ String email) {
+}
diff --git a/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/request/UpdateUserRequest.java b/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/request/UpdateUserRequest.java
new file mode 100644
index 0000000..f681080
--- /dev/null
+++ b/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/request/UpdateUserRequest.java
@@ -0,0 +1,17 @@
+package net.hackyourfuture.tickettrackingsystem.dto.request;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+
+public record UpdateUserRequest(
+
+ @NotBlank
+ @Size(min = 3)
+ String name,
+
+ @NotBlank
+ @Email
+ String email
+
+) {}
\ No newline at end of file
diff --git a/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/response/UserResponse.java b/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/response/UserResponse.java
new file mode 100644
index 0000000..a6e8734
--- /dev/null
+++ b/src/main/java/net/hackyourfuture/tickettrackingsystem/dto/response/UserResponse.java
@@ -0,0 +1,8 @@
+package net.hackyourfuture.tickettrackingsystem.dto.response;
+
+public record UserResponse(
+ Long id,
+ String name,
+ String email
+) {
+}
\ No newline at end of file
diff --git a/src/main/java/net/hackyourfuture/tickettrackingsystem/exception/DuplicateEmailException.java b/src/main/java/net/hackyourfuture/tickettrackingsystem/exception/DuplicateEmailException.java
new file mode 100644
index 0000000..a7b3025
--- /dev/null
+++ b/src/main/java/net/hackyourfuture/tickettrackingsystem/exception/DuplicateEmailException.java
@@ -0,0 +1,8 @@
+package net.hackyourfuture.tickettrackingsystem.exception;
+
+public class DuplicateEmailException extends RuntimeException {
+
+ public DuplicateEmailException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/hackyourfuture/tickettrackingsystem/exception/GlobalExceptionHandler.java b/src/main/java/net/hackyourfuture/tickettrackingsystem/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..60d9e34
--- /dev/null
+++ b/src/main/java/net/hackyourfuture/tickettrackingsystem/exception/GlobalExceptionHandler.java
@@ -0,0 +1,28 @@
+package net.hackyourfuture.tickettrackingsystem.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.Map;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity