beetask/CLAUDE.md
Gabriel Santana de Menezes 1868d069c2 chore: enforce coding standards and add project guidelines
- 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>
2026-05-12 20:04:45 -04:00

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):

  • entities não importa nada externo (sem frameworks, sem Jakarta, sem Quarkus)
  • usecase só importa entities e interfaces próprias
  • interfaceadapters importa usecase e entities, nunca frameworks
  • frameworks implementa as interfaces de usecase

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