ADR-202: Entitlement — Agregador Central
Status: Accepted
Contexto
Sem um conceito unificador, dados do cliente ficam espalhados: licenças, pedidos, faturas, contratos, service requests — cada um sem saber a que produto/serviço pertence. "Cliente X tem suporte ativo?" requer verificar 3+ sistemas. O SEN (Support Entitlement Number) da Atlassian resolve isso com um identificador único que vincula licença a acesso a suporte, mas é limitado: tipo único, formato opaco, sem ciclo de vida, sem provisioning automático.
Decisão
Adotar o conceito de Entitlement como agregador central — um código único e imutável que representa "Organização X tem acesso ao Produto/Serviço Y" — expandindo o modelo SEN da Atlassian com classes tipadas, ciclo de vida, auto-provisioning, hierarquia parent-child e policy engine.
6 Classes de Entitlement
| Classe | Prefixo | O Que Cobre | Entidades Downstream |
|---|---|---|---|
| PLG | Plugin | Licença de software | License, Download |
| ENV | Environment | Instalação de plataforma gerenciada | Environment, ServiceRequest |
| SVC | Service | Serviço contínuo ou projeto | Service, Contract, CreditBalance, ServiceRequest, Document |
| ORD | Order | Entitlement genérico de compra | Order, Invoice, Document, Download |
| AFL | Affiliate | Membro do programa de parceiros | Affiliate (SolidAffiliate) |
| EDU | Education | Treinamento, mentoria, curso | Order, Document, Download |
SVC lifecycle: Atributo lifecycle diferencia ongoing (contrato contínuo, renovação) vs project (início e fim definidos).
SVC type: Atributo type indica a natureza do serviço. Usa os mesmos valores do enum category do catálogo de produtos: hosting, support, infrastructure, consulting, development, mobile-apps, migration, upgrade, project-management. ServiceEntity valida contra esta lista.
Mapeamento de transição:
labs_project(antigo) → lifecycle:project, type:consultingcustom_development(antigo) → lifecycle:project, type:development
Formato do Código
{CLASS}-{YEAR}{MONTH}{SEQ:4d}
Exemplo: PLG-2026040142 — o 142º entitlement PLG criado em abril de 2026.
- Atômico e único (geração thread-safe)
- Imutável — uma vez atribuído, nunca muda
- Legível — classe + data visíveis no código
- Visível para o cliente (portal, emails, SRs)
Ciclo de Vida (4 estados)
active ←── Criado (auto ou manual)
│
├── → suspended (falha pagamento, hold admin)
│ ├── → active (reativado)
│ └── → cancelled
│
├── → expired (data de expiração atingida)
│ ├── → active (renovado)
│ └── → cancelled
│
└── → cancelled (revogado)
└── → active (win-back: reativa mesmo entitlement)Detalhes de transições, recuperação de pagamento, upgrade/downgrade e cancellation em REF-202-01.
Auto-Provisioning
Pagamento confirmado → EntitlementProvisioningService analisa line items → cria Entitlement da classe correta → provisiona entidades downstream. Hook middag_entitlement_provisioned dispara após criação.
Detalhes do fluxo por classe em REF-202-02.
Parent-Child Hierarchy
Entitlements podem ter relação hierárquica via parent_entitlement_id. Caso principal: SVC como contrato-âncora agrupando filhos (ENVs, PLGs, outros SVCs). Profundidade configurável (default 3). Materialized path para queries eficientes.
Detalhes em REF-202-03.
Policy Engine (10 Policies)
Padrão transversal para configuração de regras de negócio com hierarquia de override: global → entitlement class → organization → product → entitlement individual (mais específico vence).
| Policy | Governa |
|---|---|
| CreditPolicy | Expiração de créditos, carência, limites, FIFO, avulsos |
| PaymentRecoveryPolicy | Suspensão por falha de pagamento, período suspended→cancelled |
| TierChangePolicy | Upgrade/downgrade: efeito imediato vs próximo ciclo, cooldown |
| CancellationPolicy | Visibilidade pós-expiração, tempo expired→cancelled, retenção |
| NotificationPolicy | Canais, frequência, opt-out |
| ProvisioningPolicy | Auto/manual setup, approval workflow, webhook |
| RenewalPolicy | Auto-renew, grace pre-expiração, preço de renovação |
| TrialPolicy | Duração, limites durante trial, conversão automática |
| RefundPolicy | Prazo, percentual, condições, auto-refund |
| SLAPolicy | Response time, resolution time, uptime, escalação |
Detalhes em REF-202-04.
Portal: Tela "Meus Produtos"
Portal NextJS exibe Entitlements da Organization com cards expansíveis (código, produto, classe, status, validade). Substitui visões separadas de Licenses/Orders/Contracts por visão unificada.
Campos do EntitlementEntity e endpoints REST em REF-202-01 §8-9.
Consequências
Positivas:
- Um código para governar todos — qualquer consulta (suporte, billing, licença) usa o entitlement code
- Classes tipadas dizem ao sistema "que tipo de coisa é" — determina provisioning, SLA, renovação, portal
- Ciclo de vida com 4 estados cobre cenários reais (recuperação de pagamento, win-back, grace period)
- Auto-provisioning elimina criação manual de entidades downstream
- Policy engine permite configuração por nível sem código
Negativas:
- 6 classes = 6 prefixos para geração de códigos
- Hierarquia parent-child com materialized path adiciona complexidade de persistência
- Policy engine com 5 níveis de override requer resolução cuidadosa de conflitos
- Entitlement como hub central = ponto único de falha se modelo estiver errado
Referências
- REF-202-01 — Entitlement Lifecycle (estados, transições, recuperação de pagamento)
- REF-202-02 — Auto-Provisioning (fluxo por classe)
- REF-202-03 — Parent-Child Hierarchy
- REF-202-04 — Policy Engine (10 policies, hierarquia de override)
- ADR-201 — Identity (Organization como owner de entitlements)
- ADR-101 — Product Vision (entitlement-centric como diferencial, SEN)
- Modelo de domínio do Entitlement — conteúdo absorvido neste ADR e REFs
- Lições do modelo SEN Atlassian — conteúdo absorvido neste ADR