Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
27ee5aa
схема базы данных
andrej1307 May 22, 2025
16f0e48
feat: /admin/users
andrej1307 May 25, 2025
618de41
feat: ErrorAdvisor.java
andrej1307 May 25, 2025
73272f6
fix: ErrorAdvisor.java
andrej1307 May 26, 2025
8a5b7d1
feat: /admin/categories
andrej1307 May 26, 2025
07a2de3
fix: /admin/categories добавлены DTO классы
andrej1307 May 27, 2025
b4dc2da
добавлен класс event.java
andrej1307 May 28, 2025
9abd3ef
добавлен репозиторий событий и DTO
andrej1307 May 29, 2025
10759e2
feat: EventService.java, UserController.java
andrej1307 May 30, 2025
dce75ef
feat: добавлена работа с запросами на участие
andrej1307 Jun 1, 2025
3d55695
fix: доработана работа с запросами на участие
andrej1307 Jun 2, 2025
02d9e90
feat: подтверждение заявок.
andrej1307 Jun 3, 2025
9eb7326
fix: подтверждение запросов
andrej1307 Jun 3, 2025
cda0629
fix: подтверждение запросов 2
andrej1307 Jun 5, 2025
c88b518
feat: реализованы запросстатистики просмотра событий
andrej1307 Jun 8, 2025
db48cfd
feat: поиск событий
andrej1307 Jun 9, 2025
3c23627
fix: поиск событий
andrej1307 Jun 10, 2025
43ca45f
fix: поиск событий, доработка параметров поиска.
andrej1307 Jun 11, 2025
ad7ccde
feat: поиск событий администратором
andrej1307 Jun 12, 2025
ac8f7a0
тесты PostMan - OK
andrej1307 Jun 16, 2025
1d6477e
исправление ошибок стиля
andrej1307 Jun 16, 2025
1a7fbca
исправление ошибок стиля 2
andrej1307 Jun 16, 2025
0146903
исправление ошибок стиля 2
andrej1307 Jun 16, 2025
42eb6c5
исправление ошибок 3
andrej1307 Jun 17, 2025
8ae7431
fix: schema.sql
andrej1307 Jun 17, 2025
c7ae705
fix: docker-compose.yml
andrej1307 Jun 17, 2025
69985d3
fix: docker-compose.yml 2
andrej1307 Jul 3, 2025
e25ab72
fix: исправлена работа с сервером статистики
andrej1307 Jul 7, 2025
803a180
fix: исправление замечаний ревьювера
andrej1307 Jul 9, 2025
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
14,630 changes: 14,630 additions & 0 deletions Postman/ewm-main-service.json

Large diffs are not rendered by default.

1,027 changes: 1,027 additions & 0 deletions Postman/ewm-stat-service.json

Large diffs are not rendered by default.

44 changes: 23 additions & 21 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
version: '3.1'
services:
stats-server:
build: stats-server
image: stats-server
container_name: stats-server
ports:
- "9090:9090"
depends_on:
- stats-db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://stats-db:5432/statdb
- SPRING_DATASOURCE_USERNAME=statdb
- SPRING_DATASOURCE_PASSWORD=statdb

stats-db:
image: postgres:16.1
image: postgres:14-alpine
container_name: postgres-stat
ports:
- "5432:5432"
Expand All @@ -15,42 +28,31 @@ services:
interval: 5s
retries: 10

stats-server:
build: stats-server
image: stats-server
container_name: stats-server
ports:
- "9090:9090"
depends_on:
- stats-db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://stats-db:5432/statdb
- SPRING_DATASOURCE_USERNAME=statdb
- SPRING_DATASOURCE_PASSWORD=statdb

ewm-service:
build: ewm-service
image: ewm-service
container_name: ewm-service
ports:
- "8080:8080"
depends_on:
- stats-server
- ewm-db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://ewm-db:5432/ewmdb
- SPRING_DATASOURCE_USERNAME=ewmdb
- SPRING_DATASOURCE_PASSWORD=ewmdb
- STATSERVER_URL=http://stats-server:9090

ewm-db:
image: postgres:16.1
image: postgres:14-alpine
container_name: postgres-ewm
ports:
- "5434:5434"
- "5434:5432"
environment:
- POSTGRES_PASSWORD=statewm
- POSTGRES_USER=statewm
- POSTGRES_DB=statewm
- POSTGRES_PASSWORD=ewmdb
- POSTGRES_USER=ewmdb
- POSTGRES_DB=ewmdb
healthcheck:
test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER
timeout: 5s
interval: 5s
retries: 10

7 changes: 6 additions & 1 deletion ewm-service/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# ewm-service
# ewm-service
Сервис событий

Схема базы данных.
![схема базы данных](/schema.png)

17 changes: 14 additions & 3 deletions ewm-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
Expand All @@ -51,6 +51,17 @@
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>ru.practicum</groupId>
<artifactId>stat-client</artifactId>
Expand Down
Binary file added ewm-service/schema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
import org.springframework.web.util.DefaultUriBuilderFactory;
import ru.practicum.statclient.BaseClient;
import ru.practicum.statdto.HitDto;
import ru.practicum.statdto.StatsDto;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Component
public class StatsClient extends BaseClient {
private static final String PREFIX_HIT = "/hit";
private static final String PREFIX_STATS = "/stats";
private static final String PREFIX_EVENTS = "/events/";

@Autowired
public StatsClient(@Value("${statserver.url}") String serverUrl, RestTemplateBuilder builder) {
Expand All @@ -35,4 +39,33 @@ public void post(HitDto dto) {
public ResponseEntity<Object> get(Map<String, Object> parameters) {
return makeAndSendRequest(HttpMethod.GET, PREFIX_STATS, parameters, null);
}

public void hitInfo(String appName, String uri, String ip) {
HitDto hitDto = new HitDto();
hitDto.setApp(appName);
hitDto.setUri(uri);
hitDto.setIp(ip);
hitDto.setTimestamp(LocalDateTime.now());
post(hitDto);
}

public Integer getEventViews(Integer eventId, Boolean unique) {
Map<String, Object> parameters = Map.of("uris", PREFIX_EVENTS + eventId,
"unique", unique);
List<StatsDto> dtos = getStatsList(PREFIX_STATS, parameters);
if (dtos.isEmpty()) {
return 0;
}
return dtos.getFirst().getHits();
}

public List<StatsDto> getEventViewsByUris(List<String> eventUris, Boolean unique) {
StringBuilder urisBuilder = new StringBuilder(eventUris.getFirst());
for (int i = 1; i < eventUris.size(); i++) {
urisBuilder.append(",").append(eventUris.get(i));
}
Map<String, Object> parameters = Map.of("uris", urisBuilder.toString(),
"unique", unique);
return getStatsList(PREFIX_STATS, parameters);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ru.practicum.evmsevice.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.practicum.evmsevice.dto.CategoryDto;
import ru.practicum.evmsevice.dto.NewCategoryDto;
import ru.practicum.evmsevice.service.CategoryService;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/categories")
public class AdminCategoriesController {
private final CategoryService categoryService;

@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
public CategoryDto createCategory(@Validated @RequestBody NewCategoryDto categoryDto) {
log.info("Создаем категорию {}.", categoryDto.getName());
return categoryService.createCategory(categoryDto);
}

@PatchMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public CategoryDto updateCategory(@Validated @RequestBody NewCategoryDto categoryDto,
@PathVariable int id) {
log.info("Обновляем категорию id={}.", id);
return categoryService.updateCategory(id, categoryDto);
}

@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCategory(@PathVariable int id) {
log.info("Администратор удаляет категорию id={}.", id);
categoryService.deleteCategory(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ru.practicum.evmsevice.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.practicum.evmsevice.dto.CompilationDto;
import ru.practicum.evmsevice.dto.NewCompilationDto;
import ru.practicum.evmsevice.dto.PatchCompilationDto;
import ru.practicum.evmsevice.service.CompilationService;

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

@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
public CompilationDto createCompilation(@Validated @RequestBody NewCompilationDto newCompilationDto) {
log.info("Администратор создает подборку событий '{}'.", newCompilationDto.getTitle());
return compilationService.createCompilation(newCompilationDto);
}

@PatchMapping("/{compId}")
@ResponseStatus(HttpStatus.OK)
public CompilationDto updateCompilation(@PathVariable Integer compId,
@Validated @RequestBody PatchCompilationDto compilationDto) {
log.info("Администратор обновляет подборку событий '{}'.", compilationDto.getTitle());
return compilationService.patchCompilation(compId, compilationDto);
}

@DeleteMapping("/{compId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCompilation(@PathVariable Integer compId) {
log.info("Администратор удаляет подборку событий id={}.", compId);
compilationService.deleteCompilation(compId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ru.practicum.evmsevice.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.practicum.evmsevice.dto.EventFullDto;
import ru.practicum.evmsevice.dto.UpdateEventAdminRequest;
import ru.practicum.evmsevice.service.EventService;

import java.util.List;

/**
* Класс обработки запросов администратора
*/
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/events")
public class AdminEventsController {
private final EventService eventService;

@GetMapping()
@ResponseStatus(HttpStatus.OK)
public List<EventFullDto> findEvents(
@RequestParam(name = "users", required = false) List<Integer> users,
@RequestParam(name = "states", required = false) List<String> states,
@RequestParam(name = "categories", required = false) List<Integer> categories,
@RequestParam(name = "rangeStart", required = false) String rangeStart,
@RequestParam(name = "rangeEnd", required = false) String rangeEnd,
@RequestParam(name = "from", defaultValue = "0") Integer from,
@RequestParam(name = "size", defaultValue = "10") Integer size) {
log.info("Администратор запрашивает список событий. users:{}, states:{}, categories:{} rangeStart:{}, rangeStart:{}.",
users, states, categories, rangeStart, rangeEnd);
return eventService.findEventsByAdmin(states, users, categories, rangeStart, rangeEnd, from, size);
}

@PatchMapping("/{eventId}")
@ResponseStatus(HttpStatus.OK)
public EventFullDto updateEvent(@PathVariable Integer eventId,
@RequestBody @Validated UpdateEventAdminRequest eventDto) {
log.info("Администратор редактирует событие id={}. {}", eventId, eventDto);
return eventService.adminUpdateEvent(eventId, eventDto);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ru.practicum.evmsevice.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import ru.practicum.evmsevice.dto.UserDto;
import ru.practicum.evmsevice.mapper.UserMapper;
import ru.practicum.evmsevice.model.User;
import ru.practicum.evmsevice.service.UserService;

import java.util.List;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/users")
public class AdminUsersController {
private final UserService userService;

@GetMapping()
@ResponseStatus(HttpStatus.OK)
public List<UserDto> getUsers(
@RequestParam(name = "ids", required = false) List<Integer> ids,
@RequestParam(name = "from", defaultValue = "0") Integer from,
@RequestParam(name = "size", defaultValue = "10") Integer size) {
log.info("Администратор запрашивает запрашивает список пользователей. {}", ids);
List<User> users;
if (ids != null) {
users = userService.getUsers(ids);
} else {
users = userService.getUsers();
}
return users.stream()
.map(UserMapper::toUserDto)
.skip(from)
.limit(size)
.toList();
}

@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public UserDto getUser(@PathVariable Integer id) {
log.info("Выполняем поиск пользователя id={}.", id);
User user = userService.getUserById(id);
return UserMapper.toUserDto(user);
}

@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
public UserDto createUser(@Validated @RequestBody UserDto userDto) {
log.info("Создаем нового пользователя {}", userDto.toString());
User savedUser = userService.addUser(UserMapper.toUser(userDto));
return UserMapper.toUserDto(savedUser);
}

@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteUser(@PathVariable Integer id) {
log.info("Удаляем пользователя {}", id);
userService.deleteUser(id);
}

}
Loading