Pular para o conteúdo principal

MDS · Modular Development Style

Exemplos de Instância

Três cenários extremos lado a lado mostrando como o mesmo template MDS descreve um webhook, uma feature e um produto SaaS.

EXEMPLOS DE INSTÂNCIA — MDS

3 cenários extremos lado a lado mostrando como o mesmo template se renderiza em projetos de portes radicalmente diferentes.


Cenário 1 — Webhook Stripe → DB (300 linhas, 1 dev, 1 dia)

A. Identidade

  • A1 Nome: stripe-subscription-sync
  • A2 Problema: assinaturas no DB ficam dessincronizadas quando Stripe muda status
  • A3 Domínio: cobrança recorrente SaaS
  • A4 Stakeholders: time financeiro (cliente interno)
  • A5 Glossário: Subscription, Customer, Invoice, Webhook Event
  • A6 Escopo + Não-escopo: SCOPE: receber webhooks Stripe, atualizar status local. NOT-SCOPE: criar assinaturas, cobrança, reembolsos.
  • A7 Premissas: Stripe garante retry de webhook em failure.

B. Atores e Jornadas

  • B1: Stripe (sistema externo), Backend Worker (interno)
  • B2: 🟨 N/A — sistema headless, sem perfis humanos
  • B3: Jornada única: Stripe envia POST → worker valida HMAC → mapeia evento → atualiza tabela subscriptions
  • B4, B5: 🟩 omitidos

C. RFs

  • C1: RF-001 receber webhook + validar; RF-002 mapear 8 event types; RF-003 atualizar DB idempotentemente
  • C2: 🟨 RF-002 contém mapping rules — preencher (S, há lógica não-trivial)
  • C3: 🟨 N/A — status local é overwrite simples, sem state machine
  • C4, C5: 🟩 omitidos

D. RNFs

  • D1: processamento <500ms p99
  • D2: validação HMAC obrigatória; auth por secret env
  • D3: 🟨 N/A — interno, sem SLA externo
  • D4: 🟨 N/A — volume estável <1k events/dia
  • D5: Auditabilidade — log de cada webhook + resultado (sucesso/falha + payload)
  • D6: 🟨 N/A — sem dados sensíveis no payload
  • D7: 🟨 N/A — sem UI
  • D8: 🟨 N/A — single currency BRL
  • D9: 🟩 omitido
  • D10: Cadastro progressivo — tabela subscriptions recebe campos NULL conforme webhook chega

E. Modelo de Domínio

  • E1: tabela subscriptions(stripe_id PK, status, current_period_end, customer_id, raw_payload jsonb)
  • E2: 🟨 N/A — apenas 1 entidade
  • E3, E4, E5: 🟩 omitidos

F. Interfaces

  • F1: 🟨 N/A — daemon backend
  • F2: consome Stripe Events API (validation only — fallback)
  • F3: expõe POST /webhooks/stripe
  • F4: 🟨 N/A — monolito
  • F5, F6: 🟩 omitidos

G. Arquitetura

  • G1: Node 22 + Hono + Postgres 16 + Docker container em VPS Hostinger
  • G2: 🟨 ADR-001 idempotência via stripe event id como dedup key
  • G3: 🟨 N/A — single tenant, single instance
  • G4: 🟨 N/A — 1 componente
  • G5, G6, G7: 🟩 omitidos

H. Specs

  • H1: Critérios de aceitação por RF (S/N table)
  • H2: 🟨 N/A — projeto manual, sem agent autônomo implementando
  • H3: 🟩 omitido

I. Validação

  • I1: TDD nas regras de mapping + integration test contra Stripe sandbox
  • I2: preenchido por RF
  • I3: unit tests no mapping (lógica pura — S)
  • I4: integration test com Stripe CLI fixtures
  • I5: 🟨 N/A — sem UI
  • I6: 🟨 N/A — fluxo interno baixo risco
  • I7, I8, I9: 🟩 omitidos

J. Entrega

  • J1: 🟨 N/A — release única
  • J2: 🟨 N/A — 3 RFs sequenciais óbvios
  • J3: 🟨 Risco: HMAC secret rotation; Mitigação: env var via Docker secret
  • J4, J5: 🟩 omitidos

K. Operação

  • K1: Runbook 1 página (cmd restart, cmd resync histórico)
  • K2: alerta Sentry em qualquer 5xx; Grafana dashboard simples
  • K3: Postgres já tem backup automático na VPS
  • K4, K5: 🟩 omitidos

L. Entitlement

  • L1: sem entitlement em runtime (sistema headless)
  • L2: 🟨 N/A — config fixa em env vars
  • L3: 🟨 N/A — single tenant
  • L4: 🟩 omitido

M. Automação / IA-gen

  • M1: mapa: webhook recebido → atualiza DB → emite log estruturado (não dispara outro módulo)
  • M2: 🟨 N/A — sem geração estruturada relevante
  • M3: 🟨 N/A — entidade única
  • M4: 🟩 omitido

Resumo da instância

  • 🟦 BASE preenchidos: 20/20 ✔
  • 🟨 PLUGIN preenchidos: 8 ; N/A: 17 ; total 25 com resposta explícita
  • 🟩 STACK preenchidos: 0 ; omitidos: 14 (sem necessidade de justificar)

Artefato realista: 1 README de 4-6 páginas. Tempo de preenchimento: ~1-2 horas.


Cenário 2 — App de Recibos Mobile (PWA, 4 telas, 2-3 sprints)

A. Identidade

  • A1 Nome: recibo-fast
  • A2 Problema: prestadores autônomos perdem tempo emitindo recibos PDF manuais
  • A3 Domínio: finanças pessoais / PJ
  • A4 Stakeholders: Wladimir (sponsor + product owner); ~20 usuários beta na rede
  • A5 Glossário: Recibo, Cliente, Valor, Histórico
  • A6 Escopo + Não-escopo: SCOPE: criar/listar/PDF/compartilhar recibos. NOT-SCOPE: NF-e, integração bancária, multi-usuário.
  • A7 Premissas: Supabase free tier suporta volume previsto.

B. Atores e Jornadas

  • B1: Prestador (humano), Sistema (PWA)
  • B2: 🟨 N/A — todo prestador tem mesmo perfil
  • B3: J1: cadastra cliente; J2: emite recibo; J3: gera PDF; J4: compartilha link/WhatsApp
  • B4: edge: recibo retroativo; recibo recorrente
  • B5: 🟩 omitido

C. RFs

  • C1: ~25 RFs catalogados (CRUD cliente, CRUD recibo, geração PDF, share, dashboard mensal, busca)
  • C2: 🟨 cálculo: valor por extenso (PT-BR); cálculo tributário básico — preencher (S)
  • C3: 🟨 N/A — recibo só tem 2 estados livres (rascunho/emitido), transição manual
  • C4, C5: 🟩 omitidos

D. RNFs

  • D1: tempo de geração PDF <3s; tempo de open app <2s; Lighthouse PWA score ≥90
  • D2: Supabase Auth (magic link); RLS por user_id
  • D3: 🟨 N/A — beta, sem SLA
  • D4: 🟨 N/A — escala prevista <500 usuários ano 1
  • D5: Auditabilidade — log de criação/edição/delete por recibo
  • D6: LGPD — dados pessoais de cliente do prestador (consentimento + delete on request)
  • D7: WCAG AA — UI pública mobile
  • D8: 🟨 N/A — PT-BR + BRL only
  • D9: 🟩 omitido
  • D10: Cadastro progressivo — só CPF/CNPJ + nome obrigatório no cliente; demais campos NULL

E. Modelo

  • E1: entidades: User, Client, Receipt, ReceiptItem
  • E2: ER conceitual em 1 imagem (4 entidades)
  • E3, E4, E5: 🟩 omitidos

F. Interfaces

  • F1: 4 telas (Login, Home/Lista, Novo Recibo, Detalhes/PDF) + Mobile-first PWA
  • F2: consome Gotenberg pra geração PDF
  • F3: 🟨 N/A — sem API pública
  • F4: 🟨 N/A — monolito
  • F5, F6: 🟩 omitidos

G. Arquitetura

  • G1: Next.js 15 + Supabase (DB + Auth + Storage) + Gotenberg para PDF; Vercel hosting
  • G2: ADR-001 PDF via HTML→PDF (Gotenberg) seguindo pdf-generation-pattern Modulareasy; ADR-002 Auth via magic link
  • G3: 🟨 single-tenant per-user (cada user vê só os seus)
  • G4: 🟨 3 componentes: Web app, Supabase, Gotenberg container
  • G5, G6, G7: 🟩 omitidos

H. Specs

  • H1: critérios de aceitação por RF
  • H2: 🟨 RFs complexos (geração PDF, valor por extenso) ganham spec YAML — frontend-dev agent vai implementar
  • H3: 🟩 omitido

I. Validação

  • I1: TDD lógica pura + smoke visual nas 4 telas + manual exploratory beta
  • I2: por RF
  • I3: unit tests cálculos
  • I4: integration test Gotenberg
  • I5: smoke visual obrigatório (4 telas × light/dark × mobile/desktop = 16 estados)
  • I6: QA exploratório com 5 prestadores beta
  • I7, I8: 🟩 omitidos
  • I9: accessibility audit pré-launch (RNF D7)

J. Entrega

  • J1: 2 sprints — Sprint 1 CRUD; Sprint 2 PDF + share
  • J2: 🟨 dependency: J2 PDF depende de E1 + RFs do recibo
  • J3: Risco principal: latência Gotenberg em PWA mobile
  • J4, J5: 🟩 omitidos

K. Operação

  • K1: runbook 2 páginas
  • K2: Sentry + Vercel analytics
  • K3: Supabase managed backup
  • K4, K5: 🟩 omitidos

L. Entitlement

  • L1: sem entitlement em runtime (todo user tem mesma feature set)
  • L2: 🟨 N/A — config simples via env
  • L3: 🟨 N/A — sem white-label, marca única
  • L4: 🟩 omitido

M. Automação / IA-gen

  • M1: evento “recibo emitido” → opcionalmente envia WhatsApp pro cliente do prestador (Contact)
  • M2: 🟨 IA pra sugerir histórico de recibo (descrição) baseado em descrições anteriores
  • M3: 🟨 N/A — entidades isoladas, sem revalidation
  • M4: 🟩 omitido

Resumo

  • 🟦 BASE preenchidos: 20/20 ✔
  • 🟨 PLUGIN preenchidos: ~18 ; N/A: ~12
  • 🟩 STACK preenchidos: 0 ; omitidos: 14

Artefato realista: PRD de 15-25 páginas. Tempo: 2-4 horas elicitação + iteração ao longo do projeto.


Cenário 3 — ModularHub (SaaS multi-tenant white-label, 12 módulos, 6+ meses)

Resumo da instância (sem expandir por questão de tamanho — ver projeto vivo)

Status em S7 (2026-05-26):

  • 🟦 BASE (20): todos preenchidos via CANON ModularHub + arquivos individuais
  • 🟨 PLUGIN (30): virtualmente todos disparam S (multi-tenant, multi-módulo, multi-moeda, compliance LGPD, UI rica, alta auditabilidade, automação cross-módulo, IA-gen, white-label, etc) — preenchidos via inventário 12/12 + INTERFACES.md + ADRs 001-006 + DECISOES-CRAVADAS-S6
  • 🟩 STACK (14): grande maioria preenchida (event catalog, deprecation policy 30d, monitoramento futuro, plano descomissionamento OpHub V1, etc) — alguns ainda em STACK STACK (capacity planning, prompts catalog) por estarem em fase de roadmap

Artefato realista:

  • DRS 10 seções IEEE 830 (07-drs/DRS-v1.0.md, a compilar em Fase 3 S7/S8)
  • Inventário 12 arquivos de funcionalidades
  • INTERFACES.md mestre 12×12 + 88 interfaces
  • 6 ADRs (mais novos previstos pós-Conselho Fase 2)
  • 78 D-MOD-NNN + 8 refinamentos majors (DECISOES-CRAVADAS-S6.md)
  • 16 REQ-MH (aprendizados OpHub V1)
  • Tier 3 pesquisa de mercado (este S7)
  • Specs Agent sob demanda quando RFs entrarem em ciclo

Tempo: 7 sessões longas até este ponto, com folga pra mais 5+.


Insights cross-cenário

  1. Os 20 BASE são iguais em todos os 3 cenários. Volume de conteúdo varia (1 linha vs 10 páginas), mas presença é universal.

  2. PLUGIN diferencia profundamente os porte:

    • Webhook Stripe: 8 ativados / 17 N/A
    • PWA recibo: ~18 ativados / 12 N/A
    • ModularHub: ~28 ativados / 2 N/A
  3. STACK é o termômetro de maturidade do produto. Webhook tem 0 STACK; ModularHub tem 11+ STACK.

  4. N/A justificado mostra disciplina, não fraqueza. Webhook tem 17 N/A e isso é a coisa CERTA — declarar com clareza o que NÃO precisa.

  5. Mesma metodologia, mesmo vocabulário, mesmo template. A diferença entre webhook e ModularHub não é “metodologia diferente” — é composição de blocos diferente.