- Replace JPQL queries in TaskRepositoryImpl with Panache shorthand and Java filtering - Replace == null / != null with Objects.isNull() / Objects.nonNull() across all layers - Add CLAUDE.md with project conventions, architecture rules, and coding standards - Add .github/PULL_REQUEST_TEMPLATE.md for standardized PR descriptions in Portuguese - Add .claude/skills/new-task.md workflow guide (issue reading → branch → commit → PR) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.9 KiB
3.9 KiB
Bee Task — Guia de Desenvolvimento
Stack
- Backend: Quarkus + Hibernate ORM + Panache (Java 17+)
- Frontend: React + TypeScript + Tailwind CSS
- Banco de dados: PostgreSQL (via Docker Compose)
Arquitetura
O backend segue Clean Architecture adaptada:
entities/ → Domínio puro: entidades e regras de negócio
usecase/ → Casos de uso: orquestram entidades e repositórios (interfaces)
interfaceadapters/ → Controllers REST (JAX-RS), mappers de entrada/saída
frameworks/ → Implementações: Panache repositories, JPA entities, mappers de persistência
Regras de dependência (nunca viole):
entitiesnão importa nada externo (sem frameworks, sem Jakarta, sem Quarkus)usecasesó importaentitiese interfaces própriasinterfaceadaptersimportausecaseeentities, nuncaframeworksframeworksimplementa as interfaces deusecase
Padrões de Código Java
Repositories — Sem SQL nativo e sem JPQL explícito
Nas implementações de repository (frameworks/persistence/repository/), use sempre o estilo shorthand do Panache:
// CORRETO — shorthand Panache (propriedades da entidade)
find("user.email = ?1 and status = ?2", email, status).list();
find("organization.id", organizationId).stream().toList();
findByIdOptional(id).map(mapper::toDomain);
// ERRADO — JPQL explícito
find("SELECT t FROM TaskEntity t WHERE t.user.email = ?1", email);
find("select distinct t from TaskEntity t join t.history h where ...", ...);
// ERRADO — SQL nativo
getEntityManager().createNativeQuery("SELECT * FROM tasks WHERE ...");
Para consultas complexas que envolvem JOINs com coleções, prefira buscar via shorthand e filtrar em Java:
// Busca por propriedade simples + filtragem em Java
return find("user.email = ?1", email).list().stream()
.filter(entity -> entity.getHistory().stream().anyMatch(h ->
Objects.nonNull(h.getStartAt()) &&
!h.getStartAt().isAfter(end) &&
(Objects.isNull(h.getEndAt()) || !h.getEndAt().isBefore(start))))
.map(mapper::toDomain)
.toList();
Verificações de nulo — Objects.isNull e Objects.nonNull
Use sempre Objects.isNull(x) e Objects.nonNull(x) ao invés dos operadores == null e != null:
// CORRETO
if (Objects.isNull(entity.getId())) {
persist(entity);
}
if (Objects.nonNull(input.projectId())) {
task.setProject(projectRepository.findProjectById(input.projectId()).orElseThrow());
}
// ERRADO
if (entity.getId() == null) { ... }
if (input.projectId() != null) { ... }
Isso se aplica a: repositories, mappers, use cases e entities.
Exceção tolerada: ternários simples inline onde a legibilidade é melhor com !=.
Mappers de persistência
Sempre verifique nulo na entrada de métodos de mapeamento:
public static MyEntity toEntity(MyDomain domain) {
if (Objects.isNull(domain)) return null;
// ...
}
Padrão de save nos repositories
if (Objects.isNull(entity.getId())) {
persist(entity);
} else {
entity = getEntityManager().merge(entity);
}
Workflow de Tarefas
Use o skill /new-task para seguir o guia completo de início ao PR.
Branches
| Tipo | Prefixo |
|---|---|
| Funcionalidade | feat/ |
| Bug | fix/ |
| Manutenção | chore/ |
| Testes | test/ |
Commits
Formato: <tipo>: <descrição em inglês no imperativo>
feat: add task filtering by user organization
fix: prevent null pointer in task history mapper
chore: replace JPQL with Panache shorthand queries
Pull Requests
- Título em inglês, curto (< 70 chars)
- Descrição em português, seguindo
.github/PULL_REQUEST_TEMPLATE.md - Vincular a issue com
Fecha #<número>
Rodando o projeto
# Backend
cd backend
./mvnw quarkus:dev
# Frontend
cd frontend
npm install
npm run dev
# Banco de dados
docker-compose up -d