@semacode/cli 1.5.17 → 1.5.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/AGENTS.md +268 -260
  2. package/LICENSE +22 -22
  3. package/README.md +93 -61
  4. package/SEMA_BRIEF.curto.txt +8 -6
  5. package/SEMA_BRIEF.md +71 -22
  6. package/SEMA_BRIEF.micro.txt +7 -5
  7. package/SEMA_INDEX.json +931 -193
  8. package/dist/controleComercialSupabase.d.ts +326 -0
  9. package/dist/controleComercialSupabase.js +310 -0
  10. package/dist/controleComercialSupabase.js.map +1 -0
  11. package/dist/docs.js +48 -20
  12. package/dist/docs.js.map +1 -1
  13. package/dist/drift.d.ts +5 -3
  14. package/dist/drift.js +119 -116
  15. package/dist/drift.js.map +1 -1
  16. package/dist/importador.d.ts +1 -1
  17. package/dist/importador.js +1 -200
  18. package/dist/importador.js.map +1 -1
  19. package/dist/index.js +1924 -493
  20. package/dist/index.js.map +1 -1
  21. package/dist/mcpRemoto.d.ts +32 -0
  22. package/dist/mcpRemoto.js +61 -0
  23. package/dist/mcpRemoto.js.map +1 -0
  24. package/dist/projeto.js +3 -21
  25. package/dist/projeto.js.map +1 -1
  26. package/dist/tipos.d.ts +1 -1
  27. package/docs/AGENT_STARTER.md +109 -102
  28. package/docs/cli.md +89 -33
  29. package/docs/como-ensinar-a-sema-para-ia.md +42 -36
  30. package/docs/deploy.md +231 -43
  31. package/docs/documentacao.md +61 -36
  32. package/docs/env.md +63 -14
  33. package/docs/extensao-vscode.md +12 -4
  34. package/docs/fluxo-pratico-ia-sema.md +45 -35
  35. package/docs/instalacao-e-primeiro-uso.md +52 -30
  36. package/docs/integracao-com-ia.md +44 -35
  37. package/docs/mcp.md +270 -31
  38. package/docs/pagamento-ponta-a-ponta.md +40 -24
  39. package/docs/persistencia-vendor-first.md +11 -5
  40. package/docs/prompt-base-ia-sema.md +18 -11
  41. package/docs/rollback.md +17 -15
  42. package/docs/sintaxe.md +37 -229
  43. package/exemplos/agendamento.sema +105 -106
  44. package/exemplos/assinatura.sema +133 -136
  45. package/exemplos/auditoria.sema +89 -88
  46. package/exemplos/autenticacao.sema +125 -125
  47. package/exemplos/author_obra_comum.sema +294 -0
  48. package/exemplos/author_tema_sensivel.sema +264 -0
  49. package/exemplos/automacao.sema +107 -107
  50. package/exemplos/cadastro_usuario.sema +54 -54
  51. package/exemplos/calculadora.sema +78 -78
  52. package/exemplos/crud_simples.sema +89 -89
  53. package/exemplos/estoque.sema +127 -126
  54. package/exemplos/exportacao.sema +94 -94
  55. package/exemplos/fila.sema +130 -131
  56. package/exemplos/integracao_externa.sema +94 -94
  57. package/exemplos/multi_tenant.sema +140 -140
  58. package/exemplos/notificacao.sema +149 -98
  59. package/exemplos/operacao_estrategia.sema +633 -402
  60. package/exemplos/pagamento.sema +434 -222
  61. package/exemplos/pagamento_dominio.sema +35 -35
  62. package/exemplos/pedido.sema +255 -119
  63. package/exemplos/permissao.sema +121 -121
  64. package/exemplos/persistencia_vendor_first.sema +86 -86
  65. package/exemplos/profile_game.sema +114 -0
  66. package/exemplos/profile_legal.sema +105 -0
  67. package/exemplos/profile_ops.sema +110 -0
  68. package/exemplos/profile_research.sema +104 -0
  69. package/exemplos/profile_software.sema +123 -0
  70. package/exemplos/profile_workflow_n8n.sema +99 -0
  71. package/exemplos/relatorio.sema +93 -93
  72. package/exemplos/replica_analitica_erp.sema +160 -0
  73. package/exemplos/testes_embutidos.sema +45 -45
  74. package/exemplos/tratamento_erro.sema +157 -157
  75. package/exemplos/upload_arquivo.sema +93 -93
  76. package/exemplos/webhook.sema +94 -96
  77. package/llms-full.txt +34 -34
  78. package/llms.txt +17 -17
  79. package/node_modules/@sema/gerador-css/dist/index.js +563 -563
  80. package/node_modules/@sema/gerador-css/package.json +1 -1
  81. package/node_modules/@sema/gerador-dart/package.json +1 -1
  82. package/node_modules/@sema/gerador-html/dist/index.js +90 -90
  83. package/node_modules/@sema/gerador-html/package.json +1 -1
  84. package/node_modules/@sema/gerador-javascript/dist/index.js +92 -92
  85. package/node_modules/@sema/gerador-javascript/package.json +1 -1
  86. package/node_modules/@sema/gerador-lua/dist/index.js +53 -53
  87. package/node_modules/@sema/gerador-lua/package.json +1 -1
  88. package/node_modules/@sema/gerador-python/dist/index.js +122 -96
  89. package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
  90. package/node_modules/@sema/gerador-python/package.json +1 -1
  91. package/node_modules/@sema/gerador-typescript/dist/index.js +153 -153
  92. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  93. package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +2 -4
  94. package/node_modules/@sema/nucleo/dist/formatador/index.js +26 -46
  95. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +1 -1
  96. package/node_modules/@sema/nucleo/dist/ir/conversor.js +9 -204
  97. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
  98. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -35
  99. package/node_modules/@sema/nucleo/dist/lexer/tokens.js +0 -21
  100. package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +1 -1
  101. package/node_modules/@sema/nucleo/dist/parser/parser.js +0 -40
  102. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
  103. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +6 -5
  104. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +76 -307
  105. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
  106. package/node_modules/@sema/nucleo/dist/semantico/estruturas.d.ts +2 -0
  107. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js +32 -2
  108. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +1 -1
  109. package/node_modules/@sema/nucleo/package.json +1 -1
  110. package/node_modules/@sema/padroes/package.json +1 -1
  111. package/package.json +15 -15
@@ -1,157 +1,157 @@
1
- module exemplos.tratamento.erro {
2
- task executar_operacao_sensivel {
3
- input {
4
- chave: Texto required
5
- }
6
- output {
7
- protocolo: Id
8
- }
9
- rules {
10
- chave existe e chave deve_ser preenchida
11
- }
12
- effects {
13
- consulta cofre
14
- auditoria falha_operacao_sensivel
15
- }
16
- guarantees {
17
- protocolo existe
18
- }
19
- error {
20
- acesso_negado: "A chave informada nao tem permissao."
21
- recurso_indisponivel: "O servico esta temporariamente indisponivel."
22
- auditoria_obrigatoria: "Toda falha precisa ser registrada."
23
- }
24
- tests {
25
- caso "falha por acesso negado" {
26
- given {
27
- chave: "sem_permissao"
28
- }
29
-
30
- expect {
31
- sucesso: falso
32
- }
33
-
34
- error {
35
- tipo: "acesso_negado"
36
- }
37
- }
38
- }
39
- }
40
-
41
- task responder_acesso_negado {
42
- input {
43
- chave: Texto required
44
- }
45
- output {
46
- protocolo_resposta: Id
47
- }
48
- effects {
49
- notificacao cliente acesso_negado
50
- auditoria acesso_negado
51
- }
52
- guarantees {
53
- protocolo_resposta existe
54
- }
55
- tests {
56
- caso "responde acesso negado" {
57
- given {
58
- chave: "sem_permissao"
59
- }
60
-
61
- expect {
62
- sucesso: verdadeiro
63
- }
64
- }
65
- }
66
- }
67
-
68
- task responder_retentativa {
69
- input {
70
- chave: Texto required
71
- }
72
- output {
73
- protocolo_resposta: Id
74
- }
75
- effects {
76
- notificacao cliente retentativa_programada
77
- auditoria retentativa
78
- }
79
- guarantees {
80
- protocolo_resposta existe
81
- }
82
- tests {
83
- caso "agenda retentativa" {
84
- given {
85
- chave: "instavel"
86
- }
87
-
88
- expect {
89
- sucesso: verdadeiro
90
- }
91
- }
92
- }
93
- }
94
-
95
- task registrar_auditoria_falha {
96
- input {
97
- chave: Texto required
98
- }
99
- output {
100
- auditoria_id: Id
101
- }
102
- effects {
103
- auditoria falha_operacional
104
- persistencia auditoria_falha
105
- }
106
- guarantees {
107
- auditoria_id existe
108
- }
109
- tests {
110
- caso "audita falha" {
111
- given {
112
- chave: "sem_permissao"
113
- }
114
-
115
- expect {
116
- sucesso: verdadeiro
117
- }
118
- }
119
- }
120
- }
121
-
122
- task registrar_sucesso {
123
- input {
124
- protocolo: Id required
125
- }
126
- output {
127
- registro_id: Id
128
- }
129
- effects {
130
- auditoria operacao_concluida
131
- evento operacao_sensivel_concluida
132
- }
133
- guarantees {
134
- registro_id existe
135
- }
136
- tests {
137
- caso "registra sucesso" {
138
- given {
139
- protocolo: "prot_1"
140
- }
141
-
142
- expect {
143
- sucesso: verdadeiro
144
- }
145
- }
146
- }
147
- }
148
-
149
- flow resposta_segura {
150
- chave: Texto
151
- etapa tentar usa executar_operacao_sensivel com chave = chave em_sucesso concluir em_erro registrar_falha por_erro acesso_negado = tratar_acesso_negado, recurso_indisponivel = agendar_retentativa
152
- etapa tratar_acesso_negado usa responder_acesso_negado com chave = chave depende_de tentar
153
- etapa agendar_retentativa usa responder_retentativa com chave = chave depende_de tentar
154
- etapa registrar_falha usa registrar_auditoria_falha com chave = chave depende_de tentar
155
- etapa concluir usa registrar_sucesso com protocolo = tentar.protocolo depende_de tentar
156
- }
157
- }
1
+ module exemplos.tratamento.erro {
2
+ task executar_operacao_sensivel {
3
+ input {
4
+ chave: Texto required
5
+ }
6
+ output {
7
+ protocolo: Id
8
+ }
9
+ rules {
10
+ chave existe e chave deve_ser preenchida
11
+ }
12
+ effects {
13
+ consulta cofre
14
+ auditoria falha_operacao_sensivel
15
+ }
16
+ guarantees {
17
+ protocolo existe
18
+ }
19
+ error {
20
+ acesso_negado: "A chave informada nao tem permissao."
21
+ recurso_indisponivel: "O servico esta temporariamente indisponivel."
22
+ auditoria_obrigatoria: "Toda falha precisa ser registrada."
23
+ }
24
+ tests {
25
+ caso "falha por acesso negado" {
26
+ given {
27
+ chave: "sem_permissao"
28
+ }
29
+
30
+ expect {
31
+ sucesso: falso
32
+ }
33
+
34
+ error {
35
+ tipo: "acesso_negado"
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ task responder_acesso_negado {
42
+ input {
43
+ chave: Texto required
44
+ }
45
+ output {
46
+ protocolo_resposta: Id
47
+ }
48
+ effects {
49
+ notificacao cliente acesso_negado
50
+ auditoria acesso_negado
51
+ }
52
+ guarantees {
53
+ protocolo_resposta existe
54
+ }
55
+ tests {
56
+ caso "responde acesso negado" {
57
+ given {
58
+ chave: "sem_permissao"
59
+ }
60
+
61
+ expect {
62
+ sucesso: verdadeiro
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ task responder_retentativa {
69
+ input {
70
+ chave: Texto required
71
+ }
72
+ output {
73
+ protocolo_resposta: Id
74
+ }
75
+ effects {
76
+ notificacao cliente retentativa_programada
77
+ auditoria retentativa
78
+ }
79
+ guarantees {
80
+ protocolo_resposta existe
81
+ }
82
+ tests {
83
+ caso "agenda retentativa" {
84
+ given {
85
+ chave: "instavel"
86
+ }
87
+
88
+ expect {
89
+ sucesso: verdadeiro
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ task registrar_auditoria_falha {
96
+ input {
97
+ chave: Texto required
98
+ }
99
+ output {
100
+ auditoria_id: Id
101
+ }
102
+ effects {
103
+ auditoria falha_operacional
104
+ persistencia auditoria_falha
105
+ }
106
+ guarantees {
107
+ auditoria_id existe
108
+ }
109
+ tests {
110
+ caso "audita falha" {
111
+ given {
112
+ chave: "sem_permissao"
113
+ }
114
+
115
+ expect {
116
+ sucesso: verdadeiro
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ task registrar_sucesso {
123
+ input {
124
+ protocolo: Id required
125
+ }
126
+ output {
127
+ registro_id: Id
128
+ }
129
+ effects {
130
+ auditoria operacao_concluida
131
+ evento operacao_sensivel_concluida
132
+ }
133
+ guarantees {
134
+ registro_id existe
135
+ }
136
+ tests {
137
+ caso "registra sucesso" {
138
+ given {
139
+ protocolo: "prot_1"
140
+ }
141
+
142
+ expect {
143
+ sucesso: verdadeiro
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ flow resposta_segura {
150
+ chave: Texto
151
+ etapa tentar usa executar_operacao_sensivel com chave = chave em_sucesso concluir em_erro registrar_falha por_erro acesso_negado = tratar_acesso_negado, recurso_indisponivel = agendar_retentativa
152
+ etapa tratar_acesso_negado usa responder_acesso_negado com chave = chave depende_de tentar
153
+ etapa agendar_retentativa usa responder_retentativa com chave = chave depende_de tentar
154
+ etapa registrar_falha usa registrar_auditoria_falha com chave = chave depende_de tentar
155
+ etapa concluir usa registrar_sucesso com protocolo = tentar.protocolo depende_de tentar
156
+ }
157
+ }
@@ -1,93 +1,93 @@
1
- module exemplos.upload.arquivo {
2
- docs {
3
- resumo: "Upload de arquivos com validacao de tipo, tamanho e processamento."
4
- }
5
-
6
- entity Arquivo {
7
- fields {
8
- id: Id
9
- nome: Texto
10
- tipo_mime: Texto
11
- tamanho_bytes: Inteiro
12
- url: Texto
13
- status: Texto
14
- enviado_por: Id
15
- criado_em: Timestamp
16
- }
17
- }
18
-
19
- task iniciar_upload {
20
- input {
21
- nome: Texto required
22
- tipo_mime: Texto required
23
- tamanho_bytes: Inteiro required
24
- }
25
- output {
26
- upload_id: Id
27
- url_upload: Texto
28
- }
29
- rules {
30
- tipo_mime em [image/jpeg, image/png, application/pdf, text/csv]
31
- tamanho_bytes <= 10485760
32
- nome deve_ser preenchido
33
- }
34
- effects {
35
- consulta storage criticidade = alta
36
- persistencia Arquivo
37
- auditoria upload_iniciado
38
- }
39
- guarantees {
40
- upload_id existe
41
- url_upload existe
42
- }
43
- error {
44
- tipo_nao_permitido: "Tipo de arquivo nao aceito."
45
- tamanho_excedido: "Arquivo excede o limite de 10MB."
46
- storage_indisponivel: "Servico de armazenamento indisponivel."
47
- }
48
- tests {
49
- caso "inicia upload de imagem" {
50
- given { nome: "foto.jpg" tipo_mime: "image/jpeg" tamanho_bytes: 512000 }
51
- expect { sucesso: verdadeiro }
52
- }
53
- caso "rejeita arquivo muito grande" {
54
- given { nome: "video.mp4" tipo_mime: "video/mp4" tamanho_bytes: 20971520 }
55
- expect { sucesso: falso }
56
- error { tipo: "tamanho_excedido" }
57
- }
58
- }
59
- }
60
-
61
- task confirmar_upload {
62
- input {
63
- upload_id: Id required
64
- }
65
- output {
66
- arquivo: Arquivo
67
- }
68
- rules {
69
- upload_id deve_ser valido
70
- }
71
- effects {
72
- consulta storage por upload_id criticidade = alta
73
- persistencia Arquivo
74
- evento arquivo_disponivel criticidade = baixa
75
- auditoria upload_confirmado
76
- }
77
- state ciclo_arquivo {
78
- transitions {
79
- PENDENTE -> DISPONIVEL
80
- }
81
- }
82
- guarantees {
83
- arquivo existe
84
- arquivo.url existe
85
- }
86
- tests {
87
- caso "confirma upload realizado" {
88
- given { upload_id: "upl_1" }
89
- expect { sucesso: verdadeiro }
90
- }
91
- }
92
- }
93
- }
1
+ module exemplos.upload.arquivo {
2
+ docs {
3
+ resumo: "Upload de arquivos com validacao de tipo, tamanho e processamento."
4
+ }
5
+
6
+ entity Arquivo {
7
+ fields {
8
+ id: Id
9
+ nome: Texto
10
+ tipo_mime: Texto
11
+ tamanho_bytes: Inteiro
12
+ url: Texto
13
+ status: Texto
14
+ enviado_por: Id
15
+ criado_em: Timestamp
16
+ }
17
+ }
18
+
19
+ task iniciar_upload {
20
+ input {
21
+ nome: Texto required
22
+ tipo_mime: Texto required
23
+ tamanho_bytes: Inteiro required
24
+ }
25
+ output {
26
+ upload_id: Id
27
+ url_upload: Texto
28
+ }
29
+ rules {
30
+ tipo_mime em [image/jpeg, image/png, application/pdf, text/csv]
31
+ tamanho_bytes <= 10485760
32
+ nome deve_ser preenchido
33
+ }
34
+ effects {
35
+ consulta storage criticidade = alta
36
+ persistencia Arquivo
37
+ auditoria upload_iniciado
38
+ }
39
+ guarantees {
40
+ upload_id existe
41
+ url_upload existe
42
+ }
43
+ error {
44
+ tipo_nao_permitido: "Tipo de arquivo nao aceito."
45
+ tamanho_excedido: "Arquivo excede o limite de 10MB."
46
+ storage_indisponivel: "Servico de armazenamento indisponivel."
47
+ }
48
+ tests {
49
+ caso "inicia upload de imagem" {
50
+ given { nome: "foto.jpg" tipo_mime: "image/jpeg" tamanho_bytes: 512000 }
51
+ expect { sucesso: verdadeiro }
52
+ }
53
+ caso "rejeita arquivo muito grande" {
54
+ given { nome: "video.mp4" tipo_mime: "video/mp4" tamanho_bytes: 20971520 }
55
+ expect { sucesso: falso }
56
+ error { tipo: "tamanho_excedido" }
57
+ }
58
+ }
59
+ }
60
+
61
+ task confirmar_upload {
62
+ input {
63
+ upload_id: Id required
64
+ }
65
+ output {
66
+ arquivo: Arquivo
67
+ }
68
+ rules {
69
+ upload_id deve_ser valido
70
+ }
71
+ effects {
72
+ consulta storage por upload_id criticidade = alta
73
+ persistencia Arquivo
74
+ evento arquivo_disponivel criticidade = baixa
75
+ auditoria upload_confirmado
76
+ }
77
+ state ciclo_arquivo {
78
+ transitions {
79
+ PENDENTE -> DISPONIVEL
80
+ }
81
+ }
82
+ guarantees {
83
+ arquivo existe
84
+ arquivo.url existe
85
+ }
86
+ tests {
87
+ caso "confirma upload realizado" {
88
+ given { upload_id: "upl_1" }
89
+ expect { sucesso: verdadeiro }
90
+ }
91
+ }
92
+ }
93
+ }
@@ -1,96 +1,94 @@
1
- module exemplos.webhook {
2
- docs {
3
- resumo: "Recepcao, validacao e reenvio de eventos via webhook."
4
- }
5
-
6
- entity EventoWebhook {
7
- fields {
8
- id: Id
9
- origem: Texto
10
- tipo: Texto
11
- payload: Objeto
12
- status: Texto
13
- tentativas: Inteiro
14
- recebido_em: Timestamp
15
- processado_em: Timestamp
16
- }
17
- }
18
-
19
- task receber_webhook {
20
- input {
21
- origem: Texto required
22
- tipo: Texto required
23
- payload: Objeto required
24
- assinatura: Texto required
25
- }
26
- output {
27
- evento_id: Id
28
- }
29
- rules {
30
- assinatura deve_ser valida para payload
31
- origem deve_ser permitida
32
- tipo deve_ser preenchido
33
- }
34
- effects {
35
- persistencia EventoWebhook
36
- evento webhook_recebido criticidade = media
37
- auditoria recepcao_webhook
38
- }
39
- state ciclo_webhook {
40
- transitions {
41
- RECEBIDO -> EM_PROCESSAMENTO
42
- }
43
- }
44
- guarantees {
45
- evento_id existe
46
- }
47
- error {
48
- assinatura_invalida: "Assinatura do webhook nao confere."
49
- origem_nao_permitida: "Origem do webhook nao esta na lista de permitidos."
50
- }
51
- tests {
52
- caso "recebe webhook valido" {
53
- given { origem: "stripe" tipo: "payment.succeeded" payload: {} assinatura: "sig_ok" }
54
- expect { sucesso: verdadeiro }
55
- }
56
- caso "rejeita assinatura invalida" {
57
- given { origem: "stripe" tipo: "payment.succeeded" payload: {} assinatura: "sig_errada" }
58
- expect { sucesso: falso }
59
- error { tipo: "assinatura_invalida" }
60
- }
61
- }
62
- }
63
-
64
- task reenviar_webhook {
65
- input {
66
- evento_id: Id required
67
- }
68
- output {
69
- protocolo: Id
70
- }
71
- rules {
72
- evento_id deve_ser valido
73
- evento.tentativas < 5
74
- evento.status em [FALHOU, PENDENTE]
75
- }
76
- effects {
77
- consulta EventoWebhook por evento_id
78
- persistencia EventoWebhook
79
- evento webhook_reenviado
80
- auditoria reenvio_webhook
81
- }
82
- guarantees {
83
- protocolo existe
84
- }
85
- error {
86
- limite_tentativas: "Numero maximo de tentativas atingido."
87
- evento_ja_processado: "Este evento ja foi processado com sucesso."
88
- }
89
- tests {
90
- caso "reenvia evento falho" {
91
- given { evento_id: "evt_1" }
92
- expect { sucesso: verdadeiro }
93
- }
94
- }
95
- }
96
- }
1
+ module exemplos.webhook {
2
+ docs {
3
+ resumo: "Recepcao, validacao e reenvio de eventos via webhook."
4
+ }
5
+
6
+ entity EventoWebhook {
7
+ fields {
8
+ id: Id
9
+ origem: Texto
10
+ tipo: Texto
11
+ payload: Objeto
12
+ status: Texto
13
+ tentativas: Inteiro
14
+ recebido_em: Timestamp
15
+ processado_em: Timestamp
16
+ }
17
+ }
18
+
19
+ task receber_webhook {
20
+ input {
21
+ origem: Texto required
22
+ tipo: Texto required
23
+ payload: Objeto required
24
+ assinatura: Texto required
25
+ }
26
+ output {
27
+ evento_id: Id
28
+ }
29
+ rules {
30
+ assinatura deve_ser valida para payload
31
+ origem deve_ser permitida
32
+ tipo deve_ser preenchido
33
+ }
34
+ effects {
35
+ persistencia EventoWebhook
36
+ evento webhook_recebido criticidade = media
37
+ auditoria recepcao_webhook
38
+ }
39
+ state ciclo_webhook {
40
+ transitions {
41
+ RECEBIDO -> EM_PROCESSAMENTO
42
+ }
43
+ }
44
+ guarantees {
45
+ evento_id existe
46
+ }
47
+ error {
48
+ assinatura_invalida: "Assinatura do webhook nao confere."
49
+ origem_nao_permitida: "Origem do webhook nao esta na lista de permitidos."
50
+ }
51
+ tests {
52
+ caso "recebe webhook valido" {
53
+ given { origem: "stripe" tipo: "payment.succeeded" payload: "payload_ok" assinatura: "sig_ok" }
54
+ expect { sucesso: verdadeiro }
55
+ }
56
+ caso "rejeita assinatura invalida" {
57
+ given { origem: "stripe" tipo: "payment.succeeded" payload: "payload_ok" assinatura: "sig_errada" }
58
+ expect { sucesso: falso }
59
+ error { tipo: "assinatura_invalida" }
60
+ }
61
+ }
62
+ }
63
+
64
+ task reenviar_webhook {
65
+ input {
66
+ evento_id: Id required
67
+ }
68
+ output {
69
+ protocolo: Id
70
+ }
71
+ rules {
72
+ evento_id deve_ser valido
73
+ }
74
+ effects {
75
+ consulta EventoWebhook por evento_id
76
+ persistencia EventoWebhook
77
+ evento webhook_reenviado
78
+ auditoria reenvio_webhook
79
+ }
80
+ guarantees {
81
+ protocolo existe
82
+ }
83
+ error {
84
+ limite_tentativas: "Numero maximo de tentativas atingido."
85
+ evento_ja_processado: "Este evento ja foi processado com sucesso."
86
+ }
87
+ tests {
88
+ caso "reenvia evento falho" {
89
+ given { evento_id: "evt_1" }
90
+ expect { sucesso: verdadeiro }
91
+ }
92
+ }
93
+ }
94
+ }