diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/TimeEntryService.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/TimeEntryService.java index 990797b..d7483a4 100644 --- a/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/TimeEntryService.java +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/TimeEntryService.java @@ -42,7 +42,8 @@ public class TimeEntryService { private void checkTime(CreateTimeEntryDto timeEntryToCheck) { timeEntryRepository.findAllByUserAndDate(timeEntryToCheck.user().toUser(), timeEntryToCheck.date()) .filter(timeEntry -> - TimeEntryUtils.toTimeFrom.apply(timeEntry).isAfter(timeEntryToCheck.timeTo()) || TimeEntryUtils.toTimeTo.apply(timeEntry).isBefore(timeEntryToCheck.timeFrom())) + TimeEntryUtils.toTimeFrom.apply(timeEntry).isAfter(timeEntryToCheck.timeTo()) || + TimeEntryUtils.toTimeTo.apply(timeEntry).isBefore(timeEntryToCheck.timeFrom())) .switchIfEmpty(Mono.error(new TimeEntryServiceException("entry time conflict"))); } } diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/UserService.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/UserService.java index d819431..53aada9 100644 --- a/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/UserService.java +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/application/service/UserService.java @@ -51,6 +51,9 @@ public class UserService { return userRepository .findById(userId) .flatMap(user -> { + + // when teamId is not null then list of members in related team will be updated + String teamId = UserUtils.toTeamId.apply(user); if (teamId != null) { teamRepository diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/infrastructure/persistence/dao/TeamDao.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/infrastructure/persistence/dao/TeamDao.java index 807215a..ebd326b 100644 --- a/src/main/java/net/szymonsawicki/reactivetimesheetapp/infrastructure/persistence/dao/TeamDao.java +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/infrastructure/persistence/dao/TeamDao.java @@ -1,6 +1,5 @@ package net.szymonsawicki.reactivetimesheetapp.infrastructure.persistence.dao; -import net.szymonsawicki.reactivetimesheetapp.domain.team.Team; import net.szymonsawicki.reactivetimesheetapp.infrastructure.persistence.entity.TeamEntity; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import reactor.core.publisher.Mono; diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/Routing.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/Routing.java new file mode 100644 index 0000000..add305c --- /dev/null +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/Routing.java @@ -0,0 +1,4 @@ +package net.szymonsawicki.reactivetimesheetapp.web; + +public class Routing { +} diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/config/GlobalRoutingHandler.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/config/GlobalRoutingHandler.java new file mode 100644 index 0000000..b93eb6e --- /dev/null +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/config/GlobalRoutingHandler.java @@ -0,0 +1,27 @@ +package net.szymonsawicki.reactivetimesheetapp.web.config; + +import net.szymonsawicki.reactivetimesheetapp.web.error.ErrorDto; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +public interface GlobalRoutingHandler { + + // Helper method for generic request processing and error handling + + static Mono doRequest(Mono action, HttpStatus httpStatus) { + return action + .flatMap(result -> ServerResponse + .status(httpStatus) + .contentType(MediaType.APPLICATION_JSON) + .body(BodyInserters.fromValue(result)) + ) + .onErrorResume(error -> ServerResponse + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .contentType(MediaType.APPLICATION_JSON) + .body(BodyInserters.fromValue(new ErrorDto(error.getMessage()))) + ); + } +} diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/error/ErrorDto.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/error/ErrorDto.java new file mode 100644 index 0000000..8f9eea4 --- /dev/null +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/error/ErrorDto.java @@ -0,0 +1,4 @@ +package net.szymonsawicki.reactivetimesheetapp.web.error; + +public record ErrorDto(String message) { +} diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/TeamHandler.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/TeamHandler.java new file mode 100644 index 0000000..393552d --- /dev/null +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/TeamHandler.java @@ -0,0 +1,11 @@ +package net.szymonsawicki.reactivetimesheetapp.web.handler; + +import lombok.RequiredArgsConstructor; +import net.szymonsawicki.reactivetimesheetapp.application.service.TeamService; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class TeamHandler { + private final TeamService teamService; +} diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/TimeEntryHandler.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/TimeEntryHandler.java new file mode 100644 index 0000000..af97153 --- /dev/null +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/TimeEntryHandler.java @@ -0,0 +1,12 @@ +package net.szymonsawicki.reactivetimesheetapp.web.handler; + + +import lombok.RequiredArgsConstructor; +import net.szymonsawicki.reactivetimesheetapp.application.service.TimeEntryService; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class TimeEntryHandler { + private final TimeEntryService timeEntryService; +} diff --git a/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/UserHandler.java b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/UserHandler.java new file mode 100644 index 0000000..ba6f73f --- /dev/null +++ b/src/main/java/net/szymonsawicki/reactivetimesheetapp/web/handler/UserHandler.java @@ -0,0 +1,38 @@ +package net.szymonsawicki.reactivetimesheetapp.web.handler; + + +import lombok.RequiredArgsConstructor; +import net.szymonsawicki.reactivetimesheetapp.application.service.UserService; +import net.szymonsawicki.reactivetimesheetapp.domain.user.dto.CreateUserDto; +import net.szymonsawicki.reactivetimesheetapp.web.config.GlobalRoutingHandler; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +@RequiredArgsConstructor +public class UserHandler { + private final UserService userService; + + public Mono findById(ServerRequest serverRequest) { + var userId = serverRequest.pathVariable("userId"); + return GlobalRoutingHandler.doRequest(userService.findById(userId), HttpStatus.OK); + } + + public Mono findByUsername(ServerRequest serverRequest) { + var username = serverRequest.pathVariable("username"); + return GlobalRoutingHandler.doRequest(userService.findById(username), HttpStatus.OK); + } + + public Mono createUser(ServerRequest serverRequest) { + var createUsertDtoMono = serverRequest.bodyToMono(CreateUserDto.class); + return GlobalRoutingHandler.doRequest(userService.addUser(createUsertDtoMono), HttpStatus.CREATED); + } + + public Mono deleteUser(ServerRequest serverRequest) { + var userId = serverRequest.pathVariable("userId"); + return GlobalRoutingHandler.doRequest(userService.deleteUser(userId), HttpStatus.OK); + } +}