From 7fab5dbbf1a417c222b468694976c04c67cd567e Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:13:35 +0300 Subject: [PATCH 01/15] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=80=D0=B5=D0=BA=D0=B2=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main-service/pom.xml | 12 + .../event/service/EventServiceImpl.java | 2 +- .../exception/ConflictException.java | 7 + .../handler/GlobalExceptionHandler.java | 13 + ...cipationRequestEventPrivateController.java | 44 ++++ ...ParticipationRequestPrivateController.java | 39 +++ .../mapper/ParticipationRequestMapper.java | 29 +++ .../request/model/EventRequestStatus.java | 5 +- .../ParticipationRequestRepository.java | 23 ++ .../service/ParticipationRequestService.java | 20 ++ .../ParticipationRequestServiceImpl.java | 227 ++++++++++++++++++ main-service/src/main/resources/schema.sql | 17 +- .../ParticipationRequestBatchUpdateIT.java | 136 +++++++++++ .../ParticipationRequestServiceIT.java | 123 ++++++++++ .../src/test/resources/application-test.yaml | 26 ++ .../{client => request}/StatsClient.java | 2 +- .../StatsClientConfig.java | 2 +- .../{client => request}/StatsClientImpl.java | 2 +- .../{client => request}/StatsClientTest.java | 2 +- 19 files changed, 716 insertions(+), 15 deletions(-) create mode 100644 main-service/src/main/java/ru/practicum/exception/ConflictException.java create mode 100644 main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java create mode 100644 main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java create mode 100644 main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java create mode 100644 main-service/src/main/java/ru/practicum/request/repository/ParticipationRequestRepository.java create mode 100644 main-service/src/main/java/ru/practicum/request/service/ParticipationRequestService.java create mode 100644 main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java create mode 100644 main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java create mode 100644 main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java create mode 100644 main-service/src/test/resources/application-test.yaml rename stat/stat-client/src/main/java/ru/practicum/{client => request}/StatsClient.java (93%) rename stat/stat-client/src/main/java/ru/practicum/{client => request}/StatsClientConfig.java (95%) rename stat/stat-client/src/main/java/ru/practicum/{client => request}/StatsClientImpl.java (98%) rename stat/stat-client/src/test/java/ru/practicum/{client => request}/StatsClientTest.java (99%) diff --git a/main-service/pom.xml b/main-service/pom.xml index 6e7b885..c7e62ef 100644 --- a/main-service/pom.xml +++ b/main-service/pom.xml @@ -62,6 +62,18 @@ querydsl-jpa jakarta + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.h2database + h2 + runtime + diff --git a/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java b/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java index f5a456e..de6a626 100644 --- a/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java @@ -9,7 +9,7 @@ import ru.practicum.category.model.Category; import ru.practicum.category.repository.CategoryRepository; -import ru.practicum.client.StatsClient; +import ru.practicum.request.StatsClient; import ru.practicum.dto.ViewStatsDto; import ru.practicum.event.controller.EventSortBy; import ru.practicum.event.dto.*; diff --git a/main-service/src/main/java/ru/practicum/exception/ConflictException.java b/main-service/src/main/java/ru/practicum/exception/ConflictException.java new file mode 100644 index 0000000..b842f0c --- /dev/null +++ b/main-service/src/main/java/ru/practicum/exception/ConflictException.java @@ -0,0 +1,7 @@ +package ru.practicum.exception; + +public class ConflictException extends RuntimeException { + public ConflictException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index bf746af..304a1e1 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -14,6 +14,7 @@ import ru.practicum.exception.ValidationException; import ru.practicum.exception.dto.ApiError; import ru.practicum.exception.dto.Violation; +import ru.practicum.exception.ConflictException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; @@ -142,4 +143,16 @@ public ApiError handleValidationException(ValidationException e) { HttpStatus.BAD_REQUEST.toString(), LocalDateTime.now()); } + + @ResponseStatus(HttpStatus.CONFLICT) + @ExceptionHandler(ConflictException.class) + public ApiError handleConflictException(ConflictException e) { + log.warn(e.getMessage(), e); + return new ApiError( + null, + e.getMessage(), + "Conflict", + HttpStatus.CONFLICT.toString(), + LocalDateTime.now()); + } } diff --git a/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java new file mode 100644 index 0000000..7ab6cb6 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java @@ -0,0 +1,44 @@ +package ru.practicum.request.controller; + +import java.util.List; + +import jakarta.validation.Valid; + +import ru.practicum.request.dto.EventRequestStatusUpdateRequest; +import ru.practicum.request.dto.EventRequestStatusUpdateResult; +import ru.practicum.request.dto.ParticipationRequestDto; +import ru.practicum.request.service.ParticipationRequestService; + +import org.springframework.web.bind.annotation.*; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/users/{userId}/events/{eventId}/requests") +public class ParticipationRequestEventPrivateController { + private final ParticipationRequestService requestService; + + @GetMapping + public List getEventRequests( + @PathVariable Long userId, @PathVariable Long eventId) { + log.info("Get requests for eventId={} by initiator userId={}", eventId, userId); + return requestService.getEventRequestsByInitiator(userId, eventId); + } + + @PatchMapping + public EventRequestStatusUpdateResult updateRequestsStatus( + @PathVariable Long userId, + @PathVariable Long eventId, + @Valid @RequestBody EventRequestStatusUpdateRequest updateRequest) { + log.info( + "Update requests status for eventId={} by userId={}, requestIds={}, status={}", + eventId, + userId, + updateRequest.requestIds(), + updateRequest.status()); + return requestService.updateEventRequestsStatus(userId, eventId, updateRequest); + } +} diff --git a/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java new file mode 100644 index 0000000..d9863d0 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java @@ -0,0 +1,39 @@ +package ru.practicum.request.controller; + +import java.util.List; + +import ru.practicum.request.dto.ParticipationRequestDto; +import ru.practicum.request.service.ParticipationRequestService; + +import org.springframework.web.bind.annotation.*; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/users/{userId}/requests") +public class ParticipationRequestPrivateController { + private final ParticipationRequestService requestService; + + @PostMapping + public ParticipationRequestDto createRequest( + @PathVariable Long userId, @RequestParam Long eventId) { + log.info("Create participation request userId={}, eventId={}", userId, eventId); + return requestService.createRequest(userId, eventId); + } + + @GetMapping + public List getUserRequests(@PathVariable Long userId) { + log.info("Get participation requests by userId={}", userId); + return requestService.getUserRequests(userId); + } + + @PatchMapping("/{requestId}/cancel") + public ParticipationRequestDto cancelRequest( + @PathVariable Long userId, @PathVariable Long requestId) { + log.info("Cancel participation request userId={}, requestId={}", userId, requestId); + return requestService.cancelRequest(userId, requestId); + } +} diff --git a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java new file mode 100644 index 0000000..5762ced --- /dev/null +++ b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java @@ -0,0 +1,29 @@ +package ru.practicum.request.mapper; + +import java.util.List; + +import ru.practicum.request.dto.ParticipationRequestDto; +import ru.practicum.request.model.ParticipationRequest; + +public final class ParticipationRequestMapper { + private ParticipationRequestMapper() {} + + public static ParticipationRequestDto toDto(ParticipationRequest request) { + if (request == null) { + return null; + } + return new ParticipationRequestDto( + request.getCreated(), + request.getEvent().getId(), + request.getId(), + request.getRequester().getId(), + request.getStatus().name()); + } + + public static List toDtoList(List requests) { + if (requests == null) { + return List.of(); + } + return requests.stream().map(ParticipationRequestMapper::toDto).toList(); + } +} diff --git a/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java b/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java index e595013..b61a77b 100644 --- a/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java +++ b/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java @@ -3,5 +3,6 @@ public enum EventRequestStatus { PENDING, CONFIRMED, - REJECTED -} + REJECTED, + CANCELED +} \ No newline at end of file diff --git a/main-service/src/main/java/ru/practicum/request/repository/ParticipationRequestRepository.java b/main-service/src/main/java/ru/practicum/request/repository/ParticipationRequestRepository.java new file mode 100644 index 0000000..4678b92 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/request/repository/ParticipationRequestRepository.java @@ -0,0 +1,23 @@ +package ru.practicum.request.repository; + +import java.util.Collection; +import java.util.List; + +import ru.practicum.request.model.EventRequestStatus; +import ru.practicum.request.model.ParticipationRequest; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ParticipationRequestRepository extends JpaRepository { + boolean existsByEvent_IdAndRequester_Id(Long eventId, Long requesterId); + + List findAllByRequester_IdOrderByCreatedDesc(Long requesterId); + + List findAllByEvent_IdOrderByCreatedAsc(Long eventId); + + long countByEvent_IdAndStatus(Long eventId, EventRequestStatus status); + + List findAllByIdInAndEvent_Id(Collection ids, Long eventId); + + List findAllByEvent_IdAndStatus(Long eventId, EventRequestStatus status); +} diff --git a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestService.java b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestService.java new file mode 100644 index 0000000..543a5b0 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestService.java @@ -0,0 +1,20 @@ +package ru.practicum.request.service; + +import java.util.List; + +import ru.practicum.request.dto.EventRequestStatusUpdateRequest; +import ru.practicum.request.dto.EventRequestStatusUpdateResult; +import ru.practicum.request.dto.ParticipationRequestDto; + +public interface ParticipationRequestService { + ParticipationRequestDto createRequest(Long userId, Long eventId); + + List getUserRequests(Long userId); + + ParticipationRequestDto cancelRequest(Long userId, Long requestId); + + List getEventRequestsByInitiator(Long userId, Long eventId); + + EventRequestStatusUpdateResult updateEventRequestsStatus( + Long userId, Long eventId, EventRequestStatusUpdateRequest request); +} diff --git a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java new file mode 100644 index 0000000..0c41e8b --- /dev/null +++ b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java @@ -0,0 +1,227 @@ +package ru.practicum.request.service; + +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import ru.practicum.exception.ConflictException; +import ru.practicum.exception.ForbiddenAccessException; +import ru.practicum.exception.NotFoundException; +import ru.practicum.event.model.Event; +import ru.practicum.event.model.EventState; +import ru.practicum.event.repository.EventRepository; +import ru.practicum.request.dto.EventRequestStatusUpdateRequest; +import ru.practicum.request.dto.EventRequestStatusUpdateResult; +import ru.practicum.request.dto.ParticipationRequestDto; +import ru.practicum.request.mapper.ParticipationRequestMapper; +import ru.practicum.request.model.EventRequestStatus; +import ru.practicum.request.model.ParticipationRequest; +import ru.practicum.request.repository.ParticipationRequestRepository; +import ru.practicum.user.model.User; +import ru.practicum.user.repository.UserRepository; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ParticipationRequestServiceImpl implements ParticipationRequestService { + + private final ParticipationRequestRepository requestRepository; + private final EventRepository eventRepository; + private final UserRepository userRepository; + + @Override + @Transactional + public ParticipationRequestDto createRequest(Long userId, Long eventId) { + User user = getUserByIdOrThrow(userId); + Event event = getEventByIdOrThrow(eventId); + + if (requestRepository.existsByEvent_IdAndRequester_Id(eventId, userId)) { + throw new ConflictException("Request already exists"); + } + + if (event.getInitiator().getId().equals(userId)) { + throw new ConflictException("Initiator can't participate in own event"); + } + + if (!EventState.PUBLISHED.equals(event.getState())) { + throw new ConflictException("Event must be published"); + } + + long confirmed = requestRepository.countByEvent_IdAndStatus(eventId, EventRequestStatus.CONFIRMED); + if (event.getParticipantLimit() != null + && event.getParticipantLimit() > 0 + && confirmed >= event.getParticipantLimit()) { + throw new ConflictException("Participant limit has been reached"); + } + + EventRequestStatus status = EventRequestStatus.PENDING; + if (Boolean.FALSE.equals(event.getRequestModeration()) + || event.getParticipantLimit() == null + || event.getParticipantLimit() == 0) { + status = EventRequestStatus.CONFIRMED; + } + + ParticipationRequest request = + ParticipationRequest.builder() + .event(event) + .requester(user) + .created(LocalDateTime.now()) + .status(status) + .build(); + + ParticipationRequest saved = requestRepository.save(request); + return ParticipationRequestMapper.toDto(saved); + } + + @Override + public List getUserRequests(Long userId) { + getUserByIdOrThrow(userId); + return ParticipationRequestMapper.toDtoList( + requestRepository.findAllByRequester_IdOrderByCreatedDesc(userId)); + } + + @Override + @Transactional + public ParticipationRequestDto cancelRequest(Long userId, Long requestId) { + getUserByIdOrThrow(userId); + ParticipationRequest request = getRequestByIdOrThrow(requestId); + + if (!request.getRequester().getId().equals(userId)) { + throw new ForbiddenAccessException("You can't cancel request that is not yours"); + } + + request.setStatus(EventRequestStatus.CANCELED); + ParticipationRequest saved = requestRepository.save(request); + return ParticipationRequestMapper.toDto(saved); + } + + @Override + public List getEventRequestsByInitiator(Long userId, Long eventId) { + getUserByIdOrThrow(userId); + Event event = getEventByIdOrThrow(eventId); + + if (!event.getInitiator().getId().equals(userId)) { + throw new ForbiddenAccessException("You can't view requests for event that is not yours"); + } + + return ParticipationRequestMapper.toDtoList( + requestRepository.findAllByEvent_IdOrderByCreatedAsc(eventId)); + } + + @Override + @Transactional + public EventRequestStatusUpdateResult updateEventRequestsStatus( + Long userId, Long eventId, EventRequestStatusUpdateRequest updateRequest) { + getUserByIdOrThrow(userId); + Event event = getEventByIdOrThrow(eventId); + + if (!event.getInitiator().getId().equals(userId)) { + throw new ForbiddenAccessException("You can't update requests for event that is not yours"); + } + + Set ids = new HashSet<>(updateRequest.requestIds()); + List requests = requestRepository.findAllByIdInAndEvent_Id(ids, eventId); + if (requests.size() != ids.size()) { + throw new NotFoundException("Some requests were not found"); + } + + for (ParticipationRequest r : requests) { + if (!EventRequestStatus.PENDING.equals(r.getStatus())) { + throw new ConflictException("Only PENDING requests can be updated"); + } + } + + EventRequestStatus targetStatus = updateRequest.status(); + if (EventRequestStatus.CONFIRMED.equals(targetStatus)) { + return confirmRequests(event, requests); + } + if (EventRequestStatus.REJECTED.equals(targetStatus)) { + requests.forEach(r -> r.setStatus(EventRequestStatus.REJECTED)); + requestRepository.saveAll(requests); + return new EventRequestStatusUpdateResult(List.of(), ParticipationRequestMapper.toDtoList(requests)); + } + + throw new ConflictException("Unsupported status update: " + targetStatus); + } + + private EventRequestStatusUpdateResult confirmRequests(Event event, List requests) { + int limit = event.getParticipantLimit() == null ? 0 : event.getParticipantLimit(); + boolean moderation = Boolean.TRUE.equals(event.getRequestModeration()); + + if (!moderation || limit == 0) { + requests.forEach(r -> r.setStatus(EventRequestStatus.CONFIRMED)); + requestRepository.saveAll(requests); + return new EventRequestStatusUpdateResult(ParticipationRequestMapper.toDtoList(requests), List.of()); + } + + long confirmed = requestRepository.countByEvent_IdAndStatus(event.getId(), EventRequestStatus.CONFIRMED); + long available = limit - confirmed; + if (available <= 0) { + throw new ConflictException("Participant limit has been reached"); + } + + List confirmedRequests; + List rejectedRequests; + + if (requests.size() <= available) { + requests.forEach(r -> r.setStatus(EventRequestStatus.CONFIRMED)); + requestRepository.saveAll(requests); + confirmedRequests = requests; + rejectedRequests = List.of(); + } else { + confirmedRequests = requests.subList(0, (int) available); + rejectedRequests = requests.subList((int) available, requests.size()); + confirmedRequests.forEach(r -> r.setStatus(EventRequestStatus.CONFIRMED)); + rejectedRequests.forEach(r -> r.setStatus(EventRequestStatus.REJECTED)); + requestRepository.saveAll(requests); + } + + long nowConfirmed = confirmed + confirmedRequests.size(); + if (nowConfirmed >= limit) { + List pendingToReject = + requestRepository.findAllByEvent_IdAndStatus(event.getId(), EventRequestStatus.PENDING); + + Set touched = idsOf(requests); + List toReject = + pendingToReject.stream() + .filter(r -> !touched.contains(r.getId())) + .toList(); + if (!toReject.isEmpty()) { + toReject.forEach(r -> r.setStatus(EventRequestStatus.REJECTED)); + requestRepository.saveAll(toReject); + } + } + + return new EventRequestStatusUpdateResult( + ParticipationRequestMapper.toDtoList(confirmedRequests), + ParticipationRequestMapper.toDtoList(rejectedRequests)); + } + + private static Set idsOf(Collection requests) { + return requests.stream().map(ParticipationRequest::getId).collect(java.util.stream.Collectors.toSet()); + } + + private User getUserByIdOrThrow(Long userId) { + return userRepository + .findById(userId) + .orElseThrow(() -> new NotFoundException("User with id=%d not found".formatted(userId))); + } + + private Event getEventByIdOrThrow(Long eventId) { + return eventRepository + .findById(eventId) + .orElseThrow(() -> new NotFoundException("Event with id=%d not found".formatted(eventId))); + } + + private ParticipationRequest getRequestByIdOrThrow(Long requestId) { + return requestRepository + .findById(requestId) + .orElseThrow(() -> new NotFoundException("Request with id=%d not found".formatted(requestId))); + } +} diff --git a/main-service/src/main/resources/schema.sql b/main-service/src/main/resources/schema.sql index 17e4a2e..9409ff6 100644 --- a/main-service/src/main/resources/schema.sql +++ b/main-service/src/main/resources/schema.sql @@ -51,14 +51,15 @@ CREATE TABLE compilation_events CONSTRAINT fk_event FOREIGN KEY (event_id) REFERENCES event (id) ON DELETE CASCADE ); -CREATE TABLE participation_request -( - id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - status VARCHAR(20) DEFAULT 'PENDING' CHECK (status IN ('PENDING', 'CONFIRMED', 'REJECTED')), - event_id BIGINT NOT NULL, +CREATE TABLE participation_request ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + created TIMESTAMP NOT NULL, + status VARCHAR(20) NOT NULL, + event_id BIGINT NOT NULL, requester_id BIGINT NOT NULL, - CONSTRAINT fk_request_event FOREIGN KEY (event_id) REFERENCES event (id), - CONSTRAINT fk_request_user FOREIGN KEY (requester_id) REFERENCES users (id) + CONSTRAINT fk_request_user FOREIGN KEY (requester_id) REFERENCES users (id) ); + +CREATE INDEX idx_participation_request_requester_id ON participation_request (requester_id); +CREATE INDEX idx_participation_request_event_id ON participation_request (event_id); diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java new file mode 100644 index 0000000..8f8ffad --- /dev/null +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java @@ -0,0 +1,136 @@ +package ru.practicum.request; + +import static org.junit.jupiter.api.Assertions.*; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import ru.practicum.category.model.Category; +import ru.practicum.category.repository.CategoryRepository; +import ru.practicum.event.model.Event; +import ru.practicum.event.model.EventState; +import ru.practicum.event.model.Location; +import ru.practicum.event.repository.EventRepository; +import ru.practicum.request.dto.EventRequestStatusUpdateRequest; +import ru.practicum.request.dto.EventRequestStatusUpdateResult; +import ru.practicum.request.dto.ParticipationRequestDto; +import ru.practicum.request.model.EventRequestStatus; +import ru.practicum.request.repository.ParticipationRequestRepository; +import ru.practicum.request.service.ParticipationRequestService; +import ru.practicum.user.model.User; +import ru.practicum.user.repository.UserRepository; + +@SpringBootTest +@Transactional +class ParticipationRequestBatchUpdateIT { + + @Autowired + private ParticipationRequestService requestService; + + @Autowired + private ParticipationRequestRepository requestRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private EventRepository eventRepository; + + private User initiator; + private User u1; + private User u2; + private User u3; + private Category category; + + @BeforeEach + void setUp() { + requestRepository.deleteAll(); + eventRepository.deleteAll(); + userRepository.deleteAll(); + categoryRepository.deleteAll(); + + initiator = userRepository.save(User.builder().name("init").email("init@mail.com").build()); + u1 = userRepository.save(User.builder().name("u1").email("u1@mail.com").build()); + u2 = userRepository.save(User.builder().name("u2").email("u2@mail.com").build()); + u3 = userRepository.save(User.builder().name("u3").email("u3@mail.com").build()); + category = categoryRepository.save(Category.builder().name("cat").build()); + } + + @Test + void batchConfirm_shouldConfirmUpToLimit_andRejectRest_andRejectOtherPendingWhenLimitReached() { + Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 2, true)); + + ParticipationRequestDto r1 = requestService.createRequest(u1.getId(), event.getId()); + ParticipationRequestDto r2 = requestService.createRequest(u2.getId(), event.getId()); + ParticipationRequestDto r3 = requestService.createRequest(u3.getId(), event.getId()); + + EventRequestStatusUpdateResult result = + requestService.updateEventRequestsStatus( + initiator.getId(), + event.getId(), + new EventRequestStatusUpdateRequest( + List.of(r1.id(), r2.id(), r3.id()), + EventRequestStatus.CONFIRMED)); + + assertEquals(2, result.confirmedRequests().size()); + assertEquals(1, result.rejectedRequests().size()); + + List all = + requestService.getEventRequestsByInitiator(initiator.getId(), event.getId()); + + long confirmed = all.stream().filter(r -> r.status().equals(EventRequestStatus.CONFIRMED.name())).count(); + long rejected = all.stream().filter(r -> r.status().equals(EventRequestStatus.REJECTED.name())).count(); + + assertEquals(2, confirmed); + assertEquals(1, rejected); + } + + @Test + void batchReject_shouldRejectOnlyProvidedPending() { + Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, true)); + + ParticipationRequestDto r1 = requestService.createRequest(u1.getId(), event.getId()); + ParticipationRequestDto r2 = requestService.createRequest(u2.getId(), event.getId()); + + EventRequestStatusUpdateResult result = + requestService.updateEventRequestsStatus( + initiator.getId(), + event.getId(), + new EventRequestStatusUpdateRequest( + List.of(r1.id(), r2.id()), + EventRequestStatus.REJECTED)); + + assertEquals(0, result.confirmedRequests().size()); + assertEquals(2, result.rejectedRequests().size()); + } + + private Event buildEvent(EventState state, int participantLimit, boolean moderation) { + return Event.builder() + .title("title") + .annotation("ann") + .description("desc") + .createdOn(LocalDateTime.now().minusMinutes(1)) + .eventDate(LocalDateTime.now().plusDays(1)) + .paid(false) + .participantLimit(participantLimit) + .requestModeration(moderation) + .state(state) + .initiator(initiator) + .category(category) + .location(Location.builder() + .lat(BigDecimal.valueOf(55.755800)) + .lon(BigDecimal.valueOf(37.617300)) + .build()) + .build(); + } +} diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java new file mode 100644 index 0000000..f2812a4 --- /dev/null +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java @@ -0,0 +1,123 @@ +package ru.practicum.request; + +import static org.junit.jupiter.api.Assertions.*; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import ru.practicum.category.model.Category; +import ru.practicum.category.repository.CategoryRepository; +import ru.practicum.event.model.Event; +import ru.practicum.event.model.EventState; +import ru.practicum.event.model.Location; +import ru.practicum.event.repository.EventRepository; +import ru.practicum.exception.ConflictException; +import ru.practicum.request.dto.ParticipationRequestDto; +import ru.practicum.request.model.EventRequestStatus; +import ru.practicum.request.repository.ParticipationRequestRepository; +import ru.practicum.request.service.ParticipationRequestService; +import ru.practicum.user.model.User; +import ru.practicum.user.repository.UserRepository; + +@SpringBootTest +@Transactional +class ParticipationRequestServiceIT { + + @Autowired + private ParticipationRequestService requestService; + + @Autowired + private ParticipationRequestRepository requestRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private EventRepository eventRepository; + + private User initiator; + private User requester; + private Category category; + + @BeforeEach + void setUp() { + requestRepository.deleteAll(); + eventRepository.deleteAll(); + userRepository.deleteAll(); + categoryRepository.deleteAll(); + + initiator = userRepository.save(User.builder().name("init").email("init@mail.com").build()); + requester = userRepository.save(User.builder().name("req").email("req@mail.com").build()); + category = categoryRepository.save(Category.builder().name("cat").build()); + } + + @Test + void createRequest_shouldConfirmImmediately_whenModerationOff() { + Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, false)); + + ParticipationRequestDto dto = requestService.createRequest(requester.getId(), event.getId()); + + assertEquals(event.getId(), dto.event()); + assertEquals(requester.getId(), dto.requester()); + assertEquals(EventRequestStatus.CONFIRMED.name(), dto.status()); + assertNotNull(dto.created()); + assertTrue(requestRepository.existsById(dto.id())); + } + + @Test + void createRequest_shouldThrowConflict_whenEventNotPublished() { + Event event = eventRepository.save(buildEvent(EventState.PENDING, 10, true)); + + assertThrows( + ConflictException.class, + () -> requestService.createRequest(requester.getId(), event.getId())); + } + + @Test + void createRequest_shouldThrowConflict_whenRequesterIsInitiator() { + Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, true)); + + assertThrows( + ConflictException.class, + () -> requestService.createRequest(initiator.getId(), event.getId())); + } + + @Test + void cancelRequest_shouldSetCanceledStatus() { + Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, true)); + + ParticipationRequestDto created = requestService.createRequest(requester.getId(), event.getId()); + ParticipationRequestDto canceled = requestService.cancelRequest(requester.getId(), created.id()); + + assertEquals(EventRequestStatus.CANCELED.name(), canceled.status()); + } + + private Event buildEvent(EventState state, int participantLimit, boolean moderation) { + return Event.builder() + .title("title") + .annotation("ann") + .description("desc") + .createdOn(LocalDateTime.now().minusMinutes(1)) + .eventDate(LocalDateTime.now().plusDays(1)) + .paid(false) + .participantLimit(participantLimit) + .requestModeration(moderation) + .state(state) + .initiator(initiator) + .category(category) + .location(Location.builder() + .lat(BigDecimal.valueOf(55.755800)) + .lon(BigDecimal.valueOf(37.617300)) + .build()) + .build(); + } +} diff --git a/main-service/src/test/resources/application-test.yaml b/main-service/src/test/resources/application-test.yaml new file mode 100644 index 0000000..a7b2c55 --- /dev/null +++ b/main-service/src/test/resources/application-test.yaml @@ -0,0 +1,26 @@ +spring: + datasource: + url: jdbc:h2:mem:ewm-test-db;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=TRUE + driver-class-name: org.h2.Driver + username: sa + password: + + sql: + init: + mode: always + schema-locations: classpath:schema.sql + + jpa: + hibernate: + ddl-auto: none + properties: + hibernate: + format_sql: true + +logging: + level: + org.hibernate.SQL: debug + +stats-server: + url: http://localhost:9090 + app: ewm-main-service \ No newline at end of file diff --git a/stat/stat-client/src/main/java/ru/practicum/client/StatsClient.java b/stat/stat-client/src/main/java/ru/practicum/request/StatsClient.java similarity index 93% rename from stat/stat-client/src/main/java/ru/practicum/client/StatsClient.java rename to stat/stat-client/src/main/java/ru/practicum/request/StatsClient.java index cf3f0b9..0c0d0a4 100644 --- a/stat/stat-client/src/main/java/ru/practicum/client/StatsClient.java +++ b/stat/stat-client/src/main/java/ru/practicum/request/StatsClient.java @@ -1,4 +1,4 @@ -package ru.practicum.client; +package ru.practicum.request; import java.time.LocalDateTime; import java.util.List; diff --git a/stat/stat-client/src/main/java/ru/practicum/client/StatsClientConfig.java b/stat/stat-client/src/main/java/ru/practicum/request/StatsClientConfig.java similarity index 95% rename from stat/stat-client/src/main/java/ru/practicum/client/StatsClientConfig.java rename to stat/stat-client/src/main/java/ru/practicum/request/StatsClientConfig.java index aa41bc7..bd939f5 100644 --- a/stat/stat-client/src/main/java/ru/practicum/client/StatsClientConfig.java +++ b/stat/stat-client/src/main/java/ru/practicum/request/StatsClientConfig.java @@ -1,4 +1,4 @@ -package ru.practicum.client; +package ru.practicum.request; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/stat/stat-client/src/main/java/ru/practicum/client/StatsClientImpl.java b/stat/stat-client/src/main/java/ru/practicum/request/StatsClientImpl.java similarity index 98% rename from stat/stat-client/src/main/java/ru/practicum/client/StatsClientImpl.java rename to stat/stat-client/src/main/java/ru/practicum/request/StatsClientImpl.java index 2c767e2..eca356e 100644 --- a/stat/stat-client/src/main/java/ru/practicum/client/StatsClientImpl.java +++ b/stat/stat-client/src/main/java/ru/practicum/request/StatsClientImpl.java @@ -1,4 +1,4 @@ -package ru.practicum.client; +package ru.practicum.request; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; diff --git a/stat/stat-client/src/test/java/ru/practicum/client/StatsClientTest.java b/stat/stat-client/src/test/java/ru/practicum/request/StatsClientTest.java similarity index 99% rename from stat/stat-client/src/test/java/ru/practicum/client/StatsClientTest.java rename to stat/stat-client/src/test/java/ru/practicum/request/StatsClientTest.java index c4e2fdd..34120fa 100644 --- a/stat/stat-client/src/test/java/ru/practicum/client/StatsClientTest.java +++ b/stat/stat-client/src/test/java/ru/practicum/request/StatsClientTest.java @@ -1,4 +1,4 @@ -package ru.practicum.client; +package ru.practicum.request; import static org.hamcrest.Matchers.*; import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; From b98485a5271209792c7becd8e12cedc29a460768 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:17:05 +0300 Subject: [PATCH 02/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practicum/request/mapper/ParticipationRequestMapper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java index 5762ced..4dae630 100644 --- a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java +++ b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java @@ -6,7 +6,8 @@ import ru.practicum.request.model.ParticipationRequest; public final class ParticipationRequestMapper { - private ParticipationRequestMapper() {} + private ParticipationRequestMapper() { + } public static ParticipationRequestDto toDto(ParticipationRequest request) { if (request == null) { From e2c8372b3a9aa044be5fa038690f4403d67c2111 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:22:01 +0300 Subject: [PATCH 03/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParticipationRequestServiceIT.java | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java index f2812a4..a8dc86c 100644 --- a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java @@ -1,10 +1,10 @@ package ru.practicum.request; -import static org.junit.jupiter.api.Assertions.*; - import java.math.BigDecimal; import java.time.LocalDateTime; +import static org.junit.jupiter.api.Assertions.*; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -77,18 +77,14 @@ void createRequest_shouldConfirmImmediately_whenModerationOff() { void createRequest_shouldThrowConflict_whenEventNotPublished() { Event event = eventRepository.save(buildEvent(EventState.PENDING, 10, true)); - assertThrows( - ConflictException.class, - () -> requestService.createRequest(requester.getId(), event.getId())); + assertThrows(ConflictException.class, () -> requestService.createRequest(requester.getId(), event.getId())); } @Test void createRequest_shouldThrowConflict_whenRequesterIsInitiator() { Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, true)); - assertThrows( - ConflictException.class, - () -> requestService.createRequest(initiator.getId(), event.getId())); + assertThrows(ConflictException.class, () -> requestService.createRequest(initiator.getId(), event.getId())); } @Test @@ -102,22 +98,6 @@ void cancelRequest_shouldSetCanceledStatus() { } private Event buildEvent(EventState state, int participantLimit, boolean moderation) { - return Event.builder() - .title("title") - .annotation("ann") - .description("desc") - .createdOn(LocalDateTime.now().minusMinutes(1)) - .eventDate(LocalDateTime.now().plusDays(1)) - .paid(false) - .participantLimit(participantLimit) - .requestModeration(moderation) - .state(state) - .initiator(initiator) - .category(category) - .location(Location.builder() - .lat(BigDecimal.valueOf(55.755800)) - .lon(BigDecimal.valueOf(37.617300)) - .build()) - .build(); + return Event.builder().title("title").annotation("ann").description("desc").createdOn(LocalDateTime.now().minusMinutes(1)).eventDate(LocalDateTime.now().plusDays(1)).paid(false).participantLimit(participantLimit).requestModeration(moderation).state(state).initiator(initiator).category(category).location(Location.builder().lat(BigDecimal.valueOf(55.755800)).lon(BigDecimal.valueOf(37.617300)).build()).build(); } } From 0dfd7df97f63e27e63b1d9a68b99b9973ea18a69 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:24:45 +0300 Subject: [PATCH 04/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParticipationRequestBatchUpdateIT.java | 19 +++++++------------ .../ParticipationRequestServiceIT.java | 15 +++++---------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java index 8f8ffad..f037f79 100644 --- a/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java @@ -1,11 +1,11 @@ package ru.practicum.request; -import static org.junit.jupiter.api.Assertions.*; - import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; +import static org.junit.jupiter.api.Assertions.*; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -31,20 +31,15 @@ @Transactional class ParticipationRequestBatchUpdateIT { - @Autowired - private ParticipationRequestService requestService; + @Autowired private ParticipationRequestService requestService; - @Autowired - private ParticipationRequestRepository requestRepository; + @Autowired private ParticipationRequestRepository requestRepository; - @Autowired - private UserRepository userRepository; + @Autowired private UserRepository userRepository; - @Autowired - private CategoryRepository categoryRepository; + @Autowired private CategoryRepository categoryRepository; - @Autowired - private EventRepository eventRepository; + @Autowired private EventRepository eventRepository; private User initiator; private User u1; diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java index a8dc86c..8aa74e9 100644 --- a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java @@ -29,20 +29,15 @@ @Transactional class ParticipationRequestServiceIT { - @Autowired - private ParticipationRequestService requestService; + @Autowired private ParticipationRequestService requestService; - @Autowired - private ParticipationRequestRepository requestRepository; + @Autowired private ParticipationRequestRepository requestRepository; - @Autowired - private UserRepository userRepository; + @Autowired private UserRepository userRepository; - @Autowired - private CategoryRepository categoryRepository; + @Autowired private CategoryRepository categoryRepository; - @Autowired - private EventRepository eventRepository; + @Autowired private EventRepository eventRepository; private User initiator; private User requester; From a0bd56eade827ee780a0ffe5ded2db9dcf1bb9cd Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:31:20 +0300 Subject: [PATCH 05/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParticipationRequestServiceIT.java | 59 ++++++++++++++----- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java index 8aa74e9..26c57d0 100644 --- a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java @@ -1,15 +1,9 @@ package ru.practicum.request; -import java.math.BigDecimal; -import java.time.LocalDateTime; - import static org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.time.LocalDateTime; import ru.practicum.category.model.Category; import ru.practicum.category.repository.CategoryRepository; @@ -25,6 +19,12 @@ import ru.practicum.user.model.User; import ru.practicum.user.repository.UserRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + @SpringBootTest @Transactional class ParticipationRequestServiceIT { @@ -50,8 +50,11 @@ void setUp() { userRepository.deleteAll(); categoryRepository.deleteAll(); - initiator = userRepository.save(User.builder().name("init").email("init@mail.com").build()); - requester = userRepository.save(User.builder().name("req").email("req@mail.com").build()); + initiator = + userRepository.save( + User.builder().name("init").email("init@mail.com").build()); + requester = + userRepository.save(User.builder().name("req").email("req@mail.com").build()); category = categoryRepository.save(Category.builder().name("cat").build()); } @@ -59,7 +62,8 @@ void setUp() { void createRequest_shouldConfirmImmediately_whenModerationOff() { Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, false)); - ParticipationRequestDto dto = requestService.createRequest(requester.getId(), event.getId()); + ParticipationRequestDto dto = + requestService.createRequest(requester.getId(), event.getId()); assertEquals(event.getId(), dto.event()); assertEquals(requester.getId(), dto.requester()); @@ -72,27 +76,50 @@ void createRequest_shouldConfirmImmediately_whenModerationOff() { void createRequest_shouldThrowConflict_whenEventNotPublished() { Event event = eventRepository.save(buildEvent(EventState.PENDING, 10, true)); - assertThrows(ConflictException.class, () -> requestService.createRequest(requester.getId(), event.getId())); + assertThrows( + ConflictException.class, + () -> requestService.createRequest(requester.getId(), event.getId())); } @Test void createRequest_shouldThrowConflict_whenRequesterIsInitiator() { Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, true)); - assertThrows(ConflictException.class, () -> requestService.createRequest(initiator.getId(), event.getId())); + assertThrows( + ConflictException.class, + () -> requestService.createRequest(initiator.getId(), event.getId())); } @Test void cancelRequest_shouldSetCanceledStatus() { Event event = eventRepository.save(buildEvent(EventState.PUBLISHED, 10, true)); - ParticipationRequestDto created = requestService.createRequest(requester.getId(), event.getId()); - ParticipationRequestDto canceled = requestService.cancelRequest(requester.getId(), created.id()); + ParticipationRequestDto created = + requestService.createRequest(requester.getId(), event.getId()); + ParticipationRequestDto canceled = + requestService.cancelRequest(requester.getId(), created.id()); assertEquals(EventRequestStatus.CANCELED.name(), canceled.status()); } private Event buildEvent(EventState state, int participantLimit, boolean moderation) { - return Event.builder().title("title").annotation("ann").description("desc").createdOn(LocalDateTime.now().minusMinutes(1)).eventDate(LocalDateTime.now().plusDays(1)).paid(false).participantLimit(participantLimit).requestModeration(moderation).state(state).initiator(initiator).category(category).location(Location.builder().lat(BigDecimal.valueOf(55.755800)).lon(BigDecimal.valueOf(37.617300)).build()).build(); + return Event.builder() + .title("title") + .annotation("ann") + .description("desc") + .createdOn(LocalDateTime.now().minusMinutes(1)) + .eventDate(LocalDateTime.now().plusDays(1)) + .paid(false) + .participantLimit(participantLimit) + .requestModeration(moderation) + .state(state) + .initiator(initiator) + .category(category) + .location( + Location.builder() + .lat(BigDecimal.valueOf(55.755800)) + .lon(BigDecimal.valueOf(37.617300)) + .build()) + .build(); } } From 82fa7bed5ab004e2148e0c6c68d48a6efe3c1781 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:35:23 +0300 Subject: [PATCH 06/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practicum/request/ParticipationRequestServiceIT.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java index 26c57d0..8965c6f 100644 --- a/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestServiceIT.java @@ -50,11 +50,8 @@ void setUp() { userRepository.deleteAll(); categoryRepository.deleteAll(); - initiator = - userRepository.save( - User.builder().name("init").email("init@mail.com").build()); - requester = - userRepository.save(User.builder().name("req").email("req@mail.com").build()); + initiator = userRepository.save(User.builder().name("init").email("init@mail.com").build()); + requester = userRepository.save(User.builder().name("req").email("req@mail.com").build()); category = categoryRepository.save(Category.builder().name("cat").build()); } From 2a2abd840e5fd13e85fc8d6c17fff1f2a6b2a254 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:39:29 +0300 Subject: [PATCH 07/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParticipationRequestBatchUpdateIT.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java b/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java index f037f79..b8f441b 100644 --- a/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java +++ b/main-service/src/test/java/ru/practicum/request/ParticipationRequestBatchUpdateIT.java @@ -1,17 +1,11 @@ package ru.practicum.request; +import static org.junit.jupiter.api.Assertions.*; + import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.annotation.Transactional; - import ru.practicum.category.model.Category; import ru.practicum.category.repository.CategoryRepository; import ru.practicum.event.model.Event; @@ -27,6 +21,12 @@ import ru.practicum.user.model.User; import ru.practicum.user.repository.UserRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + @SpringBootTest @Transactional class ParticipationRequestBatchUpdateIT { @@ -74,8 +74,7 @@ void batchConfirm_shouldConfirmUpToLimit_andRejectRest_andRejectOtherPendingWhen initiator.getId(), event.getId(), new EventRequestStatusUpdateRequest( - List.of(r1.id(), r2.id(), r3.id()), - EventRequestStatus.CONFIRMED)); + List.of(r1.id(), r2.id(), r3.id()), EventRequestStatus.CONFIRMED)); assertEquals(2, result.confirmedRequests().size()); assertEquals(1, result.rejectedRequests().size()); @@ -83,8 +82,14 @@ void batchConfirm_shouldConfirmUpToLimit_andRejectRest_andRejectOtherPendingWhen List all = requestService.getEventRequestsByInitiator(initiator.getId(), event.getId()); - long confirmed = all.stream().filter(r -> r.status().equals(EventRequestStatus.CONFIRMED.name())).count(); - long rejected = all.stream().filter(r -> r.status().equals(EventRequestStatus.REJECTED.name())).count(); + long confirmed = + all.stream() + .filter(r -> r.status().equals(EventRequestStatus.CONFIRMED.name())) + .count(); + long rejected = + all.stream() + .filter(r -> r.status().equals(EventRequestStatus.REJECTED.name())) + .count(); assertEquals(2, confirmed); assertEquals(1, rejected); @@ -102,8 +107,7 @@ void batchReject_shouldRejectOnlyProvidedPending() { initiator.getId(), event.getId(), new EventRequestStatusUpdateRequest( - List.of(r1.id(), r2.id()), - EventRequestStatus.REJECTED)); + List.of(r1.id(), r2.id()), EventRequestStatus.REJECTED)); assertEquals(0, result.confirmedRequests().size()); assertEquals(2, result.rejectedRequests().size()); @@ -122,10 +126,11 @@ private Event buildEvent(EventState state, int participantLimit, boolean moderat .state(state) .initiator(initiator) .category(category) - .location(Location.builder() - .lat(BigDecimal.valueOf(55.755800)) - .lon(BigDecimal.valueOf(37.617300)) - .build()) + .location( + Location.builder() + .lat(BigDecimal.valueOf(55.755800)) + .lon(BigDecimal.valueOf(37.617300)) + .build()) .build(); } } From 87e48c5b234e4af01c24ae8e95ba5911d8b2b365 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:47:20 +0300 Subject: [PATCH 08/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/GlobalExceptionHandler.java | 17 ++++++--- .../ParticipationRequestServiceImpl.java | 38 +++++++++++++------ 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index 304a1e1..d39ec9e 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -8,13 +8,13 @@ import jakarta.validation.ConstraintViolationException; +import ru.practicum.exception.ConflictException; import ru.practicum.exception.ForbiddenAccessException; import ru.practicum.exception.IllegalEventUpdateException; import ru.practicum.exception.NotFoundException; import ru.practicum.exception.ValidationException; import ru.practicum.exception.dto.ApiError; import ru.practicum.exception.dto.Violation; -import ru.practicum.exception.ConflictException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; @@ -33,6 +33,7 @@ public class GlobalExceptionHandler { @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ApiError handleException(Exception e) { log.error(e.getMessage(), e); + StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); @@ -49,7 +50,7 @@ public ApiError handleException(Exception e) { @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(ConstraintViolationException.class) public ApiError handleConstraintValidationException(ConstraintViolationException e) { - final List violations = + List violations = e.getConstraintViolations().stream() .map( violation -> @@ -57,8 +58,10 @@ public ApiError handleConstraintValidationException(ConstraintViolationException violation.getPropertyPath().toString(), violation.getMessage())) .collect(Collectors.toList()); + log.warn(violations.toString()); - List errors = violations.stream().map(Violation::toString).toList(); + + List errors = violations.stream().map(Violation::toString).collect(Collectors.toList()); return new ApiError( errors, e.getMessage(), @@ -70,12 +73,14 @@ public ApiError handleConstraintValidationException(ConstraintViolationException @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException.class) public ApiError handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { - final List violations = + List violations = e.getBindingResult().getFieldErrors().stream() .map(error -> new Violation(error.getField(), error.getDefaultMessage())) .collect(Collectors.toList()); + log.warn(violations.toString()); - List errors = violations.stream().map(Violation::toString).toList(); + + List errors = violations.stream().map(Violation::toString).collect(Collectors.toList()); return new ApiError( errors, e.getMessage(), @@ -104,7 +109,7 @@ public ApiError handleDataIntegrityViolationException(DataIntegrityViolationExce null, e.getMessage(), "Some fields of RequestBody for request are invalid", - HttpStatus.NOT_FOUND.toString(), + HttpStatus.CONFLICT.toString(), LocalDateTime.now()); } diff --git a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java index 0c41e8b..7e4d3dd 100644 --- a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java @@ -5,13 +5,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; -import ru.practicum.exception.ConflictException; -import ru.practicum.exception.ForbiddenAccessException; -import ru.practicum.exception.NotFoundException; import ru.practicum.event.model.Event; import ru.practicum.event.model.EventState; import ru.practicum.event.repository.EventRepository; +import ru.practicum.exception.ConflictException; +import ru.practicum.exception.ForbiddenAccessException; +import ru.practicum.exception.NotFoundException; import ru.practicum.request.dto.EventRequestStatusUpdateRequest; import ru.practicum.request.dto.EventRequestStatusUpdateResult; import ru.practicum.request.dto.ParticipationRequestDto; @@ -53,7 +54,8 @@ public ParticipationRequestDto createRequest(Long userId, Long eventId) { throw new ConflictException("Event must be published"); } - long confirmed = requestRepository.countByEvent_IdAndStatus(eventId, EventRequestStatus.CONFIRMED); + long confirmed = + requestRepository.countByEvent_IdAndStatus(eventId, EventRequestStatus.CONFIRMED); if (event.getParticipantLimit() != null && event.getParticipantLimit() > 0 && confirmed >= event.getParticipantLimit()) { @@ -144,7 +146,8 @@ public EventRequestStatusUpdateResult updateEventRequestsStatus( if (EventRequestStatus.REJECTED.equals(targetStatus)) { requests.forEach(r -> r.setStatus(EventRequestStatus.REJECTED)); requestRepository.saveAll(requests); - return new EventRequestStatusUpdateResult(List.of(), ParticipationRequestMapper.toDtoList(requests)); + return new EventRequestStatusUpdateResult( + List.of(), ParticipationRequestMapper.toDtoList(requests)); } throw new ConflictException("Unsupported status update: " + targetStatus); @@ -157,10 +160,12 @@ private EventRequestStatusUpdateResult confirmRequests(Event event, List r.setStatus(EventRequestStatus.CONFIRMED)); requestRepository.saveAll(requests); - return new EventRequestStatusUpdateResult(ParticipationRequestMapper.toDtoList(requests), List.of()); + return new EventRequestStatusUpdateResult( + ParticipationRequestMapper.toDtoList(requests), List.of()); } - long confirmed = requestRepository.countByEvent_IdAndStatus(event.getId(), EventRequestStatus.CONFIRMED); + long confirmed = + requestRepository.countByEvent_IdAndStatus(event.getId(), EventRequestStatus.CONFIRMED); long available = limit - confirmed; if (available <= 0) { throw new ConflictException("Participant limit has been reached"); @@ -191,7 +196,7 @@ private EventRequestStatusUpdateResult confirmRequests(Event event, List toReject = pendingToReject.stream() .filter(r -> !touched.contains(r.getId())) - .toList(); + .collect(Collectors.toList()); if (!toReject.isEmpty()) { toReject.forEach(r -> r.setStatus(EventRequestStatus.REJECTED)); requestRepository.saveAll(toReject); @@ -204,24 +209,33 @@ private EventRequestStatusUpdateResult confirmRequests(Event event, List idsOf(Collection requests) { - return requests.stream().map(ParticipationRequest::getId).collect(java.util.stream.Collectors.toSet()); + return requests.stream().map(ParticipationRequest::getId).collect(Collectors.toSet()); } private User getUserByIdOrThrow(Long userId) { return userRepository .findById(userId) - .orElseThrow(() -> new NotFoundException("User with id=%d not found".formatted(userId))); + .orElseThrow( + () -> + new NotFoundException( + "User with id=%d not found".formatted(userId))); } private Event getEventByIdOrThrow(Long eventId) { return eventRepository .findById(eventId) - .orElseThrow(() -> new NotFoundException("Event with id=%d not found".formatted(eventId))); + .orElseThrow( + () -> + new NotFoundException( + "Event with id=%d not found".formatted(eventId))); } private ParticipationRequest getRequestByIdOrThrow(Long requestId) { return requestRepository .findById(requestId) - .orElseThrow(() -> new NotFoundException("Request with id=%d not found".formatted(requestId))); + .orElseThrow( + () -> + new NotFoundException( + "Request with id=%d not found".formatted(requestId))); } } From 3ba932ec288336b6e728deebcdcf3ce2da19295d Mon Sep 17 00:00:00 2001 From: basarus51 Date: Wed, 14 Jan 2026 05:56:58 +0300 Subject: [PATCH 09/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...cipationRequestEventPrivateController.java | 8 ++++++- ...ParticipationRequestPrivateController.java | 9 +++++++- .../request/model/ParticipationRequest.java | 21 ++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java index 7ab6cb6..c20a510 100644 --- a/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java +++ b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestEventPrivateController.java @@ -9,7 +9,12 @@ import ru.practicum.request.dto.ParticipationRequestDto; import ru.practicum.request.service.ParticipationRequestService; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -19,6 +24,7 @@ @RequiredArgsConstructor @RequestMapping("/users/{userId}/events/{eventId}/requests") public class ParticipationRequestEventPrivateController { + private final ParticipationRequestService requestService; @GetMapping diff --git a/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java index d9863d0..37f49f3 100644 --- a/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java +++ b/main-service/src/main/java/ru/practicum/request/controller/ParticipationRequestPrivateController.java @@ -5,7 +5,13 @@ import ru.practicum.request.dto.ParticipationRequestDto; import ru.practicum.request.service.ParticipationRequestService; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,6 +21,7 @@ @RequiredArgsConstructor @RequestMapping("/users/{userId}/requests") public class ParticipationRequestPrivateController { + private final ParticipationRequestService requestService; @PostMapping diff --git a/main-service/src/main/java/ru/practicum/request/model/ParticipationRequest.java b/main-service/src/main/java/ru/practicum/request/model/ParticipationRequest.java index 54aab5d..9e99701 100644 --- a/main-service/src/main/java/ru/practicum/request/model/ParticipationRequest.java +++ b/main-service/src/main/java/ru/practicum/request/model/ParticipationRequest.java @@ -2,21 +2,36 @@ import java.time.LocalDateTime; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import ru.practicum.event.model.Event; import ru.practicum.user.model.User; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import lombok.experimental.FieldDefaults; -import lombok.*; @Entity +@Table(name = "participation_request") @Getter @Setter @Builder @NoArgsConstructor @AllArgsConstructor -@Table(name = "participation_request") @FieldDefaults(level = AccessLevel.PRIVATE) public class ParticipationRequest { From 92d801256f3ca13c065fb1033cc51e85e2bcdc39 Mon Sep 17 00:00:00 2001 From: Ilia Egorov Date: Wed, 14 Jan 2026 17:39:38 +0300 Subject: [PATCH 10/15] spotless apply --- .../event/service/EventServiceImpl.java | 2 +- .../exception/ConflictException.java | 2 +- .../handler/GlobalExceptionHandler.java | 6 +++-- .../mapper/ParticipationRequestMapper.java | 3 +-- .../request/model/EventRequestStatus.java | 2 +- .../ParticipationRequestServiceImpl.java | 22 +++++++++++-------- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java b/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java index de6a626..25b484e 100644 --- a/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java @@ -9,7 +9,6 @@ import ru.practicum.category.model.Category; import ru.practicum.category.repository.CategoryRepository; -import ru.practicum.request.StatsClient; import ru.practicum.dto.ViewStatsDto; import ru.practicum.event.controller.EventSortBy; import ru.practicum.event.dto.*; @@ -23,6 +22,7 @@ import ru.practicum.exception.IllegalEventUpdateException; import ru.practicum.exception.NotFoundException; import ru.practicum.exception.ValidationException; +import ru.practicum.request.StatsClient; import ru.practicum.user.model.User; import ru.practicum.user.repository.UserRepository; diff --git a/main-service/src/main/java/ru/practicum/exception/ConflictException.java b/main-service/src/main/java/ru/practicum/exception/ConflictException.java index b842f0c..e2fddf1 100644 --- a/main-service/src/main/java/ru/practicum/exception/ConflictException.java +++ b/main-service/src/main/java/ru/practicum/exception/ConflictException.java @@ -4,4 +4,4 @@ public class ConflictException extends RuntimeException { public ConflictException(String message) { super(message); } -} \ No newline at end of file +} diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index d39ec9e..bc313b4 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -61,7 +61,8 @@ public ApiError handleConstraintValidationException(ConstraintViolationException log.warn(violations.toString()); - List errors = violations.stream().map(Violation::toString).collect(Collectors.toList()); + List errors = + violations.stream().map(Violation::toString).collect(Collectors.toList()); return new ApiError( errors, e.getMessage(), @@ -80,7 +81,8 @@ public ApiError handleMethodArgumentNotValidException(MethodArgumentNotValidExce log.warn(violations.toString()); - List errors = violations.stream().map(Violation::toString).collect(Collectors.toList()); + List errors = + violations.stream().map(Violation::toString).collect(Collectors.toList()); return new ApiError( errors, e.getMessage(), diff --git a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java index 4dae630..5762ced 100644 --- a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java +++ b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java @@ -6,8 +6,7 @@ import ru.practicum.request.model.ParticipationRequest; public final class ParticipationRequestMapper { - private ParticipationRequestMapper() { - } + private ParticipationRequestMapper() {} public static ParticipationRequestDto toDto(ParticipationRequest request) { if (request == null) { diff --git a/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java b/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java index b61a77b..fb21ff3 100644 --- a/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java +++ b/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java @@ -5,4 +5,4 @@ public enum EventRequestStatus { CONFIRMED, REJECTED, CANCELED -} \ No newline at end of file +} diff --git a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java index 7e4d3dd..bfff1f6 100644 --- a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java @@ -109,7 +109,8 @@ public List getEventRequestsByInitiator(Long userId, Lo Event event = getEventByIdOrThrow(eventId); if (!event.getInitiator().getId().equals(userId)) { - throw new ForbiddenAccessException("You can't view requests for event that is not yours"); + throw new ForbiddenAccessException( + "You can't view requests for event that is not yours"); } return ParticipationRequestMapper.toDtoList( @@ -124,11 +125,13 @@ public EventRequestStatusUpdateResult updateEventRequestsStatus( Event event = getEventByIdOrThrow(eventId); if (!event.getInitiator().getId().equals(userId)) { - throw new ForbiddenAccessException("You can't update requests for event that is not yours"); + throw new ForbiddenAccessException( + "You can't update requests for event that is not yours"); } Set ids = new HashSet<>(updateRequest.requestIds()); - List requests = requestRepository.findAllByIdInAndEvent_Id(ids, eventId); + List requests = + requestRepository.findAllByIdInAndEvent_Id(ids, eventId); if (requests.size() != ids.size()) { throw new NotFoundException("Some requests were not found"); } @@ -153,7 +156,8 @@ public EventRequestStatusUpdateResult updateEventRequestsStatus( throw new ConflictException("Unsupported status update: " + targetStatus); } - private EventRequestStatusUpdateResult confirmRequests(Event event, List requests) { + private EventRequestStatusUpdateResult confirmRequests( + Event event, List requests) { int limit = event.getParticipantLimit() == null ? 0 : event.getParticipantLimit(); boolean moderation = Boolean.TRUE.equals(event.getRequestModeration()); @@ -165,7 +169,8 @@ private EventRequestStatusUpdateResult confirmRequests(Event event, List= limit) { List pendingToReject = - requestRepository.findAllByEvent_IdAndStatus(event.getId(), EventRequestStatus.PENDING); + requestRepository.findAllByEvent_IdAndStatus( + event.getId(), EventRequestStatus.PENDING); Set touched = idsOf(requests); List toReject = @@ -216,9 +222,7 @@ private User getUserByIdOrThrow(Long userId) { return userRepository .findById(userId) .orElseThrow( - () -> - new NotFoundException( - "User with id=%d not found".formatted(userId))); + () -> new NotFoundException("User with id=%d not found".formatted(userId))); } private Event getEventByIdOrThrow(Long eventId) { From 30832bfdf65013f9ae350b8411f004859e6ea5d9 Mon Sep 17 00:00:00 2001 From: Ilia Egorov Date: Wed, 14 Jan 2026 17:46:16 +0300 Subject: [PATCH 11/15] chore: change mapper to @utilityclass --- .../request/mapper/ParticipationRequestMapper.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java index 5762ced..2060323 100644 --- a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java +++ b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java @@ -5,10 +5,12 @@ import ru.practicum.request.dto.ParticipationRequestDto; import ru.practicum.request.model.ParticipationRequest; -public final class ParticipationRequestMapper { - private ParticipationRequestMapper() {} +import lombok.experimental.UtilityClass; - public static ParticipationRequestDto toDto(ParticipationRequest request) { +@UtilityClass +public class ParticipationRequestMapper { + + public ParticipationRequestDto toDto(ParticipationRequest request) { if (request == null) { return null; } @@ -20,7 +22,7 @@ public static ParticipationRequestDto toDto(ParticipationRequest request) { request.getStatus().name()); } - public static List toDtoList(List requests) { + public List toDtoList(List requests) { if (requests == null) { return List.of(); } From 48dcb9e8502c4ac65b1f35c24d792b3fca132a2a Mon Sep 17 00:00:00 2001 From: basarus51 Date: Thu, 15 Jan 2026 16:12:36 +0300 Subject: [PATCH 12/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20checkstyle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/service/EventServiceImpl.java | 2 +- .../exception/ConflictException.java | 2 +- .../handler/GlobalExceptionHandler.java | 6 +++-- .../mapper/ParticipationRequestMapper.java | 3 +-- .../request/model/EventRequestStatus.java | 2 +- .../ParticipationRequestServiceImpl.java | 22 +++++++++++-------- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java b/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java index de6a626..25b484e 100644 --- a/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/event/service/EventServiceImpl.java @@ -9,7 +9,6 @@ import ru.practicum.category.model.Category; import ru.practicum.category.repository.CategoryRepository; -import ru.practicum.request.StatsClient; import ru.practicum.dto.ViewStatsDto; import ru.practicum.event.controller.EventSortBy; import ru.practicum.event.dto.*; @@ -23,6 +22,7 @@ import ru.practicum.exception.IllegalEventUpdateException; import ru.practicum.exception.NotFoundException; import ru.practicum.exception.ValidationException; +import ru.practicum.request.StatsClient; import ru.practicum.user.model.User; import ru.practicum.user.repository.UserRepository; diff --git a/main-service/src/main/java/ru/practicum/exception/ConflictException.java b/main-service/src/main/java/ru/practicum/exception/ConflictException.java index b842f0c..e2fddf1 100644 --- a/main-service/src/main/java/ru/practicum/exception/ConflictException.java +++ b/main-service/src/main/java/ru/practicum/exception/ConflictException.java @@ -4,4 +4,4 @@ public class ConflictException extends RuntimeException { public ConflictException(String message) { super(message); } -} \ No newline at end of file +} diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index d39ec9e..bc313b4 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -61,7 +61,8 @@ public ApiError handleConstraintValidationException(ConstraintViolationException log.warn(violations.toString()); - List errors = violations.stream().map(Violation::toString).collect(Collectors.toList()); + List errors = + violations.stream().map(Violation::toString).collect(Collectors.toList()); return new ApiError( errors, e.getMessage(), @@ -80,7 +81,8 @@ public ApiError handleMethodArgumentNotValidException(MethodArgumentNotValidExce log.warn(violations.toString()); - List errors = violations.stream().map(Violation::toString).collect(Collectors.toList()); + List errors = + violations.stream().map(Violation::toString).collect(Collectors.toList()); return new ApiError( errors, e.getMessage(), diff --git a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java index 4dae630..5762ced 100644 --- a/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java +++ b/main-service/src/main/java/ru/practicum/request/mapper/ParticipationRequestMapper.java @@ -6,8 +6,7 @@ import ru.practicum.request.model.ParticipationRequest; public final class ParticipationRequestMapper { - private ParticipationRequestMapper() { - } + private ParticipationRequestMapper() {} public static ParticipationRequestDto toDto(ParticipationRequest request) { if (request == null) { diff --git a/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java b/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java index b61a77b..fb21ff3 100644 --- a/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java +++ b/main-service/src/main/java/ru/practicum/request/model/EventRequestStatus.java @@ -5,4 +5,4 @@ public enum EventRequestStatus { CONFIRMED, REJECTED, CANCELED -} \ No newline at end of file +} diff --git a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java index 7e4d3dd..bfff1f6 100644 --- a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java @@ -109,7 +109,8 @@ public List getEventRequestsByInitiator(Long userId, Lo Event event = getEventByIdOrThrow(eventId); if (!event.getInitiator().getId().equals(userId)) { - throw new ForbiddenAccessException("You can't view requests for event that is not yours"); + throw new ForbiddenAccessException( + "You can't view requests for event that is not yours"); } return ParticipationRequestMapper.toDtoList( @@ -124,11 +125,13 @@ public EventRequestStatusUpdateResult updateEventRequestsStatus( Event event = getEventByIdOrThrow(eventId); if (!event.getInitiator().getId().equals(userId)) { - throw new ForbiddenAccessException("You can't update requests for event that is not yours"); + throw new ForbiddenAccessException( + "You can't update requests for event that is not yours"); } Set ids = new HashSet<>(updateRequest.requestIds()); - List requests = requestRepository.findAllByIdInAndEvent_Id(ids, eventId); + List requests = + requestRepository.findAllByIdInAndEvent_Id(ids, eventId); if (requests.size() != ids.size()) { throw new NotFoundException("Some requests were not found"); } @@ -153,7 +156,8 @@ public EventRequestStatusUpdateResult updateEventRequestsStatus( throw new ConflictException("Unsupported status update: " + targetStatus); } - private EventRequestStatusUpdateResult confirmRequests(Event event, List requests) { + private EventRequestStatusUpdateResult confirmRequests( + Event event, List requests) { int limit = event.getParticipantLimit() == null ? 0 : event.getParticipantLimit(); boolean moderation = Boolean.TRUE.equals(event.getRequestModeration()); @@ -165,7 +169,8 @@ private EventRequestStatusUpdateResult confirmRequests(Event event, List= limit) { List pendingToReject = - requestRepository.findAllByEvent_IdAndStatus(event.getId(), EventRequestStatus.PENDING); + requestRepository.findAllByEvent_IdAndStatus( + event.getId(), EventRequestStatus.PENDING); Set touched = idsOf(requests); List toReject = @@ -216,9 +222,7 @@ private User getUserByIdOrThrow(Long userId) { return userRepository .findById(userId) .orElseThrow( - () -> - new NotFoundException( - "User with id=%d not found".formatted(userId))); + () -> new NotFoundException("User with id=%d not found".formatted(userId))); } private Event getEventByIdOrThrow(Long eventId) { From e65e64c8b3484f13e016e189f7ad7835f3d415ba Mon Sep 17 00:00:00 2001 From: basarus51 Date: Fri, 16 Jan 2026 22:58:57 +0300 Subject: [PATCH 13/15] =?UTF-8?q?-=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=20ExceptionHandler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/GlobalExceptionHandler.java | 128 +++++++++++------- 1 file changed, 80 insertions(+), 48 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index 76d8ff5..c84a29d 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -6,107 +6,149 @@ import java.util.List; import java.util.stream.Collectors; -import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; -import ru.practicum.exception.dto.ApiError; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import ru.practicum.exception.*; +import ru.practicum.exception.dto.ApiError; +import ru.practicum.exception.dto.Violation; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; -import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler({ + MissingServletRequestParameterException.class, + MethodArgumentTypeMismatchException.class + }) + public ApiError handleRequestParamException(Exception e) { + log.warn(e.getMessage(), e); + return new ApiError( + null, + e.getMessage(), + "Incorrect request", + HttpStatus.BAD_REQUEST.toString(), + LocalDateTime.now()); + } + + @ResponseStatus(HttpStatus.CONFLICT) + @ExceptionHandler(ConflictException.class) + public ApiError handleConflictException(ConflictException e) { + log.warn(e.getMessage(), e); + return new ApiError( + null, + e.getMessage(), + "Conflict", + HttpStatus.CONFLICT.toString(), + LocalDateTime.now()); + } + @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ApiError handleException(Exception e) { + log.error(e.getMessage(), e); StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + String stackTrace = sw.toString(); return new ApiError( - List.of(sw.toString()), - "An error occurred while processing request", + List.of(stackTrace), + "An error occured while processing request", "Exception", HttpStatus.INTERNAL_SERVER_ERROR.toString(), LocalDateTime.now()); } - @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) - public ApiError handleConstraintViolationException(ConstraintViolationException e) { - List errors = + @ExceptionHandler(ConstraintViolationException.class) + public ApiError handleConstraintValidationException(ConstraintViolationException e) { + final List violations = e.getConstraintViolations().stream() - .map(GlobalExceptionHandler::toViolationString) + .map( + violation -> + new Violation( + violation.getPropertyPath().toString(), + violation.getMessage())) .collect(Collectors.toList()); - + log.warn(violations.toString()); + List errors = violations.stream().map(Violation::toString).toList(); return new ApiError( errors, e.getMessage(), - "Validation failed", + "Some fields of RequestBody for request are invalid", HttpStatus.BAD_REQUEST.toString(), LocalDateTime.now()); } - @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(MethodArgumentNotValidException.class) public ApiError handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { - List errors = + final List violations = e.getBindingResult().getFieldErrors().stream() - .map(GlobalExceptionHandler::toFieldErrorString) + .map(error -> new Violation(error.getField(), error.getDefaultMessage())) .collect(Collectors.toList()); - + log.warn(violations.toString()); + List errors = violations.stream().map(Violation::toString).toList(); return new ApiError( errors, e.getMessage(), - "Validation failed", + "Some fields of RequestBody for request are invalid", HttpStatus.BAD_REQUEST.toString(), LocalDateTime.now()); } - @ExceptionHandler({ValidationException.class, IllegalEventUpdateException.class}) - @ResponseStatus(HttpStatus.BAD_REQUEST) - public ApiError handleBadRequest(RuntimeException e) { + @ResponseStatus(HttpStatus.NOT_FOUND) + @ExceptionHandler(NotFoundException.class) + public ApiError handleNotFoundException(NotFoundException e) { + log.warn("Not found: {}", e.getMessage()); return new ApiError( null, e.getMessage(), - "Bad request", - HttpStatus.BAD_REQUEST.toString(), + "The required object was not found", + HttpStatus.NOT_FOUND.toString(), LocalDateTime.now()); } - @ExceptionHandler(NotFoundException.class) - @ResponseStatus(HttpStatus.NOT_FOUND) - public ApiError handleNotFound(NotFoundException e) { + @ResponseStatus(HttpStatus.CONFLICT) + @ExceptionHandler(DataIntegrityViolationException.class) + public ApiError handleDataIntegrityViolationException(DataIntegrityViolationException e) { + log.warn(e.getMessage(), e); return new ApiError( null, e.getMessage(), - "Not found", + "Some fields of RequestBody for request are invalid", HttpStatus.NOT_FOUND.toString(), LocalDateTime.now()); } - @ExceptionHandler({ConflictException.class, DataIntegrityViolationException.class}) @ResponseStatus(HttpStatus.CONFLICT) - public ApiError handleConflict(Exception e) { + @ExceptionHandler(IllegalEventUpdateException.class) + public ApiError handleIllegalEventUpdateException(IllegalEventUpdateException e) { + log.warn(e.getMessage(), e); return new ApiError( null, e.getMessage(), - "Data integrity violation", + "Trying to update event that already Published or Canceled", HttpStatus.CONFLICT.toString(), LocalDateTime.now()); } - @ExceptionHandler(ForbiddenAccessException.class) @ResponseStatus(HttpStatus.FORBIDDEN) - public ApiError handleForbidden(ForbiddenAccessException e) { + @ExceptionHandler(ForbiddenAccessException.class) + public ApiError handleForbiddenAccessException(ForbiddenAccessException e) { + log.warn(e.getMessage(), e); return new ApiError( null, e.getMessage(), @@ -115,25 +157,15 @@ public ApiError handleForbidden(ForbiddenAccessException e) { LocalDateTime.now()); } - @ExceptionHandler({ - MissingServletRequestParameterException.class, - MethodArgumentTypeMismatchException.class - }) @ResponseStatus(HttpStatus.BAD_REQUEST) - public ApiError handleRequestParamExceptions(Exception e) { + @ExceptionHandler(ValidationException.class) + public ApiError handleValidationException(ValidationException e) { + log.warn(e.getMessage(), e); return new ApiError( null, e.getMessage(), - "Validation failed", + "Incorrect request", HttpStatus.BAD_REQUEST.toString(), LocalDateTime.now()); } - - private static String toViolationString(ConstraintViolation violation) { - return violation.getPropertyPath() + ": " + violation.getMessage(); - } - - private static String toFieldErrorString(FieldError error) { - return error.getField() + ": " + error.getDefaultMessage(); - } -} +} \ No newline at end of file From b70d21286ea69f32a8255e0b69e54878d74cc946 Mon Sep 17 00:00:00 2001 From: basarus51 Date: Fri, 16 Jan 2026 23:01:17 +0300 Subject: [PATCH 14/15] - fix codestyle --- .../exception/handler/GlobalExceptionHandler.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index c84a29d..2a2647f 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -8,18 +8,18 @@ import jakarta.validation.ConstraintViolationException; -import org.springframework.web.bind.MissingServletRequestParameterException; -import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; -import ru.practicum.exception.*; import ru.practicum.exception.dto.ApiError; import ru.practicum.exception.dto.Violation; +import ru.practicum.exception.*; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import lombok.extern.slf4j.Slf4j; @@ -29,8 +29,8 @@ public class GlobalExceptionHandler { @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({ - MissingServletRequestParameterException.class, - MethodArgumentTypeMismatchException.class + MissingServletRequestParameterException.class, + MethodArgumentTypeMismatchException.class }) public ApiError handleRequestParamException(Exception e) { log.warn(e.getMessage(), e); @@ -168,4 +168,4 @@ public ApiError handleValidationException(ValidationException e) { HttpStatus.BAD_REQUEST.toString(), LocalDateTime.now()); } -} \ No newline at end of file +} From 1d81e232f445bc12c274149ee1cd982be8c57be2 Mon Sep 17 00:00:00 2001 From: Ilia Egorov Date: Sat, 17 Jan 2026 09:58:04 +0300 Subject: [PATCH 15/15] fixes --- .../handler/GlobalExceptionHandler.java | 34 +++++++++---------- .../ParticipationRequestServiceImpl.java | 3 +- main-service/src/main/resources/schema.sql | 8 ++--- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java index 2a2647f..7a51bc4 100644 --- a/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java +++ b/main-service/src/main/java/ru/practicum/exception/handler/GlobalExceptionHandler.java @@ -27,6 +27,23 @@ @RestControllerAdvice public class GlobalExceptionHandler { + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ApiError handleException(Exception e) { + log.error(e.getMessage(), e); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + String stackTrace = sw.toString(); + + return new ApiError( + List.of(stackTrace), + "An error occured while processing request", + "Exception", + HttpStatus.INTERNAL_SERVER_ERROR.toString(), + LocalDateTime.now()); + } + @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({ MissingServletRequestParameterException.class, @@ -54,23 +71,6 @@ public ApiError handleConflictException(ConflictException e) { LocalDateTime.now()); } - @ExceptionHandler(Exception.class) - @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public ApiError handleException(Exception e) { - log.error(e.getMessage(), e); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - String stackTrace = sw.toString(); - - return new ApiError( - List.of(stackTrace), - "An error occured while processing request", - "Exception", - HttpStatus.INTERNAL_SERVER_ERROR.toString(), - LocalDateTime.now()); - } - @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(ConstraintViolationException.class) public ApiError handleConstraintValidationException(ConstraintViolationException e) { diff --git a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java index 49eda0b..a4bd298 100644 --- a/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/request/service/ParticipationRequestServiceImpl.java @@ -30,6 +30,7 @@ @Service @RequiredArgsConstructor +@Transactional(readOnly = true) public class ParticipationRequestServiceImpl implements ParticipationRequestService { private final ParticipationRequestRepository requestRepository; @@ -82,7 +83,6 @@ public ParticipationRequestDto createRequest(Long userId, Long eventId) { } @Override - @Transactional(readOnly = true) public List getUserRequests(Long userId) { getUserByIdOrThrow(userId); return ParticipationRequestMapper.toDtoList( @@ -105,7 +105,6 @@ public ParticipationRequestDto cancelRequest(Long userId, Long requestId) { } @Override - @Transactional(readOnly = true) public List getEventRequestsByInitiator(Long userId, Long eventId) { getUserByIdOrThrow(userId); Event event = getEventByIdOrThrow(eventId); diff --git a/main-service/src/main/resources/schema.sql b/main-service/src/main/resources/schema.sql index 9409ff6..33d7a92 100644 --- a/main-service/src/main/resources/schema.sql +++ b/main-service/src/main/resources/schema.sql @@ -51,15 +51,13 @@ CREATE TABLE compilation_events CONSTRAINT fk_event FOREIGN KEY (event_id) REFERENCES event (id) ON DELETE CASCADE ); -CREATE TABLE participation_request ( +CREATE TABLE participation_request +( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created TIMESTAMP NOT NULL, status VARCHAR(20) NOT NULL, event_id BIGINT NOT NULL, requester_id BIGINT NOT NULL, CONSTRAINT fk_request_event FOREIGN KEY (event_id) REFERENCES event (id), - CONSTRAINT fk_request_user FOREIGN KEY (requester_id) REFERENCES users (id) + CONSTRAINT fk_request_user FOREIGN KEY (requester_id) REFERENCES users (id) ); - -CREATE INDEX idx_participation_request_requester_id ON participation_request (requester_id); -CREATE INDEX idx_participation_request_event_id ON participation_request (event_id);