Skip to content
Open
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
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<version.kikaha>2.1.8.Final</version.kikaha>
<version.logback>1.2.3</version.logback>
<version.junit>4.13.1</version.junit>
<version.javax.annotation>1.3.2</version.javax.annotation>

<!-- project structure -->
<config.dir.source>source</config.dir.source>
Expand Down Expand Up @@ -76,7 +77,7 @@
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<version>${version.javax.annotation}</version>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package backend.challenge.modules.task.converter;

import backend.challenge.modules.task.dtos.TaskDTO;
import backend.challenge.modules.task.dtos.TaskProgressDTO;
import backend.challenge.modules.task.infra.http.api.request.CreateTaskRequest;
import backend.challenge.modules.task.infra.http.api.request.UpdateTaskProgressRequest;
import backend.challenge.modules.task.infra.http.api.request.UpdateTaskRequest;
import backend.challenge.modules.task.infra.http.api.response.TaskResponse;
import backend.challenge.modules.task.models.Task;

import java.util.UUID;

public interface ITaskConverter {
TaskDTO createTaskRequestToTaskDto(CreateTaskRequest createTaskRequest);
TaskDTO updateTaskRequestToTaskDto(UpdateTaskRequest updateTaskRequest);
Task taskDtoToTask(TaskDTO taskDTO);
TaskProgressDTO updateTaskProgressRequestToTaskProgressDto(UUID taskId, UpdateTaskProgressRequest updateTaskProgressRequest);
TaskResponse taskToTaskResponse(Task task);
}
56 changes: 56 additions & 0 deletions source/backend/challenge/modules/task/converter/TaskConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package backend.challenge.modules.task.converter;

import backend.challenge.modules.task.dtos.TaskDTO;
import backend.challenge.modules.task.dtos.TaskProgressDTO;
import backend.challenge.modules.task.infra.http.api.request.CreateTaskRequest;
import backend.challenge.modules.task.infra.http.api.request.UpdateTaskProgressRequest;
import backend.challenge.modules.task.infra.http.api.request.UpdateTaskRequest;
import backend.challenge.modules.task.infra.http.api.response.TaskResponse;
import backend.challenge.modules.task.models.Task;

import javax.inject.Singleton;
import java.util.UUID;

@Singleton
public class TaskConverter implements ITaskConverter {

@Override
public TaskDTO createTaskRequestToTaskDto(CreateTaskRequest createTaskRequest) {
return TaskDTO.create()
.setTitle(createTaskRequest.getTitle())
.setDescription(createTaskRequest.getDescription());
}

@Override
public TaskDTO updateTaskRequestToTaskDto(UpdateTaskRequest updateTaskRequest) {
return TaskDTO.create()
.setTitle(updateTaskRequest.getTitle())
.setDescription(updateTaskRequest.getDescription());
}

@Override
public Task taskDtoToTask(TaskDTO taskDTO) {
return new Task()
.setTitle(taskDTO.getTitle())
.setDescription(taskDTO.getDescription());
}

@Override
public TaskProgressDTO updateTaskProgressRequestToTaskProgressDto(UUID taskId, UpdateTaskProgressRequest updateTaskProgressRequest) {
return TaskProgressDTO.create()
.setId(taskId)
.setProgress(updateTaskProgressRequest.getProgress());
}

@Override
public TaskResponse taskToTaskResponse(Task task) {
return new TaskResponse()
.setId(task.getId())
.setTitle(task.getTitle())
.setDescription(task.getDescription())
.setStatus(task.getStatus())
.setProgress(task.getProgress())
.setCreatedAt(task.getCreatedAt().toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
import lombok.Setter;
import lombok.experimental.Accessors;

import java.util.UUID;

@Getter
@Setter
@Accessors(chain = true)
@NoArgsConstructor(staticName = "create")
public class TaskProgressDTO {

private Long id;
private UUID id;
private int progress;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package backend.challenge.modules.task.exception;

import java.util.UUID;

public class InvalidTaskProgressException extends RuntimeException {

public InvalidTaskProgressException(){
super("The task progress value must not be less than 0 or greater than 100!");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package backend.challenge.modules.task.exception;

import java.util.UUID;

public class TaskNotFoundException extends RuntimeException {

public TaskNotFoundException(UUID taskId){
super("Task with id {"+taskId.toString()+"} was not found!");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package backend.challenge.modules.task.infra.http.api.request;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class CreateTaskRequest {

private String title;
private String description;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package backend.challenge.modules.task.infra.http.api.request;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class UpdateTaskProgressRequest {

private int progress;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package backend.challenge.modules.task.infra.http.api.request;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class UpdateTaskRequest {

private String title;
private String description;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package backend.challenge.modules.task.infra.http.api.response;

import backend.challenge.modules.task.enums.TaskStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.util.UUID;

@Getter
@Setter
@Accessors(chain = true)
public class TaskResponse {

private UUID id;
private String title;
private String description;
private int progress;
private TaskStatus status;
private String createdAt;

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package backend.challenge.modules.task.infra.http.controllers;

import backend.challenge.modules.task.infra.http.views.TaskView;
import backend.challenge.modules.task.converter.ITaskConverter;
import backend.challenge.modules.task.exception.TaskNotFoundException;
import backend.challenge.modules.task.infra.http.api.request.CreateTaskRequest;
import backend.challenge.modules.task.infra.http.api.request.UpdateTaskRequest;
import backend.challenge.modules.task.infra.http.error.ErrorResponse;
import backend.challenge.modules.task.models.Task;
import backend.challenge.modules.task.services.*;
import kikaha.urouting.api.*;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.UUID;
import java.util.stream.Collectors;

@Singleton
@Path("tasks")
Expand All @@ -18,58 +26,87 @@ public class TaskController {
private final IRetrieveTaskByIdService retrieveTaskByIdService;
private final IUpdateTaskService updateTaskService;

private final ITaskConverter taskConverter;

@Inject
public TaskController(
final ICreateTaskService createTaskService,
final IDeleteTaskService deleteTaskService,
final IRetrieveAllTasksService retrieveAllTasksService
) {
final ICreateTaskService createTaskService,
final IDeleteTaskService deleteTaskService,
final IRetrieveAllTasksService retrieveAllTasksService,
final IRetrieveTaskByIdService retrieveTaskByIdService,
final IUpdateTaskService updateTaskService,
final ITaskConverter taskConverter
) {
this.createTaskService = createTaskService;
this.deleteTaskService = deleteTaskService;
this.retrieveAllTasksService = retrieveAllTasksService;
this.retrieveTaskByIdService = null;
this.updateTaskService = null;
this.retrieveTaskByIdService = retrieveTaskByIdService;
this.updateTaskService = updateTaskService;
this.taskConverter = taskConverter;
}

@GET
public Response show() {
// TODO: Rota que lista todas as tarefas

return DefaultResponse.ok().entity("Hello world");
var tasksList = retrieveAllTasksService.execute();
var tasksResponse = tasksList.stream().map(taskConverter::taskToTaskResponse).collect(Collectors.toList());
return DefaultResponse.ok().entity(tasksResponse);
}

@GET
@Path("single/{taskId}")
public Response index(@PathParam("taskId") Long taskId) {
// TODO: A rota deve retornar somente a tarefa a qual o id corresponder
public Response index(@PathParam("taskId") String taskId) {
try {
var foundTask = retrieveTaskByIdService.execute(UUID.fromString(taskId));
return DefaultResponse.ok().entity(taskConverter.taskToTaskResponse(foundTask));
} catch (TaskNotFoundException e) {
var errorResponse = ErrorResponse.create()
.setError("Not Found")
.setStatus(404)
.setMessage(e.getMessage())
.setTimestamp(Instant.now().truncatedTo(ChronoUnit.SECONDS).toString());
return DefaultResponse.notFound().entity(errorResponse);
}

return DefaultResponse.ok().entity("Hello world");
}

@POST
public Response create(TaskView task) {
// TODO: A rota deve receber title e description, sendo o `title` o título da tarefa e `description` uma descrição da tarefa.

return DefaultResponse.ok().entity("Hello world");
public Response create(CreateTaskRequest task) {
var taskDto = taskConverter.createTaskRequestToTaskDto(task);
var createdTask = createTaskService.execute(taskDto);
return DefaultResponse.created("tasks/single/"+createdTask.getId()).entity(taskConverter.taskToTaskResponse(createdTask));
}

@PUT
@Path("single/{taskId}")
public Response update(@PathParam("taskId") Long taskId, Task task) {
/*
TODO: A rota deve alterar apenas o title e description da tarefa
que possua o id igual ao id correspondente nos parâmetros da rota.
*/

return DefaultResponse.ok().entity("Hello world");
public Response update(@PathParam("taskId") String taskId, UpdateTaskRequest task) {
try {
var taskDto = taskConverter.updateTaskRequestToTaskDto(task);
var updatedTask = updateTaskService.execute(UUID.fromString(taskId), taskDto);
return DefaultResponse.ok().entity(taskConverter.taskToTaskResponse(updatedTask));
} catch (TaskNotFoundException e) {
var errorResponse = ErrorResponse.create()
.setError("Not Found")
.setStatus(404)
.setMessage(e.getMessage())
.setTimestamp(Instant.now().truncatedTo(ChronoUnit.SECONDS).toString());
return DefaultResponse.notFound().entity(errorResponse);
}
}

@DELETE
@Path("single/{taskId}")
public Response delete(@PathParam("taskId") Long taskId) {
// TODO: A rota deve deletar a tarefa com o id correspondente nos parâmetros da rota

return DefaultResponse.ok().entity("Hello world");
public Response delete(@PathParam("taskId") String taskId) {
try {
deleteTaskService.execute(UUID.fromString(taskId));
return DefaultResponse.noContent();
} catch (TaskNotFoundException e) {
var errorResponse = ErrorResponse.create()
.setError("Not Found")
.setStatus(404)
.setMessage(e.getMessage())
.setTimestamp(Instant.now().truncatedTo(ChronoUnit.SECONDS).toString());
return DefaultResponse.notFound().entity(errorResponse);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
package backend.challenge.modules.task.infra.http.controllers;

import backend.challenge.modules.task.infra.http.views.TaskProgressView;
import backend.challenge.modules.task.models.Task;
import backend.challenge.modules.task.converter.ITaskConverter;
import backend.challenge.modules.task.exception.InvalidTaskProgressException;
import backend.challenge.modules.task.infra.http.api.request.UpdateTaskProgressRequest;
import backend.challenge.modules.task.infra.http.error.ErrorResponse;
import backend.challenge.modules.task.services.*;
import kikaha.urouting.api.*;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.UUID;

@Singleton
@Path("tasks/progress")
public class TaskProgressController {

private final IUpdateTaskProgressService updateTaskProgressService;

private final ITaskConverter taskConverter;

@Inject
public TaskProgressController(final IUpdateTaskProgressService updateTaskProgressService) {
public TaskProgressController(final IUpdateTaskProgressService updateTaskProgressService, ITaskConverter taskConverter) {
this.updateTaskProgressService = updateTaskProgressService;
}
this.taskConverter = taskConverter;
}

@PUT
@Path("single/{taskId}")
public Response updateProgress(@PathParam("taskId") Long taskId, TaskProgressView taskProgressView) {
/*
TODO: A rota deve alterar apenas o progresso da tarefa que possua o id igual ao id correspondente
nos parâmetros da rota.
O `progress` pode ter o valor máximo de 100, e quando ele atingi o máximo,
o `status` deve ser alterado para `COMPLETE`
*/

return DefaultResponse.ok().entity("Hello world");
public Response updateProgress(@PathParam("taskId") String taskId, UpdateTaskProgressRequest updateTaskProgressRequest) {
try {
var taskProgressDto = taskConverter.updateTaskProgressRequestToTaskProgressDto(UUID.fromString(taskId), updateTaskProgressRequest);
var updatedTask = updateTaskProgressService.execute(taskProgressDto);
return DefaultResponse.ok().entity(taskConverter.taskToTaskResponse(updatedTask));
} catch (InvalidTaskProgressException e) {
var errorResponse = ErrorResponse.create()
.setError("Bad Request")
.setStatus(400)
.setMessage(e.getMessage())
.setTimestamp(Instant.now().truncatedTo(ChronoUnit.SECONDS).toString());
return DefaultResponse.badRequest().entity(errorResponse);
}
}

}
Loading