{
  "schema_version": 1,
  "diagram_type": "architecture",
  "meta": {
    "title": "Dispositivo confiável da MFA",
    "subtitle": "30 dias sem o código, decidido pelo banco",
    "output": "dispositivo-confiavel.html",
    "quality_profile": "standard"
  },
  "lanes": [
    { "id": "humano", "label": "Pessoa" },
    { "id": "app", "label": "App" },
    { "id": "db", "label": "Banco" }
  ],
  "mainPath": ["codigo", "confiar", "tabela", "entrada", "prova"],
  "nodes": [
    { "id": "codigo", "lane": "humano", "col": 0, "type": "ui", "label": "/login/mfa", "sublabel": "MfaForm: \"Confiar neste dispositivo por 30 dias\"" },
    { "id": "confiar", "lane": "app", "col": 1, "type": "service", "label": "verifyMfa → confiarNesteDispositivo", "sublabel": "só depois do código provado; cookie httpOnly Lax 30d; audita auth.mfa_device_trusted" },
    { "id": "tabela", "lane": "db", "col": 2, "type": "database", "label": "mfa_trusted_devices", "sublabel": "SHA-256 do token + session_id; RLS sem policy, só service_role" },
    { "id": "entrada", "lane": "app", "col": 3, "type": "service", "label": "signInWithPassword · /auth/callback", "sublabel": "reconhecerDispositivoConfiavel amarra a sessão nova" },
    { "id": "prova", "lane": "db", "col": 4, "type": "database", "label": "fn_session_mfa_proven", "sublabel": "aal2 OU sem fator OU sessão reconhecida no prazo" },
    { "id": "rotas", "lane": "app", "col": 5, "type": "service", "label": "mfaEmDivida (requireRole, actions)", "sublabel": "pergunta à mesma função; falha fechado" },
    { "id": "definers", "lane": "db", "col": 5, "type": "database", "label": "definer de agenda, resposta, roteamento, conexões", "sublabel": "já chamavam fn_session_mfa_proven" },
    { "id": "seguranca", "lane": "humano", "col": 6, "type": "ui", "label": "Configurações › Segurança", "sublabel": "lista e \"Esquecer todos\"; Sair de todos e desligar a MFA também esquecem" }
  ],
  "edges": [
    { "from": "codigo", "to": "confiar" },
    { "from": "confiar", "to": "tabela" },
    { "from": "entrada", "to": "tabela" },
    { "from": "tabela", "to": "prova" },
    { "from": "rotas", "to": "prova" },
    { "from": "definers", "to": "prova" },
    { "from": "seguranca", "to": "tabela" }
  ]
}
