Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
When performing a code review, respond in Russian.
Комментарии в Pull Request обязательно должны быть на русском языке!
18 changes: 10 additions & 8 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ services:
interval: 5s
retries: 10

main-db:
ewm-db:
image: postgres:16.1
container_name: main_db
container_name: ewm_db
ports:
- "5433:5432"
environment:
- POSTGRES_DB=mainDB
- POSTGRES_DB=ewmDB
- POSTGRES_USER=dbuser
- POSTGRES_PASSWORD=12345
healthcheck:
Expand All @@ -42,14 +42,16 @@ services:
- SPRING_DATASOURCE_USERNAME=dbuser
- SPRING_DATASOURCE_PASSWORD=12345

main-service:
ewm-service:
build: ./main-service
container_name: main_service
container_name: ewm_service
ports:
- "8080:8080"
depends_on:
- main-db
- stats-server
- ewm-db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://main-db:5432/mainDB
- SPRING_DATASOURCE_URL=jdbc:postgresql://ewm-db:5432/ewmDB
- SPRING_DATASOURCE_USERNAME=dbuser
- SPRING_DATASOURCE_PASSWORD=12345
- SPRING_DATASOURCE_PASSWORD=12345
- STATS_SERVER_URL=http://stats-server:9090
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ public void deleteCategory(@PathVariable @Positive Long categoryId) {
}

@PatchMapping("/{categoryId}")
public CategoryDto updateCategory(
@PathVariable @Positive Long categoryId,
@RequestBody @Valid NewCategoryDto newCategoryDto) {
public CategoryDto updateCategory(@PathVariable @Positive Long categoryId,
@RequestBody @Valid NewCategoryDto newCategoryDto) {
log.debug("Controller: updateCategory id={}, data={}", categoryId, newCategoryDto);
return categoryService.updateCategory(categoryId, newCategoryDto);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
package ru.practicum.compilation.controller;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import ru.practicum.compilation.dto.CompilationDto;
import ru.practicum.compilation.dto.NewCompilationDto;
import ru.practicum.compilation.dto.UpdateCompilationRequest;
import ru.practicum.compilation.service.CompilationService;

@Slf4j
@RestController
@RequestMapping("/admin/compilations")
@RequiredArgsConstructor
public class AdminCompilationController {
private final CompilationService compilationService;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public CompilationDto createCompilation(@RequestBody @Valid NewCompilationDto request) {
log.debug("Controller: createCompilation data {}", request);
return compilationService.createCompilation(request);
Comment thread
internet-prodashi marked this conversation as resolved.
}

@DeleteMapping("/{compId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCompilation(@PathVariable @Positive Long compId) {
log.debug("Controller: deleteCompilation compId={}", compId);
compilationService.deleteCompilation(compId);
}

@PatchMapping("/{compId}")
public CompilationDto updateCompilation(@PathVariable @Positive Long compId,
@RequestBody @Valid UpdateCompilationRequest request) {
log.debug("Controller: updateCompilation compId={} and data {}", compId, request);
return compilationService.updateCompilation(compId, request);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
package ru.practicum.compilation.controller;

import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import ru.practicum.compilation.dto.CompilationDto;
import ru.practicum.compilation.service.CompilationService;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/compilations")
@RequiredArgsConstructor
public class PublicCompilationController {
private final CompilationService compilationService;

@GetMapping
public List<CompilationDto> getCompilations(@RequestParam(required = false) Boolean pinned,
@RequestParam(defaultValue = "0") @PositiveOrZero Integer from,
@RequestParam(defaultValue = "10") @Positive Integer size) {
Pageable pageable = PageRequest.of(from / size, size);
log.debug("Controller: getCompilations pinned={}, from={}, size={}", pinned, from, size);
return compilationService.getCompilations(pinned, pageable);
Comment thread
internet-prodashi marked this conversation as resolved.
}

@GetMapping("/{compId}")
public CompilationDto getCompilation(@PathVariable @Positive Long compId) {
log.debug("Controller: getCompilation compId={}", compId);
return compilationService.getCompilationById(compId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import ru.practicum.event.dto.EventShortDto;

import java.util.List;
import java.util.Set;

public record CompilationDto(
Long id,
List<EventShortDto> events,
Set<EventShortDto> events,
boolean pinned,
String title
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ru.practicum.compilation.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

import java.util.Set;
Expand All @@ -10,7 +9,6 @@ public record UpdateCompilationRequest(

boolean pinned,

@NotBlank(message = "Заголовок подборки не может быть пустым")
@Size(min = 1, max = 50, message = "Заголовок должен содержать от {min} до {max} символов")
String title
Comment thread
internet-prodashi marked this conversation as resolved.
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
package ru.practicum.compilation.mapper;

public class CompilationMapper {
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import ru.practicum.compilation.dto.CompilationDto;
import ru.practicum.compilation.dto.NewCompilationDto;
import ru.practicum.compilation.model.Compilation;
import ru.practicum.event.mapper.EventMapper;

@Mapper(componentModel = "spring", uses = EventMapper.class)
public interface CompilationMapper {

@Mapping(target = "id", ignore = true)
@Mapping(target = "events", ignore = true)
Compilation toEntity(NewCompilationDto request);

@Mapping(target = "events", qualifiedByName = "toEventShortWithoutStats")
CompilationDto toDto(Compilation compilation);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Compilation {
private String title;

@Column(nullable = false)
private boolean pinned = false;
private boolean pinned;

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
package ru.practicum.compilation.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.practicum.compilation.model.Compilation;

import java.util.Optional;

public interface CompilationRepository extends JpaRepository<Compilation, Long> {
Page<Compilation> findByPinned(Boolean pinned, Pageable pageable);

@Query("""
SELECT c FROM Compilation c
LEFT JOIN FETCH c.events e
LEFT JOIN FETCH e.category
LEFT JOIN FETCH e.initiator
WHERE c.id = :id""")
Optional<Compilation> findByIdWithEvents(@Param("id") Long id);

boolean existsByTitle(String title);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
package ru.practicum.compilation.service;

import org.springframework.data.domain.Pageable;
import ru.practicum.compilation.dto.CompilationDto;
import ru.practicum.compilation.dto.NewCompilationDto;
import ru.practicum.compilation.dto.UpdateCompilationRequest;

import java.util.List;

public interface CompilationService {
CompilationDto createCompilation(NewCompilationDto request);

void deleteCompilation(Long compId);

CompilationDto updateCompilation(Long compId, UpdateCompilationRequest request);

List<CompilationDto> getCompilations(Boolean pinned, Pageable pageable);

CompilationDto getCompilationById(Long compId);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,131 @@
package ru.practicum.compilation.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.practicum.compilation.dto.CompilationDto;
import ru.practicum.compilation.dto.NewCompilationDto;
import ru.practicum.compilation.dto.UpdateCompilationRequest;
import ru.practicum.compilation.mapper.CompilationMapper;
import ru.practicum.compilation.model.Compilation;
import ru.practicum.compilation.repository.CompilationRepository;
import ru.practicum.event.model.Event;
import ru.practicum.event.repository.EventRepository;
import ru.practicum.exception.ConflictException;
import ru.practicum.exception.NotFoundException;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

@Slf4j
@Service
Comment thread
internet-prodashi marked this conversation as resolved.
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CompilationServiceImpl implements CompilationService {
private final CompilationRepository compilationRepository;
private final EventRepository eventRepository;
private final CompilationMapper compilationMapper;

@Override
@Transactional
public CompilationDto createCompilation(NewCompilationDto request) {
if (compilationRepository.existsByTitle(request.title()))
throw new ConflictException("Сборник с таким названием (" + request.title() + ") уже существует");

Compilation compilation = compilationMapper.toEntity(request);

if (request.events() != null && !request.events().isEmpty()) {
List<Event> events = eventRepository.findAllByEventIds(new ArrayList<>(request.events()));

if (events.size() != request.events().size()) throw new NotFoundException("Не все события найдены");
Comment thread
internet-prodashi marked this conversation as resolved.
compilation.setEvents(new HashSet<>(events));

} else compilation.setEvents(new HashSet<>());
Compilation savedCompilation = compilationRepository.save(compilation);

log.info("Создан сборник: {}", request);
return compilationMapper.toDto(savedCompilation);
}

@Override
@Transactional
public void deleteCompilation(Long compId) {
if (!compilationRepository.existsById(compId))
throw new NotFoundException("Сборник с идентификатором " + compId + " не найден");

log.info("Удален сборник compId={}", compId);
compilationRepository.deleteById(compId);
}

@Override
@Transactional
public CompilationDto updateCompilation(Long compId, UpdateCompilationRequest request) {
Compilation compilation = getCompilationOrThrow(compId);

if (request.title() != null && !request.title().equals(compilation.getTitle())
&& compilationRepository.existsByTitle(request.title()))
throw new ConflictException("Сборник с таким названием (" + request.title() + ") уже существует");

if (request.title() != null) compilation.setTitle(request.title());
compilation.setPinned(request.pinned());

if (request.events() != null) {
Comment thread
internet-prodashi marked this conversation as resolved.
if (request.events().isEmpty()) {
compilation.setEvents(new HashSet<>());
} else {
List<Event> events = eventRepository.findAllByEventIds(new ArrayList<>(request.events()));
if (events.size() != request.events().size())
throw new NotFoundException("Некоторые события не найдены");
compilation.setEvents(new HashSet<>(events));
}
}

log.info("Обновлен сборник request={}", request);
return compilationMapper.toDto(compilationRepository.save(compilation));
}

@Override
public List<CompilationDto> getCompilations(Boolean pinned, Pageable pageable) {
Pageable sortedPageable = PageRequest.of(
pageable.getPageNumber(),
pageable.getPageSize(),
Sort.by("id").ascending()
);

Page<Compilation> compilationsPage;
if (pinned != null)
compilationsPage = compilationRepository.findByPinned(pinned, sortedPageable);
else
compilationsPage = compilationRepository.findAll(sortedPageable);

List<Compilation> compilations = compilationsPage.getContent();

if (!compilations.isEmpty()) {
log.info("Получен список сборников pinned={}, pageable={}", pinned, pageable);
return compilations.stream()
.map(compilationMapper::toDto)
Comment thread
internet-prodashi marked this conversation as resolved.
.toList();
}
log.info("Список сборников пуст");
return List.of();
}

@Override
public CompilationDto getCompilationById(Long compId) {
Compilation compilation = getCompilationOrThrow(compId);

log.info("Получен сборник compId={}", compId);
return compilationMapper.toDto(compilation);
}

private Compilation getCompilationOrThrow(Long compId) {
return compilationRepository.findByIdWithEvents(compId)
.orElseThrow(() -> new NotFoundException("Сборник с идентификатором " + compId + " не найден"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ public List<EventFullDto> getEventsAdmin(@ModelAttribute @Valid SearchEventAdmin
}

@PatchMapping("/{eventId}")
public EventFullDto updateEventAdmin(
@PathVariable @Positive Long eventId,
@RequestBody @Valid UpdateEventAdminRequest request
public EventFullDto updateEventAdmin(@PathVariable @Positive Long eventId,
@RequestBody @Valid UpdateEventAdminRequest request
) {
log.debug("Controller: updateEventAdmin id={}, data {}", eventId, request);
return eventService.updateEventAdmin(eventId, request);
Expand Down
Loading