Skip to content

Latest commit

 

History

History
147 lines (121 loc) · 10.9 KB

DOMAIN_MODEL.md

File metadata and controls

147 lines (121 loc) · 10.9 KB

DOMAIN_MODEL.md - Bounded Contexts Detalhados

Quem deve consultar: Agentes de IA, Desenvolvedores, Arquitetos Decisões que controla: Regras de negócio conceituais, limites entre contextos, invariantes de domínio Alterações que exigem validação humana: Qualquer regra que afete compatibilidade alimentar ou dados de saúde


1. Perfil Alimentar

  • Responsabilidade: Gerenciar restrições e sensibilidades alimentares do usuário.
  • Entidades: Profile, Allergy, Intolerance.
  • Value Objects: SeverityLevel (LIFESTYLE, LOW, MEDIUM, HIGH, FATAL), Restriction (allergen + severity).
  • Regras Críticas:
    • Um perfil deve ter pelo menos uma restrição para ser considerado "Ativo".
    • Mudanças em restrições FATAL exigem revalidação de todo o histórico de consumo.
    • Um perfil inativo resulta em SAFE para qualquer produto — não bloqueia nada.

2. Catálogo de Produtos

  • Responsabilidade: Inventário de produtos alimentícios com informações de segurança.
  • Entidades: Product, Ingredient.
  • Agregados: Product é a raiz. Ingredientes são entidades filhas.
  • Value Objects: AnalysisStatus (PENDING_ANALYSIS, APPROVED, FLAGGED).
  • Regras:
    • Um produto sem lista de ingredientes é marcado como PENDING_ANALYSIS.
    • O campo cross_contamination é obrigatório no cadastro.
    • Produto sem ingredientes nunca pode ter resultado SAFE no motor.

3. Catálogo de Parceiros

  • Responsabilidade: Gerenciar estabelecimentos (restaurantes, lojas) que cadastram produtos.
  • Entidades: Partner.
  • Value Objects:
    • PartnerApprovalStatus (DRAFT, PENDING_REVIEW, APPROVED, REJECTED, SUSPENDED).
    • PartnerOperationalStatus (ACTIVE, INACTIVE, TEMPORARILY_CLOSED).
    • Cnpj (Validação oficial Módulo 11 da Receita Federal com verificação dos 2 dígitos verificadores, rejeição de sequências repetidas, formatação 99.999.999/9999-99 e suporte à opcionalidade para produtores artesanais/PF).
  • Regras:
    • Um parceiro deve ter approvalStatus = APPROVED e operationalStatus = ACTIVE antes de poder publicar produtos.
    • Parceiro com cadastro em DRAFT ou PENDING_REVIEW aguarda revisão administrativa antes de operar.
    • Parceiro suspenso ou inativo perde acesso ao cadastro de novos produtos e tem seus itens sinalizados/ocultados.
    • Se informado, o CNPJ DEVE ser estritamente válido matematicamente pelas regras da Receita Federal; cadastros com CNPJ inválido são sumariamente rejeitados (fail-fast no domínio).

4. Ingredientes e Restrições (Contexto de Suporte)

  • Responsabilidade: Vocabulário controlado de ingredientes e mapeamento de alérgenos.
  • Entidades: IngredientDefinition (futuro).
  • Value Objects: AllergenType (GLUTEN, LACTOSE, NUTS, SOY, EGGS, SHELLFISH, FISH, WHEAT, SESAME, OTHER).
  • Regras:
    • ALLERGEN_SEARCH_TERMS é o mapeamento oficial de termos de busca por alérgeno.
    • Qualquer alteração nos termos de busca exige aprovação humana (impacta o motor).
    • Este contexto serve como suporte tanto ao Perfil Alimentar quanto ao Motor de Compatibilidade.

5. Compatibilidade Alimentar (Core Engine)

  • Responsabilidade: Calcular o match entre Perfil Alimentar e Produto. É o coração do CeLiLac.
  • Entidades: CompatibilityReport.
  • Value Objects: RiskLevel (SAFE, WARNING, DANGER, BLOCKED, UNEVALUATED), ConflictDetail.
  • Regras:
    • O motor deve ser agnóstico a banco de dados (Pure Domain Service).
    • Deve suportar "Traços de Alérgenos" como um modificador de risco.
    • Respeita a RN-CONSUMER-07 / Invariante 11.6: se o consumidor possui perfil incompleto/sem restrições (!profile.isActive()), o sistema retorna UNEVALUATED e isCompatible = false, eliminando a falsa sensação de segurança.
    • Respeita a Invariante 11.5 (Tolerância a Contaminação Cruzada): se acceptsCrossContamination === false, traços para severidades HIGH elevam o risco de WARNING para DANGER. Para FATAL, o resultado é sempre BLOCKED (invariante biológica imutável).
    • Respeita a RN-CONSUMER-05 (Issue #34 — aprovado 2026-08-01): uma restrição com type === ALLERGY exige severidade mínima MEDIUM. A regra é implementada em Restriction.create() (Abordagem A — Fail Fast). O AllergenEngine recebe apenas objetos de domínio válidos e não precisa corrigir dados de entrada. O campo type é propagado no ConflictDetail e no reasoning para transparência no frontend.
    • As 9 regras do motor (R1–R9) estão definidas em docs/ALLERGEN_ENGINE.md e são imutáveis sem aprovação humana.
    • ⚠️ Contexto de máxima criticidade — qualquer alteração exige aprovação humana.

6. IAM — Identidade e Acesso

  • Responsabilidade: Autenticação, autorização e gerenciamento de identidade dos usuários.
  • Entidades: User.
  • Value Objects: Email (validado), PasswordHash (bcrypt, nunca texto puro), UserRole (CELIACO, PARCEIRO, ADMIN).
  • Regras:
    • E-mail deve ser único no sistema.
    • Senha armazenada exclusivamente como hash bcrypt.
    • JWT tem validade de 7 dias (configurável via JWT_EXPIRES_IN).
    • Um usuário CELIACO não pode acessar rotas de moderação de ADMIN.
    • Alterações no mecanismo de autenticação exigem aprovação humana.

7. Avaliações e Confiança (Social Proof)

  • Responsabilidade: Coletar a percepção dos usuários sobre a acurácia dos rótulos dos produtos e construir a métrica de confiabilidade da comunidade.
  • Entidades: Review.
  • Value Objects: Rating (1 a 5 estrelas).
  • Regras:
    • Um usuário só pode avaliar um mesmo produto uma vez (Upsert na avaliação).
    • Avaliações são visíveis para qualquer usuário autenticado.

8. Administração e Moderação

  • Responsabilidade: Gestão de denúncias de dados incorretos e moderação do catálogo.
  • Entidades: Report.
  • Value Objects: ReportStatus (PENDING, IN_REVIEW, RESOLVED, DISMISSED), ReportReason (INCORRECT_INGREDIENTS, MISSING_ALLERGEN, WRONG_CROSS_CONTAMINATION, OTHER).
  • Regras:
    • Uma denúncia em estado final (RESOLVED ou DISMISSED) não pode ter seu status alterado.
    • Todo reporte entra com status PENDING.
    • Apenas ADMIN pode alterar o status de uma denúncia.

10. Consumidor

  • Responsabilidade: Gerenciar a identidade de consumo da pessoa usuária, integrando preferências de experiência, perfil de alérgenos e status de participação.
  • Entidades / Agregados: Aggregate Root Consumer (id, userId, generalPreferences, isFoodProfileComplete, isFoodProfileCritical, status, statusChangedAt, statusChangedBy, statusChangeReason).
  • Value Objects: ConsumerStatus (CONTA_CRIADA, PERFIL_INCOMPLETO, PERFIL_CONFIGURADO, PERFIL_CRITICO, ATIVO, INATIVO).
  • Regras:
    • Todo Consumer se vincula a um único userId do IAM.
    • O status do Consumidor é mantido e sincronizado com o Perfil Alimentar (FoodProfile).
    • O Consumidor pode transitar entre ATIVO e INATIVO com registro obrigatório de auditoria (statusChangedAt, statusChangedBy, statusChangeReason).
    • A desativação (INATIVO) desativa a participação personalizada nas buscas do consumidor, mas não bloqueia o acesso à conta no IAM.

11. Pedidos

  • Responsabilidade: Gerenciar o ciclo de vida de pedidos alimentares entre o consumidor e os estabelecimentos comerciais parceiros.
  • Entidades / Agregados: Aggregate Root Order (id, orderNumber, consumerId, partnerId, items, status, deliveryAddress, notes, subtotal, deliveryFee, total, isRefundEligible, createdAt, updatedAt), Entidade OrderItem (id, productId, productName, unitPrice, quantity, subtotal).
  • Value Objects: OrderStatus (CREATED, AWAITING_PAYMENT, PAID, CONFIRMED, PREPARING, READY_FOR_PICKUP, OUT_FOR_DELIVERY, DELIVERED, CANCELLED), OrderCancellationPolicy.
  • Regras Críticas:
    • Invariante Biológica Obrigatória (Trava AllergenEngine): Antes de criar qualquer pedido, todos os itens selecionados são avaliados contra o FoodProfile ativo do consumidor via AllergenEngine. Se qualquer item tiver risco BLOCKED ou DANGER, a criação do pedido é sumariamente bloqueada com FOOD_SAFETY_RISK_BLOCK.
    • Itens do Mesmo Parceiro: Um pedido não pode conter produtos de parceiros comerciais distintos.
    • Ciclo de Estados: Segue progressão estrita: CREATED ➔ AWAITING_PAYMENT ➔ PAID ➔ CONFIRMED ➔ PREPARING ➔ READY_FOR_PICKUP/OUT_FOR_DELIVERY ➔ DELIVERED.
    • Cancelamento e Reembolso: O consumidor pode cancelar pedidos em status CREATED, AWAITING_PAYMENT ou PAID. Se já pago antes do início do preparo pelo parceiro (CONFIRMED/PREPARING), o pedido é cancelado com direito a reembolso total imediato (isRefundEligible = true). Se o parceiro já iniciou a produção ou despacho, o cancelamento unilateral pelo cliente é bloqueado.

12. Pagamentos e Split Marketplace

  • Responsabilidade: Processar transações financeiras (checkout PIX e Cartão de Crédito), split automatizado de receitas marketplace e liquidação de reembolsos.
  • Entidades / Agregados: Aggregate Root Payment (id, orderId, gatewayPaymentId, method, status, amount, platformFee, netPartnerAmount, pixQrCodeUrl, pixCopyPaste, paidAt, createdAt, updatedAt), Entidade PartnerFinancialAccount (id, partnerId, asaasAccountId, pixKeyType, pixKey, isVerified, createdAt), Entidade PaymentRefund (id, paymentId, amount, reason, gatewayRefundId, createdAt).
  • Value Objects: PaymentMethod (PIX, CREDIT_CARD), PaymentStatus (PENDING, AUTHORIZED, PAID, FAILED, REFUNDED), SplitCalculator.
  • Serviços / Gateways: Porta IPaymentGateway, Adaptador AsaasPaymentGateway (integração Asaas API v3).
  • Regras Críticas:
    • Modelo de Split Marketplace (Padrão iFood):
      • Take rate da plataforma CeLiLac: 12% incidente sobre o valor dos produtos/itens.
      • Taxa operacional do gateway Asaas (R$ 1,99 no PIX ou equivalente).
      • Taxa de entrega repassada integralmente ao parceiro.
      • Valor líquido (netPartnerAmount) repassado diretamente para a subconta Asaas do parceiro comercial.
    • Idempotência do Checkout: Múltiplas requisições de checkout para o mesmo pedido em pagamento pendente retornam os dados do pagamento e QR Code já emitidos, sem gerar duplicidade de cobrança no gateway.
    • Liquidação Automática via Webhook: Notificações de liquidação de pagamento enviadas pela Asaas atualizam atomicamente o Payment para PAID e promovem o Order para PAID.
    • Reembolso Transacional: Cancelamentos elegíveis acionam o estorno da cobrança junto ao gateway e registram a auditoria em PaymentRefund.