diff --git a/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionRequest.java b/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionRequest.java index fca54be..e431730 100644 --- a/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionRequest.java @@ -5,8 +5,8 @@ import lombok.Data; @Data public class ViolationNotionRequest { private String token; - private String fileId; - private String message; private String action; + private Long violationId; private Long notionId; + private String message; } diff --git a/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionResponse.java b/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionResponse.java index 2afaca6..eea7e86 100644 --- a/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionResponse.java +++ b/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionResponse.java @@ -1,5 +1,4 @@ package ru.soune.nocopy.dto.violation; -import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Builder; import lombok.Data; import java.time.LocalDateTime; @@ -12,8 +11,7 @@ public class ViolationNotionResponse { private LocalDateTime createdAt; private LocalDateTime updatedAt; private UserInfo user; - @JsonIgnore - private FileInfo file; + private ViolationInfo violation; @Data @Builder @@ -25,8 +23,9 @@ public class ViolationNotionResponse { @Data @Builder - public static class FileInfo { - private String id; - private String originalFileName; + public static class ViolationInfo { + private Long id; + private String url; + private String host; } } diff --git a/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionsListResponse.java b/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionsListResponse.java index 884bb32..eead976 100644 --- a/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionsListResponse.java +++ b/src/main/java/ru/soune/nocopy/dto/violation/ViolationNotionsListResponse.java @@ -8,8 +8,9 @@ import java.util.List; @Data @Builder public class ViolationNotionsListResponse { - private String fileId; - private String fileName; + private Long violationId; + private String url; + private String host; private int totalCount; private List notions; } diff --git a/src/main/java/ru/soune/nocopy/entity/violation/ViolationNotion.java b/src/main/java/ru/soune/nocopy/entity/violation/ViolationNotion.java index aa93cbc..4ea82c0 100644 --- a/src/main/java/ru/soune/nocopy/entity/violation/ViolationNotion.java +++ b/src/main/java/ru/soune/nocopy/entity/violation/ViolationNotion.java @@ -34,6 +34,11 @@ public class ViolationNotion { @JsonIgnore private FileEntity file; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "violation_id", nullable = false) + @JsonIgnore + private Violation violation; + @CreatedDate @Column(name = "created_at", updatable = false, nullable = false) private LocalDateTime createdAt; diff --git a/src/main/java/ru/soune/nocopy/handler/ViolationNotionHandler.java b/src/main/java/ru/soune/nocopy/handler/ViolationNotionHandler.java index c6d1f5d..9c0a8f9 100644 --- a/src/main/java/ru/soune/nocopy/handler/ViolationNotionHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/ViolationNotionHandler.java @@ -61,19 +61,14 @@ public class ViolationNotionHandler implements RequestHandler { switch (action) { case "get_notions": return handleGetNotions(request, notionRequest, userId); - case "get_notion": return handleGetNotion(request, notionRequest, userId); - case "add_notion": return handleAddNotion(request, notionRequest, userId); - case "update_notion": return handleUpdateNotion(request, notionRequest, userId); - case "delete_notion": return handleDeleteNotion(request, notionRequest, userId); - default: return new BaseResponse( request.getMsgId(), @@ -83,21 +78,21 @@ public class ViolationNotionHandler implements RequestHandler { } } catch (IllegalArgumentException e) { - log.error("Validation error in ViolationNotionHandler: {}", e.getMessage()); + log.error("Validation error: {}", e.getMessage()); return new BaseResponse( request.getMsgId(), MessageCode.VALIDATION_ERROR.getCode(), e.getMessage(), null); } catch (SecurityException e) { - log.error("Security error in ViolationNotionHandler: {}", e.getMessage()); + log.error("Security error: {}", e.getMessage()); return new BaseResponse( request.getMsgId(), MessageCode.ACCESS_DENIED.getCode(), e.getMessage(), null); } catch (Exception e) { - log.error("Unexpected error in ViolationNotionHandler", e); + log.error("Unexpected error", e); return new BaseResponse( request.getMsgId(), MessageCode.INTERNAL_ERROR.getCode(), @@ -107,26 +102,25 @@ public class ViolationNotionHandler implements RequestHandler { } private BaseResponse handleGetNotions(BaseRequest request, ViolationNotionRequest notionRequest, Long userId) { - if (notionRequest.getFileId() == null) { + if (notionRequest.getViolationId() == null) { return new BaseResponse( request.getMsgId(), MessageCode.INVALID_JSON_BODY.getCode(), - "FileId is required for get_notions action", + "ViolationId is required for get_notions action", null); } try { - ViolationNotionsListResponse notions = notionService.getNotionsByFileId( - notionRequest.getFileId(), userId); + ViolationNotionsListResponse notions = notionService.getNotionsByViolationId( + notionRequest.getViolationId(), userId); return BaseResponse.builder() .msgId(request.getMsgId()) - .messageCode(MessageCode.SUCCESS.getCode()) .messageBody(notions) .build(); } catch (IllegalArgumentException e) { return new BaseResponse( request.getMsgId(), - MessageCode.FILE_NOT_FOUND.getCode(), + MessageCode.NOTION_NOT_FOUND.getCode(), e.getMessage(), null); } @@ -136,7 +130,7 @@ public class ViolationNotionHandler implements RequestHandler { if (notionRequest.getNotionId() == null) { return new BaseResponse( request.getMsgId(), - MessageCode.NOTION_NOT_FOUND.getCode(), + MessageCode.INVALID_JSON_BODY.getCode(), "NotionId is required for get_notion action", null); } @@ -146,7 +140,6 @@ public class ViolationNotionHandler implements RequestHandler { notionRequest.getNotionId(), userId); return BaseResponse.builder() .msgId(request.getMsgId()) - .messageCode(MessageCode.SUCCESS.getCode()) .messageBody(notion) .build(); } catch (IllegalArgumentException e) { @@ -159,28 +152,27 @@ public class ViolationNotionHandler implements RequestHandler { } private BaseResponse handleAddNotion(BaseRequest request, ViolationNotionRequest notionRequest, Long userId) { - if (notionRequest.getFileId() == null) { + if (notionRequest.getViolationId() == null) { return new BaseResponse( request.getMsgId(), - MessageCode.FILE_NOT_FOUND.getCode(), - "FileId is required for add_notion action", + MessageCode.INVALID_JSON_BODY.getCode(), + "ViolationId is required for add_notion action", null); } if (notionRequest.getMessage() == null || notionRequest.getMessage().trim().isEmpty()) { return new BaseResponse( request.getMsgId(), - MessageCode.MESSAGE_IS_REQUIRED_FOR_NOTION.getCode(), + MessageCode.INVALID_JSON_BODY.getCode(), "Message is required for add_notion action", null); } try { ViolationNotionResponse created = notionService.createNotion( - notionRequest.getFileId(), userId, notionRequest.getMessage()); + notionRequest.getViolationId(), userId, notionRequest.getMessage()); return BaseResponse.builder() .msgId(request.getMsgId()) - .messageCode(MessageCode.SUCCESS.getCode()) .messageBody(created) .build(); } catch (IllegalArgumentException e) { @@ -196,7 +188,7 @@ public class ViolationNotionHandler implements RequestHandler { if (notionRequest.getNotionId() == null) { return new BaseResponse( request.getMsgId(), - MessageCode.NOTION_NOT_FOUND.getCode(), + MessageCode.INVALID_JSON_BODY.getCode(), "NotionId is required for update_notion action", null); } @@ -204,7 +196,7 @@ public class ViolationNotionHandler implements RequestHandler { if (notionRequest.getMessage() == null || notionRequest.getMessage().trim().isEmpty()) { return new BaseResponse( request.getMsgId(), - MessageCode.MESSAGE_IS_REQUIRED_FOR_NOTION.getCode(), + MessageCode.INVALID_JSON_BODY.getCode(), "Message is required for update_notion action", null); } @@ -214,7 +206,6 @@ public class ViolationNotionHandler implements RequestHandler { notionRequest.getNotionId(), userId, notionRequest.getMessage()); return BaseResponse.builder() .msgId(request.getMsgId()) - .messageCode(MessageCode.SUCCESS.getCode()) .messageBody(updated) .build(); } catch (IllegalArgumentException e) { @@ -236,7 +227,7 @@ public class ViolationNotionHandler implements RequestHandler { if (notionRequest.getNotionId() == null) { return new BaseResponse( request.getMsgId(), - MessageCode.NOTION_NOT_FOUND.getCode(), + MessageCode.INVALID_JSON_BODY.getCode(), "NotionId is required for delete_notion action", null); } @@ -250,7 +241,6 @@ public class ViolationNotionHandler implements RequestHandler { .build(); return BaseResponse.builder() .msgId(request.getMsgId()) - .messageCode(MessageCode.SUCCESS.getCode()) .messageBody(deleteResponse) .build(); } catch (IllegalArgumentException e) { @@ -264,7 +254,7 @@ public class ViolationNotionHandler implements RequestHandler { request.getMsgId(), MessageCode.ACCESS_DENIED.getCode(), e.getMessage(), - MessageCode.ACCESS_DENIED.getDescription()); + null); } } } diff --git a/src/main/java/ru/soune/nocopy/repository/ViolationNotionRepository.java b/src/main/java/ru/soune/nocopy/repository/ViolationNotionRepository.java index 129321d..ce6b74b 100644 --- a/src/main/java/ru/soune/nocopy/repository/ViolationNotionRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/ViolationNotionRepository.java @@ -10,15 +10,13 @@ import java.util.List; @Repository public interface ViolationNotionRepository extends JpaRepository { - @Query("SELECT vn FROM ViolationNotion vn " + "JOIN FETCH vn.user " + - "WHERE vn.file.id = :fileId " + + "WHERE vn.violation.id = :violationId " + "ORDER BY vn.createdAt DESC") - List findByFileId(@Param("fileId") String fileId); + List findByViolationId(@Param("violationId") Long violationId); - @Query("SELECT COUNT(vn) FROM ViolationNotion vn WHERE vn.file.id = :fileId") - long countByFileId(@Param("fileId") String fileId); + @Query("SELECT COUNT(vn) FROM ViolationNotion vn WHERE vn.violation.id = :violationId") + long countByViolationId(@Param("violationId") Long violationId); - void deleteByFileId(String fileId); } diff --git a/src/main/java/ru/soune/nocopy/service/violation/ViolationNotionService.java b/src/main/java/ru/soune/nocopy/service/violation/ViolationNotionService.java index d608386..5be8b6a 100644 --- a/src/main/java/ru/soune/nocopy/service/violation/ViolationNotionService.java +++ b/src/main/java/ru/soune/nocopy/service/violation/ViolationNotionService.java @@ -6,13 +6,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.nocopy.dto.violation.ViolationNotionResponse; import ru.soune.nocopy.dto.violation.ViolationNotionsListResponse; -import ru.soune.nocopy.entity.company.Company; -import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.user.User; +import ru.soune.nocopy.entity.violation.Violation; import ru.soune.nocopy.entity.violation.ViolationNotion; -import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.repository.UserRepository; import ru.soune.nocopy.repository.ViolationNotionRepository; +import ru.soune.nocopy.repository.ViolationRepository; import java.util.List; import java.util.stream.Collectors; @@ -23,27 +22,25 @@ import java.util.stream.Collectors; public class ViolationNotionService { private final ViolationNotionRepository notionRepository; - private final UserRepository userRepository; - - private final FileEntityRepository fileRepository; + private final ViolationRepository violationRepository; @Transactional(readOnly = true) - public ViolationNotionsListResponse getNotionsByFileId(String fileId, Long userId) { - FileEntity file = fileRepository.findById(fileId) - .orElseThrow(() -> new IllegalArgumentException("File not found: " + fileId)); - checkPermission(userId, file); + public ViolationNotionsListResponse getNotionsByViolationId(Long violationId, Long userId) { + Violation violation = violationRepository.findById(violationId) + .orElseThrow(() -> new IllegalArgumentException("Violation not found: " + violationId)); - List notions = notionRepository.findByFileId(fileId); - long totalCount = notionRepository.countByFileId(fileId); + List notions = notionRepository.findByViolationId(violationId); + long totalCount = notionRepository.countByViolationId(violationId); List notionResponses = notions.stream() .map(this::mapToResponse) .collect(Collectors.toList()); return ViolationNotionsListResponse.builder() - .fileId(fileId) - .fileName(file.getOriginalFileName()) + .violationId(violationId) + .url(violation.getUrl()) + .host(violation.getHost()) .totalCount((int) totalCount) .notions(notionResponses) .build(); @@ -54,7 +51,7 @@ public class ViolationNotionService { ViolationNotion notion = notionRepository.findById(notionId) .orElseThrow(() -> new IllegalArgumentException("Notion not found: " + notionId)); - if (!notion.getFile().getUserId().equals(userId) && !notion.getUser().getId().equals(userId)) { + if (!notion.getUser().getId().equals(userId)) { throw new SecurityException("User does not have access to this notion"); } @@ -62,33 +59,24 @@ public class ViolationNotionService { } @Transactional - public ViolationNotionResponse createNotion(String fileId, Long userId, String message) { + public ViolationNotionResponse createNotion(Long violationId, Long userId, String message) { User user = userRepository.findById(userId) .orElseThrow(() -> new IllegalArgumentException("User not found: " + userId)); - FileEntity file = fileRepository.findById(fileId) - .orElseThrow(() -> new IllegalArgumentException("File not found: " + fileId)); + Violation violation = violationRepository.findById(violationId) + .orElseThrow(() -> new IllegalArgumentException("Violation not found: " + violationId)); ViolationNotion notion = new ViolationNotion(); notion.setUser(user); - notion.setFile(file); + notion.setViolation(violation); notion.setMessage(message); ViolationNotion saved = notionRepository.save(notion); + log.info("Created notion for violation: {} by user: {}", violationId, userId); return mapToResponse(saved); } - @Transactional - public void deleteNotion(Long notionId, Long userId) { - ViolationNotion notion = notionRepository.findById(notionId) - .orElseThrow(() -> new IllegalArgumentException("Notion not found: " + notionId)); - - checkPermission(userId, notion.getFile()); - - notionRepository.delete(notion); - } - @Transactional public ViolationNotionResponse updateNotion(Long notionId, Long userId, String message) { ViolationNotion notion = notionRepository.findById(notionId) @@ -100,39 +88,40 @@ public class ViolationNotionService { notion.setMessage(message); ViolationNotion updated = notionRepository.save(notion); - log.info("Updated notion with id: {} by user: {}", notionId, userId); + log.info("Updated notion: {} by user: {}", notionId, userId); return mapToResponse(updated); } + @Transactional + public void deleteNotion(Long notionId, Long userId) { + ViolationNotion notion = notionRepository.findById(notionId) + .orElseThrow(() -> new IllegalArgumentException("Notion not found: " + notionId)); + + if (!notion.getUser().getId().equals(userId)) { + throw new SecurityException("Only author can delete this notion"); + } + + notionRepository.delete(notion); + log.info("Deleted notion: {} by user: {}", notionId, userId); + } + private ViolationNotionResponse mapToResponse(ViolationNotion notion) { return ViolationNotionResponse.builder() .id(notion.getId()) .message(notion.getMessage()) .createdAt(notion.getCreatedAt()) + .updatedAt(notion.getUpdatedAt()) .user(ViolationNotionResponse.UserInfo.builder() .id(notion.getUser().getId()) .fullName(notion.getUser().getFullName()) .email(notion.getUser().getEmail()) .build()) + .violation(ViolationNotionResponse.ViolationInfo.builder() + .id(notion.getViolation().getId()) + .url(notion.getViolation().getUrl()) + .host(notion.getViolation().getHost()) + .build()) .build(); } - - private void checkPermission(long userId, FileEntity file) { - User user = userRepository.findById(userId).orElseThrow(() -> - new IllegalArgumentException("User not found: " + userId)); - Company company = user.getCompany(); - - if (company != null) { - List companyUsers = company.getUsers() - .stream() - .map(User::getId) - .toList(); - if (!companyUsers.contains(userId)) { - throw new SecurityException("User does not have access to this file"); - } - } else if (!file.getUserId().equals(userId)) { - throw new SecurityException("User does not have access to this file"); - } - } }