diff --git a/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java b/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java index 926fa69..41388e8 100644 --- a/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java +++ b/src/main/java/ru/soune/nocopy/configuration/HandlerConfig.java @@ -35,7 +35,8 @@ public class HandlerConfig { ViolationNotionHandler violationNotionHandler, ComplaintEntityHandler complaintEntityHandler, UserInfoHandler userInfoHandler, - NotificationHandler notificationHandler + NotificationHandler notificationHandler, + UserVerificationHandler userVerificationHandler ) { Map map = new HashMap<>(); map.put(20001, login); @@ -62,6 +63,7 @@ public class HandlerConfig { map.put(30013, complaintEntityHandler); map.put(30014, userInfoHandler); map.put(30015, notificationHandler); + map.put(30016, userVerificationHandler); return map; } diff --git a/src/main/java/ru/soune/nocopy/controller/ApiController.java b/src/main/java/ru/soune/nocopy/controller/ApiController.java index 9ac7f92..1e21322 100644 --- a/src/main/java/ru/soune/nocopy/controller/ApiController.java +++ b/src/main/java/ru/soune/nocopy/controller/ApiController.java @@ -37,6 +37,7 @@ import ru.soune.nocopy.repository.UserRepository; import ru.soune.nocopy.service.FileSimilarityService; import ru.soune.nocopy.service.file.*; import ru.soune.nocopy.service.register.AuthService; +import ru.soune.nocopy.service.user.moderation.UserVerificationService; import ru.soune.nocopy.util.FileUtil; import java.io.File; @@ -76,6 +77,8 @@ public class ApiController { private final ZipService zipService; + private final UserVerificationService userVerificationService; + @PostMapping("/v{version}/data") public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, @PathVariable("version") int version) { diff --git a/src/main/java/ru/soune/nocopy/dto/MessageCode.java b/src/main/java/ru/soune/nocopy/dto/MessageCode.java index 34e903d..b3e24b1 100644 --- a/src/main/java/ru/soune/nocopy/dto/MessageCode.java +++ b/src/main/java/ru/soune/nocopy/dto/MessageCode.java @@ -59,7 +59,9 @@ public enum MessageCode { USER_NOT_ACTIVE(2, "User not active"), NOTION_NOT_FOUND(4, "Notion not found"), NOT_FOUND(4, "Notion not found"), - MESSAGE_IS_REQUIRED_FOR_NOTION(4, "Message is required for notion"); + MESSAGE_IS_REQUIRED_FOR_NOTION(4, "Message is required for notion"), + USER_VERIFICATIONS_NOT_FOUND(4, "Verifications not found"), + ADMIN_USER_NOT_FOUND(4, "Verifications ,user or admin not found"); private final Integer code; diff --git a/src/main/java/ru/soune/nocopy/dto/user/moderation/UserVerificationRequest.java b/src/main/java/ru/soune/nocopy/dto/user/moderation/UserVerificationRequest.java new file mode 100644 index 0000000..34c8f6b --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/user/moderation/UserVerificationRequest.java @@ -0,0 +1,12 @@ +package ru.soune.nocopy.dto.user.moderation; + +import lombok.Data; + +@Data +public class UserVerificationRequest { + private String message; + private Long userId; + private Boolean verified; + private Long adminId; + private String action; +} diff --git a/src/main/java/ru/soune/nocopy/dto/user/moderation/UserVerificationResponse.java b/src/main/java/ru/soune/nocopy/dto/user/moderation/UserVerificationResponse.java new file mode 100644 index 0000000..7247038 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/dto/user/moderation/UserVerificationResponse.java @@ -0,0 +1,15 @@ +package ru.soune.nocopy.dto.user.moderation; + +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@Builder +public class UserVerificationResponse { + private Long userVerificationId; + private Long userId; + private LocalDateTime updateTime; + private String moderationStatus; +} diff --git a/src/main/java/ru/soune/nocopy/entity/user/ModerationStatus.java b/src/main/java/ru/soune/nocopy/entity/user/ModerationStatus.java new file mode 100644 index 0000000..a081ed9 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/entity/user/ModerationStatus.java @@ -0,0 +1,15 @@ +package ru.soune.nocopy.entity.user; + +import lombok.Getter; + +@Getter +public enum ModerationStatus { + NOT_VERIFIED("not_verified") , VERIFICATION_IN_PROGRESS("verification_in_progress"), + VERIFIED("verified"), VERIFICATION_FAILED("verification_failed"); + + private final String name; + + private ModerationStatus(String name) { + this.name = name; + } +} diff --git a/src/main/java/ru/soune/nocopy/entity/user/User.java b/src/main/java/ru/soune/nocopy/entity/user/User.java index 0c58638..63404dc 100644 --- a/src/main/java/ru/soune/nocopy/entity/user/User.java +++ b/src/main/java/ru/soune/nocopy/entity/user/User.java @@ -106,6 +106,9 @@ public class User { @ToString.Exclude private UserNotActive userNotActive; + @Column(name = "verification_status") + private ModerationStatus verificationStatus = ModerationStatus.NOT_VERIFIED; + public TariffInfo getActiveTariffInfo() { if (company != null && company.getTariffInfo() != null) { return company.getTariffInfo(); diff --git a/src/main/java/ru/soune/nocopy/entity/user/moderation/UserVerification.java b/src/main/java/ru/soune/nocopy/entity/user/moderation/UserVerification.java new file mode 100644 index 0000000..71b1d1e --- /dev/null +++ b/src/main/java/ru/soune/nocopy/entity/user/moderation/UserVerification.java @@ -0,0 +1,44 @@ +package ru.soune.nocopy.entity.user.moderation; + +import jakarta.persistence.*; +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import ru.soune.nocopy.entity.user.ModerationStatus; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "user_verification") +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Getter +@Setter +public class UserVerification { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "user_id", unique = true, nullable = false) + private Long userId; + + @CreatedDate + @Column(name = "created_at", updatable = false, nullable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @Column(name = "message") + private String message; + + @Column(name = "admin_id") + private Long adminId; + + @Enumerated(EnumType.STRING) + @Column(name = "status") + private ModerationStatus moderationStatus; +} diff --git a/src/main/java/ru/soune/nocopy/handler/UserVerificationHandler.java b/src/main/java/ru/soune/nocopy/handler/UserVerificationHandler.java new file mode 100644 index 0000000..d635bd1 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/handler/UserVerificationHandler.java @@ -0,0 +1,98 @@ +package ru.soune.nocopy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.soune.nocopy.dto.BaseRequest; +import ru.soune.nocopy.dto.BaseResponse; +import ru.soune.nocopy.dto.MessageCode; +import ru.soune.nocopy.dto.file.ActionResponse; +import ru.soune.nocopy.dto.user.moderation.UserVerificationRequest; +import ru.soune.nocopy.dto.user.moderation.UserVerificationResponse; +import ru.soune.nocopy.entity.user.moderation.UserVerification; +import ru.soune.nocopy.service.user.moderation.UserVerificationService; + +import java.util.Arrays; +import java.util.List; + +@Component +@RequiredArgsConstructor +@Slf4j +public class UserVerificationHandler implements RequestHandler { + + private final UserVerificationService userVerificationService; + + private final ObjectMapper objectMapper; + + @Override + public BaseResponse handle(BaseRequest request) throws Exception { + UserVerificationRequest userVerificationRequest = objectMapper.convertValue(request.getMessageBody(), + UserVerificationRequest.class); + String action = userVerificationRequest.getAction(); + + switch (action) { + case "get_all_verifications": + return handleVerifications(request, userVerificationRequest); + case "verified": + return handleVerified(request, userVerificationRequest); + default: + ActionResponse response = ActionResponse.builder() + .action(action) + .availableActions(Arrays.asList( + "get_all_verifications", "verified")) + .build(); + return new BaseResponse(request.getMsgId(), + MessageCode.INVALID_ACTION.getCode(), + "Invalid action: " + action, + response); + } + } + + private BaseResponse handleVerifications(BaseRequest request, UserVerificationRequest userVerificationRequest) throws Exception { + List verifications = userVerificationService.verifications(); + + if (verifications.isEmpty()) { + return new BaseResponse(request.getMsgId(), MessageCode.USER_VERIFICATIONS_NOT_FOUND.getCode(), + MessageCode.USER_VERIFICATIONS_NOT_FOUND.getDescription(), null); + } + + List verificationResponses = verifications.stream().map(this::convertDto).toList(); + + return BaseResponse.builder() + .msgId(request.getMsgId()) + .messageBody(verificationResponses) + .build(); + } + + private BaseResponse handleVerified(BaseRequest request, UserVerificationRequest userVerificationRequest) throws Exception { + UserVerification userVerification = userVerificationService.verifyUser(userVerificationRequest.getUserId(), userVerificationRequest.getMessage(), + userVerificationRequest.getAdminId(), userVerificationRequest.getVerified()); + + if (userVerification == null) { + return new BaseResponse(request.getMsgId(), + MessageCode.ADMIN_USER_NOT_FOUND.getCode(), + MessageCode.ADMIN_USER_NOT_FOUND.getDescription(), + null); + } + + return BaseResponse.builder() + .msgId(request.getMsgId()) + .messageBody(UserVerificationResponse.builder() + .userVerificationId(userVerification.getId()) + .moderationStatus(userVerification.getModerationStatus().toString()) + .userId(userVerification.getUserId())) + .build(); + } + + + private UserVerificationResponse convertDto(UserVerification userVerification) { + return UserVerificationResponse.builder() + .userVerificationId(userVerification.getId()) + .userId(userVerification.getUserId()) + .moderationStatus(userVerification.getModerationStatus().name()) + .updateTime(userVerification.getUpdatedAt()) + .build(); + + } +} diff --git a/src/main/java/ru/soune/nocopy/repository/UserVerificationRepository.java b/src/main/java/ru/soune/nocopy/repository/UserVerificationRepository.java new file mode 100644 index 0000000..b491506 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/repository/UserVerificationRepository.java @@ -0,0 +1,12 @@ +package ru.soune.nocopy.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.soune.nocopy.entity.user.ModerationStatus; +import ru.soune.nocopy.entity.user.moderation.UserVerification; + +import java.util.List; + +public interface UserVerificationRepository extends JpaRepository { + List findByUserId(Long userId); + ListfindByUserIdAndModerationStatus(Long userId, ModerationStatus moderationStatus); +} diff --git a/src/main/java/ru/soune/nocopy/service/file/moderation/ModerationFileService.java b/src/main/java/ru/soune/nocopy/service/file/moderation/ModerationFileService.java index 57e462c..6a859a0 100644 --- a/src/main/java/ru/soune/nocopy/service/file/moderation/ModerationFileService.java +++ b/src/main/java/ru/soune/nocopy/service/file/moderation/ModerationFileService.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import ru.soune.nocopy.entity.file.moderation.ModerationPassportFile; import ru.soune.nocopy.repository.ModerationFileRepository; +import ru.soune.nocopy.service.user.moderation.UserVerificationService; import java.util.List; import java.util.Map; @@ -14,6 +15,8 @@ public class ModerationFileService { private final ModerationFileRepository moderationFileRepository; + private final UserVerificationService userVerificationService; + public void addFiles(Long userId, Map files) { List moderationFileRepositoryByStatus = moderationFileRepository.findByStatus(ModerationFileStatus.ACTIVE.getName()); @@ -33,6 +36,8 @@ public class ModerationFileService { moderationFileRepository.save(moderationFile); } + + userVerificationService.initUserVerification(userId); } public List getActiveFiles() { diff --git a/src/main/java/ru/soune/nocopy/service/user/moderation/UserVerificationService.java b/src/main/java/ru/soune/nocopy/service/user/moderation/UserVerificationService.java new file mode 100644 index 0000000..342ae80 --- /dev/null +++ b/src/main/java/ru/soune/nocopy/service/user/moderation/UserVerificationService.java @@ -0,0 +1,66 @@ +package ru.soune.nocopy.service.user.moderation; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.soune.nocopy.entity.user.ModerationStatus; +import ru.soune.nocopy.entity.user.User; +import ru.soune.nocopy.entity.user.moderation.UserVerification; +import ru.soune.nocopy.repository.UserRepository; +import ru.soune.nocopy.repository.UserVerificationRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class UserVerificationService { + + private final UserRepository userRepository; + + private final UserVerificationRepository userVerificationRepository; + + public void initUserVerification(Long userId) { + User user = userRepository.findById(userId).orElse(null); + + if (user == null) return; + + UserVerification userVerification = UserVerification.builder() + .moderationStatus(ModerationStatus.VERIFICATION_IN_PROGRESS) + .build(); + + userVerificationRepository.save(userVerification); + + user.setVerificationStatus(ModerationStatus.VERIFICATION_IN_PROGRESS); + + userRepository.save(user); + } + + public UserVerification verifyUser(Long userId, String message, Long adminId, boolean verified) { + User user = userRepository.findById(userId).orElse(null); + + if (user == null) return null; + + UserVerification userVerification = userVerificationRepository.findById(userId).orElse(null); + + if (userVerification == null) return null; + + ModerationStatus moderationStatus = verified ? ModerationStatus.VERIFIED: ModerationStatus.VERIFICATION_FAILED; + + userVerification.setModerationStatus(moderationStatus); + + if (message != null) userVerification.setMessage(message); + + userVerification.setAdminId(adminId); + + UserVerification save = userVerificationRepository.save(userVerification); + + user.setVerificationStatus(moderationStatus); + + userRepository.save(user); + + return save; + } + + public List verifications() { + return userVerificationRepository.findAll(); + } +}