Nota histórica: a concessão local do papel
SELLERdescrita abaixo não foi implementada e precisa ser redesenhada para o FusionAuth. Ver arquitetura de autenticação.
Nota de referência (não é ADR): como decidir em qual módulo mora um fluxo que atravessa dois
contextos, usando o onboarding de seller como caso concreto (User vive em identity, Seller
vive em catalog). Serve para quando o cadastro de seller / concessão do papel SELLER entrar em
pauta. Relaciona-se com a regra de referência por ID entre módulos
(ADR-0001) e com o gatilho de módulo auth dedicado
(ADR-0002).
catalog referencia userId → catalog → identity. Identity é upstream, catalog é downstream.
Consequência imediata: o fluxo de onboarding não pode morar em identity, porque ele precisa
criar um Seller, e identity não pode saber o que é Seller.
No módulo dono do "esqueleto" do resultado. "Virar seller" gira em torno da entidade Seller
→ o fluxo é do catalog. Fica um RegisterSellerUseCase (ou SellerOnboardingUseCase) que:
Seller (dado dele, tabela dele — tranquilo);SELLER ao user — escrita no território de identity, então não toca
users/user_roles direto. Chama uma porta publicada de identity.Identity publica uma interface pública pequena (IdentityRoleService / IdentityApi) e esconde o
resto. Catalog depende da interface, nunca das entities de identity. É a mesma disciplina de
"controller não chama repositório direto", elevada para entre módulos: nunca se alcança as
entranhas do outro módulo, só a API que ele decidiu expor.
Como ainda é um banco só, duas escolhas honestas:
grantRole no mesmo @Transactional. Simples
e consistente já; custo: acopla os módulos no nível da transação (rollback cruza a fronteira).SellerRegistered; identity escuta e concede o papel.
Desacopla de verdade e é a costura que se quer quando os módulos virarem serviços; custo:
consistência eventual (por um instante, seller sem o papel).Decisão atual (recomendação): síncrono via porta publicada. Honesto, simples, história limpa
("catalog orquestra, identity expõe API, dependência num sentido só"). O evento fica como próximo
passo natural — candidato a ADR: "hoje chamada síncrona por porta; quando surgir refresh/OAuth ou
split de serviço, migrar grantRole para evento SellerRegistered."
IdentityRoleService.catalog/application/seller/RegisterSellerUseCase
└─ chama → identity.api.IdentityRoleService.grantRole(userId, Role.SELLER)