diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index 61414c9..2ec385f 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -125,7 +125,8 @@ private String getFullPath(String fileType, String userLogin) { } private String getFileType(MultipartFile file) { - return file.getContentType().split("/")[1]; + String fileName = file.getOriginalFilename(); + return fileName != null ? fileName.substring(fileName.lastIndexOf('.') + 1) : null; } private File convertMultiPartToFile(MultipartFile file) diff --git a/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java b/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java new file mode 100644 index 0000000..35d9acb --- /dev/null +++ b/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java @@ -0,0 +1,28 @@ +package com.provedcode.talent.controller; + +import com.provedcode.talent.model.dto.ProofSkillsDTO; +import com.provedcode.talent.service.TalentSkillsService; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@Slf4j +@Validated +@AllArgsConstructor + +@RestController +@RequestMapping("/api/v4/talents") +public class TalentSkillsController { + TalentSkillsService talentSkillsService; + + @PostMapping("/{talent-id}/proofs/{proof-id}/skills") + void addSkillOnProof(@PathVariable("talent-id") long talentId, + @PathVariable("proof-id") long proofId, + @RequestBody @Valid ProofSkillsDTO skills, + Authentication authentication) { + talentSkillsService.addSkillsOnProof(talentId, proofId, skills, authentication); + } +} diff --git a/src/main/java/com/provedcode/talent/model/dto/ProofSkillsDTO.java b/src/main/java/com/provedcode/talent/model/dto/ProofSkillsDTO.java new file mode 100644 index 0000000..d65e05e --- /dev/null +++ b/src/main/java/com/provedcode/talent/model/dto/ProofSkillsDTO.java @@ -0,0 +1,13 @@ +package com.provedcode.talent.model.dto; + +import jakarta.validation.constraints.NotEmpty; +import lombok.Builder; + +import java.util.List; + +@Builder +public record ProofSkillsDTO( + @NotEmpty + List skills +) { +} diff --git a/src/main/java/com/provedcode/talent/model/entity/Skills.java b/src/main/java/com/provedcode/talent/model/entity/Skills.java index 009d911..2bc6d0f 100644 --- a/src/main/java/com/provedcode/talent/model/entity/Skills.java +++ b/src/main/java/com/provedcode/talent/model/entity/Skills.java @@ -10,7 +10,7 @@ @Getter @Setter @Entity -@Table(name = "skills") +@Table(name = "skill") public class Skills { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/provedcode/talent/model/entity/TalentProof.java b/src/main/java/com/provedcode/talent/model/entity/TalentProof.java index b04ca20..549dbea 100644 --- a/src/main/java/com/provedcode/talent/model/entity/TalentProof.java +++ b/src/main/java/com/provedcode/talent/model/entity/TalentProof.java @@ -44,8 +44,8 @@ public class TalentProof { @OneToMany(fetch = FetchType.EAGER, mappedBy = "proof", cascade = CascadeType.ALL, orphanRemoval = true) private List kudos; @ManyToMany - @JoinTable(name = "talent_skills", + @JoinTable(name = "talent_skill", joinColumns = @JoinColumn(name = "proof_id"), inverseJoinColumns = @JoinColumn(name = "skill_id")) - private Set skillses = new LinkedHashSet<>(); + private Set skills = new LinkedHashSet<>(); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/repo/SkillsRepository.java b/src/main/java/com/provedcode/talent/repo/SkillsRepository.java new file mode 100644 index 0000000..0f17989 --- /dev/null +++ b/src/main/java/com/provedcode/talent/repo/SkillsRepository.java @@ -0,0 +1,7 @@ +package com.provedcode.talent.repo; + +import com.provedcode.talent.model.entity.Skills; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SkillsRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/TalentSkillsService.java b/src/main/java/com/provedcode/talent/service/TalentSkillsService.java new file mode 100644 index 0000000..7fdd351 --- /dev/null +++ b/src/main/java/com/provedcode/talent/service/TalentSkillsService.java @@ -0,0 +1,64 @@ +package com.provedcode.talent.service; + +import com.provedcode.talent.model.ProofStatus; +import com.provedcode.talent.model.dto.ProofSkillsDTO; +import com.provedcode.talent.model.entity.Skills; +import com.provedcode.talent.model.entity.TalentProof; +import com.provedcode.talent.repo.SkillsRepository; +import com.provedcode.talent.repo.TalentProofRepository; +import com.provedcode.talent.repo.TalentRepository; +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.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; + +import static org.springframework.http.HttpStatus.*; + +@Transactional +@Service +@AllArgsConstructor +public class TalentSkillsService { + SkillsRepository skillsRepository; + TalentRepository talentRepository; + UserInfoRepository userInfoRepository; + TalentProofRepository talentProofRepository; + + static BiConsumer isValidUserEditTalent = (talentId, userInfo) -> { + if (!userInfo.getTalent().getId().equals(talentId)) { + throw new ResponseStatusException(CONFLICT, "you can`t change another talent"); + } + }; + + public void addSkillsOnProof(long talentId, long proofId, ProofSkillsDTO skills, Authentication authentication) { + if (!talentRepository.existsById(talentId)) { + throw new ResponseStatusException(NOT_FOUND, "talent with id = %s not found".formatted(talentId)); + } + UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND)); + TalentProof talentProof = talentProofRepository.findById(proofId) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "proof with id = %s not found".formatted(proofId))); + if (!talentProof.getStatus().equals(ProofStatus.DRAFT)) { + throw new ResponseStatusException(CONFLICT, "proof status must be DRAFT"); + } + + isValidUserEditTalent.accept(talentId, userInfo); + if (skills.skills().stream().anyMatch(i -> !skillsRepository.existsById(i))) { + throw new ResponseStatusException(BAD_REQUEST, "no such skill with id"); + } + + Set skillsSet = new HashSet<>(skillsRepository.findAllById(skills.skills())); + + talentProof.getSkills().addAll(skillsSet); + talentProofRepository.save(talentProof); + } + + +}