Backend de marketplace multi-vendedor, escrito em Java/Spring, com escopo deliberadamente estreito e profundidade concentrada no núcleo: pedido, pagamento e estoque. Não é uma loja completa — é uma demonstração de modelagem de domínio, concorrência, consistência e operação sob falha. O nicho (tecnologia e cultura geek) é só o pano de fundo; a arquitetura é o ponto.
Critério de sucesso do projeto: um revisor técnico abre o repositório e, em poucos minutos, vê rigor no fluxo de pedido (máquina de estados, idempotência de pagamento, estoque correto sob concorrência) — não 30 endpoints CRUD genéricos. Ver design/escopo para os cortes deliberados de escopo.
Para quem tem pouco tempo, nessa ordem:
Monólito modular. Um único deploy, seis bounded contexts (identity, catalog, estoque,
pedidos, pagamento, notificação) com fronteiras impostas pelo Spring Modulith e verificadas
em teste — nenhum módulo acessa os internals de outro, só a API pública que ele decide expor.
DDD tático e hexagonal são aplicados seletivamente, só onde há invariante real para proteger
(Pedidos, Pagamento e o núcleo pequeno de Estoque); os módulos de apoio permanecem
simples/CRUD de propósito. Razão completa em ADR-0001.
tsvector/GIN)Either) para erros de negócio como valor, em vez de exceção — ver
ADR-0004Em desenvolvimento incremental por fatia vertical. Hoje:
identity — inicia login e cadastro hospedados no FusionAuth e expõe a sessão atual.
Credenciais e login social são geridos pelo FusionAuth.catalog — domínio, persistência e casos de uso de vendedores/categorias/produtos, com
busca pública combinável (categoria + faixa de preço + full-text). Ainda sem camada HTTP
própria.estoque, pedidos, pagamento, notificação — ainda não implementados; o desenho está
em design/nucleo-pedido-pagamento-estoque.md,
escrito antes da construção.Pré-requisitos: Java 21 (ver .sdkmanrc), PostgreSQL da aplicação e uma Application configurada no FusionAuth com self-service registration habilitado.
A API sobe em http://localhost:8080; documentação interativa em /scalar. Testes de
integração usam Testcontainers e sobem um Postgres descartável automaticamente:
Para aplicar apenas as migrations, sem iniciar a API, use o perfil Maven que
carrega o .env e executa o Flyway:
Configure as URLs http://localhost:8080/login/oauth2/code/fusionauth e
http://localhost:8080/post-logout nas Authorized Redirect URLs da Application no FusionAuth.
FUSIONAUTH_URL deve ser alcançável pelo navegador e pelo backend. Em produção, defina
SESSION_COOKIE_SECURE=true; use
SESSION_COOKIE_SAME_SITE=none junto com HTTPS se o frontend estiver em outro site e
preencha CORS_ALLOWED_ORIGINS com as origens exatas, separadas por vírgula.
O frontend inicia o fluxo em GET /api/auth/login ou GET /api/auth/register.
Após o callback, o backend redireciona para APP_LOGIN_SUCCESS_URL (por padrão,
/api/auth/me). GET /api/auth/me retorna id, email e name sem tokens.
Antes de POST /api/auth/logout ou de outra chamada de
escrita, obtenha GET /api/auth/csrf e envie o token no header indicado por
headerName. O cookie JSESSIONID deve acompanhar essas requisições. O logout deve ser
submetido como navegação de navegador (por exemplo, um formulário POST), pois a resposta
redireciona para o logout SSO do FusionAuth e depois para APP_POST_LOGOUT_URL. A rota
/post-logout ainda não possui página e retorna 404 por enquanto.
O banco do marketplace não cria tabelas locais de usuários ou credenciais.
sellers.user_id guarda o ID do usuário no FusionAuth (sub do OIDC). Como as
migrations foram renumeradas para um banco novo, recrie o banco de desenvolvimento
se já tiver executado as migrations antigas. O Java Client do FusionAuth não é
necessário neste fluxo; ele pode ser adicionado quando houver operações
administrativas da API REST.
Executar aplicação
Aplicar migrações
Executar o ciclo Maven até a fase de testes limitadas à execução às classes informadas
mvn spring-boot:run./mvnw -Pmigrate initialize./mvnw -Dtest=AuthControllerSecurityTest,FusionAuthAuthorizationRequestResolverTest testcp .env.example .env
# edite .env com as credenciais do Postgres e com FUSIONAUTH_CLIENT_ID/CLIENT_SECRET
./mvnw spring-boot:run./mvnw test./mvnw -Pmigrate initialize