@semacode/cli 1.5.17 → 1.5.18

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 (66) hide show
  1. package/README.md +104 -112
  2. package/SEMA_BRIEF.curto.txt +6 -6
  3. package/SEMA_BRIEF.md +17 -24
  4. package/SEMA_BRIEF.micro.txt +5 -5
  5. package/SEMA_INDEX.json +86 -224
  6. package/dist/drift.d.ts +3 -3
  7. package/dist/drift.js +5 -111
  8. package/dist/drift.js.map +1 -1
  9. package/dist/importador.d.ts +1 -1
  10. package/dist/importador.js +1 -200
  11. package/dist/importador.js.map +1 -1
  12. package/dist/index.js +59 -479
  13. package/dist/index.js.map +1 -1
  14. package/dist/projeto.js +0 -20
  15. package/dist/projeto.js.map +1 -1
  16. package/dist/tipos.d.ts +1 -1
  17. package/docs/AGENT_STARTER.md +9 -8
  18. package/docs/cli.md +106 -119
  19. package/docs/como-ensinar-a-sema-para-ia.md +4 -4
  20. package/docs/env.md +56 -56
  21. package/docs/fluxo-pratico-ia-sema.md +171 -167
  22. package/docs/integracao-com-ia.md +98 -96
  23. package/docs/mcp.md +51 -53
  24. package/docs/pagamento-ponta-a-ponta.md +11 -1
  25. package/docs/persistencia-vendor-first.md +1 -1
  26. package/docs/prompt-base-ia-sema.md +6 -5
  27. package/docs/rollback.md +1 -1
  28. package/docs/sintaxe.md +196 -394
  29. package/exemplos/agendamento.sema +0 -1
  30. package/exemplos/assinatura.sema +0 -3
  31. package/exemplos/auditoria.sema +2 -1
  32. package/exemplos/estoque.sema +2 -1
  33. package/exemplos/fila.sema +2 -3
  34. package/exemplos/multi_tenant.sema +2 -2
  35. package/exemplos/notificacao.sema +53 -2
  36. package/exemplos/operacao_estrategia.sema +231 -0
  37. package/exemplos/pagamento.sema +214 -2
  38. package/exemplos/pedido.sema +156 -20
  39. package/exemplos/replica_analitica_erp.sema +160 -0
  40. package/exemplos/webhook.sema +2 -4
  41. package/node_modules/@sema/gerador-css/package.json +1 -1
  42. package/node_modules/@sema/gerador-dart/package.json +1 -1
  43. package/node_modules/@sema/gerador-html/package.json +1 -1
  44. package/node_modules/@sema/gerador-javascript/package.json +1 -1
  45. package/node_modules/@sema/gerador-lua/package.json +1 -1
  46. package/node_modules/@sema/gerador-python/package.json +1 -1
  47. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  48. package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +2 -4
  49. package/node_modules/@sema/nucleo/dist/formatador/index.js +14 -42
  50. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +1 -1
  51. package/node_modules/@sema/nucleo/dist/ir/conversor.js +9 -204
  52. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
  53. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -35
  54. package/node_modules/@sema/nucleo/dist/lexer/tokens.js +0 -21
  55. package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +1 -1
  56. package/node_modules/@sema/nucleo/dist/parser/parser.js +0 -40
  57. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
  58. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +6 -5
  59. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +76 -307
  60. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
  61. package/node_modules/@sema/nucleo/dist/semantico/estruturas.d.ts +2 -0
  62. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js +32 -2
  63. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +1 -1
  64. package/node_modules/@sema/nucleo/package.json +1 -1
  65. package/node_modules/@sema/padroes/package.json +1 -1
  66. package/package.json +14 -14
@@ -1,6 +1,6 @@
1
1
  module exemplos.pagamento {
2
2
  docs {
3
- resumo: "Vertical oficial de pagamento da Sema 0.5,usado como referencia de utilidade real controlada."
3
+ resumo: "Vertical oficial de pagamento IA-first: contrato operacional para agente governar cobranca, estado, erro, efeito, seguranca e retry sem inventar comportamento."
4
4
  }
5
5
 
6
6
  use exemplos.pagamento.dominio
@@ -15,6 +15,46 @@ module exemplos.pagamento {
15
15
  pagamento: Pagamento
16
16
  status: StatusPagamento
17
17
  }
18
+ authz {
19
+ escopo: pagamentos.processar
20
+ tenant: obrigatorio
21
+ }
22
+ dados {
23
+ classificacao_padrao: financeiro
24
+ redacao_log: obrigatoria
25
+ input {
26
+ pagamento_id: interno
27
+ valor: financeiro
28
+ token: segredo
29
+ }
30
+ output {
31
+ pagamento: financeiro
32
+ status: interno
33
+ }
34
+ }
35
+ audit {
36
+ evento: pagamento.processado
37
+ ator: auth.usuario
38
+ correlacao: request_id
39
+ retencao: "180d"
40
+ motivo: obrigatorio
41
+ }
42
+ segredos {
43
+ gateway_pagamento_token {
44
+ origem: vault
45
+ escopo: runtime
46
+ acesso: gateway_pagamento
47
+ rotacao: "30d"
48
+ nao_logar: verdadeiro
49
+ nao_retornar: verdadeiro
50
+ mascarar: verdadeiro
51
+ }
52
+ }
53
+ forbidden {
54
+ shell.exec
55
+ log.segredo
56
+ retorno.credencial
57
+ }
18
58
  rules {
19
59
  valor > 0
20
60
  token existe
@@ -27,6 +67,18 @@ module exemplos.pagamento {
27
67
  notificacao cliente comprovante_pagamento criticidade = media
28
68
  auditoria pagamento criticidade = alta
29
69
  }
70
+ vinculos {
71
+ recurso: gateway_pagamento
72
+ tabela: pagamentos
73
+ evento: pagamento_autorizado
74
+ }
75
+ execucao {
76
+ idempotencia: verdadeiro
77
+ timeout: "15s"
78
+ retry: "2x exponencial"
79
+ compensacao: "registrar_falha_pagamento"
80
+ criticidade_operacional: alta
81
+ }
30
82
  state ciclo_pagamento {
31
83
  transitions {
32
84
  PENDENTE -> AUTORIZADO
@@ -53,6 +105,8 @@ module exemplos.pagamento {
53
105
 
54
106
  expect {
55
107
  sucesso: verdadeiro
108
+ status: "AUTORIZADO"
109
+ pagamento: "pag_1"
56
110
  }
57
111
  }
58
112
  caso "pagamento recusado por autorizacao" {
@@ -95,6 +149,31 @@ module exemplos.pagamento {
95
149
  output {
96
150
  status: StatusPagamento
97
151
  }
152
+ authz {
153
+ escopo: pagamentos.confirmar
154
+ tenant: obrigatorio
155
+ }
156
+ dados {
157
+ classificacao_padrao: financeiro
158
+ redacao_log: obrigatoria
159
+ input {
160
+ pagamento_id: interno
161
+ }
162
+ output {
163
+ status: interno
164
+ }
165
+ }
166
+ audit {
167
+ evento: pagamento.confirmado
168
+ ator: sistema.pagamentos
169
+ correlacao: request_id
170
+ retencao: "180d"
171
+ motivo: obrigatorio
172
+ }
173
+ forbidden {
174
+ shell.exec
175
+ log.segredo
176
+ }
98
177
  rules {
99
178
  pagamento_id existe
100
179
  }
@@ -104,6 +183,18 @@ module exemplos.pagamento {
104
183
  evento pagamento_confirmado criticidade = media
105
184
  auditoria conciliacao_pagamento criticidade = alta
106
185
  }
186
+ vinculos {
187
+ recurso: gateway_pagamento
188
+ tabela: pagamentos
189
+ evento: pagamento_confirmado
190
+ }
191
+ execucao {
192
+ idempotencia: verdadeiro
193
+ timeout: "15s"
194
+ retry: "2x exponencial"
195
+ compensacao: "registrar_timeout_pagamento"
196
+ criticidade_operacional: alta
197
+ }
107
198
  state ciclo_pagamento {
108
199
  transitions {
109
200
  AUTORIZADO -> PROCESSADO
@@ -120,6 +211,7 @@ module exemplos.pagamento {
120
211
 
121
212
  expect {
122
213
  sucesso: verdadeiro
214
+ status: "PROCESSADO"
123
215
  }
124
216
  }
125
217
  }
@@ -133,10 +225,47 @@ module exemplos.pagamento {
133
225
  output {
134
226
  protocolo_notificacao: Id
135
227
  }
228
+ authz {
229
+ escopo: pagamentos.notificar_falha
230
+ tenant: obrigatorio
231
+ }
232
+ dados {
233
+ classificacao_padrao: interno
234
+ redacao_log: obrigatoria
235
+ input {
236
+ pagamento_id: interno
237
+ motivo: interno
238
+ }
239
+ output {
240
+ protocolo_notificacao: interno
241
+ }
242
+ }
243
+ audit {
244
+ evento: pagamento.falha_notificada
245
+ ator: sistema.pagamentos
246
+ correlacao: request_id
247
+ retencao: "180d"
248
+ motivo: obrigatorio
249
+ }
250
+ forbidden {
251
+ shell.exec
252
+ log.segredo
253
+ }
136
254
  effects {
137
255
  notificacao cliente falha_pagamento criticidade = alta
138
256
  auditoria falha_pagamento criticidade = media
139
257
  }
258
+ vinculos {
259
+ evento: falha_pagamento
260
+ recurso: canal_notificacao
261
+ }
262
+ execucao {
263
+ idempotencia: verdadeiro
264
+ timeout: "10s"
265
+ retry: "3x exponencial"
266
+ compensacao: "registrar_auditoria_falha"
267
+ criticidade_operacional: alta
268
+ }
140
269
  guarantees {
141
270
  protocolo_notificacao existe
142
271
  }
@@ -149,6 +278,7 @@ module exemplos.pagamento {
149
278
 
150
279
  expect {
151
280
  sucesso: verdadeiro
281
+ protocolo_notificacao: "notif_1"
152
282
  }
153
283
  }
154
284
  }
@@ -161,10 +291,46 @@ module exemplos.pagamento {
161
291
  output {
162
292
  auditoria_id: Id
163
293
  }
294
+ authz {
295
+ escopo: pagamentos.registrar_timeout
296
+ tenant: obrigatorio
297
+ }
298
+ dados {
299
+ classificacao_padrao: interno
300
+ redacao_log: obrigatoria
301
+ input {
302
+ pagamento_id: interno
303
+ }
304
+ output {
305
+ auditoria_id: interno
306
+ }
307
+ }
308
+ audit {
309
+ evento: pagamento.timeout_registrado
310
+ ator: sistema.pagamentos
311
+ correlacao: request_id
312
+ retencao: "180d"
313
+ motivo: obrigatorio
314
+ }
315
+ forbidden {
316
+ shell.exec
317
+ log.segredo
318
+ }
164
319
  effects {
165
320
  auditoria timeout_gateway criticidade = alta
166
321
  persistencia incidente_pagamento criticidade = media
167
322
  }
323
+ vinculos {
324
+ tabela: incidentes_pagamento
325
+ evento: timeout_gateway
326
+ }
327
+ execucao {
328
+ idempotencia: verdadeiro
329
+ timeout: "10s"
330
+ retry: "nenhum"
331
+ compensacao: "notificar_operacao"
332
+ criticidade_operacional: alta
333
+ }
168
334
  guarantees {
169
335
  auditoria_id existe
170
336
  }
@@ -176,6 +342,7 @@ module exemplos.pagamento {
176
342
 
177
343
  expect {
178
344
  sucesso: verdadeiro
345
+ auditoria_id: "aud_1"
179
346
  }
180
347
  }
181
348
  }
@@ -187,7 +354,7 @@ module exemplos.pagamento {
187
354
  token: Texto
188
355
  etapa autorizar usa processar_pagamento com pagamento_id = pagamento_id, valor = valor, token = token em_sucesso confirmar em_erro registrar_falha por_erro autorizacao_negada = notificar_falha, timeout_gateway = registrar_timeout
189
356
  etapa confirmar usa confirmar_pagamento com pagamento_id = pagamento_id depende_de autorizar
190
- etapa notificar_falha usa notificar_falha_pagamento com pagamento_id = pagamento_id, motivo = autorizacao_negada depende_de autorizar
357
+ etapa notificar_falha usa notificar_falha_pagamento com pagamento_id = pagamento_id, motivo = "autorizacao_negada" depende_de autorizar
191
358
  etapa registrar_timeout usa registrar_timeout_pagamento com pagamento_id = pagamento_id depende_de autorizar
192
359
  etapa registrar_falha usa registrar_timeout_pagamento com pagamento_id = pagamento_id depende_de autorizar
193
360
  effects {
@@ -200,6 +367,51 @@ module exemplos.pagamento {
200
367
  metodo: POST
201
368
  caminho: /pagamentos/processar
202
369
  task: processar_pagamento
370
+ auth {
371
+ modo: obrigatorio
372
+ principal: usuario
373
+ origem: publica
374
+ }
375
+ authz {
376
+ escopo: pagamentos.processar
377
+ tenant: obrigatorio
378
+ }
379
+ dados {
380
+ classificacao_padrao: financeiro
381
+ redacao_log: obrigatoria
382
+ input {
383
+ pagamento_id: interno
384
+ valor: financeiro
385
+ token: segredo
386
+ }
387
+ output {
388
+ pagamento: financeiro
389
+ status: interno
390
+ }
391
+ }
392
+ audit {
393
+ evento: pagamento.processado.publico
394
+ ator: auth.usuario
395
+ correlacao: request_id
396
+ retencao: "180d"
397
+ motivo: obrigatorio
398
+ }
399
+ segredos {
400
+ gateway_pagamento_token {
401
+ origem: vault
402
+ escopo: runtime
403
+ acesso: gateway_pagamento
404
+ rotacao: "30d"
405
+ nao_logar: verdadeiro
406
+ nao_retornar: verdadeiro
407
+ mascarar: verdadeiro
408
+ }
409
+ }
410
+ forbidden {
411
+ shell.exec
412
+ log.segredo
413
+ retorno.credencial
414
+ }
203
415
  input {
204
416
  pagamento_id: Id required
205
417
  valor: Decimal required
@@ -1,13 +1,42 @@
1
1
  module exemplos.pedido {
2
2
  docs {
3
- resumo: "Ciclo completo de pedido com itens, aprovacao e entrega."
3
+ resumo: "Ciclo completo de pedido IA-first com dependencias explicitas para pagamento e estoque."
4
+ }
5
+
6
+ use exemplos.pagamento
7
+ use exemplos.estoque
8
+
9
+ enum StatusPedido {
10
+ RASCUNHO,
11
+ AGUARDANDO_PAGAMENTO,
12
+ APROVADO,
13
+ CANCELADO,
14
+ ENVIADO,
15
+ ENTREGUE
16
+ }
17
+
18
+ state ciclo_pedido {
19
+ fields {
20
+ status: StatusPedido
21
+ }
22
+ invariants {
23
+ status em [RASCUNHO, AGUARDANDO_PAGAMENTO, APROVADO, CANCELADO, ENVIADO, ENTREGUE]
24
+ }
25
+ transitions {
26
+ RASCUNHO -> AGUARDANDO_PAGAMENTO
27
+ AGUARDANDO_PAGAMENTO -> APROVADO
28
+ AGUARDANDO_PAGAMENTO -> CANCELADO
29
+ APROVADO -> CANCELADO
30
+ APROVADO -> ENVIADO
31
+ ENVIADO -> ENTREGUE
32
+ }
4
33
  }
5
34
 
6
35
  entity Pedido {
7
36
  fields {
8
37
  id: Id
9
38
  cliente_id: Id
10
- status: Texto
39
+ status: StatusPedido
11
40
  total: Decimal
12
41
  criado_em: Timestamp
13
42
  }
@@ -30,18 +59,59 @@ module exemplos.pedido {
30
59
  }
31
60
  output {
32
61
  pedido: Pedido
62
+ status: StatusPedido
63
+ }
64
+ authz {
65
+ escopo: pedidos.criar
66
+ tenant: obrigatorio
67
+ }
68
+ dados {
69
+ classificacao_padrao: interno
70
+ redacao_log: obrigatoria
71
+ input {
72
+ cliente_id: pii
73
+ itens: interno
74
+ }
75
+ output {
76
+ pedido: financeiro
77
+ status: interno
78
+ }
79
+ }
80
+ audit {
81
+ evento: pedido.criado
82
+ ator: auth.usuario
83
+ correlacao: request_id
84
+ retencao: "180d"
85
+ motivo: obrigatorio
86
+ }
87
+ forbidden {
88
+ shell.exec
89
+ log.segredo
90
+ retorno.credencial
33
91
  }
34
92
  rules {
35
93
  itens deve_ser nao_vazio
36
94
  cliente_id deve_ser valido
37
95
  }
38
96
  effects {
39
- consulta Cliente por cliente_id
40
- consulta Produto por cada item.produto_id
41
- persistencia Pedido
42
- persistencia ItemPedido
97
+ consulta Cliente por cliente_id criticidade = media
98
+ consulta Produto por cada item.produto_id criticidade = media
99
+ persistencia Pedido criticidade = alta
100
+ persistencia ItemPedido criticidade = alta
43
101
  evento pedido_criado criticidade = media
44
- auditoria criacao_pedido
102
+ auditoria criacao_pedido criticidade = media
103
+ }
104
+ vinculos {
105
+ tabela: pedidos
106
+ tabela: itens_pedido
107
+ evento: pedido_criado
108
+ }
109
+ execucao {
110
+ idempotencia: verdadeiro
111
+ timeout: "10s"
112
+ retry: "nenhum"
113
+ compensacao: "cancelar_pedido"
114
+ criticidade_operacional: alta
45
115
  }
46
116
  state ciclo_pedido {
47
117
  transitions {
@@ -50,7 +120,7 @@ module exemplos.pedido {
50
120
  }
51
121
  guarantees {
52
122
  pedido existe
53
- pedido.total > 0
123
+ status == AGUARDANDO_PAGAMENTO
54
124
  }
55
125
  error {
56
126
  cliente_invalido: "Cliente nao encontrado."
@@ -59,8 +129,16 @@ module exemplos.pedido {
59
129
  }
60
130
  tests {
61
131
  caso "cria pedido valido" {
62
- given { cliente_id: "cli_1" itens: [{produto_id: "prod_1", quantidade: 2}] }
63
- expect { sucesso: verdadeiro }
132
+ given {
133
+ cliente_id: "cli_1"
134
+ itens: "prod_1:2"
135
+ }
136
+
137
+ expect {
138
+ sucesso: verdadeiro
139
+ status: "AGUARDANDO_PAGAMENTO"
140
+ pedido: "ped_1"
141
+ }
64
142
  }
65
143
  }
66
144
  }
@@ -68,22 +146,63 @@ module exemplos.pedido {
68
146
  task cancelar_pedido {
69
147
  input {
70
148
  pedido_id: Id required
149
+ status_atual: StatusPedido required
71
150
  motivo: Texto required
72
151
  }
73
152
  output {
74
153
  protocolo: Id
154
+ status: StatusPedido
155
+ }
156
+ authz {
157
+ escopo: pedidos.cancelar
158
+ tenant: obrigatorio
159
+ }
160
+ dados {
161
+ classificacao_padrao: interno
162
+ redacao_log: obrigatoria
163
+ input {
164
+ pedido_id: interno
165
+ status_atual: interno
166
+ motivo: interno
167
+ }
168
+ output {
169
+ protocolo: interno
170
+ status: interno
171
+ }
172
+ }
173
+ audit {
174
+ evento: pedido.cancelado
175
+ ator: auth.usuario
176
+ correlacao: request_id
177
+ retencao: "180d"
178
+ motivo: obrigatorio
179
+ }
180
+ forbidden {
181
+ shell.exec
182
+ log.segredo
75
183
  }
76
184
  rules {
77
185
  pedido_id deve_ser valido
78
- pedido.status em [AGUARDANDO_PAGAMENTO, APROVADO]
186
+ status_atual em [AGUARDANDO_PAGAMENTO, APROVADO]
79
187
  motivo deve_ser preenchido
80
188
  }
81
189
  effects {
82
- persistencia Pedido
190
+ persistencia Pedido criticidade = alta
83
191
  evento pedido_cancelado criticidade = alta
84
- notificacao cliente pedido_cancelado
192
+ notificacao cliente pedido_cancelado criticidade = media
85
193
  auditoria cancelamento_pedido criticidade = media
86
194
  }
195
+ vinculos {
196
+ tabela: pedidos
197
+ evento: pedido_cancelado
198
+ }
199
+ execucao {
200
+ idempotencia: verdadeiro
201
+ timeout: "10s"
202
+ retry: "nenhum"
203
+ compensacao: "notificar_operacao"
204
+ criticidade_operacional: alta
205
+ }
87
206
  state ciclo_pedido {
88
207
  transitions {
89
208
  AGUARDANDO_PAGAMENTO -> CANCELADO
@@ -92,26 +211,43 @@ module exemplos.pedido {
92
211
  }
93
212
  guarantees {
94
213
  protocolo existe
95
- pedido.status == CANCELADO
214
+ status == CANCELADO
96
215
  }
97
216
  error {
98
217
  pedido_nao_cancelavel: "Pedido ja enviado ou entregue nao pode ser cancelado."
99
218
  }
100
219
  tests {
101
220
  caso "cancela pedido pendente" {
102
- given { pedido_id: "ped_1" motivo: "Desistencia do cliente" }
103
- expect { sucesso: verdadeiro }
221
+ given {
222
+ pedido_id: "ped_1"
223
+ status_atual: "AGUARDANDO_PAGAMENTO"
224
+ motivo: "Desistencia do cliente"
225
+ }
226
+
227
+ expect {
228
+ sucesso: verdadeiro
229
+ protocolo: "cancel_1"
230
+ status: "CANCELADO"
231
+ }
104
232
  }
105
233
  }
106
234
  }
107
235
 
108
236
  flow aprovacao_pedido {
109
237
  pedido_id: Id
238
+ valor: Decimal
239
+ produto_id: Id
240
+ quantidade: Inteiro
110
241
  token_pagamento: Texto
111
- etapa pagar usa processar_pagamento com pedido_id = pedido_id, token = token_pagamento em_sucesso reservar em_erro cancelar_por_pagamento
112
- etapa reservar usa reservar_estoque com pedido_id = pedido_id depende_de pagar em_erro cancelar_por_estoque
113
- etapa cancelar_por_pagamento usa cancelar_pedido com pedido_id = pedido_id, motivo = "Pagamento recusado" depende_de pagar
114
- etapa cancelar_por_estoque usa cancelar_pedido com pedido_id = pedido_id, motivo = "Estoque insuficiente" depende_de reservar
242
+ itens_reservados: Texto
243
+ status_cancelamento: StatusPedido
244
+ motivo_pagamento_recusado: Texto
245
+ motivo_estoque_insuficiente: Texto
246
+ etapa pagar usa processar_pagamento com pagamento_id = pedido_id, valor = valor, token = token_pagamento em_sucesso reservar em_erro cancelar_por_pagamento
247
+ etapa reservar usa reservar_estoque com produto_id = produto_id, quantidade = quantidade, pedido_id = pedido_id depende_de pagar em_sucesso aprovar em_erro cancelar_por_estoque
248
+ etapa aprovar usa criar_pedido com cliente_id = pedido_id, itens = itens_reservados depende_de reservar
249
+ etapa cancelar_por_pagamento usa cancelar_pedido com pedido_id = pedido_id, status_atual = status_cancelamento, motivo = motivo_pagamento_recusado depende_de pagar
250
+ etapa cancelar_por_estoque usa cancelar_pedido com pedido_id = pedido_id, status_atual = status_cancelamento, motivo = motivo_estoque_insuficiente depende_de reservar
115
251
  effects {
116
252
  auditoria fluxo_aprovacao_pedido criticidade = alta
117
253
  }
@@ -0,0 +1,160 @@
1
+ module exemplos.replica.analitica_erp {
2
+ docs {
3
+ resumo: "Exemplo publico neutro de replica analitica ERP para banco analytics: agente pode consultar a origem operacional em modo leitura e persistir apenas no destino analitico."
4
+ }
5
+
6
+ database erp_origem_mariadb {
7
+ engine: mysql
8
+ consistency: forte
9
+ durability: alta
10
+ transaction_model: bloqueio
11
+ query_model: sql
12
+ capabilities {
13
+ read_only
14
+ views
15
+ }
16
+ table vendas_operacionais {
17
+ entity: VendaOperacional
18
+ }
19
+ query extrair_vendas {
20
+ mode: sql
21
+ }
22
+ }
23
+
24
+ database analytics_postgres {
25
+ engine: postgres
26
+ schema: public
27
+ consistency: eventual
28
+ durability: alta
29
+ transaction_model: mvcc
30
+ query_model: sql
31
+ capabilities {
32
+ upsert
33
+ views
34
+ }
35
+ table vendas_analytics {
36
+ entity: VendaAnalitica
37
+ }
38
+ query carregar_vendas_analytics {
39
+ mode: sql
40
+ }
41
+ }
42
+
43
+ entity VendaOperacional {
44
+ fields {
45
+ id: Id
46
+ loja_id: Id
47
+ data_venda: Data
48
+ valor_total: Decimal
49
+ payload_origem: Objeto
50
+ }
51
+ invariants {
52
+ id existe
53
+ loja_id existe
54
+ data_venda existe
55
+ valor_total >= 0
56
+ }
57
+ }
58
+
59
+ entity VendaAnalitica {
60
+ fields {
61
+ id: Id
62
+ loja_id: Id
63
+ data_venda: Data
64
+ valor_total: Decimal
65
+ sincronizado_em: Timestamp
66
+ }
67
+ invariants {
68
+ id existe
69
+ loja_id existe
70
+ data_venda existe
71
+ valor_total >= 0
72
+ sincronizado_em existe
73
+ }
74
+ }
75
+
76
+ task sincronizar_vendas_erp_para_analytics {
77
+ input {
78
+ loja_id: Id required
79
+ periodo_inicio: Data required
80
+ periodo_fim: Data required
81
+ }
82
+ output {
83
+ registros_sincronizados: Inteiro
84
+ banco_producao_modificado: Booleano
85
+ sincronizado_em: Timestamp
86
+ }
87
+ authz {
88
+ escopo: analytics.replica.sincronizar
89
+ tenant: obrigatorio
90
+ }
91
+ dados {
92
+ classificacao_padrao: interno
93
+ redacao_log: obrigatoria
94
+ input {
95
+ loja_id: interno
96
+ periodo_inicio: interno
97
+ periodo_fim: interno
98
+ }
99
+ output {
100
+ registros_sincronizados: interno
101
+ banco_producao_modificado: interno
102
+ sincronizado_em: interno
103
+ }
104
+ }
105
+ audit {
106
+ evento: analytics.replica.erp_sincronizada
107
+ ator: sistema.analytics
108
+ correlacao: request_id
109
+ retencao: "180d"
110
+ motivo: obrigatorio
111
+ }
112
+ forbidden {
113
+ shell.exec
114
+ log.segredo
115
+ retorno.credencial
116
+ }
117
+ rules {
118
+ loja_id deve_ser valido
119
+ periodo_inicio deve_ser anterior_a periodo_fim
120
+ }
121
+ effects {
122
+ consulta erp_origem_mariadb criticidade = alta
123
+ persistencia analytics_postgres criticidade = media
124
+ auditoria sincronizacao_vendas criticidade = alta
125
+ }
126
+ vinculos {
127
+ recurso: erp_origem_mariadb
128
+ recurso: analytics_postgres
129
+ tabela: vendas_operacionais
130
+ tabela: vendas_analytics
131
+ }
132
+ execucao {
133
+ idempotencia: verdadeiro
134
+ timeout: "60s"
135
+ retry: "3x exponencial"
136
+ compensacao: "reexecutar_janela_analitica"
137
+ criticidade_operacional: alta
138
+ }
139
+ guarantees {
140
+ registros_sincronizados >= 0
141
+ banco_producao_modificado == falso
142
+ sincronizado_em existe
143
+ }
144
+ tests {
145
+ caso "sincroniza janela sem escrever na origem" {
146
+ given {
147
+ loja_id: "loja_001"
148
+ periodo_inicio: "2026-05-01"
149
+ periodo_fim: "2026-05-15"
150
+ }
151
+
152
+ expect {
153
+ sucesso: verdadeiro
154
+ registros_sincronizados: 42
155
+ banco_producao_modificado: falso
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }