package ru.soune.nocopy.service.file; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.orm.ObjectOptimisticLockingFailureException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.nocopy.dto.file.CheckIncrementResult; import ru.soune.nocopy.dto.file.CheckStatus; import ru.soune.nocopy.entity.user.ProtectedFileCheck; import ru.soune.nocopy.entity.user.User; import ru.soune.nocopy.exception.RetryableException; import ru.soune.nocopy.repository.ProtectedFileCheckRepository; import ru.soune.nocopy.repository.UserRepository; @Service @RequiredArgsConstructor @Slf4j public class CheckCounterService { private final ProtectedFileCheckRepository protectedFileCheckRepository; private final UserRepository userRepository; @Transactional public void incrementCheckCount(Long userId, String mimeType) { try { ProtectedFileCheck check = protectedFileCheckRepository.findByUser_Id(userId).orElse(null); User user = userRepository.findById(userId).orElse(null); if (check == null) { check = initProtectCheckLimit(user,0); } boolean success = check.writeCheck(mimeType); if (success) { protectedFileCheckRepository.save(check); log.info("Check count incremented for user {}: count={}", userId, check.getCountChecked()); CheckIncrementResult.success(check.getCountChecked()); } } catch (ObjectOptimisticLockingFailureException e) { log.warn("Optimistic lock failure for user {}, retrying...", userId); throw new RetryableException("Please try again"); } } @Transactional(readOnly = true) public CheckStatus getCurrentStatus(Long userId) { ProtectedFileCheck check = protectedFileCheckRepository.findByUser_Id(userId) .orElseThrow(NullPointerException::new); return CheckStatus.builder() .userId(userId) .countChecked(check.getCountChecked()) .lastCheckAt(check.getLastCheckAt()) .build(); } public ProtectedFileCheck initProtectCheckLimit(User user, Integer checked) { ProtectedFileCheck check = ProtectedFileCheck.builder() .user(user) .countChecked(checked) .build(); return protectedFileCheckRepository.save(check); } @Transactional public ProtectedFileCheck updateLimit(User user, Integer limit) { ProtectedFileCheck check = ProtectedFileCheck.builder() .user(user) .build(); return protectedFileCheckRepository.save(check); } }