Pular para o conteúdo
He4rt / Docs
Toggle sidebar
Interno noindex

Referência técnica — acessível, mas fora dos buscadores.

Discord
Engenharia Leitura · 4 min Onboarding
Aceito
15/06/2026 documento interno · noindex

Onboarding polimórfico por tipo, com etapas auditáveis

Deciders: danielhe4rt danielhe4rt

Status: Accepted Date: 2026-06-15 Deciders: danielhe4rt

Contexto

Os Squads da He4rt rodam hoje no informal (grupos de WhatsApp, sem liderança formal). A primeira entrega de software ataca governança (capitão/subcapitão, eleição, etc.) e, antes dela, uma camada de Entrada que filtra quem realmente quer integrar a comunidade e contribuir.

Essa Entrada — chamada no documento da P.O. de "pré-triagem" — é universal e obrigatória: ninguém se candidata a um squad nem propõe um squad novo sem concluí-la. Duas perguntas de fronteira apareceram:

  1. Esse onboarding é específico de um squad ou global da comunidade? A pré-triagem é sobre pertencer à comunidade, não a um squad específico, e reusa pesado o identity (vínculo GitHub via ExternalIdentity). Colocá-la dentro de squads amarraria um conceito universal a um consumidor específico.
  2. Quantos formatos? O time já enxerga mais de um tipo de entradaWelcome (entrada na comunidade) e Squads (entrada no programa) — e quer outros no futuro, cada um com seu próprio contrato de payload e processamento.

Modelar a pré-triagem como uma máquina de estados fixa (form → desafio) resolveria o Squads de hoje, mas não comportaria novos tipos sem refator.

Decisão

Criar um módulo de domínio novo, onboarding, dono de máquinas de onboarding polimórficas por tipo. squads (e futuros consumidores) apenas leem o gate de conclusão.

Polimorfismo (enum → handler)

Persistência (modelo + etapas)

Modelo único discriminado por type + tabela de etapas (opção "C" avaliada):

onboardings — uma linha por (tenant_id, user_id, type):

Coluna Tipo Notas
id uuid (PK) HasUuids
tenant_id uuid (FK) tenant-scoped (convenção do repo, multi-tenant-ready)
user_id uuid (FK)
type string OnboardingType (welcome | squads | …)
status string ciclo de vida genérico: in_progress/paused/completed/rejected
completed_at timestamptz?
paused_at timestamptz?
timestamps tz
UNIQUE (tenant_id, user_id, type)

onboarding_steps — uma linha por etapa do fluxo:

Coluna Tipo Notas
id uuid (PK)
onboarding_id uuid (FK)
step_key string semântica do handler (form, git_challenge, …)
status string pending/done/…
data jsonb payload da etapa, validado pelo DTO do tipo
completed_at timestamptz?
timestamps tz
UNIQUE (onboarding_id, step_key)

A tabela de etapas (em vez de só um payload JSON no modelo) foi escolhida por dar auditoria e histórico por etapa de graça — relevante pro desafio Git, que tem reenvio com evolução e pausa/retoma.

Cadeia entre tipos

prerequisites() declara dependências inter-tipo: Squads exige Welcome concluído para poder iniciar. O gate que o squads consome é Onboarding::isCompleted(user, tenant, Squads) — apelidado de APTO no domínio.

Alternativas consideradas

Consequências

Positivas

Negativas / diferidas

Review trigger

Revisitar quando (a) o Núcleo do jogo for refinado e a gente decidir se ele é um OnboardingType ou um consumidor do gate; ou (b) surgir um tipo cujo estado de etapa não caiba no par modelo+steps.