Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

39 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SummitCore

Uma REST API production-grade para gerenciamento de eventos.

ConstruΓ­da com Clean Architecture β€” use cases isolados, domΓ­nio protegido, zero vazamento de infraestrutura.

Β 

Java Spring Boot PostgreSQL Docker Flyway Maven CI/CD Status License

Β 

🌐 Language / Idioma: English Β· PortuguΓͺs

Β 

InΓ­cio RΓ‘pido Β· Arquitetura Β· API Reference Β· DecisΓ΅es de Design Β· Roadmap

Β 

Clean Architecture aplicada com rigor Use Cases como cidadΓ£os de primeira classe Config 12-Factor compliant
Zero vazamento do domain model Custom exceptions & handler global Schema versionado com Flyway
Identificadores gerados automaticamente CI/CD com GitHub Actions Deploy-ready com Docker

O Problema

Durante o desenvolvimento de APIs, Γ© comum comeΓ§ar com uma estrutura simples: controllers chamando services, services acessando repositories e entidades sendo retornadas diretamente nas respostas.

Embora essa abordagem funcione em projetos menores, ela pode gerar problemas conforme a aplicaΓ§Γ£o cresce, como acoplamento entre camadas, dificuldade de manutenΓ§Γ£o e dependΓͺncia direta da estrutura do banco de dados.

O SummitCore foi desenvolvido buscando uma arquitetura mais organizada e escalΓ‘vel, utilizando Clean Architecture para separar regras de negΓ³cio da infraestrutura.

O projeto aplica:

  • Use Cases para centralizar a lΓ³gica de negΓ³cio;
  • DTOs para separar os contratos da API das entidades de persistΓͺncia;
  • Tratamento global de exceΓ§Γ΅es;
  • Flyway para gerenciamento de migrations;
  • ConfiguraΓ§Γ£o atravΓ©s de variΓ‘veis de ambiente.

InΓ­cio RΓ‘pido

PrΓ©-requisitos: JDK 17+, Maven 3.8+, Docker

git clone https://github.com/your-username/summitcore-api.git
cd summitcore-api

Inicie o PostgreSQL via Docker:

docker compose up -d

Configure as variΓ‘veis de ambiente (ou use seu .env):

export SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/summitcore
export SPRING_DATASOURCE_USERNAME=your_username
export SPRING_DATASOURCE_PASSWORD=your_password

Build e execuΓ§Γ£o:

mvn clean install
mvn spring-boot:run

API disponΓ­vel em http://localhost:8080. Nenhuma configuraΓ§Γ£o manual de schema necessΓ‘ria β€” o Flyway executa as migrations automaticamente na inicializaΓ§Γ£o.


Arquitetura

Clean Architecture. O domΓ­nio nΓ£o sabe nada sobre Spring, JPA ou PostgreSQL. A infraestrutura se adapta ao domΓ­nio β€” nunca o contrΓ‘rio.

  HTTP Request
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Presentation Layer                         β”‚
β”‚  EventController                            β”‚
β”‚  Gerencia HTTP, rotas e status codes        β”‚
β”‚  Retorna DTOs β€” nunca domain models         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Core β€” Use Cases                           β”‚
β”‚  CreateEventCase / FindAllEventCase         β”‚
β”‚  FindByIdEventCase / FilterEventCase        β”‚
β”‚  DeleteEventByIdCase / UpdateEventCase      β”‚
β”‚  Todas as regras de negΓ³cio vivem aqui      β”‚
β”‚  Depende apenas de interfaces Gateway       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Core β€” Gateway (interface)                 β”‚
β”‚  EventGateway                               β”‚
β”‚  Fronteira entre domΓ­nio e infraestrutura   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Infrastructure β€” Gateway (impl)            β”‚
β”‚  EventRepositoryGateway                     β”‚
β”‚  Implementa EventGateway via JPA            β”‚
β”‚  Usa EventEntityMapper para conversΓ£o       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PostgreSQL 15+ (Docker)                    β”‚
β”‚  Schema gerenciado por Flyway migrations    β”‚
β”‚  Nunca exposto ao domΓ­nio diretamente       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

A divisΓ£o Core / Infrastructure

O package core Γ© domΓ­nio puro β€” entidades, enums, interfaces e implementaΓ§Γ΅es de use cases, e a interface EventGateway. Ele nΓ£o tem nenhuma dependΓͺncia de Spring Data, JPA ou qualquer preocupaΓ§Γ£o de infraestrutura.

O package infrastructure Γ© onde o Spring vive β€” EventRepositoryGateway implementa EventGateway, EventRepository se comunica com o PostgreSQL, os mappers convertem entre entidades de domΓ­nio e entidades JPA, e o BeanConfiguration conecta tudo.


API Reference

Eventos

MΓ©todo Rota DescriΓ§Γ£o Status
GET api/events Lista todos os eventos 200
GET api/events/{id} Busca evento por ID 200 / 404
GET api/events/filter/identifier Filtra eventos pelo identificador 200 / 404
POST api/events Cria um novo evento 201 / 409
PUT api/events/{id} Atualiza um evento 200 / 404
DELETE api/events/{id} Remove um evento por ID 204 / 404

Exemplos de Request

Criando um evento:

curl -X POST http://localhost:8080/events \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring Boot Workshop",
    "description": "SessΓ£o prΓ‘tica sobre Spring Boot 3 e Clean Architecture.",
    "date": "2026-07-15",
    "type": "WORKSHOP"
  }'
{
  "success": true,
  "data": {
    "identifier": "b3f1c2d4-e5a6-7890-abcd-ef1234567890",
    "name": "Spring Boot Workshop",
    "description": "SessΓ£o prΓ‘tica sobre Spring Boot 3 e Clean Architecture.",
    "date": "2026-07-15",
    "type": "WORKSHOP"
  }
}

Atualizando um evento:

curl -X PUT http://localhost:8080/events/b3f1c2d4-e5a6-7890-abcd-ef1234567890 \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring Boot Workshop β€” AvanΓ§ado",
    "description": "Deep dive em Spring Boot 3, Clean Architecture e estratΓ©gias de teste.",
    "date": "2026-07-20",
    "type": "WORKSHOP"
  }'
{
  "success": true,
  "data": {
    "identifier": "b3f1c2d4-e5a6-7890-abcd-ef1234567890",
    "name": "Spring Boot Workshop β€” AvanΓ§ado",
    "description": "Deep dive em Spring Boot 3, Clean Architecture e estratΓ©gias de teste.",
    "date": "2026-07-20",
    "type": "WORKSHOP"
  }
}

Todas as respostas sΓ£o encapsuladas em ApiResponse β€” um envelope consistente com um campo success e um campo data. O identifier Γ© um UUID gerado automaticamente pelo domΓ­nio na criaΓ§Γ£o β€” o cliente nunca precisa fornecΓͺ-lo.


Tratamento de ExceΓ§Γ΅es

Os erros sΓ£o tratados globalmente via GlobalExceptionHandler. Nenhum bloco try/catch espalhado pelos controllers.

ExceΓ§Γ£o HTTP Status Quando
DuplicateEventException 409 Conflict Evento com os mesmos dados jΓ‘ existe
EventNotFoundException 404 Not Found Recurso nΓ£o encontrado pelo identifier

Todas as respostas de erro seguem o mesmo envelope ApiResponse das respostas de sucesso β€” formato previsΓ­vel em toda a API.


DecisΓ΅es de Design

Cada padrΓ£o aqui Γ© uma escolha deliberada, nΓ£o boilerplate.

Clean Architecture β€” O domΓ­nio fica no centro e nΓ£o depende de nada. A infraestrutura se adapta a ele. Isso significa que o banco de dados, o framework e a camada HTTP podem todos mudar sem tocar em nenhum use case.

Use Cases como interfaces + implementaΓ§Γ΅es β€” CreateEventCase Γ© uma interface; CreateEventCaseImpl Γ© sua implementaΓ§Γ£o. Use cases sΓ£o injetados pela interface, mantendo os chamadores desacoplados da lΓ³gica concreta. Trocar implementaΓ§Γ΅es ou fazer mock em testes nΓ£o exige nenhuma refatoraΓ§Γ£o.

EventGateway como fronteira β€” O domΓ­nio nunca chama um repository diretamente. Ele chama EventGateway, uma interface que ele mesmo possui. O EventRepositoryGateway na camada de infraestrutura implementa essa interface. A direΓ§Γ£o de dependΓͺncia sempre aponta para dentro.

Identifier gerado automaticamente β€” O identifier (UUID) Γ© gerado pela camada de domΓ­nio na criaΓ§Γ£o, nΓ£o delegado Γ  sequence do banco de dados. Isso mantΓ©m o domΓ­nio no controle de sua prΓ³pria identidade β€” nenhuma preocupaΓ§Γ£o de infraestrutura vaza para o core.

Dual mapper pattern β€” EventMapper converte entre entidades de domΓ­nio e DTOs para a presentation layer. EventEntityMapper converte entre entidades de domΓ­nio e entidades JPA para a persistence layer. Cada mapper tem uma ΓΊnica responsabilidade bem definida.

ApiResponse envelope β€” Todas as respostas β€” sucesso e erro β€” compartilham o mesmo wrapper. Os clients sempre sabem o formato que vΓ£o receber, independentemente do endpoint.

EventType enum β€” Os tipos de evento nΓ£o sΓ£o strings livres no banco de dados. SΓ£o um enum de primeira classe no domΓ­nio, aplicado no nΓ­vel de tipo antes que qualquer coisa chegue Γ  persistΓͺncia.

Tratamento global de exceΓ§Γ΅es β€” @RestControllerAdvice intercepta exceΓ§Γ΅es tipadas e as mapeia para respostas HTTP. Os controllers ficam limpos. O formato de erro Γ© consistente em toda a API.

Flyway migrations β€” MudanΓ§as de schema sΓ£o arquivos SQL versionados. Todo ambiente executa exatamente as mesmas migrations na mesma ordem. Nenhum schema drift entre mΓ‘quinas.

Config 12-Factor β€” As credenciais do banco de dados vΓͺm de variΓ‘veis de ambiente. O mesmo artefato roda em qualquer ambiente sem modificaΓ§Γ£o.

GitHub Actions CI/CD β€” Build, test e deploy sΓ£o automatizados via workflow files. Todo push para main aciona o pipeline β€” sem passos manuais, sem surpresas por ambiente.


Database Schema

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            event             β”‚
│──────────────────────────────│
β”‚ identifier  (UUID, PK)       β”‚
β”‚ name                         β”‚
β”‚ description                  β”‚
β”‚ date                         β”‚
β”‚ type        (EventType)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

O schema Γ© versionado via Flyway. V1__create_table_event.sql define a estrutura inicial. V2__rename_column_identify_to_identifier.sql corrige o nome da coluna. A fonte da verdade Γ© sempre a cadeia de migrations β€” nΓ£o o ddl-auto do Hibernate.


Estrutura do Projeto

src/
└── main/
    └── java/
        └── com/summitcore/
            β”œβ”€β”€ core/
            β”‚   β”œβ”€β”€ entities/       # Domain entity β€” Event
            β”‚   β”œβ”€β”€ enums/          # EventType
            β”‚   β”œβ”€β”€ exception/      # DuplicateEventException, EventNotFoundException
            β”‚   β”œβ”€β”€ gateway/        # Interface EventGateway
            β”‚   └── useCases/       # Interfaces + implementaΓ§Γ΅es dos use cases
            └── infrastructure/
                β”œβ”€β”€ config/         # BeanConfiguration β€” wiring de DI
                β”œβ”€β”€ exception/      # GlobalExceptionHandler
                β”œβ”€β”€ gateway/        # EventRepositoryGateway (implementa EventGateway)
                β”œβ”€β”€ mapper/         # EventEntityMapper, EventMapper
                β”œβ”€β”€ persistence/    # EventEntity, EventRepository (JPA)
                β”œβ”€β”€ presentation/   # EventController
                β”œβ”€β”€ request/        # EventRequest (inbound DTO)
                └── response/       # ApiResponse, EventResponse (outbound DTOs)
    └── resources/
        └── db/migration/
            β”‚   V1__create_table_event.sql
            β”‚   V2__rename_column_identify_to_identifier.sql
            application.yml
.github/
└── workflows/
    └── ci.yml                      # GitHub Actions β€” build, test, deploy

Tech Stack

Componente Tecnologia Por quΓͺ
Linguagem Java 17 LTS Records, pattern matching, suporte de longo prazo
Framework Spring Boot 3.x PadrΓ£o da indΓΊstria, ecossistema de DI poderoso
PersistΓͺncia Spring Data JPA + Hibernate AbstraΓ§Γ£o limpa sobre JDBC
Banco de Dados PostgreSQL 15+ ConfiΓ‘vel, comprovado em produΓ§Γ£o
Container Docker + Docker Compose Ambientes reproduzΓ­veis
Migrations Flyway Schema versionado
Build Maven 3.8+ Lifecycle previsΓ­vel
CI/CD GitHub Actions Pipeline automatizado de build, test e deploy

Roadmap

  • Identifier UUID gerado automaticamente
  • Deploy pipeline via GitHub Actions (em desenvolvimento)
  • AutenticaΓ§Γ£o com Spring Security + JWT
  • Expandir cobertura de custom exceptions para todos os cenΓ‘rios de erro
  • PaginaΓ§Γ£o e ordenaΓ§Γ£o nos endpoints de listagem
  • OpΓ§Γ΅es adicionais de filtro (intervalo de datas, localizaΓ§Γ£o)
  • Testes unitΓ‘rios e de integraΓ§Γ£o

Contribuindo

Issues e PRs sΓ£o bem-vindos. Se vocΓͺ estΓ‘ adicionando uma feature, comece pelo use case β€” a lΓ³gica de negΓ³cio pertence ao core, nΓ£o aos controllers ou implementaΓ§Γ΅es de gateway.

LicenΓ§a

MIT β€” veja LICENSE.



Desenvolvido por Andrius Anselmi Β· LinkedIn

About

Backend API for managing events, attendees, registrations, and scheduling.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages