diff --git a/pom.xml b/pom.xml index 2db888c..c890aeb 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ 21 + 3.3.1 @@ -82,6 +83,27 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven-checkstyle-plugin.version} + + + true + true + true + checkstyle.xml + + + + + + check + + compile + + + diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index bb17668..4cdcdc7 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,12 +1,55 @@ package ru.practicum.shareit.item; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.constraints.Positive; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.item.dto.ItemDto; +import ru.practicum.shareit.item.service.ItemService; +import ru.practicum.shareit.validation.OnCreate; +import ru.practicum.shareit.validation.OnUpdate; + +import java.util.Collection; /** * TODO Sprint add-controllers. */ @RestController @RequestMapping("/items") +@RequiredArgsConstructor public class ItemController { + + private static final String USER_ID_HEADER = "X-Sharer-User-Id"; + private final ItemService itemService; + + @GetMapping("/{itemId}") + public ItemDto getItem(@PathVariable @Positive Long itemId) { + return itemService.getItem(itemId); + } + + @GetMapping("/search") + public Collection searchItems(@RequestParam String text) { + return itemService.searchItems(text); + } + + @GetMapping + public Collection getItems(@RequestHeader(USER_ID_HEADER) @Positive Long userId) { + return itemService.getItems(userId); + } + + @PostMapping + public ItemDto addItem( + @RequestHeader(USER_ID_HEADER) @Positive Long userId, + @RequestBody @Validated(OnCreate.class) ItemDto itemDto) { + return itemService.addItem(userId, itemDto); + } + + @PatchMapping("/{itemId}") + public ItemDto updateItem( + @RequestHeader(USER_ID_HEADER) @Positive Long userId, + @PathVariable @Positive Long itemId, + @RequestBody @Validated(OnUpdate.class) ItemDto itemDto) { + return itemService.updateItem(userId, itemId, itemDto); + } + } diff --git a/src/main/java/ru/practicum/shareit/item/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/ItemMapper.java new file mode 100644 index 0000000..05c0b4d --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/ItemMapper.java @@ -0,0 +1,24 @@ +package ru.practicum.shareit.item; + +import ru.practicum.shareit.item.dto.ItemDto; +import ru.practicum.shareit.item.model.Item; + +public class ItemMapper { + public static Item toItem(ItemDto itemDto) { + Item item = new Item(); + item.setId(itemDto.getId()); + item.setName(itemDto.getName()); + item.setDescription(itemDto.getDescription()); + item.setIsAvailable(itemDto.getAvailable()); + return item; + } + + public static ItemDto toItemDto(Item item) { + ItemDto itemDto = new ItemDto(); + itemDto.setId(item.getId()); + itemDto.setName(item.getName()); + itemDto.setDescription(item.getDescription()); + itemDto.setAvailable(item.getIsAvailable()); + return itemDto; + } +} diff --git a/src/main/java/ru/practicum/shareit/item/dao/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/dao/ItemRepository.java new file mode 100644 index 0000000..d785762 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dao/ItemRepository.java @@ -0,0 +1,18 @@ +package ru.practicum.shareit.item.dao; + +import ru.practicum.shareit.item.model.Item; + +import java.util.Collection; +import java.util.Optional; + +public interface ItemRepository { + Optional getItem(Long itemId); + + Collection searchItems(String text); + + Collection getItems(Long userId); + + Item addItem(Item item); + + Optional updateItem(Item item); +} diff --git a/src/main/java/ru/practicum/shareit/item/dao/ItemRepositoryInMemory.java b/src/main/java/ru/practicum/shareit/item/dao/ItemRepositoryInMemory.java new file mode 100644 index 0000000..e899f9b --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dao/ItemRepositoryInMemory.java @@ -0,0 +1,78 @@ +package ru.practicum.shareit.item.dao; + +import org.springframework.stereotype.Repository; +import ru.practicum.shareit.item.model.Item; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +@Repository +public class ItemRepositoryInMemory implements ItemRepository { + + private final Map storage = new ConcurrentHashMap<>(); + private final AtomicLong idCounter = new AtomicLong(1L); + + @Override + public Optional getItem(Long itemId) { + return Optional.ofNullable(storage.get(itemId)); + } + + @Override + public Collection searchItems(String text) { + return storage.values() + .stream() + .filter(Item::getIsAvailable) + .filter(item -> + item.getName().toLowerCase(Locale.ROOT).contains(text) || + item.getDescription().toLowerCase(Locale.ROOT).contains(text)) + .toList(); + } + + @Override + public Collection getItems(Long userId) { + return storage.values() + .stream() + .filter(item -> Objects.equals(item.getOwnerId(), userId)) + .toList(); + } + + @Override + public Item addItem(Item item) { + Long id = idCounter.getAndIncrement(); + item.setId(id); + storage.put(id, item); + + return item; + } + + @Override + public Optional updateItem(Item newItem) { + if (!storage.containsKey(newItem.getId())) { + return Optional.empty(); + } + + Item oldItem = storage.get(newItem.getId()); + patchItem(oldItem, newItem); + + return Optional.of(oldItem); + } + + private void patchItem(Item oldItem, Item newItem) { + String name = newItem.getName(); + String description = newItem.getDescription(); + Boolean isAvailable = newItem.getIsAvailable(); + + if (name != null) { + oldItem.setName(name); + } + + if (description != null) { + oldItem.setDescription(description); + } + + if (isAvailable != null) { + oldItem.setIsAvailable(isAvailable); + } + } +} diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java index 9319d7d..c26a3ca 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java @@ -1,7 +1,28 @@ package ru.practicum.shareit.item.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.validation.OnCreate; +import ru.practicum.shareit.validation.OnUpdate; + /** * TODO Sprint add-controllers. */ +@Data +@AllArgsConstructor +@NoArgsConstructor public class ItemDto { + private Long id; + @Size(groups = OnUpdate.class, min = 1, message = "Название предмета должно быть заполнено") + @NotBlank(groups = OnCreate.class, message = "Название предмета должно быть заполнено") + private String name; + @Size(groups = OnUpdate.class, min = 1, message = "Описание предмета должно быть заполнено") + @NotBlank(groups = OnCreate.class, message = "Описание предмета должно быть заполнено") + private String description; + @NotNull(groups = OnCreate.class, message = "Статус должен быть заполнен") + private Boolean available; } diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 44eb73d..93f135d 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,7 +1,19 @@ package ru.practicum.shareit.item.model; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + /** * TODO Sprint add-controllers. */ +@Data +@AllArgsConstructor +@NoArgsConstructor public class Item { + private Long id; + private String name; + private String description; + private Boolean isAvailable; + private Long ownerId; } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java new file mode 100644 index 0000000..d5ac715 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.item.service; + +import ru.practicum.shareit.item.dto.ItemDto; + +import java.util.Collection; + +public interface ItemService { + ItemDto getItem(Long itemId); + + Collection searchItems(String text); + + Collection getItems(Long userId); + + ItemDto addItem(Long userId, ItemDto itemDto); + + ItemDto updateItem(Long userId, Long itemId, ItemDto itemDto); +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java new file mode 100644 index 0000000..4b633b8 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -0,0 +1,92 @@ +package ru.practicum.shareit.item.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.practicum.shareit.item.ItemMapper; +import ru.practicum.shareit.item.dao.ItemRepository; +import ru.practicum.shareit.item.dto.ItemDto; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.dao.UserRepository; +import ru.practicum.shareit.validation.NotFoundException; + +import java.util.Collection; +import java.util.Collections; +import java.util.Locale; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class ItemServiceImpl implements ItemService { + + private final ItemRepository itemRepository; + private final UserRepository userRepository; + + @Override + public ItemDto getItem(Long itemId) { + Optional maybeItem = itemRepository.getItem(itemId); + + if (maybeItem.isPresent()) { + return ItemMapper.toItemDto(maybeItem.get()); + } + + throw new NotFoundException("Предмет с id " + itemId + " не найден"); + } + + @Override + public Collection searchItems(String text) { + if (text == null || text.isBlank()) { + return Collections.emptyList(); + } + + text = text.toLowerCase(Locale.ROOT); + + return itemRepository.searchItems(text) + .stream() + .map(ItemMapper::toItemDto) + .toList(); + } + + @Override + public Collection getItems(Long userId) { + throwIfUserNotFound(userId); + + Collection items = itemRepository.getItems(userId); + + return items.stream() + .map(ItemMapper::toItemDto) + .toList(); + } + + @Override + public ItemDto addItem(Long userId, ItemDto itemDto) { + throwIfUserNotFound(userId); + + Item item = ItemMapper.toItem(itemDto); + item.setOwnerId(userId); + + return ItemMapper.toItemDto(itemRepository.addItem(item)); + } + + @Override + public ItemDto updateItem(Long userId, Long itemId, ItemDto itemDto) { + throwIfUserNotFound(userId); + + Item item = ItemMapper.toItem(itemDto); + item.setOwnerId(userId); + item.setId(itemId); + + Optional maybeItem = itemRepository.updateItem(item); + + if (maybeItem.isPresent()) { + return ItemMapper.toItemDto(maybeItem.get()); + } + + throw new NotFoundException("Предмет с id " + itemId + " не найден"); + } + + private void throwIfUserNotFound(Long userId) { + if (!userRepository.contains(userId)) { + throw new NotFoundException("Пользователь с id " + userId + " не найден"); + } + } +} diff --git a/src/main/java/ru/practicum/shareit/user/User.java b/src/main/java/ru/practicum/shareit/user/User.java deleted file mode 100644 index ae6e7f3..0000000 --- a/src/main/java/ru/practicum/shareit/user/User.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.user; - -/** - * TODO Sprint add-controllers. - */ -public class User { -} diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 03039b9..4da9340 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -1,12 +1,44 @@ package ru.practicum.shareit.user; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.constraints.Positive; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.service.UserService; +import ru.practicum.shareit.validation.OnCreate; +import ru.practicum.shareit.validation.OnUpdate; /** * TODO Sprint add-controllers. */ @RestController @RequestMapping(path = "/users") +@RequiredArgsConstructor public class UserController { + + private final UserService userService; + + @GetMapping("/{userId}") + public User getUser(@PathVariable @Positive Long userId) { + return userService.getUser(userId); + } + + @PostMapping + public User addUser(@RequestBody @Validated(OnCreate.class) UserDto user) { + return userService.addUser(user); + } + + @PatchMapping("/{userId}") + public User updateUser( + @PathVariable @Positive Long userId, + @RequestBody @Validated(OnUpdate.class) UserDto user) { + return userService.updateUser(userId, user); + } + + @DeleteMapping("/{userId}") + public void deleteUser(@PathVariable @Positive Long userId) { + userService.deleteUser(userId); + } } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java new file mode 100644 index 0000000..7adf898 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -0,0 +1,13 @@ +package ru.practicum.shareit.user; + +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.model.User; + +public class UserMapper { + public static User toUser(UserDto userDto) { + User user = new User(); + user.setName(userDto.getName()); + user.setEmail(userDto.getEmail()); + return user; + } +} diff --git a/src/main/java/ru/practicum/shareit/user/dao/UserRepository.java b/src/main/java/ru/practicum/shareit/user/dao/UserRepository.java new file mode 100644 index 0000000..2f185ef --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dao/UserRepository.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.user.dao; + +import ru.practicum.shareit.user.model.User; + +import java.util.Optional; + +public interface UserRepository { + Optional getUser(Long userId); + + User addUser(User user); + + Optional updateUser(User user); + + boolean deleteUser(Long userId); + + boolean contains(Long userId); +} diff --git a/src/main/java/ru/practicum/shareit/user/dao/UserRepositoryInMemory.java b/src/main/java/ru/practicum/shareit/user/dao/UserRepositoryInMemory.java new file mode 100644 index 0000000..aadb2c1 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dao/UserRepositoryInMemory.java @@ -0,0 +1,82 @@ +package ru.practicum.shareit.user.dao; + +import org.springframework.stereotype.Repository; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.validation.NotUniqueException; + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +@Repository +public class UserRepositoryInMemory implements UserRepository { + + private final Map storage = new ConcurrentHashMap<>(); + private final AtomicLong idCounter = new AtomicLong(1L); + + @Override + public Optional getUser(Long userId) { + return Optional.ofNullable(storage.get(userId)); + } + + @Override + public User addUser(User user) { + if (isEmailTaken(user.getEmail())) { + throw new NotUniqueException("Email " + user.getEmail() + " уже занят"); + } + + Long id = idCounter.getAndIncrement(); + user.setId(id); + storage.put(id, user); + + return user; + } + + @Override + public Optional updateUser(User newUser) { + if (!storage.containsKey(newUser.getId())) { + return Optional.empty(); + } + + User oldUser = storage.get(newUser.getId()); + patchUser(oldUser, newUser); + + return Optional.of(oldUser); + + } + + @Override + public boolean deleteUser(Long userId) { + User user = storage.remove(userId); + + return user != null; + } + + @Override + public boolean contains(Long userId) { + return storage.containsKey(userId); + } + + private boolean isEmailTaken(String email) { + return storage.values() + .stream() + .anyMatch(user -> user.getEmail().equals(email)); + } + + private void patchUser(User oldUser, User newUser) { + String name = newUser.getName(); + String email = newUser.getEmail(); + + if (name != null) { + oldUser.setName(name); + } + + if (email != null) { + if (isEmailTaken(email)) { + throw new NotUniqueException("Email " + email + " уже занят"); + } + oldUser.setEmail(email); + } + } +} diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDto.java b/src/main/java/ru/practicum/shareit/user/dto/UserDto.java new file mode 100644 index 0000000..bf5f27c --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDto.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.user.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Data; +import ru.practicum.shareit.validation.OnCreate; +import ru.practicum.shareit.validation.OnUpdate; + +@Data +public class UserDto { + @Size(groups = OnUpdate.class, min = 1, message = "Имя пользователя должно быть заполнено") + @NotBlank(groups = OnCreate.class, message = "Имя пользователя должно быть заполнено") + private String name; + @NotNull(groups = OnCreate.class, message = "Почта должна быть заполнена") + @Email(groups = {OnCreate.class, OnUpdate.class}, message = "Почта должна соответствовать формату") + private String email; +} diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/src/main/java/ru/practicum/shareit/user/model/User.java new file mode 100644 index 0000000..0a07207 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.user.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * TODO Sprint add-controllers. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class User { + private Long id; + private String name; + private String email; +} diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java new file mode 100644 index 0000000..ba3e769 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -0,0 +1,14 @@ +package ru.practicum.shareit.user.service; + +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.model.User; + +public interface UserService { + User getUser(Long userId); + + User addUser(UserDto userDto); + + User updateUser(Long userId, UserDto userDto); + + void deleteUser(Long userId); +} diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java new file mode 100644 index 0000000..82250d9 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -0,0 +1,49 @@ +package ru.practicum.shareit.user.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.dao.UserRepository; +import ru.practicum.shareit.user.dto.UserDto; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.validation.NotFoundException; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + + @Override + public User getUser(Long userId) { + Optional maybeUser = userRepository.getUser(userId); + + return maybeUser.orElseThrow(() -> new NotFoundException("Пользователь с id " + userId + " не найден")); + } + + @Override + public User addUser(UserDto userDto) { + return userRepository.addUser(UserMapper.toUser(userDto)); + } + + @Override + public User updateUser(Long userId, UserDto userDto) { + User user = UserMapper.toUser(userDto); + user.setId(userId); + + Optional maybeUser = userRepository.updateUser(user); + + return maybeUser.orElseThrow(() -> new NotFoundException("Пользователь с id " + userId + " не найден")); + } + + @Override + public void deleteUser(Long userId) { + boolean isDeleted = userRepository.deleteUser(userId); + + if (!isDeleted) { + throw new NotFoundException("Пользователь с id " + userId + " не найден"); + } + } +} diff --git a/src/main/java/ru/practicum/shareit/validation/GlobalExceptionHandler.java b/src/main/java/ru/practicum/shareit/validation/GlobalExceptionHandler.java new file mode 100644 index 0000000..64b34f4 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/validation/GlobalExceptionHandler.java @@ -0,0 +1,40 @@ +package ru.practicum.shareit.validation; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions( + MethodArgumentNotValidException ex) { + + Map errors = new HashMap<>(); + + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); + } + + @ExceptionHandler(NotFoundException.class) + public ResponseEntity> handleNotFoundException(NotFoundException ex) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Collections.singletonMap("error", ex.getMessage())); + } + + @ExceptionHandler(NotUniqueException.class) + public ResponseEntity> handleNotUniqueException(NotUniqueException ex) { + return ResponseEntity.status(HttpStatus.CONFLICT).body(Collections.singletonMap("error", ex.getMessage())); + } +} diff --git a/src/main/java/ru/practicum/shareit/validation/NotFoundException.java b/src/main/java/ru/practicum/shareit/validation/NotFoundException.java new file mode 100644 index 0000000..d47b817 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/validation/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.validation; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/validation/NotUniqueException.java b/src/main/java/ru/practicum/shareit/validation/NotUniqueException.java new file mode 100644 index 0000000..7881e2a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/validation/NotUniqueException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.validation; + +public class NotUniqueException extends RuntimeException { + public NotUniqueException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/validation/OnCreate.java b/src/main/java/ru/practicum/shareit/validation/OnCreate.java new file mode 100644 index 0000000..5f99494 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/validation/OnCreate.java @@ -0,0 +1,4 @@ +package ru.practicum.shareit.validation; + +public interface OnCreate { +} diff --git a/src/main/java/ru/practicum/shareit/validation/OnUpdate.java b/src/main/java/ru/practicum/shareit/validation/OnUpdate.java new file mode 100644 index 0000000..39f429a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/validation/OnUpdate.java @@ -0,0 +1,4 @@ +package ru.practicum.shareit.validation; + +public interface OnUpdate { +}