diff --git a/backend/pronunciationAppBack/pom.xml b/backend/pronunciationAppBack/pom.xml
index 68220ba2e..0c420b7eb 100644
--- a/backend/pronunciationAppBack/pom.xml
+++ b/backend/pronunciationAppBack/pom.xml
@@ -39,6 +39,12 @@
lombok
true
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ 3.3.7
+
+
org.springframework.boot
spring-boot-starter-web
@@ -60,11 +66,6 @@
postgresql
runtime
-
- org.projectlombok
- lombok
- true
-
org.springframework.boot
spring-boot-starter-test
diff --git a/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/controller/AppUserController.java b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/controller/AppUserController.java
new file mode 100644
index 000000000..ed6878041
--- /dev/null
+++ b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/controller/AppUserController.java
@@ -0,0 +1,89 @@
+package dev.pronunciationAppBack.controller;
+
+import dev.pronunciationAppBack.model.AppUser;
+import dev.pronunciationAppBack.service.AppUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("/api/users")
+public class AppUserController {
+
+ @Autowired
+ private AppUserService appUserService;
+
+ @GetMapping
+ public ResponseEntity> getAllUsers() {
+ List users = appUserService.getAllUsers();
+ HttpHeaders headers = getCommonHeaders("Get all users");
+
+ return !users.isEmpty()
+ ? new ResponseEntity<>(users, headers, HttpStatus.OK)
+ : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND);
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getUserById(@PathVariable String id) {
+ Optional user = appUserService.findAppUserById(id);
+ HttpHeaders headers = getCommonHeaders("Get user by ID");
+
+ return user.map(value -> new ResponseEntity<>(value, headers, HttpStatus.OK))
+ .orElseGet(() -> new ResponseEntity<>(headers, HttpStatus.NOT_FOUND));
+ }
+
+ @PostMapping()
+ public ResponseEntity createUser(@RequestBody AppUser user) {
+ Optional createdUser = appUserService.createAppUser(user);
+ HttpHeaders headers = getCommonHeaders("Create a new user");
+
+ return createdUser.map(value -> new ResponseEntity<>(value, headers, HttpStatus.CREATED))
+ .orElseGet(() -> new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST));
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity updateUser(@PathVariable String id, @RequestBody AppUser user) {
+ Optional updatedUser = appUserService.updateAppUser(user);
+ HttpHeaders headers = getCommonHeaders("Update a user");
+
+ return updatedUser.map(value -> new ResponseEntity<>(value, headers, HttpStatus.OK))
+ .orElseGet(() -> new ResponseEntity<>(headers, HttpStatus.NOT_FOUND));
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteUser(@PathVariable String id) {
+ HttpHeaders headers = getCommonHeaders("Delete a user");
+
+ return appUserService.deleteAppUser(id)
+ ? new ResponseEntity<>("User deleted", headers, HttpStatus.OK)
+ : new ResponseEntity<>("User not found", headers, HttpStatus.NOT_FOUND);
+
+ }
+
+ @GetMapping("/findBy")
+ public ResponseEntity getAppUserByEmail(@RequestParam String email) {
+ Optional user = appUserService.findAppUserByEmail(email);
+ HttpHeaders headers = getCommonHeaders("Get user by email");
+
+ return user.map(value -> new ResponseEntity<>(value, headers, HttpStatus.OK))
+ .orElseGet(() -> new ResponseEntity<>(headers, HttpStatus.NOT_FOUND));
+ }
+
+ private HttpHeaders getCommonHeaders(String description) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("desc", description);
+ headers.add("content-type", "application/json");
+ headers.add("date", new Date().toString());
+ headers.add("server", "Spring Boot");
+ headers.add("version", "1.0.0");
+ headers.add("user-count", String.valueOf(appUserService.getAppUserCount()));
+ headers.add("object", "appUsers");
+ return headers;
+ }
+}
diff --git a/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/model/AppUser.java b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/model/AppUser.java
new file mode 100644
index 000000000..1946720b4
--- /dev/null
+++ b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/model/AppUser.java
@@ -0,0 +1,53 @@
+package dev.pronunciationAppBack.model;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.validation.constraints.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+@Entity
+@Getter @Setter @NoArgsConstructor
+public class AppUser {
+
+ @Id
+ private String id;
+
+ @NotBlank(message = "Name should not be empty")
+ @Size(min = 3, max=40, message = "Name should be between 3 and 40 characters")
+ private String name;
+
+ @NotBlank(message = "Email should not be empty")
+ @Email(message = "Please enter a valid email address")
+ private String email;
+
+ @NotBlank(message = "Password should not be empty")
+ @Size(min = 6, max=20, message = "Password should be between 6 and 20 characters")
+ private String password;
+
+ @Min(value = 3, message = "Age should be between 3 and 100")
+ @Max(value = 100, message = "Age should be between 3 and 100")
+ private int age;
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate joinDate;
+
+ public AppUser(String id, String name, String email, String password, int age, LocalDate joinDate) {
+ this.id = id;
+ this.name = name;
+ this.email = email;
+ this.password = password;
+ this.age = age;
+ this.joinDate = joinDate != null ? joinDate : LocalDate.now();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("User{id='%s', name='%s', email='%s', age=%d, joinDate=%s}",
+ id, name, email, age, joinDate);
+ }
+}
diff --git a/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/repository/AppUserRepository.java b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/repository/AppUserRepository.java
new file mode 100644
index 000000000..3b35c4451
--- /dev/null
+++ b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/repository/AppUserRepository.java
@@ -0,0 +1,12 @@
+package dev.pronunciationAppBack.repository;
+
+import dev.pronunciationAppBack.model.AppUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+
+public interface AppUserRepository extends JpaRepository {
+ Optional findByEmail(String email);
+}
+
diff --git a/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/service/AppUserService.java b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/service/AppUserService.java
new file mode 100644
index 000000000..9272c9969
--- /dev/null
+++ b/backend/pronunciationAppBack/src/main/java/dev/pronunciationAppBack/service/AppUserService.java
@@ -0,0 +1,62 @@
+package dev.pronunciationAppBack.service;
+
+import dev.pronunciationAppBack.model.AppUser;
+import dev.pronunciationAppBack.repository.AppUserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class AppUserService {
+
+ @Autowired
+ private AppUserRepository appUserRepository;
+
+ public List getAllUsers() {
+ return appUserRepository.findAll();
+ }
+
+ public Optional findAppUserById(String id) {
+ return appUserRepository.findById(id);
+ }
+
+ public Optional createAppUser(AppUser appUser) {
+ return Optional.of(appUserRepository.save(appUser));
+ }
+
+ public Optional updateAppUser(AppUser appUserDetails) {
+ Optional existingUser = findAppUserById(appUserDetails.getId());
+
+ if (existingUser.isPresent()) {
+ AppUser updatedUser = existingUser.get();
+ updatedUser.setName(appUserDetails.getName());
+ updatedUser.setEmail(appUserDetails.getEmail());
+ updatedUser.setPassword(appUserDetails.getPassword());
+ return Optional.of(appUserRepository.save(updatedUser));
+ }
+ return Optional.empty();
+
+ }
+
+ public boolean deleteAppUser(String id) {
+ appUserRepository.deleteById(id);
+ Optional deletedUser = appUserRepository.findById(id);
+ return deletedUser.isEmpty();
+ }
+
+ public Optional findAppUserByEmail(String email) {
+ return appUserRepository.findByEmail(email);
+ }
+
+ public boolean deleteAllAppUsers() {
+ appUserRepository.deleteAll();
+ return getAppUserCount() == 0;
+ }
+
+ public long getAppUserCount() {
+ return appUserRepository.count();
+ }
+
+}
diff --git a/backend/pronunciationAppBack/src/main/resources/application.properties b/backend/pronunciationAppBack/src/main/resources/application.properties
index 83cb16f3e..44860e451 100644
--- a/backend/pronunciationAppBack/src/main/resources/application.properties
+++ b/backend/pronunciationAppBack/src/main/resources/application.properties
@@ -12,9 +12,9 @@ spring.h2.console.enabled=true
# H2 LOCAL DB SERVER
-spring.datasource.url=jdbc:h2:/home/albert/MyProjects/DataBase/pronunciationDB/pronunciationDB.db
-spring.datasource.username=albert
-spring.datasource.password=1234
+spring.datasource.url=jdbc:h2:/home/aguizzo/Databases
+spring.datasource.username=admin
+spring.datasource.password=admin
# DDL OPTIONS: create-drop, create, update, none, validate
spring.jpa.hibernate.ddl-auto=none
\ No newline at end of file
diff --git a/backend/pronunciationAppBack/src/test/resources/application.properties b/backend/pronunciationAppBack/src/test/resources/application.properties
new file mode 100644
index 000000000..b49d63df4
--- /dev/null
+++ b/backend/pronunciationAppBack/src/test/resources/application.properties
@@ -0,0 +1,8 @@
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=
+spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
+
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.show-sql=true
\ No newline at end of file