From a179c66f430d109a1bdf6bf5f4f619bdc2d1ba1b Mon Sep 17 00:00:00 2001 From: xLima12 Date: Tue, 5 May 2026 19:32:20 -0300 Subject: [PATCH 1/5] api(auth): implement resources for authentication and user management --- .../presentation/rest/auth/AuthResource.java | 31 +++++++++++++ .../presentation/rest/users/UserResource.java | 43 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 backend/src/main/java/dev/flima/presentation/rest/auth/AuthResource.java create mode 100644 backend/src/main/java/dev/flima/presentation/rest/users/UserResource.java diff --git a/backend/src/main/java/dev/flima/presentation/rest/auth/AuthResource.java b/backend/src/main/java/dev/flima/presentation/rest/auth/AuthResource.java new file mode 100644 index 0000000..47b31c8 --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/auth/AuthResource.java @@ -0,0 +1,31 @@ +package dev.flima.presentation.rest.auth; + +import dev.flima.application.auth.dtos.request.LoginDTORequest; +import dev.flima.application.auth.dtos.response.LoginDTOResponse; +import dev.flima.application.auth.usecases.LoginUseCase; +import jakarta.validation.Valid; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +@Path("/auth") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class AuthResource { + + private final LoginUseCase loginUseCase; + + public AuthResource(LoginUseCase loginUseCase) { + this.loginUseCase = loginUseCase; + } + + @POST + public Response login(@Valid LoginDTORequest loginDTO) { + LoginDTOResponse response = loginUseCase.execute(loginDTO); + return Response.status(Response.Status.ACCEPTED).entity(response).build(); + } + +} diff --git a/backend/src/main/java/dev/flima/presentation/rest/users/UserResource.java b/backend/src/main/java/dev/flima/presentation/rest/users/UserResource.java new file mode 100644 index 0000000..74a0d8a --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/users/UserResource.java @@ -0,0 +1,43 @@ +package dev.flima.presentation.rest.users; + +import dev.flima.application.users.usecases.GetUserUseCase; +import dev.flima.application.users.usecases.CreateUserUseCase; +import dev.flima.application.users.dtos.request.UserDTORequest; +import dev.flima.application.users.dtos.response.UserDTOResponse; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +@Path("/__users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class UserResource { + + private final CreateUserUseCase createUserUseCase; + private final GetUserUseCase getUserUseCase; + + public UserResource(CreateUserUseCase createUserUseCase, GetUserUseCase getUserUseCase) { + this.createUserUseCase = createUserUseCase; + this.getUserUseCase = getUserUseCase; + } + + @POST + @PermitAll + public Response create(@Valid UserDTORequest userDTO) { + createUserUseCase.execute(userDTO); + return Response.status(Response.Status.CREATED).build(); + } + + @GET + @Path("/{username}") + public Response getUser(@PathParam("username") String username) { + UserDTOResponse response = getUserUseCase.execute(username); + return Response.status(Response.Status.OK).entity(response).build(); + } + +} From 5cde87588ac3e56b9c5a2820849321af36eaa2cd Mon Sep 17 00:00:00 2001 From: xLima12 Date: Tue, 5 May 2026 19:32:30 -0300 Subject: [PATCH 2/5] api(admin): implement resources for managing site statistics, tech stack and content --- .../rest/contents/ContentResource.java | 77 +++++++++++++++++++ .../rest/stacks/StackResource.java | 77 +++++++++++++++++++ .../presentation/rest/stats/StatResource.java | 77 +++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 backend/src/main/java/dev/flima/presentation/rest/contents/ContentResource.java create mode 100644 backend/src/main/java/dev/flima/presentation/rest/stacks/StackResource.java create mode 100644 backend/src/main/java/dev/flima/presentation/rest/stats/StatResource.java diff --git a/backend/src/main/java/dev/flima/presentation/rest/contents/ContentResource.java b/backend/src/main/java/dev/flima/presentation/rest/contents/ContentResource.java new file mode 100644 index 0000000..0fb6e7f --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/contents/ContentResource.java @@ -0,0 +1,77 @@ +package dev.flima.presentation.rest.contents; + +import dev.flima.application.contents.dtos.request.ContentDTORequest; +import dev.flima.application.contents.dtos.response.ContentDTOResponse; +import dev.flima.application.contents.dtos.response.CreateContentDTOResponse; +import dev.flima.application.contents.usecases.*; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/contents") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class ContentResource { + + private final CreateContentUseCase createContentUseCase; + private final UpdateContentUseCase updateContentUseCase; + private final DeleteContentUseCase deleteContentUseCase; + private final GetContentUseCase getContentUseCase; + private final GetAllContentUseCase getAllContentUseCase; + + public ContentResource( + CreateContentUseCase createContentUseCase, + UpdateContentUseCase updateContentUseCase, + DeleteContentUseCase deleteContentUseCase, + GetContentUseCase getContentUseCase, + GetAllContentUseCase getAllContentUseCase + ) { + this.createContentUseCase = createContentUseCase; + this.updateContentUseCase = updateContentUseCase; + this.deleteContentUseCase = deleteContentUseCase; + this.getContentUseCase = getContentUseCase; + this.getAllContentUseCase = getAllContentUseCase; + } + + @POST + public Response create(@Valid ContentDTORequest contentDTORequest) { + CreateContentDTOResponse response = createContentUseCase.execute(contentDTORequest); + return Response.status(Response.Status.CREATED).entity(response).build(); + } + + @PUT + @Path("/{id}") + public Response update(@Valid @PathParam("id") UUID id, ContentDTORequest contentDTORequest) { + ContentDTOResponse response = updateContentUseCase.execute(id, contentDTORequest); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @Path("/{id}") + public Response getById(@PathParam("id") UUID id) { + ContentDTOResponse response = getContentUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @PermitAll + public Response getAll() { + List response = getAllContentUseCase.execute(); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @DELETE + @Path("/{id}") + public Response delete(@PathParam("id") UUID id) { + deleteContentUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } +} diff --git a/backend/src/main/java/dev/flima/presentation/rest/stacks/StackResource.java b/backend/src/main/java/dev/flima/presentation/rest/stacks/StackResource.java new file mode 100644 index 0000000..b666d1e --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/stacks/StackResource.java @@ -0,0 +1,77 @@ +package dev.flima.presentation.rest.stacks; + +import dev.flima.application.stacks.dtos.request.StackDTORequest; +import dev.flima.application.stacks.dtos.response.CreateStackDTOResponse; +import dev.flima.application.stacks.dtos.response.StackDTOResponse; +import dev.flima.application.stacks.usecases.*; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/stacks") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class StackResource { + + private final CreateStackUseCase createStackUseCase; + private final UpdateStackUseCase updateStackUseCase; + private final DeleteStackUseCase deleteStackUseCase; + private final GetStackUseCase getStackUseCase; + private final GetAllStackUseCase getAllStackUseCase; + + public StackResource( + CreateStackUseCase createStackUseCase, + UpdateStackUseCase updateStackUseCase, + DeleteStackUseCase deleteStackUseCase, + GetStackUseCase getStackUseCase, + GetAllStackUseCase getAllStackUseCase + ) { + this.createStackUseCase = createStackUseCase; + this.updateStackUseCase = updateStackUseCase; + this.deleteStackUseCase = deleteStackUseCase; + this.getStackUseCase = getStackUseCase; + this.getAllStackUseCase = getAllStackUseCase; + } + + @POST + public Response create(@Valid StackDTORequest stackDTO) { + CreateStackDTOResponse response = createStackUseCase.execute(stackDTO); + return Response.status(Response.Status.CREATED).entity(response).build(); + } + + @PUT + @Path("/{id}") + public Response update(@Valid @PathParam("id") UUID id, StackDTORequest stackDTO) { + StackDTOResponse response = updateStackUseCase.execute(id, stackDTO); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @Path("/{id}") + public Response getById(@PathParam("id") UUID id) { + StackDTOResponse response = getStackUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @PermitAll + public Response getAll() { + List list = getAllStackUseCase.execute(); + return Response.status(Response.Status.OK).entity(list).build(); + } + + @DELETE + @Path("/{id}") + public Response delete(@PathParam("id") UUID id) { + deleteStackUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } +} diff --git a/backend/src/main/java/dev/flima/presentation/rest/stats/StatResource.java b/backend/src/main/java/dev/flima/presentation/rest/stats/StatResource.java new file mode 100644 index 0000000..581056c --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/stats/StatResource.java @@ -0,0 +1,77 @@ +package dev.flima.presentation.rest.stats; + +import dev.flima.application.stats.dtos.request.StatDTORequest; +import dev.flima.application.stats.dtos.response.CreateStatDTOResponse; +import dev.flima.application.stats.dtos.response.StatDTOResponse; +import dev.flima.application.stats.usecases.*; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/stats") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class StatResource { + + private final CreateStatUseCase createStatUseCase; + private final GetStatUseCase getStatUseCase; + private final GetAllStatUseCase getAllStatUseCase; + private final UpdateStatUseCase updateStatUseCase; + private final DeleteStatUseCase deleteStatUseCase; + + public StatResource( + CreateStatUseCase createStatUseCase, + GetStatUseCase getStatUseCase, + GetAllStatUseCase getAllStatUseCase, + UpdateStatUseCase updateStatUseCase, + DeleteStatUseCase deleteStatUseCase + ) { + this.createStatUseCase = createStatUseCase; + this.getStatUseCase = getStatUseCase; + this.getAllStatUseCase = getAllStatUseCase; + this.updateStatUseCase = updateStatUseCase; + this.deleteStatUseCase = deleteStatUseCase; + } + + @POST + public Response create(@Valid StatDTORequest statsDTO) { + CreateStatDTOResponse response = createStatUseCase.execute(statsDTO); + return Response.status(Response.Status.CREATED).entity(response).build(); + } + + @PUT + @Path("/{id}") + public Response update(@Valid @PathParam("id") UUID id, StatDTORequest statsDTO) { + StatDTOResponse response = updateStatUseCase.execute(id, statsDTO); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @Path("/{id}") + public Response getById(@PathParam("id") UUID id) { + StatDTOResponse response = getStatUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @PermitAll + public Response getAll() { + List response = getAllStatUseCase.execute(); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @DELETE + @Path("/{id}") + public Response delete(@PathParam("id") UUID id) { + deleteStatUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } +} From e46d3a9df87e378ae9885c76ab8d095ea69681ce Mon Sep 17 00:00:00 2001 From: xLima12 Date: Tue, 5 May 2026 19:32:36 -0300 Subject: [PATCH 3/5] api(portfolio): implement resources for projects, professional experience and education --- .../rest/educations/EducationResource.java | 77 +++++++++++++++++++ .../rest/experiences/ExperienceResource.java | 77 +++++++++++++++++++ .../rest/projects/ProjectResource.java | 76 ++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 backend/src/main/java/dev/flima/presentation/rest/educations/EducationResource.java create mode 100644 backend/src/main/java/dev/flima/presentation/rest/experiences/ExperienceResource.java create mode 100644 backend/src/main/java/dev/flima/presentation/rest/projects/ProjectResource.java diff --git a/backend/src/main/java/dev/flima/presentation/rest/educations/EducationResource.java b/backend/src/main/java/dev/flima/presentation/rest/educations/EducationResource.java new file mode 100644 index 0000000..54416c8 --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/educations/EducationResource.java @@ -0,0 +1,77 @@ +package dev.flima.presentation.rest.educations; + +import dev.flima.application.educations.dtos.request.EducationDTORequest; +import dev.flima.application.educations.dtos.response.CreateEducationDTOResponse; +import dev.flima.application.educations.dtos.response.EducationDTOResponse; +import dev.flima.application.educations.usecases.*; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/educations") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class EducationResource { + + private final CreateEducationUseCase createEducationUseCase; + private final UpdateEducationUseCase updateEducationUseCase; + private final DeleteEducationUseCase deleteEducationUseCase; + private final GetEducationUseCase getEducationUseCase; + private final GetAllEducationUseCase getAllEducationUseCase; + + public EducationResource( + CreateEducationUseCase createEducationUseCase, + UpdateEducationUseCase updateEducationUseCase, + DeleteEducationUseCase deleteEducationUseCase, + GetEducationUseCase getEducationUseCase, + GetAllEducationUseCase getAllEducationUseCase + ) { + this.createEducationUseCase = createEducationUseCase; + this.updateEducationUseCase = updateEducationUseCase; + this.deleteEducationUseCase = deleteEducationUseCase; + this.getEducationUseCase = getEducationUseCase; + this.getAllEducationUseCase = getAllEducationUseCase; + } + + @POST + public Response create(@Valid EducationDTORequest educationDTO) { + CreateEducationDTOResponse response = createEducationUseCase.execute(educationDTO); + return Response.status(Response.Status.CREATED).entity(response).build(); + } + + @PUT + @Path("/{id}") + public Response update(@Valid @PathParam("id") UUID id, EducationDTORequest educationDTO) { + EducationDTOResponse response = updateEducationUseCase.execute(id, educationDTO); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @Path("/{id}") + public Response getById(@PathParam("id") UUID id) { + EducationDTOResponse response = getEducationUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @PermitAll + public Response getAll() { + List response = getAllEducationUseCase.execute(); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @DELETE + @Path("/{id}") + public Response delete(@PathParam("id") UUID id) { + deleteEducationUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } +} diff --git a/backend/src/main/java/dev/flima/presentation/rest/experiences/ExperienceResource.java b/backend/src/main/java/dev/flima/presentation/rest/experiences/ExperienceResource.java new file mode 100644 index 0000000..80e05c0 --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/experiences/ExperienceResource.java @@ -0,0 +1,77 @@ +package dev.flima.presentation.rest.experiences; + +import dev.flima.application.experiences.dtos.request.ExperienceDTORequest; +import dev.flima.application.experiences.dtos.response.CreateExperienceDTOResponse; +import dev.flima.application.experiences.dtos.response.ExperienceDTOResponse; +import dev.flima.application.experiences.usecases.*; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/experiences") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class ExperienceResource { + + private final CreateExperienceUseCase createExperienceUseCase; + private final GetExperienceUseCase getExperienceUseCase; + private final UpdateExperienceUseCase updateExperienceUseCase; + private final DeleteExperienceUseCase deleteExperienceUseCase; + private final GetAllExperienceUseCase getAllExperienceUseCase; + + public ExperienceResource( + CreateExperienceUseCase createExperienceUseCase, + GetExperienceUseCase getExperienceUseCase, + UpdateExperienceUseCase updateExperienceUseCase, + DeleteExperienceUseCase deleteExperienceUseCase, + GetAllExperienceUseCase getAllExperienceUseCase + ) { + this.createExperienceUseCase = createExperienceUseCase; + this.getExperienceUseCase = getExperienceUseCase; + this.updateExperienceUseCase = updateExperienceUseCase; + this.deleteExperienceUseCase = deleteExperienceUseCase; + this.getAllExperienceUseCase = getAllExperienceUseCase; + } + + @POST + public Response create(@Valid ExperienceDTORequest experienceDTO) { + CreateExperienceDTOResponse response = createExperienceUseCase.execute(experienceDTO); + return Response.status(Response.Status.CREATED).entity(response).build(); + } + + @PUT + @Path("/{id}") + public Response update(@Valid @PathParam("id") UUID id, ExperienceDTORequest experienceDTO) { + ExperienceDTOResponse response = updateExperienceUseCase.execute(id, experienceDTO); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @Path("/{id}") + public Response getById(@PathParam("id") UUID id) { + ExperienceDTOResponse response = getExperienceUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @PermitAll + public Response getAll() { + List response = getAllExperienceUseCase.execute(); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @DELETE + @Path("/{id}") + public Response delete(@PathParam("id") UUID id) { + deleteExperienceUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } +} diff --git a/backend/src/main/java/dev/flima/presentation/rest/projects/ProjectResource.java b/backend/src/main/java/dev/flima/presentation/rest/projects/ProjectResource.java new file mode 100644 index 0000000..a30c68f --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/projects/ProjectResource.java @@ -0,0 +1,76 @@ +package dev.flima.presentation.rest.projects; + +import dev.flima.application.projects.dtos.request.ProjectDTORequest; +import dev.flima.application.projects.dtos.response.CreateProjectDTOResponse; +import dev.flima.application.projects.dtos.response.ProjectDTOResponse; +import dev.flima.application.projects.usecases.*; +import dev.flima.domain.users.Role; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/projects") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class ProjectResource { + + private final CreateProjectUseCase createProjectUseCase; + private final UpdateProjectUseCase updateProjectUseCase; + private final DeleteProjectUseCase deleteProjectUseCase; + private final GetProjectUseCase getProjectUseCase; + private final GetAllProjectsUseCase getAllProjectsUseCase; + + public ProjectResource(CreateProjectUseCase createProjectUseCase, + UpdateProjectUseCase updateProjectUseCase, + DeleteProjectUseCase deleteProjectUseCase, + GetProjectUseCase getProjectUseCase, + GetAllProjectsUseCase getAllProjectsUseCase + ) { + this.createProjectUseCase = createProjectUseCase; + this.updateProjectUseCase = updateProjectUseCase; + this.deleteProjectUseCase = deleteProjectUseCase; + this.getProjectUseCase = getProjectUseCase; + this.getAllProjectsUseCase = getAllProjectsUseCase; + } + + @POST + public Response create(@Valid ProjectDTORequest projectDTO) { + CreateProjectDTOResponse response = createProjectUseCase.execute(projectDTO); + return Response.status(Response.Status.CREATED).entity(response).build(); + } + + @PUT + @Path("{id}") + public Response update(@Valid @PathParam("id") UUID id, ProjectDTORequest projectDTO) { + ProjectDTOResponse response = updateProjectUseCase.execute(id, projectDTO); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @Path("{id}") + public Response getById(@PathParam("id") UUID id) { + ProjectDTOResponse response = getProjectUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + @PermitAll + public Response getAll() { + List response = getAllProjectsUseCase.execute(); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @DELETE + @Path("{id}") + public Response delete(@PathParam("id") UUID id) { + deleteProjectUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } +} From 9474c65d35b41d409956281fc7d8c34099e58938 Mon Sep 17 00:00:00 2001 From: xLima12 Date: Tue, 5 May 2026 19:32:42 -0300 Subject: [PATCH 4/5] api(messages): implement resource for contact form and common API DTOs --- .../presentation/rest/dto/ErrorResponse.java | 28 ++++++ .../rest/messages/MessageResource.java | 89 +++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 backend/src/main/java/dev/flima/presentation/rest/dto/ErrorResponse.java create mode 100644 backend/src/main/java/dev/flima/presentation/rest/messages/MessageResource.java diff --git a/backend/src/main/java/dev/flima/presentation/rest/dto/ErrorResponse.java b/backend/src/main/java/dev/flima/presentation/rest/dto/ErrorResponse.java new file mode 100644 index 0000000..119e556 --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/dto/ErrorResponse.java @@ -0,0 +1,28 @@ +package dev.flima.presentation.rest.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.time.LocalDateTime; +import java.util.List; + +public record ErrorResponse( + String message, + int status, + LocalDateTime timestamp, + + @JsonInclude(JsonInclude.Include.NON_NULL) + List details +) { + public ErrorResponse { + if (timestamp == null) { + timestamp = LocalDateTime.now(); + } + } + + public static ErrorResponse of(String message, int status) { + return new ErrorResponse(message, status, LocalDateTime.now(), null); + } + + public static ErrorResponse of(String message, int status, List details) { + return new ErrorResponse(message, status, LocalDateTime.now(), details); + } +} \ No newline at end of file diff --git a/backend/src/main/java/dev/flima/presentation/rest/messages/MessageResource.java b/backend/src/main/java/dev/flima/presentation/rest/messages/MessageResource.java new file mode 100644 index 0000000..6972b2e --- /dev/null +++ b/backend/src/main/java/dev/flima/presentation/rest/messages/MessageResource.java @@ -0,0 +1,89 @@ +package dev.flima.presentation.rest.messages; + +import dev.flima.application.messages.dtos.request.MessageDTORequest; +import dev.flima.application.messages.dtos.request.RepliedMessageDTORequest; +import dev.flima.application.messages.dtos.response.MessageDTOResponse; +import dev.flima.application.messages.usecases.*; +import dev.flima.domain.users.Role; +import dev.flima.infrastructure.messaging.ContactMessagingAdapter; +import jakarta.annotation.security.PermitAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.inject.Inject; +import jakarta.validation.Valid; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.util.List; +import java.util.UUID; + +@Path("/messages") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@RolesAllowed({Role.Labels.OWNER}) +public class MessageResource { + + private final CreateMessageUseCase createMessageUseCase; + private final GetMessageUseCase getMessageUseCase; + private final GetAllMessageUseCase getAllMessageUseCase; + private final DeleteMessaUseCase deleteMessageUseCase; + private final RepliedMessageUseCase repliedMessageUseCase; + private final ReadMessageUseCase readMessageUseCase; + + public MessageResource( + CreateMessageUseCase createMessageUseCase, + GetMessageUseCase getMessageUseCase, + GetAllMessageUseCase getAllMessageUseCase, + DeleteMessaUseCase deleteMessageUseCase, + RepliedMessageUseCase repliedMessageUseCase, + ReadMessageUseCase readMessageUseCase + ) { + this.createMessageUseCase = createMessageUseCase; + this.getMessageUseCase = getMessageUseCase; + this.getAllMessageUseCase = getAllMessageUseCase; + this.deleteMessageUseCase = deleteMessageUseCase; + this.repliedMessageUseCase = repliedMessageUseCase; + this.readMessageUseCase = readMessageUseCase; + } + + @POST + @PermitAll + public Response create(@Valid MessageDTORequest messageDTO) { + createMessageUseCase.execute(messageDTO); + return Response.status(Response.Status.CREATED).build(); + } + + @GET + @Path("/{id}") + public Response getById(@PathParam("id") UUID id) { + MessageDTOResponse response = getMessageUseCase.execute(id); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @GET + public Response getAll() { + List response = getAllMessageUseCase.execute(); + return Response.status(Response.Status.OK).entity(response).build(); + } + + @DELETE + @Path("/{id}") + public Response delete(@PathParam("id") UUID id) { + deleteMessageUseCase.execute(id); + return Response.status(Response.Status.NO_CONTENT).build(); + } + + @POST + @Path("/{id}") + public Response sendMail(@Valid @PathParam("id") UUID id, RepliedMessageDTORequest request) { + repliedMessageUseCase.execute(id, request); + return Response.status(Response.Status.ACCEPTED).build(); + } + + @POST + @Path("/read/{id}") + public Response read(@PathParam("id") UUID id) { + readMessageUseCase.execute(id); + return Response.status(Response.Status.ACCEPTED).build(); + } +} From 6fc427b03aebaa0eaa0254b85313d55be7a6cb83 Mon Sep 17 00:00:00 2001 From: xLima12 Date: Tue, 5 May 2026 19:33:01 -0300 Subject: [PATCH 5/5] chore(backend): finalize pom.xml with all necessary Quarkus extensions --- backend/pom.xml | 217 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 backend/pom.xml diff --git a/backend/pom.xml b/backend/pom.xml new file mode 100644 index 0000000..f81f7a9 --- /dev/null +++ b/backend/pom.xml @@ -0,0 +1,217 @@ + + + 4.0.0 + dev.flima + portfolio-flima-dev + 1.0.0-SNAPSHOT + quarkus + + + 3.15.0 + 25 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.34.5 + true + 3.5.4 + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + ${quarkus.platform.group-id} + quarkus-camel-bom + ${quarkus.platform.version} + pom + import + + + + + + + io.quarkus + quarkus-rest + + + io.quarkus + quarkus-hibernate-orm-panache + + + io.quarkiverse.mapstruct + quarkus-mapstruct + 1.1.0 + + + org.mapstruct + mapstruct + 1.6.3 + + + com.password4j + password4j + 1.8.4 + + + io.quarkus + quarkus-smallrye-jwt-build + 3.35.0 + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-rest-jackson + + + io.quarkus + quarkus-mailer + + + io.quarkus + quarkus-hibernate-validator + + + io.quarkus + quarkus-smallrye-jwt + + + org.apache.camel.quarkus + camel-quarkus-smallrye-reactive-messaging + + + io.quarkus + quarkus-kafka-client + + + io.quarkus + quarkus-messaging-kafka + + + io.quarkus + quarkus-flyway + + + io.quarkus + quarkus-jdbc-postgresql + + + io.quarkiverse.bucket4j + quarkus-bucket4j + 1.0.7 + + + io.quarkus + quarkus-smallrye-health + + + io.quarkus + quarkus-micrometer-registry-prometheus + + + io.quarkus + quarkus-jacoco + + + io.quarkus + quarkus-junit + test + + + io.quarkus + quarkus-junit5-mockito + test + + + io.quarkus + quarkus-test-security + test + + + io.quarkus + quarkus-test-kafka-companion + test + + + io.rest-assured + rest-assured + test + + + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + maven-compiler-plugin + ${compiler-plugin.version} + + true + + + + maven-surefire-plugin + ${surefire-plugin.version} + + @{argLine} + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + + @{argLine} + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + native + + + native + + + + false + false + true + + + +