Skip to content

Commit

Permalink
Merge pull request #3 from TY95MC/feature_comments
Browse files Browse the repository at this point in the history
Stage 3. Feature comments. 1 iteration
  • Loading branch information
TY95MC authored Jan 24, 2024
2 parents db94ad5 + 072c573 commit e043bcf
Show file tree
Hide file tree
Showing 12 changed files with 3,323 additions and 3 deletions.
78 changes: 76 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,76 @@
# java-explore-with-me
Template repository for ExploreWithMe project.
https://github.com/TY95MC/java-explore-with-me/pull/3
<h1 align="center">Привет, я <a href="https://github.com/TY95MC" target="_blank">Игорь</a>
<img src="https://github.com/blackcater/blackcater/raw/main/images/Hi.gif" height="32"/></h1>
<h3 align="center">Я студент Яндекс.Практикума, курс Java-разработчик. Это мой дипломный проект.</h3>

***

### Серверное приложение-афиша ExploreWithMe (англ. «исследуй со мной») позволяет пользователям делиться информацией об интересных событиях и находить компанию для участия в них.
###Приложение является микросервисным и состоит из двух сервисов:
1. Основной сервис - содержит в себе информацию о проводимых событиях, датах проведения событий, количестве участников и другую полезную информацию о мероприятиях.
Сервис также позволяет отправлять заявки на участие в данных событиях и комментировать их(при условии, что подана заявка на участие).
2. Сервис статистики собирает информацию о просмотрах событий, что позволяет пользователям получать подборку из самых активно просматриваемых событий.

Каждый сервис подключается к отдельной PostgreSQL базе данных.

***

###Эндпоинты

- Пользователи
- POST /admin/users - Добавление нового пользователя
- GET /admin/users - Возвращает информацию обо всех пользователях (учитываются параметры ограничения выборки), либо о конкретных (учитываются указанные идентификаторы)
- DELETE /admin/users/{userId} - Удаление пользователя по его идентификатору
- Категории
- POST /admin/categories - Добавление новой категории события. Имя категории должно быть уникальным
- PATCH /admin/categories/{catId} - Обновление существующей категории по идентификатору. Имя категории должно быть уникальным
- DELETE /admin/categories/{catId} - Удаление категории по идентификатору. С категорией не должно быть связано ни одного события.
- GET /categories - Получение категорий
- GET /categories/{catId} - Получение информации о категории по идентификатору
- События
- POST /users/{userId}/events - Добавление нового события пользователем. Дата и время на которые намечено событие не может быть раньше, чем через два часа от текущего момента
- PATCH /users/{userId}/events/{eventId} - Изменение события, добавленного текущим пользователем. Изменить можно только отмененные события или события в состоянии ожидания модерации. Дата и время на которые намечено событие не может быть раньше, чем через два часа от текущего момента.
- GET /users/{userId}/events - Получение событий, добавленных текущим пользователем
- GET /users/{userId}/events/{eventId} - Получение полной информации о событии, добавленном текущим пользователем
- PATCH /admin/events/{eventId} - Редактирование данных любого события администратором
- GET /admin/events - Эндпоинт возвращает полную информацию обо всех событиях подходящих под переданные условия
- GET /events - Получение опубликованных событий с возможностью фильтрации
- GET /events/{id} - Получение подробной информации об опубликованном событии по его идентификатору
- Подборки событий
- POST /admin/compilations - Добавление новой подборки событий. Подборка может не содержать событий
- PATCH /admin/compilations/{compId} - Обновить информацию о подборке по ее идентификатору
- DELETE /admin/compilations/{compId} - Удаление подборки по ее идентификатору
- GET /compilations - Получение подборок событий
- GET /compilations/{compId} - Получение подборки событий по ее идентификатору
- Запросы на участие
- GET /users/{userId}/requests - Получение информации о заявках текущего пользователя на участие в чужих событиях.
- POST /users/{userId}/requests - Добавление запроса от текущего пользователя на участие в событии. Нельзя добавить повторный запрос. Инициатор события не может добавить запрос на участие в своём событии. Нельзя участвовать в неопубликованном событии. Если для события отключена пре-модерация запросов на участие, то запрос автоматически перейдет в состояние подтвержденного.
- PATCH /users/{userId}/requests/{requestId}/cancel - Отмена своего запроса на участие в событии
- PATCH /users/{userId}/events/{eventId}/requests - Изменение статуса (подтверждена, отмена) заявок на участие в событии текущего пользователя
- GET /users/{userId}/events/{eventId}/requests - Получение информации о запросах на участие в событии текущего пользователя
- Комментарии к событиям
- POST /users/{userId}/events/{eventId}/comments - Добавление комментария текущего пользователя к событию. Добавить комментарий может только инициатор события или пользователь, отправивший заявку на участие в событии/
- PATCH /users/{userId}/events/{eventId}/comments/{commentId} - Редактирование комментария. Может быть выполнено только автором.
- PATCH /admin/events/{eventId}/comments/{commentId} - Редактирование комментария
- DELETE /users/{userId}/comments/{commentId} - Удаление комментария. Может быть выполнено только автором.
- DELETE /admin/users/{userId}/comments/{commentId} - Удаление комментария
- GET /events/{eventId}/comments - Получение комментариев к событию\
- GET /users/{userId}/events/{eventId}/comments - Получение всех комментариев пользователя к событию
- GET /admin/events/{eventId}/comments - Получение администратором комментариев к событию с полной технической информацией

***

Мной реализована дополнительная функциональность - возможность комментирования событий.

***
###Стек технологий
Java, Maven, Spring-Boot, Hibernate, Postgresql, Lombok, Docker-compose, RestTemplate

***
###Запуск приложения
* Сборка проекта
* mvn clean
* mvn package
* Запуск docker-compose.yml
* войти в директорию, содержащую файл docker-compose.yml
* выполнить команду docker-compose up --build
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package ru.practicum.comment;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import ru.practicum.comment.model.dto.CommentDto;
import ru.practicum.comment.model.dto.NewCommentDto;
import ru.practicum.comment.model.dto.ShortCommentDto;
import ru.practicum.comment.service.CommentService;

import javax.validation.Valid;
import javax.validation.constraints.Positive;
import java.util.List;

@RestController
@RequiredArgsConstructor
@Validated
public class CommentController {

private final CommentService service;

@RequestMapping(value = "/users/{userId}/events/{eventId}/comments", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public CommentDto add(@PathVariable @Positive Long userId, @PathVariable @Positive Long eventId,
@RequestBody @Valid NewCommentDto dto) {
return service.addNewComment(userId, eventId, dto);
}

@RequestMapping(value = "/users/{userId}/events/{eventId}/comments/{commentId}", method = RequestMethod.PATCH)
public ShortCommentDto update(@PathVariable @Positive Long userId, @PathVariable @Positive Long eventId,
@PathVariable @Positive Long commentId, @RequestBody @Valid NewCommentDto dto) {
return service.update(userId, eventId, commentId, dto);
}

@RequestMapping(value = "admin/events/{eventId}/comments/{commentId}", method = RequestMethod.PATCH)
public CommentDto adminUpdate(@PathVariable @Positive Long eventId,
@PathVariable @Positive Long commentId, @RequestBody @Valid CommentDto dto) {
return service.adminUpdate(eventId, commentId, dto);
}

@RequestMapping(value = "/users/{userId}/comments/{commentId}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable @Positive Long userId, @PathVariable @Positive Long commentId) {
service.delete(userId, commentId);
}

@RequestMapping(value = "admin/users/{userId}/comments/{commentId}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void adminDelete(@PathVariable @Positive Long userId, @PathVariable @Positive Long commentId) {
service.adminDelete(userId, commentId);
}

@RequestMapping(value = "events/{eventId}/comments", method = RequestMethod.GET)
public List<ShortCommentDto> getComments(@PathVariable @Positive Long eventId) {
return service.getEventComments(eventId);
}

@RequestMapping(value = "/users/{userId}/events/{eventId}/comments", method = RequestMethod.GET)
public List<ShortCommentDto> getUserComments(@PathVariable @Positive Long userId, @PathVariable @Positive Long eventId) {
return service.getEventUserComments(userId, eventId);
}

@RequestMapping(value = "admin/events/{eventId}/comments", method = RequestMethod.GET)
public List<CommentDto> getAdminComments(@PathVariable @Positive Long eventId) {
return service.getAdminEventComments(eventId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ru.practicum.comment.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ru.practicum.event.model.Event;
import ru.practicum.user.model.User;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.time.LocalDateTime;

import static ru.practicum.constants.Constants.DATE_TIME_FORMAT;

@Entity
@Table(name = "comments")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String text;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "event_id", referencedColumnName = "id")
private Event event;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id", referencedColumnName = "id")
private User author;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_TIME_FORMAT)
private LocalDateTime created;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.practicum.comment.model;

import org.mapstruct.Mapper;
import ru.practicum.comment.model.dto.CommentDto;
import ru.practicum.comment.model.dto.NewCommentDto;
import ru.practicum.comment.model.dto.ShortCommentDto;

@Mapper(componentModel = "spring")
public interface CommentMapper {
Comment mapNewCommentDtoToComment(NewCommentDto dto);

CommentDto mapCommentToCommentDto(Comment comment);

ShortCommentDto mapCommentToShortCommentDto(Comment comment);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ru.practicum.comment.model.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ru.practicum.event.model.dto.EventFullDto;
import ru.practicum.user.model.dto.UserDto;

import java.time.LocalDateTime;

import static ru.practicum.constants.Constants.DATE_TIME_FORMAT;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class CommentDto {
private Long id;

private String text;

private EventFullDto event;

private UserDto author;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_TIME_FORMAT)
private LocalDateTime created;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ru.practicum.comment.model.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class NewCommentDto {
@NotBlank
@Size(min = 2, max = 1000)
private String text;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.practicum.comment.model.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ru.practicum.event.model.dto.EventShortDto;
import ru.practicum.user.model.dto.UserShortDto;

import java.time.LocalDateTime;

import static ru.practicum.constants.Constants.DATE_TIME_FORMAT;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class ShortCommentDto {
private String text;

private EventShortDto event;

private UserShortDto author;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_TIME_FORMAT)
private LocalDateTime created;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.practicum.comment.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import ru.practicum.comment.model.Comment;

import java.util.List;

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {
List<Comment> findAllByEventId(Long eventId);

List<Comment> findAllByEventIdAndAuthorId(Long eventId, Long authorId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ru.practicum.comment.service;

import ru.practicum.comment.model.dto.CommentDto;
import ru.practicum.comment.model.dto.NewCommentDto;
import ru.practicum.comment.model.dto.ShortCommentDto;

import java.util.List;

public interface CommentService {
CommentDto addNewComment(Long userId, Long eventId, NewCommentDto dto);

ShortCommentDto update(Long userId, Long eventId, Long commentId, NewCommentDto dto);

CommentDto adminUpdate(Long eventId, Long commentId, CommentDto dto);

void delete(Long userId, Long commentId);

void adminDelete(Long userId, Long commentId);

List<ShortCommentDto> getEventComments(Long eventId);

List<ShortCommentDto> getEventUserComments(Long userId, Long eventId);

List<CommentDto> getAdminEventComments(Long eventId);
}
Loading

0 comments on commit e043bcf

Please sign in to comment.