feat: Introduce Problem Management module with CRUD, API, and tests - #6
Conversation
…PI, persistence layer, and related configurations
…REST API with interface documentation and annotations
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdiciona o domínio ChangesGerenciamento de problems
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant ProblemController
participant ProblemWebMapper
participant CreateProblemUseCase
participant ProblemPersistenceAdapter
Client->>ProblemController: envia requisição HTTP
ProblemController->>ProblemWebMapper: converte request em command
ProblemController->>CreateProblemUseCase: executa operação
CreateProblemUseCase->>ProblemPersistenceAdapter: salva ou consulta Problem
ProblemPersistenceAdapter-->>CreateProblemUseCase: retorna Problem
CreateProblemUseCase-->>ProblemController: retorna resultado
ProblemController-->>Client: responde com DTO e status HTTP
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (8)
backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemController.java (1)
52-60: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winAdicione limites de validação nos parâmetros de paginação
pageesize.Sem limite superior em
size, um cliente pode solicitar páginas muito grandes, gerando consultas custosas. Valores negativos também não são bloqueados na borda HTTP, podendo resultar em erro 500 ao invés de 400.💡 Sugestão
public ResponseEntity<Page<ProblemSummaryResponse>> getAllByProject( `@PathVariable` UUID projectId, - `@RequestParam`(defaultValue = "0") int page, - `@RequestParam`(defaultValue = "10") int size + `@RequestParam`(defaultValue = "0") `@Min`(0) int page, + `@RequestParam`(defaultValue = "10") `@Min`(1) `@Max`(100) int size ){🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemController.java` around lines 52 - 60, Atualize o método getAllByProject para validar os parâmetros de paginação na borda HTTP: rejeite page negativo e size menor que 1, e defina um limite superior apropriado para size. Use as anotações de validação existentes no projeto para que entradas inválidas resultem em resposta 400 antes de executar getAllProblemsByProjectUseCase.backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/CreateProblemRequest.java (1)
13-14: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winConsidere limitar o tamanho de
errorDescriptionesolution.Diferente de
title, esses campos não possuem@Sizemáximo, permitindo payloads arbitrariamente grandes que podem causar falhas de persistência caso a coluna correspondente tenha limite de tamanho.💡 Sugestão
+ `@Size`(max = 5000, message = "Error description must be at most 5000 characters") String errorDescription, + `@Size`(max = 5000, message = "Solution must be at most 5000 characters") String solution,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/CreateProblemRequest.java` around lines 13 - 14, Adicione uma restrição `@Size` com limite máximo adequado aos campos errorDescription e solution no DTO CreateProblemRequest, alinhando-os ao tamanho suportado pelas colunas persistidas e mantendo a validação existente de title.backend/src/test/java/com/devaulty/backend/adapter/in/web/problem/ProblemControllerIT.java (1)
193-271: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCobertura de teste incompleta para update/updateStatus.
Diferente de
getProblemByIdedeleteProblem, os testes deupdateProblemeupdateProblemStatusnão cobrem cenários de projeto inexistente, problema inexistente ou problema pertencente a outro projeto. Considere adicionar esses casos para manter paridade de cobertura com os demais endpoints.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/test/java/com/devaulty/backend/adapter/in/web/problem/ProblemControllerIT.java` around lines 193 - 271, Expand the updateProblem and updateProblemStatus integration tests to cover missing projects, missing problems, and problems belonging to a different project. Add requests for each scenario and assert the same not-found or ownership response status used by getProblemById and deleteProblem, while preserving the existing successful and validation cases.backend/src/main/java/com/devaulty/backend/application/impl/problem/UpdateProblemImpl.java (1)
27-32: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLógica de validação duplicada entre casos de uso.
O bloco de validação (projeto existe → problem existe → problem pertence ao projeto) é idêntico ao usado em
UpdateProblemStatusImpl(ver snippet de contexto) e, pelo padrão observado emCreateProblemImpl, provavelmente se repete em outros casos de uso do módulo. Considere extrair essa validação para um componente compartilhado (ex.:ProblemAccessValidatorou método utilitário) injetado nos casos de uso, reduzindo duplicação e centralizando a regra de negócio.♻️ Exemplo de extração
public class ProblemAccessValidator { private final ProjectRepositoryPort projectRepositoryPort; private final ProblemRepositoryPort problemRepositoryPort; public Problem validateAndGet(UUID projectId, UUID problemId) { if (!projectRepositoryPort.existsById(projectId)) throw new ResourceNotFoundException("Project", projectId); Problem problem = problemRepositoryPort.findById(problemId) .orElseThrow(() -> new ResourceNotFoundException("Problem", problemId)); if (!problem.getProjectId().equals(projectId)) throw new ResourceNotFoundException("Problem", problemId); return problem; } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/application/impl/problem/UpdateProblemImpl.java` around lines 27 - 32, Extraia a validação compartilhada de existência do projeto, obtenção do problema e verificação de pertencimento para um componente reutilizável, como ProblemAccessValidator, com um método que retorne o Problem validado. Injete e utilize esse componente em UpdateProblemImpl e UpdateProblemStatusImpl, removendo os blocos duplicados e preservando as exceções e a ordem atual das validações.backend/src/main/java/com/devaulty/backend/application/port/out/persistence/ProblemRepositoryPort.java (1)
14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsidere usar
Pageableem vez deint page, int size.Já se usa
Page<Problem>do Spring Data como tipo de retorno; usarPageablecomo parâmetro de entrada seria mais idiomático, evitaria validação manual de limites e habilitaria ordenação nativa (Sort).♻️ Sugestão de refactor
- Page<Problem> findAllByProject(UUID projectId, int page, int size); + Page<Problem> findAllByProject(UUID projectId, Pageable pageable);Isso implicaria ajustes em
ProblemPersistenceAdaptereGetAllProblemsByProjectImpl.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/application/port/out/persistence/ProblemRepositoryPort.java` at line 14, Atualize o contrato de ProblemRepositoryPort para receber Pageable em vez de int page e int size, preservando o retorno Page<Problem>. Ajuste ProblemPersistenceAdapter e GetAllProblemsByProjectImpl para propagar e utilizar o Pageable diretamente, removendo validações manuais de paginação e permitindo ordenação via Sort.backend/src/main/java/com/devaulty/backend/application/impl/problem/DeleteProblemImpl.java (1)
23-34: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicação de lógica de validação entre casos de uso.
A validação "projeto existe" + "problem pertence ao projeto" (linhas 24-30) é replicada quase identicamente em
UpdateProblemStatusImpl(linhas 27-32). Considere extrair um helper reutilizável (ex.: um método em uma classe de validação compartilhada) para reduzir duplicação e manter consistência caso a regra mude.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/application/impl/problem/DeleteProblemImpl.java` around lines 23 - 34, Extraia a validação combinada de existência do projeto e pertencimento do problem em um helper ou classe de validação compartilhada, reutilizando-a em DeleteProblemImpl.execute e UpdateProblemStatusImpl. Substitua os blocos duplicados por essa validação, preservando as exceções ResourceNotFoundException e suas mensagens atuais.backend/src/main/java/com/devaulty/backend/application/port/in/problem/GetAllProblemsByProjectUseCase.java (1)
1-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffPorta de entrada acoplada a
org.springframework.data.domain.Page.O contrato do caso de uso (camada de aplicação/domínio) depende diretamente de um tipo do Spring Data. Isso acopla a porta de entrada a um framework específico, indo contra o princípio de inversão de dependência da arquitetura limpa (a porta deveria ser agnóstica de infraestrutura). Considere expor um DTO de paginação próprio (ex.:
PagedResult<Problem>) na camada de aplicação e converter paraPageapenas no adaptador web.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/application/port/in/problem/GetAllProblemsByProjectUseCase.java` around lines 1 - 10, A interface GetAllProblemsByProjectUseCase está acoplada ao tipo Page do Spring Data. Substitua o retorno por um DTO de paginação próprio da camada de aplicação, como PagedResult<Problem>, removendo o import de org.springframework.data.domain.Page; atualize as implementações e adaptadores para converter esse resultado em Page somente na camada web.backend/src/main/java/com/devaulty/backend/application/impl/problem/GetAllProblemsByProjectImpl.java (1)
25-30: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winSem limite para
sizena paginação.
executedelega direto aproblemRepositoryPort.findAllByProject(projectId, page, size)sem validar/limitarsize, permitindo requisições com tamanho de página arbitrariamente grande, o que pode gerar queries custosas. Se essa validação já existir na camada de DTO/controller (ex.:@Maxno request), pode ignorar este comentário.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/src/main/java/com/devaulty/backend/application/impl/problem/GetAllProblemsByProjectImpl.java` around lines 25 - 30, Adicione uma validação ou limite máximo para o parâmetro size no método execute de GetAllProblemsByProjectImpl antes de delegá-lo a problemRepositoryPort.findAllByProject. Rejeite ou normalize valores acima do limite definido pelas regras existentes, reutilizando a constante ou validação já adotada no projeto; se o controller/DTO já garantir esse limite, mantenha o fluxo atual.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemApi.java`:
- Around line 91-96: Adicione validações Bean Validation aos parâmetros page e
size de getAllByProject, rejeitando valores negativos e impondo um limite
superior apropriado para size com `@Min/`@Max. Garanta que a validação de
parâmetros do controlador esteja habilitada para que entradas inválidas retornem
400 em vez de alcançar a lógica de paginação.
In
`@backend/src/main/java/com/devaulty/backend/adapter/out/persistence/problem/ProblemPersistenceAdapter.java`:
- Around line 29-34: Atualize o método save da classe ProblemPersistenceAdapter
para evitar a falha tardia de getReferenceById: busque o projeto com findById,
valide a ausência e lance a exceção de aplicação ResourceNotFoundException (ou a
exceção equivalente já adotada no projeto) antes de associá-lo à ProblemEntity.
Preserve o fluxo de persistência e mapeamento quando o projeto existir.
In
`@backend/src/main/java/com/devaulty/backend/application/impl/problem/GetProblemByIdImpl.java`:
- Line 26: Corrija a validação de projeto em GetProblemByIdImpl#execute para
passar projectId, em vez de id, ao lançar ResourceNotFoundException para
"Project". Preserve o restante do fluxo e a validação do problema sem
alterações.
---
Nitpick comments:
In
`@backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/CreateProblemRequest.java`:
- Around line 13-14: Adicione uma restrição `@Size` com limite máximo adequado aos
campos errorDescription e solution no DTO CreateProblemRequest, alinhando-os ao
tamanho suportado pelas colunas persistidas e mantendo a validação existente de
title.
In
`@backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemController.java`:
- Around line 52-60: Atualize o método getAllByProject para validar os
parâmetros de paginação na borda HTTP: rejeite page negativo e size menor que 1,
e defina um limite superior apropriado para size. Use as anotações de validação
existentes no projeto para que entradas inválidas resultem em resposta 400 antes
de executar getAllProblemsByProjectUseCase.
In
`@backend/src/main/java/com/devaulty/backend/application/impl/problem/DeleteProblemImpl.java`:
- Around line 23-34: Extraia a validação combinada de existência do projeto e
pertencimento do problem em um helper ou classe de validação compartilhada,
reutilizando-a em DeleteProblemImpl.execute e UpdateProblemStatusImpl. Substitua
os blocos duplicados por essa validação, preservando as exceções
ResourceNotFoundException e suas mensagens atuais.
In
`@backend/src/main/java/com/devaulty/backend/application/impl/problem/GetAllProblemsByProjectImpl.java`:
- Around line 25-30: Adicione uma validação ou limite máximo para o parâmetro
size no método execute de GetAllProblemsByProjectImpl antes de delegá-lo a
problemRepositoryPort.findAllByProject. Rejeite ou normalize valores acima do
limite definido pelas regras existentes, reutilizando a constante ou validação
já adotada no projeto; se o controller/DTO já garantir esse limite, mantenha o
fluxo atual.
In
`@backend/src/main/java/com/devaulty/backend/application/impl/problem/UpdateProblemImpl.java`:
- Around line 27-32: Extraia a validação compartilhada de existência do projeto,
obtenção do problema e verificação de pertencimento para um componente
reutilizável, como ProblemAccessValidator, com um método que retorne o Problem
validado. Injete e utilize esse componente em UpdateProblemImpl e
UpdateProblemStatusImpl, removendo os blocos duplicados e preservando as
exceções e a ordem atual das validações.
In
`@backend/src/main/java/com/devaulty/backend/application/port/in/problem/GetAllProblemsByProjectUseCase.java`:
- Around line 1-10: A interface GetAllProblemsByProjectUseCase está acoplada ao
tipo Page do Spring Data. Substitua o retorno por um DTO de paginação próprio da
camada de aplicação, como PagedResult<Problem>, removendo o import de
org.springframework.data.domain.Page; atualize as implementações e adaptadores
para converter esse resultado em Page somente na camada web.
In
`@backend/src/main/java/com/devaulty/backend/application/port/out/persistence/ProblemRepositoryPort.java`:
- Line 14: Atualize o contrato de ProblemRepositoryPort para receber Pageable em
vez de int page e int size, preservando o retorno Page<Problem>. Ajuste
ProblemPersistenceAdapter e GetAllProblemsByProjectImpl para propagar e utilizar
o Pageable diretamente, removendo validações manuais de paginação e permitindo
ordenação via Sort.
In
`@backend/src/test/java/com/devaulty/backend/adapter/in/web/problem/ProblemControllerIT.java`:
- Around line 193-271: Expand the updateProblem and updateProblemStatus
integration tests to cover missing projects, missing problems, and problems
belonging to a different project. Add requests for each scenario and assert the
same not-found or ownership response status used by getProblemById and
deleteProblem, while preserving the existing successful and validation cases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 5fa54ef6-6540-4de2-85cf-e20ba96e042e
📒 Files selected for processing (41)
backend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemApi.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemController.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/ProblemWebMapper.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/CreateProblemRequest.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/ProblemSummaryResponse.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/ProblemViewResponse.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/UpdateProblemRequest.javabackend/src/main/java/com/devaulty/backend/adapter/in/web/problem/dto/UpdateProblemStatusRequest.javabackend/src/main/java/com/devaulty/backend/adapter/out/persistence/problem/ProblemEntity.javabackend/src/main/java/com/devaulty/backend/adapter/out/persistence/problem/ProblemMapper.javabackend/src/main/java/com/devaulty/backend/adapter/out/persistence/problem/ProblemPersistenceAdapter.javabackend/src/main/java/com/devaulty/backend/adapter/out/persistence/problem/SpringDataProblemRepository.javabackend/src/main/java/com/devaulty/backend/application/impl/problem/CreateProblemImpl.javabackend/src/main/java/com/devaulty/backend/application/impl/problem/DeleteProblemImpl.javabackend/src/main/java/com/devaulty/backend/application/impl/problem/GetAllProblemsByProjectImpl.javabackend/src/main/java/com/devaulty/backend/application/impl/problem/GetProblemByIdImpl.javabackend/src/main/java/com/devaulty/backend/application/impl/problem/UpdateProblemImpl.javabackend/src/main/java/com/devaulty/backend/application/impl/problem/UpdateProblemStatusImpl.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/CreateProblemCommand.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/CreateProblemUseCase.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/DeleteProblemUseCase.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/GetAllProblemsByProjectUseCase.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/GetProblemByIdUseCase.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/UpdateProblemCommand.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/UpdateProblemStatusCommand.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/UpdateProblemStatusUseCase.javabackend/src/main/java/com/devaulty/backend/application/port/in/problem/UpdateProblemUseCase.javabackend/src/main/java/com/devaulty/backend/application/port/out/persistence/ProblemRepositoryPort.javabackend/src/main/java/com/devaulty/backend/domain/model/Problem.javabackend/src/main/java/com/devaulty/backend/domain/model/enums/ProblemSeverity.javabackend/src/main/java/com/devaulty/backend/domain/model/enums/ProblemStatus.javabackend/src/main/java/com/devaulty/backend/infrastructure/configuration/ProblemBeanConfig.javabackend/src/main/resources/db/changelog/changesets/004-create-problems-table.yamlbackend/src/main/resources/db/changelog/db.changelog-master.yamlbackend/src/test/java/com/devaulty/backend/adapter/in/web/problem/ProblemControllerIT.javabackend/src/test/java/com/devaulty/backend/application/impl/problem/CreateProblemImplTest.javabackend/src/test/java/com/devaulty/backend/application/impl/problem/DeleteProblemImplTest.javabackend/src/test/java/com/devaulty/backend/application/impl/problem/GetAllProblemsByProjectImplTest.javabackend/src/test/java/com/devaulty/backend/application/impl/problem/GetProblemByIdImplTest.javabackend/src/test/java/com/devaulty/backend/application/impl/problem/UpdateProblemImplTest.javabackend/src/test/java/com/devaulty/backend/application/impl/problem/UpdateProblemStatusImplTest.java
…n GetProblemByIdImpl
This pull request introduces a new "Problem" management module for tracking, viewing, updating, and deleting problems (errors/issues) within a project. It adds a complete REST API, DTOs, mapping, and service layer implementations, following a clean architecture approach. The changes are organized into API/controller definitions, DTOs and mapping, and service logic.
API and Controller Layer:
ProblemApi) and controller (ProblemController) for CRUD operations on problems within a project, including endpoints to create, retrieve (single and paginated), update, update status, and delete problems. These endpoints are fully documented with OpenAPI annotations and proper response handling. [1] [2]DTOs and Mapping:
CreateProblemRequest,UpdateProblemRequest,UpdateProblemStatusRequest,ProblemSummaryResponse, andProblemViewResponse, with validation constraints and field definitions. [1] [2] [3] [4] [5]ProblemWebMapperusing MapStruct to convert between DTOs and domain commands/models, ensuring clean separation between API and domain layers.Service/Use Case Implementations:
CreateProblemImpl), retrieve all by project (GetAllProblemsByProjectImpl), and delete (DeleteProblemImpl). These include validation for project existence and proper error handling. [1] [2] [3]These changes lay the groundwork for robust problem/error tracking per project, with clear separation of concerns and extensibility for future features.
Summary by CodeRabbit