diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index 64141d0..70a2d6f 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -1,12 +1,23 @@ package com.provedcode.aws.controller; +import com.amazonaws.HttpMethod; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; import com.provedcode.aws.service.FileService; +import com.provedcode.config.AWSProperties; +import com.provedcode.util.annotations.doc.controller.aws.GetAllAWSBucketFilesDevApiDoc; +import com.provedcode.util.annotations.doc.controller.aws.GetFileInfoDevApiDoc; +import com.provedcode.util.annotations.doc.controller.aws.PostSetNewUserImageApiDoc; import lombok.AllArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.net.URL; +import java.time.Instant; +import java.util.Arrays; +import java.util.Date; import java.util.List; @RestController @@ -14,17 +25,42 @@ @RequestMapping("/api/v3/talents") public class AWSS3BucketController { FileService fileService; + AWSProperties awsProperties; + AmazonS3 amazonS3; + @PostSetNewUserImageApiDoc @PreAuthorize("hasRole('TALENT')") @PostMapping("/image/upload") public void setNewUserImage(@RequestParam("file") MultipartFile file, - Authentication authentication) { + Authentication authentication) { fileService.setNewUserImage(file, authentication); } + @GetFileInfoDevApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/files") List getAllFiles() { return fileService.listAllFiles(); } + + @GetAllAWSBucketFilesDevApiDoc + @PreAuthorize("hasRole('TALENT')") + @PostMapping("/aws/test-of-filetype") + String testTypeOfFile(@RequestParam("file") MultipartFile file, + Authentication authentication) { + return Arrays.stream(file.getContentType().split("/")).toList().get(1) + " " + file.getOriginalFilename() + + " " + file.getName() + " " + file.getResource(); + } + + @GetMapping("/aws/test") + URL getURL() { + GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(awsProperties.bucket(), "MykhailoOrdyntsev@gmail.com/image.jpeg") + .withMethod(HttpMethod.GET); + Instant expiration = Instant.now().plusMillis(1000L * 60 * 60 * 24 * 7); + + urlRequest.setExpiration(Date.from(expiration)); + URL url = amazonS3.generatePresignedUrl(urlRequest); + return url; + } + } diff --git a/src/main/java/com/provedcode/aws/service/FileService.java b/src/main/java/com/provedcode/aws/service/FileService.java index 78d722b..369898a 100644 --- a/src/main/java/com/provedcode/aws/service/FileService.java +++ b/src/main/java/com/provedcode/aws/service/FileService.java @@ -8,8 +8,11 @@ public interface FileService { String saveFile(MultipartFile file); + byte[] downloadFile(String filename); + String deleteFile(String filename); + List listAllFiles(); void setNewUserImage(MultipartFile file, Authentication authentication); diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index 679c443..439ee94 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -8,30 +8,34 @@ import com.provedcode.talent.repo.TalentRepository; import com.provedcode.user.model.entity.UserInfo; import com.provedcode.user.repo.UserInfoRepository; +import com.provedcode.util.PhotoService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.server.ResponseStatusException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Arrays; import java.util.List; import static org.apache.http.entity.ContentType.*; -import static org.springframework.http.HttpStatus.NOT_FOUND; -import static org.springframework.http.HttpStatus.NOT_IMPLEMENTED; +import static org.springframework.http.HttpStatus.*; @Service @AllArgsConstructor @Slf4j +@Transactional public class S3Service implements FileService { AWSProperties awsProperties; AmazonS3 s3; UserInfoRepository userInfoRepository; TalentRepository talentRepository; + PhotoService photoService; @Override public String saveFile(MultipartFile file) { @@ -71,29 +75,36 @@ public List listAllFiles() { @Override public void setNewUserImage(MultipartFile file, Authentication authentication) { if (file.isEmpty()) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "file must be not empty, actual file-size: %s".formatted(file.getSize())); + throw new ResponseStatusException(BAD_REQUEST, "file must be not empty, actual file-size: %s".formatted(file.getSize())); } - if (!List.of(IMAGE_JPEG.getMimeType(), IMAGE_PNG.getMimeType(), IMAGE_GIF.getMimeType()).contains(file.getContentType())) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "not supported type: %s".formatted(file.getContentType())); + if (photoService.isFileImage(file)) { + throw new ResponseStatusException(BAD_REQUEST, "not supported type: %s".formatted(file.getContentType())); } UserInfo user = userInfoRepository.findByLogin(authentication.getName()) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "user with login = {%s} not found".formatted(authentication.getName()))); - String fileName = file.getOriginalFilename(); - - String userLogin = authentication.getName(); - String fullPath = "%s/%s".formatted(userLogin, fileName); try { - File f = convertMultiPartToFile(file); + String fileType = file.getContentType().split("/")[1]; + String userLogin = authentication.getName(); + + String fullPath = "%s/%s".formatted(userLogin, "image.%s".formatted(fileType)); + File f = photoService.degradePhoto(convertMultiPartToFile(file)); + + if (user.getTalent().getImageName() != null) + s3.deleteObject(awsProperties.bucket(), user.getTalent().getImageName()); s3.putObject(awsProperties.bucket(), fullPath, f); log.info("image = {}", s3.getUrl(awsProperties.bucket(), fullPath).toString()); + user.getTalent().setImage(s3.getUrl(awsProperties.bucket(), fullPath).toString()); + user.getTalent().setImageName(fullPath); + talentRepository.save(user.getTalent()); - } catch (RuntimeException | IOException e) { - throw new ResponseStatusException(NOT_IMPLEMENTED); + } catch (Exception e) { + throw new ResponseStatusException(SERVICE_UNAVAILABLE, "problems with connection to aws s3"); } + } private File convertMultiPartToFile(MultipartFile file) diff --git a/src/main/java/com/provedcode/config/InitConfig.java b/src/main/java/com/provedcode/config/InitConfig.java index f4d24bb..82aa7cb 100644 --- a/src/main/java/com/provedcode/config/InitConfig.java +++ b/src/main/java/com/provedcode/config/InitConfig.java @@ -1,29 +1,29 @@ -package com.provedcode.config; - -import com.provedcode.user.mapper.UserInfoMapper; -import com.provedcode.user.repo.UserInfoRepository; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.CommandLineRunner; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -@AllArgsConstructor -public class InitConfig implements CommandLineRunner { - UserInfoRepository userInfoRepository; - PasswordEncoder passwordEncoder; - UserInfoMapper userInfoMapper; - - @Override - public void run(String... args) throws Exception { - // TODO: Method to change passwords for already created users from data1.sql - userInfoRepository.saveAll( - userInfoRepository.findAll().stream() - .map(i -> { - i.setPassword(passwordEncoder.encode(i.getPassword())); - return i; - }).toList()); - } -} \ No newline at end of file +//package com.provedcode.config; +// +//import com.provedcode.user.mapper.UserInfoMapper; +//import com.provedcode.user.repo.UserInfoRepository; +//import lombok.AllArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.boot.CommandLineRunner; +//import org.springframework.security.crypto.password.PasswordEncoder; +//import org.springframework.stereotype.Component; +// +//@Slf4j +//@Component +//@AllArgsConstructor +//public class InitConfig implements CommandLineRunner { +// UserInfoRepository userInfoRepository; +// PasswordEncoder passwordEncoder; +// UserInfoMapper userInfoMapper; +// +// @Override +// public void run(String... args) throws Exception { +// // TODO: Method to change passwords for already created users from data1.sql +// userInfoRepository.saveAll( +// userInfoRepository.findAll().stream() +// .map(i -> { +// i.setPassword(passwordEncoder.encode(i.getPassword())); +// return i; +// }).toList()); +// } +//} \ No newline at end of file diff --git a/src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java b/src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java new file mode 100644 index 0000000..a77af66 --- /dev/null +++ b/src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java @@ -0,0 +1,17 @@ +package com.provedcode.handlers; + +import com.provedcode.handlers.dto.ErrorDTO; +import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +@ControllerAdvice +public class AwsS3ExceptionHandler { + @ExceptionHandler(FileSizeLimitExceededException.class) + public ResponseEntity fileSizeLimitExceededExceptionHandler(FileSizeLimitExceededException e) { + return ResponseEntity.status(BAD_REQUEST).body(new ErrorDTO("file size is too large")); + } +} diff --git a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java index cf460c5..7da4cc8 100644 --- a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java +++ b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java @@ -1,24 +1,34 @@ package com.provedcode.handlers; -import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.WebRequest; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.server.ResponseStatusException; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; @ControllerAdvice public class TalentExceptionHandler { - @ExceptionHandler(ResponseStatusException.class) - private ResponseEntity responseStatusExceptionHandler(ResponseStatusException exception) { - return ResponseEntity.status(exception.getStatusCode()).body(exception.getBody()); + public static boolean ignoreSQLException(String sqlState) { + + if (sqlState == null) { + System.out.println("The SQL state is not defined!"); + return false; + } + + // X0Y32: Jar file already exists in schema + if (sqlState.equalsIgnoreCase("X0Y32")) + return true; + + // 42Y55: Table already exists in schema + if (sqlState.equalsIgnoreCase("42Y55")) + return true; + + return false; } @ExceptionHandler({SQLException.class}) @@ -29,10 +39,10 @@ public void printSQLException(SQLException ex) { e.printStackTrace(System.err); System.err.println("SQLState: " + - ((SQLException) e).getSQLState()); + ((SQLException) e).getSQLState()); System.err.println("Error Code: " + - ((SQLException) e).getErrorCode()); + ((SQLException) e).getErrorCode()); System.err.println("Message: " + e.getMessage()); @@ -46,59 +56,51 @@ public void printSQLException(SQLException ex) { } } - public static boolean ignoreSQLException(String sqlState) { - - if (sqlState == null) { - System.out.println("The SQL state is not defined!"); - return false; - } - - // X0Y32: Jar file already exists in schema - if (sqlState.equalsIgnoreCase("X0Y32")) - return true; - - // 42Y55: Table already exists in schema - if (sqlState.equalsIgnoreCase("42Y55")) - return true; - - return false; + @ExceptionHandler(ResponseStatusException.class) + private ResponseEntity responseStatusExceptionHandler(ResponseStatusException exception) { + return ResponseEntity.status(exception.getStatusCode()).body(exception.getBody()); } - @ExceptionHandler({ Exception.class }) - public ResponseEntity handleAll(Exception ex, WebRequest request) { - ApiError apiError = new ApiError( - HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "error occurred"); - return new ResponseEntity( - apiError, new HttpHeaders(), apiError.getStatus()); + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + private ResponseEntity responseStatusExceptionHandler(ConstraintViolationException exception) { + ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, exception.getMessage(), exception.toString()); + return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus()); } +// @ExceptionHandler({ Exception.class }) +// public ResponseEntity handleAll(Exception ex, WebRequest request) { +// ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "error occurred"); +// return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus()); +// } + //MethodArgumentNotValidException – This exception is thrown // when an argument annotated with @Valid failed validation: // @ResponseStatus(HttpStatus.BAD_REQUEST) // @ExceptionHandler(MethodArgumentNotValidException.class) -// public Map handleValidationExceptions( -// MethodArgumentNotValidException ex) { +// public Map handleValidationExceptions(MethodArgumentNotValidException ex) { // Map errors = new HashMap<>(); -// ex.getBindingResult().getAllErrors().forEach((error) -> { -// String fieldName = ((FieldError) error).getField(); -// String errorMessage = error.getDefaultMessage(); -// errors.put(fieldName, errorMessage); -// }); +// ex.getBindingResult().getAllErrors().forEach( +// (error) -> { +// String fieldName = ((FieldError) error).getField(); +// String errorMessage = error.getDefaultMessage(); +// errors.put(fieldName, errorMessage); +// }); // return errors; // } - @ExceptionHandler({ ConstraintViolationException.class }) - public ResponseEntity handleConstraintViolation( - ConstraintViolationException ex, WebRequest request) { - List errors = new ArrayList<>(); - for (ConstraintViolation violation : ex.getConstraintViolations()) { - errors.add(violation.getRootBeanClass().getName() + " " + - violation.getPropertyPath() + ": " + violation.getMessage()); - } - - ApiError apiError = - new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors); - return new ResponseEntity( - apiError, new HttpHeaders(), apiError.getStatus()); - } +// @ExceptionHandler({ ConstraintViolationException.class }) +// public ResponseEntity handleConstraintViolation( +// ConstraintViolationException ex, WebRequest request) { +// List errors = new ArrayList<>(); +// for (ConstraintViolation violation : ex.getConstraintViolations()) { +// errors.add(violation.getRootBeanClass().getName() + " " + +// violation.getPropertyPath() + ": " + violation.getMessage()); +// } +// +// ApiError apiError = +// new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors); +// return new ResponseEntity( +// apiError, new HttpHeaders(), apiError.getStatus()); +// } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/handlers/dto/ErrorDTO.java b/src/main/java/com/provedcode/handlers/dto/ErrorDTO.java new file mode 100644 index 0000000..8269a4c --- /dev/null +++ b/src/main/java/com/provedcode/handlers/dto/ErrorDTO.java @@ -0,0 +1,7 @@ +package com.provedcode.handlers.dto; + +import lombok.Builder; + +@Builder +public record ErrorDTO (String message) { +} diff --git a/src/main/java/com/provedcode/kudos/controller/KudosController.java b/src/main/java/com/provedcode/kudos/controller/KudosController.java index 20f8bce..7f18175 100644 --- a/src/main/java/com/provedcode/kudos/controller/KudosController.java +++ b/src/main/java/com/provedcode/kudos/controller/KudosController.java @@ -1,107 +1,48 @@ package com.provedcode.kudos.controller; +import com.provedcode.kudos.model.request.SetAmountKudos; +import com.provedcode.kudos.model.response.KudosAmount; import com.provedcode.kudos.model.response.KudosAmountWithSponsor; import com.provedcode.kudos.service.KudosService; -import com.provedcode.kudos.model.response.KudosAmount; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.kudos.GetAmountOfKudosApiDoc; +import com.provedcode.util.annotations.doc.controller.kudos.GetKudosForSponsorApiDoc; +import com.provedcode.util.annotations.doc.controller.kudos.PostAddKudosToProofApiDoc; +import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Optional; + @RestController @AllArgsConstructor +@Validated @RequestMapping("/api/v3/") public class KudosController { KudosService kudosService; - @Operation(summary = "Get all available kudos from a sponsor") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = KudosAmount.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to see other sponsor kudos)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @GetKudosForSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @GetMapping("/sponsors/{sponsor-id}/kudos") - KudosAmount getKudosForSponsor(@PathVariable("sponsor-id") long id, Authentication authentication) { - return kudosService.getKudosForSponsor(id, authentication); + KudosAmount getKudosForSponsor(@PathVariable("sponsor-id") long sponsorId, Authentication authentication) { + return kudosService.getKudosForSponsor(sponsorId, authentication); } - @Operation(summary = "As a sponsor I want to estimate talent proof by giving kudos") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if sponsor does not have enough kudos)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) - @PreAuthorize("hasRole('SPONSOR')") - @PostMapping("/proofs/{proof-id}/kudos/{amount}") - void addKudosToProof(@PathVariable("proof-id") long id, - @PathVariable("amount") Long amount, - Authentication authentication) { - kudosService.addKudosToProof(id, amount, authentication); - } - - @Operation(summary = "Amount of “kudos” given by sponsors and who gave the “kudos” on proof") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = KudosAmountWithSponsor.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the talent wants to see)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @GetAmountOfKudosApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/proofs/{proof-id}/kudos") - KudosAmountWithSponsor getProofKudos(@PathVariable("proof-id") long id, Authentication authentication) { - return kudosService.getProofKudos(id, authentication); + KudosAmountWithSponsor getProofKudos(@PathVariable("proof-id") long proofId, Authentication authentication) { + return kudosService.getProofKudos(proofId, authentication); + } + + @PostAddKudosToProofApiDoc + @PreAuthorize("hasRole('SPONSOR')") + @PostMapping("/proofs/{proof-id}/kudos") + void addKudosToProof(@PathVariable("proof-id") long proofId, + @RequestBody @Valid Optional amount, + Authentication authentication) { + kudosService.addKudosToProof(proofId, amount, authentication); } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/kudos/model/entity/Kudos.java b/src/main/java/com/provedcode/kudos/model/entity/Kudos.java index 8cacb21..259c387 100644 --- a/src/main/java/com/provedcode/kudos/model/entity/Kudos.java +++ b/src/main/java/com/provedcode/kudos/model/entity/Kudos.java @@ -17,8 +17,8 @@ public class Kudos { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; - @Column(name = "amount_kudos") - private Long amountKudos; + @Column(name = "amount") + private Long amount; @ManyToOne @JoinColumn(name = "sponsor_id") private Sponsor sponsor; diff --git a/src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java b/src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java new file mode 100644 index 0000000..3d7bbd2 --- /dev/null +++ b/src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java @@ -0,0 +1,9 @@ +package com.provedcode.kudos.model.request; + +import jakarta.validation.constraints.PositiveOrZero; + +public record SetAmountKudos( + @PositiveOrZero + Long amount +) { +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java b/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java index 16b302b..75b80f9 100644 --- a/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java +++ b/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java @@ -8,6 +8,6 @@ @Builder public record KudosAmountWithSponsor( Long allKudosOnProof, - Map kudosFromSponsor + Map kudosFromSponsor ) { } diff --git a/src/main/java/com/provedcode/kudos/repository/KudosRepository.java b/src/main/java/com/provedcode/kudos/repository/KudosRepository.java index 529129e..3b0f629 100644 --- a/src/main/java/com/provedcode/kudos/repository/KudosRepository.java +++ b/src/main/java/com/provedcode/kudos/repository/KudosRepository.java @@ -1,10 +1,10 @@ package com.provedcode.kudos.repository; import com.provedcode.kudos.model.entity.Kudos; -import com.provedcode.talent.model.entity.Talent; -import com.provedcode.talent.model.entity.TalentProof; import org.springframework.data.jpa.repository.JpaRepository; public interface KudosRepository extends JpaRepository { - long countByProof_Id(Long id); + long countByProofId(Long id); + + boolean existsBySponsorIdAndProofId(Long sponsorId, Long proofId); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/kudos/service/KudosService.java b/src/main/java/com/provedcode/kudos/service/KudosService.java index 65dd7bf..f506391 100644 --- a/src/main/java/com/provedcode/kudos/service/KudosService.java +++ b/src/main/java/com/provedcode/kudos/service/KudosService.java @@ -1,6 +1,7 @@ package com.provedcode.kudos.service; import com.provedcode.kudos.model.entity.Kudos; +import com.provedcode.kudos.model.request.SetAmountKudos; import com.provedcode.kudos.model.response.KudosAmount; import com.provedcode.kudos.model.response.KudosAmountWithSponsor; import com.provedcode.kudos.repository.KudosRepository; @@ -8,6 +9,7 @@ import com.provedcode.sponsor.model.dto.SponsorDTO; import com.provedcode.sponsor.model.entity.Sponsor; import com.provedcode.sponsor.repository.SponsorRepository; +import com.provedcode.talent.model.ProofStatus; import com.provedcode.talent.model.entity.Talent; import com.provedcode.talent.model.entity.TalentProof; import com.provedcode.talent.repo.TalentProofRepository; @@ -22,6 +24,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import static org.springframework.http.HttpStatus.*; @@ -37,75 +40,92 @@ public class KudosService { TalentRepository talentRepository; SponsorMapper sponsorMapper; - - public void addKudosToProof(long id, Long amount, Authentication authentication) { - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + public void addKudosToProof(long proofId, Optional setAmountKudos, Authentication authentication) { + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Sponsor with id = %s not found".formatted(id))); + "User with login = %s not found".formatted( + login))); Sponsor sponsor = sponsorRepository.findById(userInfo.getSponsor().getId()).orElseThrow( () -> new ResponseStatusException(NOT_FOUND, - String.format("sponsor with id = %d not found", id))); - TalentProof talentProof = talentProofRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "Proof with id = %s not found".formatted(id))); - if (sponsor.getAmountKudos() < amount) { + "Sponsor with login = %s not found".formatted(login))); + TalentProof talentProof = talentProofRepository.findById(proofId) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Proof with id = %d not found".formatted( + proofId))); + + if (kudosRepository.existsBySponsorIdAndProofId(sponsor.getId(), talentProof.getId())) + throw new ResponseStatusException(FORBIDDEN, "The sponsor has already set kudos to this proof"); + if (!talentProof.getStatus().equals(ProofStatus.PUBLISHED)) + throw new ResponseStatusException(FORBIDDEN, "Proof that was kudosed does not have the PUBLISHED status"); + + long obtainedAmount = setAmountKudos.orElse(new SetAmountKudos(1L)).amount(); + if (sponsor.getAmountKudos() < obtainedAmount) { throw new ResponseStatusException(FORBIDDEN, "The sponsor cannot give more kudos than he has"); } - if (amount <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "amount of kudos must be greater than 0"); - } - sponsor.setAmountKudos(sponsor.getAmountKudos() - amount); + sponsor.setAmountKudos(sponsor.getAmountKudos() - obtainedAmount); kudosRepository.save(Kudos.builder() - .amountKudos(amount) + .amount(obtainedAmount) .proof(talentProof) .sponsor(sponsor) .build()); } @Transactional(readOnly = true) - public KudosAmount getKudosForSponsor(long id, Authentication authentication) { - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + public KudosAmount getKudosForSponsor(long sponsorId, Authentication authentication) { + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Sponsor with id = %s not found".formatted(id))); - Sponsor sponsor = sponsorRepository.findById(userInfo.getSponsor().getId()).orElseThrow( - () -> new ResponseStatusException(NOT_FOUND, - String.format("Sponsor with id = %d not found", id))); - if (sponsor.getId() != userInfo.getSponsor().getId()) { + "User with login = %s not found".formatted( + login))); + if (!userInfo.getSponsor().getId().equals(sponsorId)) { throw new ResponseStatusException(FORBIDDEN, "Only the account owner can view the number of kudos"); } + Sponsor sponsor = sponsorRepository.findById(sponsorId).orElseThrow( + () -> new ResponseStatusException(NOT_FOUND, + String.format("Sponsor with id = %d not found", sponsorId))); return new KudosAmount(sponsor.getAmountKudos()); } @Transactional(readOnly = true) - public KudosAmountWithSponsor getProofKudos(long id, Authentication authentication) { - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + public KudosAmountWithSponsor getProofKudos(long proofId, Authentication authentication) { + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Sponsor with id = %s not found".formatted(id))); + "User with login = %s not found".formatted( + login))); Talent talent = talentRepository.findById(userInfo.getId()) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Talent with id = %s not found".formatted(id))); - TalentProof talentProof = talentProofRepository.findById(id) + "Talent with login = %s not found".formatted( + login))); + TalentProof talentProof = talentProofRepository.findById(proofId) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Proof with id = %s not found".formatted(id))); + "Proof with id = %s not found".formatted( + proofId))); - if (talent.getId() == talentProof.getTalent().getId()) { - Map kudosFromSponsor = talentProof.getKudos().stream() + Long countOfAllKudos = talentProof.getKudos().stream() + .map(Kudos::getAmount) + .reduce(0L, (prev, next) -> prev + next); + + if (talent.getId().equals(talentProof.getTalent().getId())) { + Map kudosFromSponsor = talentProof.getKudos().stream() .collect(Collectors.toMap( - sponsor -> sponsorMapper.toDto(sponsor.getSponsor()), - Kudos::getAmountKudos, - (sponsor, kudos) -> sponsor, + Kudos::getAmount, + proof -> proof.getSponsor() != null + ? sponsorMapper.toDto( + proof.getSponsor()) + : SponsorDTO.builder().build(), + (prev, next) -> next, HashMap::new )); - Long counter = talentProof.getKudos().stream().map(i -> i.getAmountKudos()) - .mapToLong(Long::intValue).sum(); + return KudosAmountWithSponsor.builder() - .allKudosOnProof(counter) + .allKudosOnProof(countOfAllKudos) .kudosFromSponsor(kudosFromSponsor) .build(); } else { - Long counter = talentProof.getKudos().stream().map(i -> i.getAmountKudos()) - .mapToLong(Long::intValue).sum(); return KudosAmountWithSponsor.builder() - .allKudosOnProof(counter) + .allKudosOnProof(countOfAllKudos) .kudosFromSponsor(null).build(); } } diff --git a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java index ea61f10..39c5bad 100644 --- a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java +++ b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java @@ -2,135 +2,56 @@ import com.provedcode.sponsor.mapper.SponsorMapper; import com.provedcode.sponsor.model.dto.SponsorDTO; -import com.provedcode.sponsor.model.dto.SponsorEditDTO; +import com.provedcode.sponsor.model.request.EditSponsor; import com.provedcode.sponsor.service.SponsorService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.sponsor.DeleteSponsorApiDoc; +import com.provedcode.util.annotations.doc.controller.sponsor.GetAllSponsorsApiDoc; +import com.provedcode.util.annotations.doc.controller.sponsor.GetSponsorApiDoc; +import com.provedcode.util.annotations.doc.controller.sponsor.PatchEditSponsorApiDoc; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.PositiveOrZero; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Optional; @RestController @AllArgsConstructor +@Validated @RequestMapping("/api/v3") public class SponsorController { SponsorService sponsorService; SponsorMapper sponsorMapper; - @Operation(summary = "Get all sponsors (SponsorDTO)") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = Page.class, subTypes = {SponsorDTO.class}))), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST (parameter: page or size are incorrect)", - content = @Content) - }) + @GetAllSponsorsApiDoc @GetMapping("/sponsors") - @ResponseStatus(HttpStatus.OK) - Page getSponsors(@RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size) { + Page getSponsors(@RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size) { return sponsorService.getAllSponsors(page, size).map(sponsorMapper::toDto); } - @Operation(summary = "Get sponsor", - description = "As a sponsor I want to have an opportunity to see my own profile with information") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = SponsorDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "501", - description = "NOT_IMPLEMENTED (login is not valid)", - content = @Content) - }) + @GetSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @GetMapping("/sponsors/{id}") SponsorDTO getSponsor(@PathVariable("id") long id, Authentication authentication) { return sponsorMapper.toDto(sponsorService.getSponsorById(id, authentication)); } - @Operation(summary = "Edit information about sponsor", - description = "As a sponsor I want to have an opportunity to edit my personal profile by adding new information, " + - "changing already existing information.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = SponsorDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to change the sponsor)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content), - @ApiResponse( - responseCode = "501", - description = "NOT_IMPLEMENTED (login is not valid)", - content = @Content) - }) + @PatchEditSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @PatchMapping("/sponsors/{id}") SponsorDTO editSponsor(@PathVariable("id") long id, - @RequestBody SponsorEditDTO sponsorEditDTO, + @RequestBody EditSponsor editSponsor, Authentication authentication) { - return sponsorMapper.toDto(sponsorService.editSponsorById(id, sponsorEditDTO, authentication)); + return sponsorMapper.toDto(sponsorService.editSponsorById(id, editSponsor, authentication)); } - @Operation(summary = "Delete sponsor", - description = "As a sponsor I want to have an opportunity to delete personal accounts.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content), - @ApiResponse(responseCode = "404", - description = "NOT FOUND ", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to delete the talent)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST (incorrect id)", - content = @Content), - @ApiResponse( - responseCode = "501", - description = "NOT_IMPLEMENTED (login is not valid)", - content = @Content), - }) + @DeleteSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @DeleteMapping("/sponsors/{id}") void deleteSponsor(@PathVariable("id") long id, Authentication authentication) { diff --git a/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java b/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java index adffbbd..62c3b62 100644 --- a/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java +++ b/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java @@ -1,7 +1,9 @@ package com.provedcode.sponsor.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +@Builder public record SponsorDTO( Long id, @JsonProperty("first_name") diff --git a/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java b/src/main/java/com/provedcode/sponsor/model/request/EditSponsor.java similarity index 81% rename from src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java rename to src/main/java/com/provedcode/sponsor/model/request/EditSponsor.java index 82867a5..55bf951 100644 --- a/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java +++ b/src/main/java/com/provedcode/sponsor/model/request/EditSponsor.java @@ -1,10 +1,10 @@ -package com.provedcode.sponsor.model.dto; +package com.provedcode.sponsor.model.request; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Builder; @Builder -public record SponsorEditDTO( +public record EditSponsor( Long id, @JsonProperty("first_name") String firstName, diff --git a/src/main/java/com/provedcode/sponsor/service/SponsorService.java b/src/main/java/com/provedcode/sponsor/service/SponsorService.java index 933fb69..8beaba7 100644 --- a/src/main/java/com/provedcode/sponsor/service/SponsorService.java +++ b/src/main/java/com/provedcode/sponsor/service/SponsorService.java @@ -2,9 +2,10 @@ import com.provedcode.config.PageProperties; import com.provedcode.kudos.model.entity.Kudos; -import com.provedcode.sponsor.model.dto.SponsorEditDTO; import com.provedcode.sponsor.model.entity.Sponsor; +import com.provedcode.sponsor.model.request.EditSponsor; import com.provedcode.sponsor.repository.SponsorRepository; +import com.provedcode.sponsor.utill.ValidateSponsorForCompliance; import com.provedcode.user.model.entity.UserInfo; import com.provedcode.user.repo.UserInfoRepository; import lombok.AllArgsConstructor; @@ -18,7 +19,8 @@ import java.util.List; import java.util.Optional; -import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.FORBIDDEN; @Service @AllArgsConstructor @@ -27,70 +29,64 @@ public class SponsorService { PageProperties pageProperties; SponsorRepository sponsorRepository; UserInfoRepository userInfoRepository; + ValidateSponsorForCompliance validateSponsorForCompliance; @Transactional(readOnly = true) - public Page getAllSponsors(Optional page, Optional size) { - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - return sponsorRepository.findAll(PageRequest.of(page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()))); + public Page getAllSponsors(Integer page, Integer size) { + return sponsorRepository.findAll(PageRequest.of(page, size)); } @Transactional(readOnly = true) public Sponsor getSponsorById(long id, Authentication authentication) { - Sponsor sponsor = sponsorRepository.findById(id).orElseThrow( - () -> new ResponseStatusException(NOT_FOUND, String.format("sponsor with id = %d not found", id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); - - if (!sponsor.getId().equals(user.getSponsor().getId())) - throw new ResponseStatusException(FORBIDDEN, "The user cannot view someone else's profile"); - return sponsor; + Optional user = userInfoRepository.findByLogin(authentication.getName()); + Optional sponsor = sponsorRepository.findById(id); + validateSponsorForCompliance.userVerification(sponsor, user, id); + return sponsor.get(); } - public Sponsor editSponsorById(long id, SponsorEditDTO sponsorEditDTO, Authentication authentication) { - Sponsor sponsor = sponsorRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "sponsor with id = %s not found".formatted(id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); - if (!sponsor.getId().equals(user.getSponsor().getId())) { - throw new ResponseStatusException(FORBIDDEN, "The user cannot edit someone else's profile"); - } + public Sponsor editSponsorById(long id, EditSponsor editSponsor, Authentication authentication) { + Optional user = userInfoRepository.findByLogin(authentication.getName()); + Optional sponsor = sponsorRepository.findById(id); + validateSponsorForCompliance.userVerification(sponsor, user, id); + checkEditSponsorNull(editSponsor); - if (sponsorEditDTO.firstName() != null) { - sponsor.setFirstName(sponsorEditDTO.firstName()); + Sponsor editableSponsor = sponsor.get(); + if (editSponsor.firstName() != null) { + editableSponsor.setFirstName(editSponsor.firstName()); } - if (sponsorEditDTO.lastName() != null) { - sponsor.setLastName(sponsorEditDTO.lastName()); + if (editSponsor.lastName() != null) { + editableSponsor.setLastName(editSponsor.lastName()); } - if (sponsorEditDTO.image() != null) { - sponsor.setImage(sponsorEditDTO.image()); + if (editSponsor.image() != null) { + editableSponsor.setImage(editSponsor.image()); } - if (sponsorEditDTO.countOfKudos() != null) { - if (sponsorEditDTO.countOfKudos() > 0) { - sponsor.setAmountKudos(sponsor.getAmountKudos() + sponsorEditDTO.countOfKudos()); + if (editSponsor.countOfKudos() != null) { + if (editSponsor.countOfKudos() > 0) { + editableSponsor.setAmountKudos(editableSponsor.getAmountKudos() + editSponsor.countOfKudos()); } else { throw new ResponseStatusException(BAD_REQUEST, "count of kudos must be greater than 0"); } } - return sponsorRepository.save(sponsor); + return sponsorRepository.save(editableSponsor); } public void deleteSponsor(long id, Authentication authentication) { - Sponsor sponsor = sponsorRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "sponsor with id = %s not found".formatted(id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); - if (!sponsor.getId().equals(user.getSponsor().getId())) { - throw new ResponseStatusException(FORBIDDEN, "The user cannot edit someone else's profile"); - } + Optional user = userInfoRepository.findByLogin(authentication.getName()); + Optional sponsor = sponsorRepository.findById(id); + validateSponsorForCompliance.userVerification(sponsor, user, id); + + Sponsor deletableSponsor = sponsor.get(); + List kudosList = deletableSponsor.getKudoses().stream().map(i -> { + i.setSponsor(null); + return i; + }).toList(); + deletableSponsor.setKudoses(kudosList); + userInfoRepository.delete(user.get()); + } - List kudosList = sponsor.getKudoses().stream().map(i -> {i.setSponsor(null); return i;}).toList(); - sponsor.setKudoses(kudosList); - userInfoRepository.delete(user); + private void checkEditSponsorNull(EditSponsor editSponsor) { + if (editSponsor.firstName() == null && editSponsor.lastName() == null && editSponsor.image() == null && + editSponsor.countOfKudos() == null) + throw new ResponseStatusException(FORBIDDEN, "you did not provide information to make changes"); } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java b/src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java new file mode 100644 index 0000000..ce8a6d0 --- /dev/null +++ b/src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java @@ -0,0 +1,24 @@ +package com.provedcode.sponsor.utill; + +import com.provedcode.sponsor.model.entity.Sponsor; +import com.provedcode.user.model.entity.UserInfo; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.Optional; + +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Service +public class ValidateSponsorForCompliance { + + public void userVerification(Optional sponsor, Optional userInfo, long sponsorId) { + if (sponsor.isEmpty() || userInfo.isEmpty()) { + throw new ResponseStatusException(NOT_FOUND, String.format("sponsor with id = %d not found", sponsorId)); + } + if (userInfo.get().getSponsor().getId() != sponsorId) { + throw new ResponseStatusException(FORBIDDEN); + } + } +} diff --git a/src/main/java/com/provedcode/talent/controller/TalentController.java b/src/main/java/com/provedcode/talent/controller/TalentController.java index 5ab3d23..1b9e20d 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentController.java @@ -1,25 +1,28 @@ package com.provedcode.talent.controller; +import com.provedcode.config.PageProperties; import com.provedcode.talent.mapper.TalentMapper; import com.provedcode.talent.model.dto.FullTalentDTO; import com.provedcode.talent.model.dto.ShortTalentDTO; import com.provedcode.talent.model.request.EditTalent; import com.provedcode.talent.service.TalentService; import com.provedcode.user.model.dto.SessionInfoDTO; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.talent.DeleteTalentApiDoc; +import com.provedcode.util.annotations.doc.controller.talent.GetAllTalentsApiDoc; +import com.provedcode.util.annotations.doc.controller.talent.GetTalentApiDoc; +import com.provedcode.util.annotations.doc.controller.talent.PatchEditTalentApiDoc; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.PositiveOrZero; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Optional; @@ -29,47 +32,20 @@ @AllArgsConstructor @RequestMapping("/api/v2") @Tag(name = "talent", description = "Talent API") +@Validated public class TalentController { TalentService talentService; TalentMapper talentMapper; - @Operation(summary = "Get all talents (ShortTalentDTO)", - description = "As a guest I want to see a page with a list of all “talents” cards displayed with a short description about them") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = Page.class, subTypes = {ShortTalentDTO.class}))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST (parameter: page or size are incorrect)", - content = @Content) - }) + @GetAllTalentsApiDoc @GetMapping("/talents") - @ResponseStatus(HttpStatus.OK) - Page getTalents(@RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size) { + @Validated + Page getTalents(@RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size) { return talentService.getTalentsPage(page, size).map(talentMapper::talentToShortTalentDTO); } - @Operation(summary = "Get talent", - description = "As a talent I want to have an opportunity to see the full information about the talent") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = FullTalentDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - }) + @GetTalentApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/talents/{id}") FullTalentDTO getTalent(@PathVariable("id") long id, Authentication authentication) { @@ -78,29 +54,7 @@ FullTalentDTO getTalent(@PathVariable("id") long id, Authentication authenticati return talentMapper.talentToFullTalentDTO(talentService.getTalentById(id)); } - @Operation(summary = "Edit information about talent", - description = "As a talent I want to have an opportunity to edit my personal profile by adding new information, changing already existing information") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = FullTalentDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to change the talent)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @PatchEditTalentApiDoc @PreAuthorize("hasRole('TALENT')") @PatchMapping("/talents/{talent-id}") FullTalentDTO editTalent(@PathVariable("talent-id") long id, @@ -109,28 +63,7 @@ FullTalentDTO editTalent(@PathVariable("talent-id") long id, return talentMapper.talentToFullTalentDTO(talentService.editTalent(id, editTalent, authentication)); } - @Operation(summary = "Delete talent", - description = "As a talent I want to have an opportunity to delete personal accounts") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content), - @ApiResponse(responseCode = "404", - description = "NOT FOUND ", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to delete the talent)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST (incorrect id)", - content = @Content) - }) + @DeleteTalentApiDoc @PreAuthorize("hasRole('TALENT')") @DeleteMapping("/talents/{id}") SessionInfoDTO deleteTalent(@PathVariable("id") long id, Authentication authentication) { diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index 7cff2be..2b5e769 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -6,71 +6,42 @@ import com.provedcode.talent.model.dto.StatusDTO; import com.provedcode.talent.model.request.AddProof; import com.provedcode.talent.service.TalentProofService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.proof.*; import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.PositiveOrZero; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.Optional; - @RestController @AllArgsConstructor @RequestMapping("/api/v2/talents") +@Validated public class TalentProofController { TalentProofService talentProofService; TalentProofMapper talentProofMapper; - @Operation(summary = "Get all proofs", - description = "As a guest I want to see a list of all proofs displayed anonymously") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = Page.class, subTypes = {ProofDTO.class}))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, parameter: page, size or order-by are incorrect", - content = @Content) - }) + @GetAllProofsApiDoc @GetMapping("/proofs") - Page getAllProofs(@RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size, - @RequestParam(value = "order-by") Optional orderBy, + Page getAllProofs(@RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size, + @RequestParam(value = "order-by", defaultValue = "ASC") + @Pattern(regexp = "asc|desc", + flags = {Pattern.Flag.CASE_INSENSITIVE}, + message = "'direction' query param must be equals ASC or DESC") + String orderBy, @RequestParam(value = "sort-by", defaultValue = "created") String... sortBy) { return talentProofService.getAllProofsPage(page, size, orderBy, sortBy).map(talentProofMapper::toProofDTO); } - @Operation(summary = "Get proof") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ProofDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, parameter: page, proof-id or size are incorrect", - content = @Content) - }) + @GetTalentProofByProofIdApiDoc @GetMapping("/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, @@ -78,63 +49,23 @@ ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, return talentProofMapper.toProofDTO(talentProofService.getTalentProof(proofId, authentication)); } - @Operation(summary = "Get all talent proofs", - description = "As a talent I want to see all proofs in personal profile page") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = FullProofDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, wrong @RequestParam like page, size, order-by, sort-by or incorrect talent-id", - content = @Content) - }) + @GetTalentInformationWithProofsApiDoc @GetMapping("/{talent-id}/proofs") @PreAuthorize("hasRole('TALENT')") FullProofDTO getTalentInformationWithProofs(Authentication authentication, @PathVariable("talent-id") Long talentId, - @RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size, - @RequestParam(value = "order-by") Optional orderBy, + @RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size, + @RequestParam(value = "order-by", defaultValue = "ASC") + @Pattern(regexp = "asc|desc", + flags = {Pattern.Flag.CASE_INSENSITIVE}, + message = "'direction' query param must be equals ASC or DESC") + String orderBy, @RequestParam(value = "sort-by", defaultValue = "created") String... sortBy) { return talentProofService.getTalentProofs(talentId, page, size, orderBy, authentication, sortBy); } - @Operation(summary = "Add proof", - description = "As a talent I want to have an opportunity to add my personal proof") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ProofDTO.class)), - headers = {@Header(name = "Location", - description = "The URI of the created proof", - schema = @Schema(type = "string"))} - ), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, (wrong data to add or incorrect talent-id)", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to add the proof)", - content = @Content) - }) + @PostAddProofApiDoc @PostMapping("/{talent-id}/proofs") @PreAuthorize("hasRole('TALENT')") ResponseEntity addProof(@PathVariable(value = "talent-id") long talentId, @@ -143,29 +74,7 @@ ResponseEntity addProof(@PathVariable(value = "talent-id") long talentId, return talentProofService.addProof(addProof, talentId, authentication); } - @Operation(summary = "Edit information about proof", - description = "As a talent I want to have an opportunity to edit my personal proofs") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ProofDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, (wrong data to edit or incorrect talent-id, proof-id)", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to edit the proof)", - content = @Content) - }) + @PatchEditProofApiDoc @PatchMapping("/{talent-id}/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") ProofDTO editProof(Authentication authentication, @@ -176,30 +85,7 @@ ProofDTO editProof(Authentication authentication, talentProofService.editTalentProof(talentId, proofId, proof, authentication)); } - @Operation(summary = "Delete proof", - description = "As a talent I want to have an opportunity to delete my personal proofs") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = StatusDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST, (incorrect talent-id,proof-id)", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to delete the proof or " + - "impossible change proofs status from DRAFT to HIDDEN, it should be PUBLISHED)", - content = @Content) - }) + @DeleteProofApiDoc @DeleteMapping("/{talent-id}/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") StatusDTO deleteProof(@PathVariable(value = "talent-id") long talentId, diff --git a/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java b/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java index 10d8885..b67b317 100644 --- a/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java +++ b/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java @@ -1,7 +1,7 @@ package com.provedcode.talent.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.provedcode.annotations.UrlList; +import com.provedcode.util.annotations.UrlList; import jakarta.validation.constraints.NotEmpty; import lombok.Builder; diff --git a/src/main/java/com/provedcode/talent/model/entity/Talent.java b/src/main/java/com/provedcode/talent/model/entity/Talent.java index 331ad63..9e65c3a 100644 --- a/src/main/java/com/provedcode/talent/model/entity/Talent.java +++ b/src/main/java/com/provedcode/talent/model/entity/Talent.java @@ -35,6 +35,9 @@ public class Talent { @URL @Column(name = "image", length = 300) private String image; + @Column(name = "image_name", length = 100) + private String imageName; + @OneToOne(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private TalentDescription talentDescription; @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) diff --git a/src/main/java/com/provedcode/talent/model/request/EditTalent.java b/src/main/java/com/provedcode/talent/model/request/EditTalent.java index 1014536..cc3dbc1 100644 --- a/src/main/java/com/provedcode/talent/model/request/EditTalent.java +++ b/src/main/java/com/provedcode/talent/model/request/EditTalent.java @@ -1,8 +1,7 @@ package com.provedcode.talent.model.request; import com.fasterxml.jackson.annotation.JsonProperty; -import com.provedcode.annotations.UrlList; -import jakarta.validation.constraints.NotEmpty; +import com.provedcode.util.annotations.UrlList; import lombok.Builder; import java.util.List; diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index e4783b4..3880350 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -29,10 +29,10 @@ import java.net.URI; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.List; import java.util.Optional; -import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; @Service @AllArgsConstructor @@ -46,33 +46,15 @@ public class TalentProofService { ValidateTalentForCompliance validateTalentForCompliance; @Transactional(readOnly = true) - public Page getAllProofsPage(Optional page, Optional size, Optional orderBy, + public Page getAllProofsPage(Integer page, Integer size, String orderBy, String... sortBy) { - PageRequest pageRequest; - String sortDirection = orderBy.orElseGet(Sort.DEFAULT_DIRECTION::name); - - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - if (!sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) && - !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { - throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); - } - - try { - pageRequest = PageRequest.of( - page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()), - Sort.Direction.valueOf(sortDirection.toUpperCase()), - sortBy - ); - return talentProofRepository.findByStatus(ProofStatus.PUBLISHED, pageRequest); - } catch (RuntimeException exception) { - throw new ResponseStatusException(BAD_REQUEST, exception.getMessage()); - } + PageRequest pageRequest = PageRequest.of( + page, + size, + Sort.Direction.valueOf(orderBy.toUpperCase()), + sortBy + ); + return talentProofRepository.findByStatus(ProofStatus.PUBLISHED, pageRequest); } @Transactional(readOnly = true) @@ -83,7 +65,7 @@ public TalentProof getTalentProof(long proofId, Authentication authentication) { () -> new ResponseStatusException(NOT_FOUND, "user with this token not found")); if (talentProof.getTalent().getId().equals(userInfo.getTalent().getId()) || - talentProof.getStatus().equals(ProofStatus.PUBLISHED)) { + talentProof.getStatus().equals(ProofStatus.PUBLISHED)) { return talentProof; } else { throw new ResponseStatusException(FORBIDDEN); @@ -91,62 +73,37 @@ public TalentProof getTalentProof(long proofId, Authentication authentication) { } @Transactional(readOnly = true) - public FullProofDTO getTalentProofs(Long talentId, Optional page, Optional size, - Optional direction, Authentication authentication, - String... sortProperties) { + public FullProofDTO getTalentProofs(Long talentId, Integer page, Integer size, String direction, + Authentication authentication, String... sortProperties) { Talent talent = talentRepository.findById(talentId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %s not found".formatted( - talentId))); - UserInfo userInfo = userInfoRepository.findById(talentId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %s not found".formatted( - talentId))); + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, + "Talent with id = %d not found".formatted( + talentId))); + UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); Page proofs; - PageRequest pageRequest; - String sortDirection = direction.orElseGet(Sort.DEFAULT_DIRECTION::name); - - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - if (!sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) && - !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { - throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); - } - - try { - pageRequest = PageRequest.of( - page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()), - Sort.Direction.valueOf(sortDirection.toUpperCase()), - sortProperties - ); - if (!userInfo.getLogin().equals(authentication.getName())) { - proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); - } else { - proofs = talentProofRepository.findByTalentId(talentId, pageRequest); - } - } catch (RuntimeException exception) { - throw new ResponseStatusException(BAD_REQUEST, exception.getMessage()); + PageRequest pageRequest = PageRequest.of(page, size, Sort.Direction.valueOf(direction.toUpperCase()), + sortProperties + ); + if (!userInfo.getTalent().getId().equals(talentId)) { + proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); + } else { + proofs = talentProofRepository.findByTalentId(talentId, pageRequest); } - return FullProofDTO.builder() - .id(talent.getId()) - .image(talent.getImage()) - .firstName(talent.getFirstName()) - .lastName(talent.getLastName()) - .specialization(talent.getSpecialization()) - .proofs(proofs.map(i -> ProofDTO.builder() - .id(i.getId()) - .created(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") - .format(i.getCreated())) - .link(i.getLink()) - .text(i.getText()) - .status(i.getStatus()).build())) - .build(); + .id(talent.getId()) + .image(talent.getImage()) + .firstName(talent.getFirstName()) + .lastName(talent.getLastName()) + .specialization(talent.getSpecialization()) + .proofs(proofs.map(i -> ProofDTO.builder() + .id(i.getId()) + .created(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") + .format(i.getCreated())) + .link(i.getLink()) + .text(i.getText()) + .status(i.getStatus()).build())) + .build(); } public ResponseEntity addProof(AddProof addProof, long talentId, Authentication authentication) { @@ -156,13 +113,12 @@ public ResponseEntity addProof(AddProof addProof, long talentId, Authenticati validateTalentForCompliance.userVerification(talent, userInfo, talentId); TalentProof talentProof = TalentProof.builder() - .talent(talent.get()) - .link(addProof.link()) - .text(addProof.text()) - .status(ProofStatus.DRAFT) - .created(LocalDateTime.now()) - .build(); - + .talent(talent.get()) + .link(addProof.link()) + .text(addProof.text()) + .status(ProofStatus.DRAFT) + .created(LocalDateTime.now()) + .build(); talentProofRepository.save(talentProof); URI location = ServletUriComponentsBuilder @@ -188,14 +144,11 @@ public TalentProof editTalentProof(long talentId, long proofId, ProofDTO proof, throw new ResponseStatusException(FORBIDDEN, "you cannot change proofs status to DRAFT"); if (oldProofStatus == ProofStatus.DRAFT && proof.status() == ProofStatus.HIDDEN) throw new ResponseStatusException(FORBIDDEN, - "you cannot change proofs status from DRAFT to HIDDEN, it should be PUBLISHED"); + "you cannot change proofs status from DRAFT to HIDDEN, it should be PUBLISHED"); if (proof.link() == null && proof.text() == null) { oldProof.setStatus(proof.status()); } else { - if (oldProofStatus != ProofStatus.DRAFT) - throw new ResponseStatusException(FORBIDDEN, "you cannot edit proofs without DRAFT status"); - oldProof.setLink(proof.link() != null ? proof.link() : oldProof.getLink()) .setText(proof.text() != null ? proof.text() : oldProof.getText()) .setStatus(proof.status()); diff --git a/src/main/java/com/provedcode/talent/service/TalentService.java b/src/main/java/com/provedcode/talent/service/TalentService.java index 93fb180..48a854d 100644 --- a/src/main/java/com/provedcode/talent/service/TalentService.java +++ b/src/main/java/com/provedcode/talent/service/TalentService.java @@ -1,22 +1,151 @@ package com.provedcode.talent.service; -import com.provedcode.talent.model.dto.ShortTalentDTO; -import com.provedcode.talent.model.entity.Talent; +import com.provedcode.config.PageProperties; +import com.provedcode.talent.model.entity.*; import com.provedcode.talent.model.request.EditTalent; +import com.provedcode.talent.repo.TalentProofRepository; +import com.provedcode.talent.repo.TalentRepository; +import com.provedcode.talent.utill.ValidateTalentForCompliance; import com.provedcode.user.model.dto.SessionInfoDTO; -import org.springframework.security.core.Authentication; +import com.provedcode.user.model.entity.UserInfo; +import com.provedcode.user.repo.AuthorityRepository; +import com.provedcode.user.repo.UserInfoRepository; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; -import com.provedcode.talent.model.dto.FullTalentDTO; +import org.springframework.data.domain.PageRequest; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; +import java.util.List; import java.util.Optional; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Service +@Slf4j +@AllArgsConstructor +@Transactional +public class TalentService { + AuthorityRepository authorityRepository; + TalentProofRepository talentProofRepository; + TalentRepository talentRepository; + UserInfoRepository userInfoRepository; + PageProperties pageProperties; + ValidateTalentForCompliance validateTalentForCompliance; + + @Transactional(readOnly = true) + public Page getTalentsPage(Integer page, Integer size) { + return talentRepository.findAll(PageRequest.of(page, size)); + } + + @Transactional(readOnly = true) + public Talent getTalentById(long id) { + return talentRepository.findById(id).orElseThrow(() -> new ResponseStatusException(NOT_FOUND)); + } + + public Talent editTalent(long id, EditTalent editTalent, Authentication authentication) { + Optional talent = talentRepository.findById(id); + Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); + validateTalentForCompliance.userVerification(talent, userInfo, id); + checkEditTalentNull(editTalent); + + Talent editableTalent = talent.get(); + + TalentDescription editableTalentDescription = editableTalent.getTalentDescription(); + List editableTalentTalents = editableTalent.getTalentTalents(); + List editableTalentLinks = editableTalent.getTalentLinks(); + List editableTalentContacts = editableTalent.getTalentContacts(); + List editableTalentAttachedFiles = editableTalent.getTalentAttachedFiles(); + + if (editTalent.firstName() != null) { + editableTalent.setFirstName(editTalent.firstName()); + } + if (editTalent.lastName() != null) { + editableTalent.setLastName(editTalent.lastName()); + } + if (editTalent.specialization() != null) { + editableTalent.setSpecialization(editTalent.specialization()); + } + if (editTalent.image() != null) { + editableTalent.setImage(editTalent.image()); + } + if (editTalent.additionalInfo() != null || editTalent.bio() != null) { + if (editableTalentDescription != null) { + if (editTalent.additionalInfo() != null) + editableTalentDescription.setAdditionalInfo(editTalent.additionalInfo()); + if (editTalent.bio() != null) + editableTalentDescription.setBio(editTalent.bio()); + } else { + editableTalentDescription = TalentDescription.builder() + .additionalInfo(editTalent.additionalInfo()) + .bio(editTalent.bio()) + .talent(editableTalent) + .build(); + } + editableTalent.setTalentDescription(editableTalentDescription); + } + if (editTalent.talents() != null) { + editableTalentTalents.clear(); + editableTalentTalents.addAll(editTalent.talents().stream().map(s -> TalentTalents.builder() + .talent(editableTalent) + .talentName(s) + .build()).toList()); + editableTalent.setTalentTalents(editableTalentTalents); + } + if (editTalent.links() != null) { + editableTalentLinks.clear(); + editableTalentLinks.addAll(editTalent.links().stream().map(s -> TalentLink.builder() + .talent(editableTalent) + .link(s) + .build()).toList()); + editableTalent.setTalentLinks(editableTalentLinks); + } + if (editTalent.contacts() != null) { + editableTalentContacts.clear(); + editableTalentContacts.addAll(editTalent.contacts().stream().map(s -> TalentContact.builder() + .talent(editableTalent) + .contact(s) + .build()).toList()); + editableTalent.setTalentContacts(editableTalentContacts); + } + if (editTalent.attachedFiles() != null) { + editableTalentAttachedFiles.clear(); + editableTalentAttachedFiles.addAll(editTalent.attachedFiles().stream().map(s -> TalentAttachedFile.builder() + .talent(editableTalent) + .attachedFile( + s) + .build()) + .toList()); + editableTalent.setTalentAttachedFiles(editableTalentAttachedFiles); + } + return talentRepository.save(editableTalent); + } + + public SessionInfoDTO deleteTalentById(long id, Authentication authentication) { + Optional talent = talentRepository.findById(id); + Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); + + validateTalentForCompliance.userVerification(talent, userInfo, id); -public interface TalentService { - Page getTalentsPage(Optional page, Optional size); + UserInfo user = userInfo.get(); + Talent entity = talent.get(); - Talent getTalentById(long id); + user.getAuthorities().clear(); + userInfoRepository.delete(user); + talentRepository.delete(entity); - Talent editTalent(long id, EditTalent editTalent, Authentication authentication); + return new SessionInfoDTO("deleted", "null"); + } - SessionInfoDTO deleteTalentById(long id, Authentication authentication); + private void checkEditTalentNull(EditTalent editTalent) { + if (editTalent.firstName() == null && editTalent.lastName() == null && editTalent.image() == null && + editTalent.specialization() == null && editTalent.additionalInfo() == null && editTalent.bio() == null && + editTalent.talents() == null && editTalent.links() == null && editTalent.contacts() == null && + editTalent.attachedFiles() == null) + throw new ResponseStatusException(BAD_REQUEST, "you did not provide information to make changes"); + } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java b/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java deleted file mode 100644 index 29939c7..0000000 --- a/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.provedcode.talent.service.impl; - -import com.provedcode.config.PageProperties; -import com.provedcode.talent.model.entity.*; -import com.provedcode.talent.model.request.EditTalent; -import com.provedcode.talent.repo.TalentProofRepository; -import com.provedcode.talent.repo.TalentRepository; -import com.provedcode.talent.service.TalentService; -import com.provedcode.talent.utill.ValidateTalentForCompliance; -import com.provedcode.user.model.dto.SessionInfoDTO; -import com.provedcode.user.model.entity.UserInfo; -import com.provedcode.user.repo.AuthorityRepository; -import com.provedcode.user.repo.UserInfoRepository; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.server.ResponseStatusException; - -import java.util.List; -import java.util.Optional; - -import static org.springframework.http.HttpStatus.*; - -@Service -@Slf4j -@AllArgsConstructor -@Transactional -public class TalentServiceImpl implements TalentService { - AuthorityRepository authorityRepository; - TalentProofRepository talentProofRepository; - TalentRepository talentRepository; - UserInfoRepository userInfoRepository; - PageProperties pageProperties; - ValidateTalentForCompliance validateTalentForCompliance; - - @Override - @Transactional(readOnly = true) - public Page getTalentsPage(Optional page, Optional size) { - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - return talentRepository.findAll(PageRequest.of(page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()))); - } - - @Override - @Transactional(readOnly = true) - public Talent getTalentById(long id) { - Optional talent = talentRepository.findById(id); - if (talent.isEmpty()) { - throw new ResponseStatusException(NOT_FOUND, String.format("talent with id = %d not found", id)); - } - return talent.get(); - } - - @Override - public Talent editTalent(long id, EditTalent editTalent, Authentication authentication) { - if (editTalent.firstName() == null && editTalent.lastName() == null && editTalent.image() == null && - editTalent.specialization() == null && editTalent.additionalInfo() == null && editTalent.bio() == null && - editTalent.talents() == null && editTalent.links() == null && editTalent.contacts() == null && - editTalent.attachedFiles() == null) - throw new ResponseStatusException(BAD_REQUEST, "you did not provide information to make changes"); - - Optional talent = talentRepository.findById(id); - Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - - validateTalentForCompliance.userVerification(talent, userInfo, id); - - Talent editableTalent = talent.get(); - long idEditableTalent = editableTalent.getId(); - - TalentDescription editableTalentDescription = editableTalent.getTalentDescription(); - List editableTalentTalents = editableTalent.getTalentTalents(); - List editableTalentLinks = editableTalent.getTalentLinks(); - List editableTalentContacts = editableTalent.getTalentContacts(); - List editableTalentAttachedFile = editableTalent.getTalentAttachedFiles(); - - if (editableTalentDescription != null) { - editableTalentDescription - .setAdditionalInfo(editTalent.additionalInfo() != null ? editTalent.additionalInfo() - : editableTalentDescription.getAdditionalInfo()) - .setBio(editTalent.bio() != null ? editTalent.bio() : editableTalentDescription.getBio()); - } else { - editableTalentDescription = TalentDescription.builder() - .additionalInfo(editTalent.additionalInfo()) - .bio(editTalent.bio()) - .talent(editableTalent) - .build(); - } - - if (editTalent.talents() != null) { - editableTalentTalents.clear(); - editableTalentTalents.addAll(editTalent.talents().stream().map(s -> TalentTalents.builder() - .talent(editableTalent) - .talentName(s) - .build()).toList()); - } - - if (editTalent.links() != null) { - editableTalentLinks.clear(); - editableTalentLinks.addAll(editTalent.links().stream().map(l -> TalentLink.builder() - .talent(editableTalent) - .link(l) - .build()).toList()); - } - - if (editTalent.contacts() != null) { - editableTalentContacts.clear(); - editableTalentContacts.addAll(editTalent.contacts().stream().map(s -> TalentContact.builder() - .talent(editableTalent) - .contact(s) - .build()).toList()); - } - - if (editTalent.attachedFiles() != null) { - editableTalentAttachedFile.clear(); - editableTalentAttachedFile.addAll(editTalent.attachedFiles().stream().map(s -> TalentAttachedFile.builder() - .talent(editableTalent) - .attachedFile( - s) - .build()) - .toList()); - } - - editableTalent.setFirstName( - editTalent.firstName() != null ? editTalent.firstName() : editableTalent.getFirstName()) - .setLastName(editTalent.lastName() != null ? editTalent.lastName() : editableTalent.getLastName()) - .setSpecialization(editTalent.specialization() != null ? editTalent.specialization() - : editableTalent.getSpecialization()) - .setImage(editTalent.image() != null ? editTalent.image() : editableTalent.getImage()) - .setTalentDescription(editableTalentDescription) - .setTalentTalents(editableTalentTalents) - .setTalentLinks(editableTalentLinks) - .setTalentContacts(editableTalentContacts) - .setTalentAttachedFiles(editableTalentAttachedFile); - - return talentRepository.save(editableTalent); - } - - @Override - public SessionInfoDTO deleteTalentById(long id, Authentication authentication) { - Optional talent = talentRepository.findById(id); - Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - - validateTalentForCompliance.userVerification(talent, userInfo, id); - - UserInfo user = userInfo.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED)); - Talent entity = talent.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED)); - - user.getAuthorities().clear(); - userInfoRepository.delete(user); - talentRepository.delete(entity); - - return new SessionInfoDTO("deleted", "null"); - } -} \ No newline at end of file diff --git a/src/main/java/com/provedcode/user/controller/AuthenticationController.java b/src/main/java/com/provedcode/user/controller/AuthenticationController.java index 69559c6..b30ee13 100644 --- a/src/main/java/com/provedcode/user/controller/AuthenticationController.java +++ b/src/main/java/com/provedcode/user/controller/AuthenticationController.java @@ -4,16 +4,13 @@ import com.provedcode.user.model.dto.TalentRegistrationDTO; import com.provedcode.user.model.dto.UserInfoDTO; import com.provedcode.user.service.AuthenticationService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.user.PostSponsorRegistrationApiDoc; +import com.provedcode.util.annotations.doc.controller.user.PostTalentRegistrationApiDoc; +import com.provedcode.util.annotations.doc.controller.user.PostUserLoginApiDoc; import jakarta.validation.Valid; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -24,63 +21,20 @@ public class AuthenticationController { AuthenticationService authenticationService; - @Operation(summary = "Login") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = UserInfoDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT_FOUND (Talent not registered)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content) - }) + @PostUserLoginApiDoc @PostMapping("/v2/login") UserInfoDTO login(Authentication authentication) { return authenticationService.login(authentication.getName(), authentication.getAuthorities()); } - @Operation(summary = "Talent Registration") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", - description = "CREATED", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = UserInfoDTO.class))), - @ApiResponse(responseCode = "409", - description = "CONFLICT (user with login already exists)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST", - content = @Content), - }) + @PostTalentRegistrationApiDoc @PostMapping("/v2/talents/register") @ResponseStatus(HttpStatus.CREATED) UserInfoDTO register(@RequestBody @Valid TalentRegistrationDTO user) { return authenticationService.register(user); } - @Operation(summary = "Sponsor Registration") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", - description = "CREATED", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = UserInfoDTO.class))), - @ApiResponse(responseCode = "409", - description = "CONFLICT (user with login already exists)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST", - content = @Content), - }) + @PostSponsorRegistrationApiDoc @PostMapping("/v3/sponsors/register") @ResponseStatus(HttpStatus.CREATED) UserInfoDTO register(@RequestBody @Valid SponsorRegistrationDTO user) { diff --git a/src/main/java/com/provedcode/user/util/UserInfoValidator.java b/src/main/java/com/provedcode/user/util/UserInfoValidator.java new file mode 100644 index 0000000..04dd6c4 --- /dev/null +++ b/src/main/java/com/provedcode/user/util/UserInfoValidator.java @@ -0,0 +1,24 @@ +package com.provedcode.user.util; + +import com.provedcode.user.model.entity.UserInfo; +import com.provedcode.user.repo.UserInfoRepository; +import lombok.AllArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ResponseStatusException; + +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Component +@AllArgsConstructor +public class UserInfoValidator { + UserInfoRepository userInfoRepository; + + public UserInfo findByLoginOrElseThrow(Authentication authentication) { + String login = authentication.getName(); + return userInfoRepository.findByLogin(login) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Sponsor with login = %s not found".formatted( + login))); + } +} diff --git a/src/main/java/com/provedcode/util/PhotoService.java b/src/main/java/com/provedcode/util/PhotoService.java new file mode 100644 index 0000000..a7b74d3 --- /dev/null +++ b/src/main/java/com/provedcode/util/PhotoService.java @@ -0,0 +1,49 @@ +package com.provedcode.util; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static org.apache.http.entity.ContentType.*; + + +@Service +@AllArgsConstructor +public class PhotoService { + public File degradePhoto(File photoFile) throws IOException { + // загружаем изображение из файла + BufferedImage originalImage = ImageIO.read(photoFile); + + // устанавливаем новый размер для изображения + int newWidth = 300; + int newHeight = 300; + + // создаем новое изображение с новым размером + Image resizedImage = originalImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH); + + // создаем новый файл для уменьшенного изображения + String fileName = photoFile.getName(); + String fileType = fileName.substring(fileName.lastIndexOf('.') + 1); + File newFile = new File(photoFile.getParent(), fileName); + + // записываем уменьшенное изображение в новый файл + BufferedImage outputImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); + outputImage.createGraphics().drawImage(resizedImage, 0, 0, null); + ImageIO.write(outputImage, fileType, newFile); + + // возвращаем новый файл + return newFile; + } + + public boolean isFileImage(MultipartFile file) { + return !List.of(IMAGE_JPEG.getMimeType(), IMAGE_PNG.getMimeType(), IMAGE_GIF.getMimeType()) + .contains(file.getContentType()); + } +} diff --git a/src/main/java/com/provedcode/annotations/UrlList.java b/src/main/java/com/provedcode/util/annotations/UrlList.java similarity index 84% rename from src/main/java/com/provedcode/annotations/UrlList.java rename to src/main/java/com/provedcode/util/annotations/UrlList.java index 6a792bc..1530ae9 100644 --- a/src/main/java/com/provedcode/annotations/UrlList.java +++ b/src/main/java/com/provedcode/util/annotations/UrlList.java @@ -1,6 +1,6 @@ -package com.provedcode.annotations; +package com.provedcode.util.annotations; -import com.provedcode.annotations.impl.UrlListValidator; +import com.provedcode.util.annotations.impl.UrlListValidator; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java new file mode 100644 index 0000000..7e45042 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java @@ -0,0 +1,34 @@ +package com.provedcode.util.annotations.doc.controller.aws; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Dev`s endpoint, uses to get names of all files at AWS S3") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS"), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "503", + description = "SERVICE UNAVAILABLE (connection to AWS S3 failed)", + content = @Content + ) +}) +public @interface GetAllAWSBucketFilesDevApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java new file mode 100644 index 0000000..a11c8c0 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java @@ -0,0 +1,29 @@ +package com.provedcode.util.annotations.doc.controller.aws; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Dev`s endpoint, uses to get information about file") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS"), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content) +}) +public @interface GetFileInfoDevApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java new file mode 100644 index 0000000..562e1f1 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.aws; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Set new Talent`s image") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS"), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN", + content = @Content), + @ApiResponse( + responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "503", + description = "SERVICE UNAVAILABLE (connection to AWS S3 failed)", + content = @Content + ) +}) +public @interface PostSetNewUserImageApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java new file mode 100644 index 0000000..9ea3669 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.kudos; + +import com.provedcode.kudos.model.response.KudosAmountWithSponsor; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Amount of “kudos” given by sponsors and who gave the “kudos” on proof") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = KudosAmountWithSponsor.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the talent wants to see)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface GetAmountOfKudosApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java new file mode 100644 index 0000000..2798f09 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.kudos; + + +import com.provedcode.kudos.model.response.KudosAmount; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all available kudos from a sponsor") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = KudosAmount.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to see other sponsor kudos)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface GetKudosForSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java new file mode 100644 index 0000000..77d5ed6 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java @@ -0,0 +1,37 @@ +package com.provedcode.util.annotations.doc.controller.kudos; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "As a sponsor I want to estimate talent proof by giving kudos") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if sponsor does not have enough kudos)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface PostAddKudosToProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java new file mode 100644 index 0000000..5f77466 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java @@ -0,0 +1,43 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.StatusDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Delete proof", + description = "As a talent I want to have an opportunity to delete my personal proofs") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = StatusDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST, (incorrect talent-id,proof-id)", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to delete the proof or " + + "impossible change proofs status from DRAFT to HIDDEN, it should be PUBLISHED)", + content = @Content) +}) +public @interface DeleteProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java new file mode 100644 index 0000000..514600d --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java @@ -0,0 +1,35 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.data.domain.Page; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all proofs", + description = "As a guest I want to see a list of all proofs displayed anonymously") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Page.class, subTypes = {ProofDTO.class}))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, parameter: page, size or order-by are incorrect", + content = @Content) +}) +public @interface GetAllProofsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java new file mode 100644 index 0000000..1d6a200 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java @@ -0,0 +1,38 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.FullProofDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all talent proofs", + description = "As a talent I want to see all proofs in personal profile page") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = FullProofDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, wrong @RequestParam like page, size, order-by, sort-by or incorrect talent-id", + content = @Content) +}) +public @interface GetTalentInformationWithProofsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java new file mode 100644 index 0000000..89ef17d --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java @@ -0,0 +1,37 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get proof") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ProofDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, parameter: page, proof-id or size are incorrect", + content = @Content) +}) +public @interface GetTalentProofByProofIdApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java new file mode 100644 index 0000000..9dca387 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Edit information about proof", + description = "As a talent I want to have an opportunity to edit my personal proofs") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ProofDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, (wrong data to edit or incorrect talent-id, proof-id)", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to edit the proof)", + content = @Content) +}) +public @interface PatchEditProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java new file mode 100644 index 0000000..13fe563 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java @@ -0,0 +1,48 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Add proof", + description = "As a talent I want to have an opportunity to add my personal proof") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ProofDTO.class)), + headers = {@Header(name = "Location", + description = "The URI of the created proof", + schema = @Schema(type = "string"))} + ), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, (wrong data to add or incorrect talent-id)", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to add the proof)", + content = @Content) +}) +public @interface PostAddProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java new file mode 100644 index 0000000..17968c1 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Delete sponsor", + description = "As a sponsor I want to have an opportunity to delete personal accounts.") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content), + @ApiResponse(responseCode = "404", + description = "NOT FOUND ", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to delete the talent)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST (incorrect id)", + content = @Content), + @ApiResponse( + responseCode = "501", + description = "NOT_IMPLEMENTED (login is not valid)", + content = @Content), +}) +public @interface DeleteSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java new file mode 100644 index 0000000..5423fac --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java @@ -0,0 +1,31 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import com.provedcode.sponsor.model.dto.SponsorDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.data.domain.Page; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all sponsors (SponsorDTO)") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Page.class, subTypes = {SponsorDTO.class}))), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST (parameter: page or size are incorrect)", + content = @Content) +}) +public @interface GetAllSponsorsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java new file mode 100644 index 0000000..c194749 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java @@ -0,0 +1,38 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import com.provedcode.sponsor.model.dto.SponsorDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get sponsor", + description = "As a sponsor I want to have an opportunity to see my own profile with information") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = SponsorDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "501", + description = "NOT_IMPLEMENTED (login is not valid)", + content = @Content) +}) +public @interface GetSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java new file mode 100644 index 0000000..dd5b45f --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java @@ -0,0 +1,47 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import com.provedcode.sponsor.model.dto.SponsorDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Edit information about sponsor", + description = "As a sponsor I want to have an opportunity to edit my personal profile by adding new information, " + + "changing already existing information.") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = SponsorDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to change the sponsor)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "501", + description = "NOT_IMPLEMENTED (login is not valid)", + content = @Content) +}) +public @interface PatchEditSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java new file mode 100644 index 0000000..6f0fd00 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java @@ -0,0 +1,38 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Delete talent", + description = "As a talent I want to have an opportunity to delete personal accounts") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content), + @ApiResponse(responseCode = "404", + description = "NOT FOUND ", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to delete the talent)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST (incorrect id)", + content = @Content) +}) +public @interface DeleteTalentApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java new file mode 100644 index 0000000..e5eea66 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java @@ -0,0 +1,35 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import com.provedcode.talent.model.dto.ShortTalentDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.data.domain.Page; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all talents (ShortTalentDTO)", + description = "As a guest I want to see a page with a list of all “talents” cards displayed with a short description about them") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Page.class, subTypes = {ShortTalentDTO.class}))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST (parameter: page or size are incorrect)", + content = @Content) +}) +public @interface GetAllTalentsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java new file mode 100644 index 0000000..50b42e4 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java @@ -0,0 +1,34 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import com.provedcode.talent.model.dto.FullTalentDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get talent", + description = "As a talent I want to have an opportunity to see the full information about the talent") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = FullTalentDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), +}) +public @interface GetTalentApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java new file mode 100644 index 0000000..565688e --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import com.provedcode.talent.model.dto.FullTalentDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Edit information about talent", + description = "As a talent I want to have an opportunity to edit my personal profile by adding new information, changing already existing information") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = FullTalentDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to change the talent)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface PatchEditTalentApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java new file mode 100644 index 0000000..608da55 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java @@ -0,0 +1,33 @@ +package com.provedcode.util.annotations.doc.controller.user; + +import com.provedcode.user.model.dto.UserInfoDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Sponsor Registration") +@ApiResponses(value = { + @ApiResponse(responseCode = "201", + description = "CREATED", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = UserInfoDTO.class))), + @ApiResponse(responseCode = "409", + description = "CONFLICT (user with login already exists)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST", + content = @Content), +}) +public @interface PostSponsorRegistrationApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java new file mode 100644 index 0000000..1ed2517 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java @@ -0,0 +1,33 @@ +package com.provedcode.util.annotations.doc.controller.user; + +import com.provedcode.user.model.dto.UserInfoDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Talent Registration") +@ApiResponses(value = { + @ApiResponse(responseCode = "201", + description = "CREATED", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = UserInfoDTO.class))), + @ApiResponse(responseCode = "409", + description = "CONFLICT (user with login already exists)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST", + content = @Content), +}) +public @interface PostTalentRegistrationApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java new file mode 100644 index 0000000..7948e5c --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java @@ -0,0 +1,37 @@ +package com.provedcode.util.annotations.doc.controller.user; + +import com.provedcode.user.model.dto.UserInfoDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Login") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = UserInfoDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT_FOUND (Talent not registered)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content) +}) +public @interface PostUserLoginApiDoc { +} diff --git a/src/main/java/com/provedcode/annotations/impl/UrlListValidator.java b/src/main/java/com/provedcode/util/annotations/impl/UrlListValidator.java similarity index 88% rename from src/main/java/com/provedcode/annotations/impl/UrlListValidator.java rename to src/main/java/com/provedcode/util/annotations/impl/UrlListValidator.java index ac473d7..b06a1ac 100644 --- a/src/main/java/com/provedcode/annotations/impl/UrlListValidator.java +++ b/src/main/java/com/provedcode/util/annotations/impl/UrlListValidator.java @@ -1,6 +1,6 @@ -package com.provedcode.annotations.impl; +package com.provedcode.util.annotations.impl; -import com.provedcode.annotations.UrlList; +import com.provedcode.util.annotations.UrlList; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 4b8f38f..6bd5814 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,7 +1,5 @@ spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.url=jdbc:h2:mem:./testdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH -spring.jpa.hibernate.ddl-auto=none -spring.sql.init.mode=always #logging.level.web=DEBUG #logging.level.sql=DEBUG \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 810d9a1..b0ad889 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1,5 +1,3 @@ spring.datasource.username=${DB_LOGIN} spring.datasource.password=${DB_PASSWORD} -spring.datasource.url=jdbc:postgresql://${DB_URL} -spring.jpa.hibernate.ddl-auto=none -spring.sql.init.mode=always \ No newline at end of file +spring.datasource.url=jdbc:postgresql://${DB_URL} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index dbc8154..f91aa56 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -11,7 +11,8 @@ spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.datasource.driver-class-name=org.postgresql.Driver spring.h2.console.enabled=true spring.h2.console.path=/h2 -spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.ddl-auto=none +spring.sql.init.mode=always ## ## AWS S3 properties ## @@ -22,14 +23,14 @@ aws-s3.bucket=${BUCKET} ## ## Generate DDL files to create DB ## -spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create-drop -spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql -spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata +#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create-drop +#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql +#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata ## ## Generate DDL files to drop DB ## -spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-target=drop.sql -spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-source=metadata +#spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-target=drop.sql +#spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-source=metadata ## ## DEFAULT PAGE PROPS ## diff --git a/src/main/resources/db/changelog/changeset/V1/data-V1.sql b/src/main/resources/db/changelog/changeset/V1/data-V1.sql new file mode 100644 index 0000000..3b8e80a --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V1/data-V1.sql @@ -0,0 +1,547 @@ +--liquibase formatted sql +--changeset dennis:1 + +insert into authority (id, authority) +values (1, 'TALENT'); +-- -- FOR USER AUTHORITY +-- -- SELECT USER_INFO.ID , LOGIN , PASSWORD, talent_id , AUTHORITY FROM +-- -- USER_INFO +-- -- JOIN user_authorities ON talent_id = USER_INFO.ID +-- -- JOIN AUTHORITY ON AUTHORITY.ID = id + +insert into talent (first_name, last_name, specialization, image) +values ('Serhii', 'Soloviov', 'Java-Developer', 'https://i.pinimg.com/564x/e1/08/49/e10849923a8b2e85a7adf494ebd063e6.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'My cat`s name is Igor'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring boot'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'H2 Database'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here I wrote a program that transforms the written code into music', 'PUBLISHED', '2022-01-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-03-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2021-06-08 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'SerhiiSoloviov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Mykhailo', 'Ordyntsev', 'Java-Developer', 'https://i.pinimg.com/564x/c2/41/31/c24131fe00218467721ba5bacdf0a256.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'I very like anime'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Hibernate'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Boot'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'DRAFT', '2022-08-07 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'HIDDEN', '2022-04-08 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2022-09-02 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Denis', 'Boyko', 'Java-Developer', 'https://i.pinimg.com/564x/2a/0c/08/2a0c08c421e253ca895c3fdc8c9e08d9.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'I`m a student '); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Security'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Core'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DenisBoyko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DenisBoyko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DenisBoyko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'DRAFT', '2022-02-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2021-09-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-04-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'DenisBoyko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Ihor', 'Schurenko', 'Java-Developer', 'https://i.pinimg.com/564x/e1/11/2f/e1112f0b7b63644dc3e313084936dedb.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'I will get married soon'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'REST API'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here I describe my rest api project in java', 'PUBLISHED', '2021-08-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2022-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-05-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Dmytro', 'Uzun', 'Dev-Ops', 'https://i.pinimg.com/564x/1c/af/87/1caf8771ef3edf351f6f2bf6f1c0a276.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'I am instructing a team that is currently writing my own biography for me.', 'He-he-he, hello everyone!'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Docker'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Mentor'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DmytroUzun_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DmytroUzun_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DmytroUzun_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://github.com/ProvedCode', 'My project where I am a team mentor', 'PUBLISHED', '2023-02-08 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2021-03-03 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-09-05 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'DmytroUzun@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Viktor', 'Voloshko', 'Dev-Ops', 'https://i.pinimg.com/564x/a9/51/ab/a951ab682413b89617235e65564c1e5e.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is dev-ops.', 'I like videogames!'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Docker'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'HIDDEN', '2022-02-09 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2020-04-02 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-08-06 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Olha', 'Moiseienko', 'QA', 'https://i.pinimg.com/564x/6d/9d/43/6d9d437baf4db114c047d927307beb84.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Jira'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'HIDDEN', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'My QA Jira project', 'PUBLISHED', '2022-09-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2021-01-09 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Maxim', 'Kiyashko', 'QA', 'https://i.pinimg.com/564x/80/2d/58/802d58b0302985f9486893d499d3634d.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'My custom Arduino OS', 'PUBLISHED', '2023-08-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-01-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'PUBLISHED', '2023-02-09 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Nikolaiev', 'Oleksii', 'QA', 'https://i.pinimg.com/564x/54/d1/0d/54d10dfce64afefabc9fbbce5de82c87.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_third_talents'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Link to my magnum opus:', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksiio@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Artem', 'Lytvynenko', 'QA', 'https://i.pinimg.com/564x/87/63/55/87635509c5fa7ee496ec351fa7e67eaa.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here I wrote tasks for the project', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Daniil', 'Yevtukhov', 'Java-Script-Developer', 'https://i.pinimg.com/564x/fe/b1/37/feb137d88a3d1c8fb28796db6cbc576f.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is JavaScript developer.', 'I have my own Instagram'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'JavaScript Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'React'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'My main project where I am making REACT application', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'HIDDEN', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Ruslan', 'Morozov', 'Java-Script-Developer', 'https://i.pinimg.com/736x/36/ae/0e/36ae0ea4aad656f7c3d3175bc33b8399.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is JavaScript developer.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'JavaScript Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'React'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Node.js'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here my container for styles', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Ihor', 'Kopieichykov', 'Java-Script-Developer', 'https://i.pinimg.com/564x/0d/f0/83/0df083121bac75f64e3d93c7c5682d04.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is JavaScript developer.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'JavaScript Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'React'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Angular'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here is my JavaScript library', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here is my main project in Angular', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/V1/drop-V1.sql b/src/main/resources/db/changelog/changeset/V1/drop-V1.sql new file mode 100644 index 0000000..09b1124 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V1/drop-V1.sql @@ -0,0 +1,14 @@ +--liquibase formatted sql +--changeset mykhailo:2 + +drop table if exists authority cascade; +drop table if exists talent cascade; +drop table if exists talent_attached_file cascade; +drop table if exists talent_contact cascade; +drop table if exists talent_description cascade; +drop table if exists talent_link cascade; +drop table if exists talent_proofs cascade; +drop table if exists talent_talents cascade; +drop table if exists user_authorities cascade; +drop table if exists user_info cascade; +drop table if exists kudos cascade; diff --git a/src/main/resources/db/changelog/changeset/V1/schema-V1.sql b/src/main/resources/db/changelog/changeset/V1/schema-V1.sql new file mode 100644 index 0000000..7eccc32 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V1/schema-V1.sql @@ -0,0 +1,132 @@ +-- liquibase formatted sql +-- changeset dennis:1 + +drop table if exists authority cascade; + +CREATE TABLE authority +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + authority VARCHAR(20) NOT NULL, + CONSTRAINT pk_authority PRIMARY KEY (id) +); + +drop table if exists talent cascade; +CREATE TABLE talent +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + first_name VARCHAR(20), + last_name VARCHAR(20), + specialization VARCHAR(30), + image VARCHAR(300), + CONSTRAINT pk_talent PRIMARY KEY (id) +); + +drop table if exists talent_attached_file cascade; +CREATE TABLE talent_attached_file +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + attached_file VARCHAR(100), + CONSTRAINT pk_talent_attached_file PRIMARY KEY (id) +); + +drop table if exists talent_contact cascade; +CREATE TABLE talent_contact +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + contact VARCHAR(255), + CONSTRAINT pk_talent_contact PRIMARY KEY (id) +); + +drop table if exists talent_description cascade; +CREATE TABLE talent_description +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + bio VARCHAR(255), + addition_info VARCHAR(255), + CONSTRAINT pk_talent_description PRIMARY KEY (id) +); + +drop table if exists talent_link cascade; +CREATE TABLE talent_link +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + link VARCHAR(255), + CONSTRAINT pk_talent_link PRIMARY KEY (id) +); + +drop table if exists talent_proofs cascade; +CREATE TABLE talent_proofs +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + link VARCHAR(100), + text VARCHAR(255), + status VARCHAR(20) NOT NULL, + created TIMESTAMP, + CONSTRAINT pk_talent_proofs PRIMARY KEY (id) +); + +drop table if exists talent_talents cascade; +CREATE TABLE talent_talents +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + talent_name VARCHAR(255), + CONSTRAINT pk_talent_talents PRIMARY KEY (id) +); + +drop table if exists user_authorities cascade; +CREATE TABLE user_authorities +( + authority_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + CONSTRAINT pk_user_authorities PRIMARY KEY (authority_id, user_id) +); + +drop table if exists user_info cascade; +CREATE TABLE user_info +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + login VARCHAR(100) NOT NULL, + password VARCHAR(255) NOT NULL, + CONSTRAINT pk_user_info PRIMARY KEY (id) +); + + +drop table if exists kudos cascade; +CREATE TABLE kudos +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT, + proof_id BIGINT, + CONSTRAINT pk_kudos PRIMARY KEY (id) +); + + +ALTER TABLE talent_attached_file + ADD CONSTRAINT FK_TALENT_ATTACHED_FILE_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_contact + ADD CONSTRAINT FK_TALENT_CONTACT_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_description + ADD CONSTRAINT FK_TALENT_DESCRIPTION_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_link + ADD CONSTRAINT FK_TALENT_LINK_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_proofs + ADD CONSTRAINT FK_TALENT_PROOFS_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_talents + ADD CONSTRAINT FK_TALENT_TALENTS_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE user_info + ADD CONSTRAINT FK_USER_INFO_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE user_authorities + ADD CONSTRAINT fk_useaut_on_authority FOREIGN KEY (authority_id) REFERENCES authority (id); +ALTER TABLE user_authorities + ADD CONSTRAINT fk_useaut_on_user_info FOREIGN KEY (user_id) REFERENCES user_info (id); +ALTER TABLE kudos + ADD CONSTRAINT FK_KUDOS_ON_PROOF FOREIGN KEY (proof_id) REFERENCES talent_proofs (id); +ALTER TABLE kudos + ADD CONSTRAINT FK_KUDOS_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/add-data.sql b/src/main/resources/db/changelog/changeset/V2/data-V2.sql similarity index 96% rename from src/main/resources/db/changelog/changeset/add-data.sql rename to src/main/resources/db/changelog/changeset/V2/data-V2.sql index ce9026b..a5de8d5 100644 --- a/src/main/resources/db/changelog/changeset/add-data.sql +++ b/src/main/resources/db/changelog/changeset/V2/data-V2.sql @@ -1,5 +1,5 @@ --liquibase formatted sql ---changeset dennis:1 +--changeset mykhailo:2 -- -- FOR USER AUTHORITY -- -- SELECT USER_INFO.ID , LOGIN , PASSWORD, talent_id , AUTHORITY FROM @@ -50,7 +50,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2021-06-08 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'SerhiiSoloviov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'SerhiiSoloviov@gmail.com', '$2a$10$EzYxG1DEUek/veK.HzP7B.ynSKE42VbLb4pvFd/v4OwGPNol6buEC'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -93,7 +93,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2022-09-02 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev@gmail.com', '$2a$10$XD60M86n1MDf3AMIixgnnOQq9JVYnnX/umlNFcre0GoC2XgSN/Cfq'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -134,7 +134,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-04-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'DenisBoyko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'DenisBoyko@gmail.com', '$2a$10$tLm27FGH8Sabz57eNkTwm.bSnhmJHINcqt7dNfZI0NfOwD2o/Drse'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -174,7 +174,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-05-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'IhorShchurenko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'IhorShchurenko@gmail.com', '$2a$10$X.d4hR.yRf3cK0Go20aTTukOI9u/Zu2cj5WU0iTcDihyhJ5vUHXkq'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -216,7 +216,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-09-05 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'DmytroUzun@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'DmytroUzun@gmail.com', '$2a$10$J2Yuh10BWHy8XYk.T5rd2uOwk/h5EYG1eVXTAOkTkTdQcc5Qzd9.y'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -256,7 +256,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-08-06 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'ViktorVoloshko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko@gmail.com', '$2a$10$eZX3hBvllxkmH.juZzN72uvFYtphkrxsj14K5BnHHKy4coRV9FMvq'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -298,7 +298,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2021-01-09 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko@gmail.com', '$2a$10$lvvX7DZOwCS/Q7zSo.k.oeayTcKHh8rO1yBBkgIbU4VAC7abPfIa2'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -338,7 +338,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'PUBLISHED', '2023-02-09 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'MaximKiyashko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'MaximKiyashko@gmail.com', '$2a$10$y.g9qHYUOPEkIL8xDc2h1.EdVAG5DYh6OKxf9CRb6s16oHHbr8Bny'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -380,7 +380,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'NikolaievOleksiio@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'NikolaievOleksiio@gmail.com', '$2a$10$nDObO3nDlhWev29qCnzNuOszdg/.ANaMlTirDVWVyLMapYmtSSqza'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -420,7 +420,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko@gmail.com', '$2a$10$.M2fHh9NXbkbnrVHeT.lYeInA8K2khuMUL08iG4NuXs18KIeFBmwG'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -460,7 +460,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov@gmail.com', '$2a$10$cDxp6U/YcObKMwZNgtEB5eZFLWXuwFU0lIUSPIkfPdvq9l8JUqGea'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -502,7 +502,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'RuslanMorozov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'RuslanMorozov@gmail.com', '$2a$10$Hfzp4b6r825g1ZqGzxmal..VNKvo7F4v4YFpBZZ036hmO.7UIWlaK'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -544,7 +544,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'IhorKopieichykov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov@gmail.com', '$2a$10$D4KM50WemOahkFv1fkrPX.MvVESsE0TYWlkh5TypTE/q4nlv8ooyS'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -553,7 +553,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Maksym', 'Khudoliy', 'https://i.pinimg.com/564x/e1/08/49/e10849923a8b2e85a7adf494ebd063e6.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'MaksymKhudoliy@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'MaksymKhudoliy@gmail.com', '$2a$10$pDrAuawhi3ADZpVDDr7C6eAcaQwDr5oQ9GdZUUZHSsqyM/vVkpruy'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); @@ -562,7 +562,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Oleksandr', 'Butrym', 'https://i.pinimg.com/564x/c2/41/31/c24131fe00218467721ba5bacdf0a256.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'OleksandrButrym@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'OleksandrButrym@gmail.com', '$2a$10$R0o8os0t86qyBvg0bO/a6ukuy9VesLapxIkZFLjNupWjvr5Hdjyge'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); @@ -571,7 +571,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Olha', 'Shutylieva', 'https://i.pinimg.com/564x/2a/0c/08/2a0c08c421e253ca895c3fdc8c9e08d9.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'OlhaShutylieva@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'OlhaShutylieva@gmail.com', '$2a$10$UzwVTVR7E2BW.5hA4XWgy.g0XcM.UbIMBoY1cDnYNPQDhCXEa7eGm'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); @@ -580,16 +580,16 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Vladyslav', 'Khrychov', 'https://i.pinimg.com/564x/e1/11/2f/e1112f0b7b63644dc3e313084936dedb.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'VladyslavKhrychov@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'VladyslavKhrychov@gmail.com', '$2a$10$o2va23ZPVVSptyCaSBO/oubpML4xEPZo9Ie0ASt154zNVSKdFrN02'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (100, 1, 1); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (200, 2, 1); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (200, 3, 1); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (300, 4, 1); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/V2/drop-V2.sql b/src/main/resources/db/changelog/changeset/V2/drop-V2.sql new file mode 100644 index 0000000..7b0ee1f --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V2/drop-V2.sql @@ -0,0 +1,15 @@ +--liquibase formatted sql +--changeset mykhailo:2 + +drop table if exists authority cascade; +drop table if exists talent cascade; +drop table if exists talent_attached_file cascade; +drop table if exists talent_contact cascade; +drop table if exists talent_description cascade; +drop table if exists talent_link cascade; +drop table if exists talent_proofs cascade; +drop table if exists talent_talents cascade; +drop table if exists user_authorities cascade; +drop table if exists user_info cascade; +drop table if exists kudos cascade; +drop table if exists sponsor cascade; diff --git a/src/main/resources/db/changelog/changeset/create-tables.sql b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql similarity index 85% rename from src/main/resources/db/changelog/changeset/create-tables.sql rename to src/main/resources/db/changelog/changeset/V2/schema-V2.sql index 18a84f4..19ba151 100644 --- a/src/main/resources/db/changelog/changeset/create-tables.sql +++ b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql @@ -1,7 +1,8 @@ -- liquibase formatted sql --- changeset dennis:1 +-- changeset mykhailo:2 + +-- tables for sprint 3.2 -drop table if exists authority cascade; CREATE TABLE authority ( @@ -9,8 +10,6 @@ CREATE TABLE authority authority VARCHAR(20) NOT NULL, CONSTRAINT pk_authority PRIMARY KEY (id) ); - -drop table if exists talent cascade; CREATE TABLE talent ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -18,10 +17,9 @@ CREATE TABLE talent last_name VARCHAR(20), specialization VARCHAR(30), image VARCHAR(300), + image_name VARCHAR(100), CONSTRAINT pk_talent PRIMARY KEY (id) ); - -drop table if exists talent_attached_file cascade; CREATE TABLE talent_attached_file ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -29,8 +27,6 @@ CREATE TABLE talent_attached_file attached_file VARCHAR(100), CONSTRAINT pk_talent_attached_file PRIMARY KEY (id) ); - -drop table if exists talent_contact cascade; CREATE TABLE talent_contact ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -38,39 +34,31 @@ CREATE TABLE talent_contact contact VARCHAR(255), CONSTRAINT pk_talent_contact PRIMARY KEY (id) ); - -drop table if exists talent_description cascade; CREATE TABLE talent_description ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, talent_id BIGINT NOT NULL, - bio VARCHAR(255), - addition_info VARCHAR(255), + bio VARCHAR(2000), + addition_info VARCHAR(500), CONSTRAINT pk_talent_description PRIMARY KEY (id) ); - -drop table if exists talent_link cascade; CREATE TABLE talent_link ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, talent_id BIGINT NOT NULL, - link VARCHAR(255), + link VARCHAR(500), CONSTRAINT pk_talent_link PRIMARY KEY (id) ); - -drop table if exists talent_proofs cascade; CREATE TABLE talent_proofs ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, talent_id BIGINT NOT NULL, link VARCHAR(100), - text VARCHAR(255), + text VARCHAR(1000), status VARCHAR(20) NOT NULL, created TIMESTAMP, CONSTRAINT pk_talent_proofs PRIMARY KEY (id) ); - -drop table if exists talent_talents cascade; CREATE TABLE talent_talents ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -78,16 +66,12 @@ CREATE TABLE talent_talents talent_name VARCHAR(255), CONSTRAINT pk_talent_talents PRIMARY KEY (id) ); - -drop table if exists user_authorities cascade; CREATE TABLE user_authorities ( authority_id BIGINT NOT NULL, user_id BIGINT NOT NULL, CONSTRAINT pk_user_authorities PRIMARY KEY (authority_id, user_id) ); - -drop table if exists user_info cascade; CREATE TABLE user_info ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -97,18 +81,14 @@ CREATE TABLE user_info password VARCHAR(255) NOT NULL, CONSTRAINT pk_user_info PRIMARY KEY (id) ); - -drop table if exists kudos cascade; CREATE TABLE kudos ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, sponsor_id BIGINT, proof_id BIGINT, - amount_kudos BIGINT, + amount BIGINT, CONSTRAINT pk_kudos PRIMARY KEY (id) ); - -drop table if exists sponsor cascade; CREATE TABLE sponsor ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 41cf880..4a6438c 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -1,6 +1,9 @@ databaseChangeLog: - include: - file: db/changelog/changeset/create-tables.sql - + file: db/changelog/changeset/V1/drop-V1.sql - include: - file: db/changelog/changeset/add-data.sql + file: db/changelog/changeset/V2/drop-V2.sql + - include: + file: db/changelog/changeset/V2/schema-V2.sql + - include: + file: db/changelog/changeset/V2/data-V2.sql \ No newline at end of file