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