@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,35 +1,35 @@
1
- module exemplos.pagamento.dominio {
2
- docs {
3
- resumo: "Contratos de dominio compartilhados pelo vertical oficial de pagamento da Sema 0.5."
4
- }
5
-
6
- entity Pagamento {
7
- fields {
8
- id: Id
9
- valor: Decimal
10
- status: StatusPagamento
11
- }
12
- }
13
-
14
- enum StatusPagamento {
15
- PENDENTE,
16
- AUTORIZADO,
17
- RECUSADO,
18
- PROCESSADO
19
- }
20
-
21
- state ciclo_pagamento {
22
- fields {
23
- status: StatusPagamento
24
- conciliado: Booleano
25
- }
26
- invariants {
27
- status existe
28
- }
29
- transitions {
30
- PENDENTE -> AUTORIZADO
31
- AUTORIZADO -> PROCESSADO
32
- PENDENTE -> RECUSADO
33
- }
34
- }
35
- }
1
+ module exemplos.pagamento.dominio {
2
+ docs {
3
+ resumo: "Contratos de dominio compartilhados pelo vertical oficial de pagamento da Sema 0.5."
4
+ }
5
+
6
+ entity Pagamento {
7
+ fields {
8
+ id: Id
9
+ valor: Decimal
10
+ status: StatusPagamento
11
+ }
12
+ }
13
+
14
+ enum StatusPagamento {
15
+ PENDENTE,
16
+ AUTORIZADO,
17
+ RECUSADO,
18
+ PROCESSADO
19
+ }
20
+
21
+ state ciclo_pagamento {
22
+ fields {
23
+ status: StatusPagamento
24
+ conciliado: Booleano
25
+ }
26
+ invariants {
27
+ status existe
28
+ }
29
+ transitions {
30
+ PENDENTE -> AUTORIZADO
31
+ AUTORIZADO -> PROCESSADO
32
+ PENDENTE -> RECUSADO
33
+ }
34
+ }
35
+ }
@@ -1,119 +1,255 @@
1
- module exemplos.pedido {
2
- docs {
3
- resumo: "Ciclo completo de pedido com itens, aprovacao e entrega."
4
- }
5
-
6
- entity Pedido {
7
- fields {
8
- id: Id
9
- cliente_id: Id
10
- status: Texto
11
- total: Decimal
12
- criado_em: Timestamp
13
- }
14
- }
15
-
16
- entity ItemPedido {
17
- fields {
18
- id: Id
19
- pedido_id: Id
20
- produto_id: Id
21
- quantidade: Inteiro
22
- preco_unitario: Decimal
23
- }
24
- }
25
-
26
- task criar_pedido {
27
- input {
28
- cliente_id: Id required
29
- itens: Lista required
30
- }
31
- output {
32
- pedido: Pedido
33
- }
34
- rules {
35
- itens deve_ser nao_vazio
36
- cliente_id deve_ser valido
37
- }
38
- effects {
39
- consulta Cliente por cliente_id
40
- consulta Produto por cada item.produto_id
41
- persistencia Pedido
42
- persistencia ItemPedido
43
- evento pedido_criado criticidade = media
44
- auditoria criacao_pedido
45
- }
46
- state ciclo_pedido {
47
- transitions {
48
- RASCUNHO -> AGUARDANDO_PAGAMENTO
49
- }
50
- }
51
- guarantees {
52
- pedido existe
53
- pedido.total > 0
54
- }
55
- error {
56
- cliente_invalido: "Cliente nao encontrado."
57
- item_invalido: "Um ou mais produtos nao existem."
58
- carrinho_vazio: "O pedido deve ter ao menos um item."
59
- }
60
- tests {
61
- caso "cria pedido valido" {
62
- given { cliente_id: "cli_1" itens: [{produto_id: "prod_1", quantidade: 2}] }
63
- expect { sucesso: verdadeiro }
64
- }
65
- }
66
- }
67
-
68
- task cancelar_pedido {
69
- input {
70
- pedido_id: Id required
71
- motivo: Texto required
72
- }
73
- output {
74
- protocolo: Id
75
- }
76
- rules {
77
- pedido_id deve_ser valido
78
- pedido.status em [AGUARDANDO_PAGAMENTO, APROVADO]
79
- motivo deve_ser preenchido
80
- }
81
- effects {
82
- persistencia Pedido
83
- evento pedido_cancelado criticidade = alta
84
- notificacao cliente pedido_cancelado
85
- auditoria cancelamento_pedido criticidade = media
86
- }
87
- state ciclo_pedido {
88
- transitions {
89
- AGUARDANDO_PAGAMENTO -> CANCELADO
90
- APROVADO -> CANCELADO
91
- }
92
- }
93
- guarantees {
94
- protocolo existe
95
- pedido.status == CANCELADO
96
- }
97
- error {
98
- pedido_nao_cancelavel: "Pedido ja enviado ou entregue nao pode ser cancelado."
99
- }
100
- tests {
101
- caso "cancela pedido pendente" {
102
- given { pedido_id: "ped_1" motivo: "Desistencia do cliente" }
103
- expect { sucesso: verdadeiro }
104
- }
105
- }
106
- }
107
-
108
- flow aprovacao_pedido {
109
- pedido_id: Id
110
- 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
115
- effects {
116
- auditoria fluxo_aprovacao_pedido criticidade = alta
117
- }
118
- }
119
- }
1
+ module exemplos.pedido {
2
+ docs {
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
+ }
33
+ }
34
+
35
+ entity Pedido {
36
+ fields {
37
+ id: Id
38
+ cliente_id: Id
39
+ status: StatusPedido
40
+ total: Decimal
41
+ criado_em: Timestamp
42
+ }
43
+ }
44
+
45
+ entity ItemPedido {
46
+ fields {
47
+ id: Id
48
+ pedido_id: Id
49
+ produto_id: Id
50
+ quantidade: Inteiro
51
+ preco_unitario: Decimal
52
+ }
53
+ }
54
+
55
+ task criar_pedido {
56
+ input {
57
+ cliente_id: Id required
58
+ itens: Lista required
59
+ }
60
+ output {
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
91
+ }
92
+ rules {
93
+ itens deve_ser nao_vazio
94
+ cliente_id deve_ser valido
95
+ }
96
+ effects {
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
101
+ evento pedido_criado criticidade = media
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
115
+ }
116
+ state ciclo_pedido {
117
+ transitions {
118
+ RASCUNHO -> AGUARDANDO_PAGAMENTO
119
+ }
120
+ }
121
+ guarantees {
122
+ pedido existe
123
+ status == AGUARDANDO_PAGAMENTO
124
+ }
125
+ error {
126
+ cliente_invalido: "Cliente nao encontrado."
127
+ item_invalido: "Um ou mais produtos nao existem."
128
+ carrinho_vazio: "O pedido deve ter ao menos um item."
129
+ }
130
+ tests {
131
+ caso "cria pedido valido" {
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
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ task cancelar_pedido {
147
+ input {
148
+ pedido_id: Id required
149
+ status_atual: StatusPedido required
150
+ motivo: Texto required
151
+ }
152
+ output {
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
183
+ }
184
+ rules {
185
+ pedido_id deve_ser valido
186
+ status_atual em [AGUARDANDO_PAGAMENTO, APROVADO]
187
+ motivo deve_ser preenchido
188
+ }
189
+ effects {
190
+ persistencia Pedido criticidade = alta
191
+ evento pedido_cancelado criticidade = alta
192
+ notificacao cliente pedido_cancelado criticidade = media
193
+ auditoria cancelamento_pedido criticidade = media
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
+ }
206
+ state ciclo_pedido {
207
+ transitions {
208
+ AGUARDANDO_PAGAMENTO -> CANCELADO
209
+ APROVADO -> CANCELADO
210
+ }
211
+ }
212
+ guarantees {
213
+ protocolo existe
214
+ status == CANCELADO
215
+ }
216
+ error {
217
+ pedido_nao_cancelavel: "Pedido ja enviado ou entregue nao pode ser cancelado."
218
+ }
219
+ tests {
220
+ caso "cancela pedido pendente" {
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
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ flow aprovacao_pedido {
237
+ pedido_id: Id
238
+ valor: Decimal
239
+ produto_id: Id
240
+ quantidade: Inteiro
241
+ token_pagamento: Texto
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
251
+ effects {
252
+ auditoria fluxo_aprovacao_pedido criticidade = alta
253
+ }
254
+ }
255
+ }
@@ -1,121 +1,121 @@
1
- module exemplos.permissao {
2
- docs {
3
- resumo: "Controle de acesso baseado em papeis e permissoes granulares."
4
- }
5
-
6
- entity Papel {
7
- fields {
8
- id: Id
9
- nome: Texto
10
- descricao: Texto
11
- }
12
- }
13
-
14
- entity Permissao {
15
- fields {
16
- id: Id
17
- recurso: Texto
18
- acao: Texto
19
- descricao: Texto
20
- }
21
- }
22
-
23
- task atribuir_papel {
24
- input {
25
- usuario_id: Id required
26
- papel_id: Id required
27
- }
28
- output {
29
- atribuicao_id: Id
30
- }
31
- rules {
32
- usuario_id deve_ser valido
33
- papel_id deve_ser valido
34
- }
35
- effects {
36
- consulta Usuario por usuario_id
37
- consulta Papel por papel_id
38
- persistencia AtribuicaoPapel
39
- evento papel_atribuido criticidade = media
40
- auditoria atribuicao_papel criticidade = alta
41
- }
42
- guarantees {
43
- atribuicao_id existe
44
- }
45
- error {
46
- usuario_nao_encontrado: "Usuario nao localizado."
47
- papel_nao_encontrado: "Papel nao localizado."
48
- atribuicao_duplicada: "Usuario ja possui este papel."
49
- }
50
- tests {
51
- caso "atribui papel admin" {
52
- given { usuario_id: "usr_1" papel_id: "papel_admin" }
53
- expect { sucesso: verdadeiro }
54
- }
55
- }
56
- }
57
-
58
- task verificar_permissao {
59
- input {
60
- usuario_id: Id required
61
- recurso: Texto required
62
- acao: Texto required
63
- }
64
- output {
65
- autorizado: Booleano
66
- }
67
- rules {
68
- usuario_id deve_ser valido
69
- recurso deve_ser preenchido
70
- acao deve_ser preenchida
71
- }
72
- effects {
73
- consulta AtribuicaoPapel por usuario_id
74
- consulta PermissaoPapel por papel_id
75
- auditoria verificacao_permissao
76
- }
77
- guarantees {
78
- autorizado existe
79
- }
80
- tests {
81
- caso "usuario autorizado" {
82
- given { usuario_id: "usr_admin" recurso: "relatorios" acao: "exportar" }
83
- expect { sucesso: verdadeiro }
84
- }
85
- caso "usuario sem permissao" {
86
- given { usuario_id: "usr_basico" recurso: "admin" acao: "deletar" }
87
- expect { sucesso: verdadeiro }
88
- }
89
- }
90
- }
91
-
92
- task revogar_papel {
93
- input {
94
- usuario_id: Id required
95
- papel_id: Id required
96
- motivo: Texto required
97
- }
98
- output {
99
- protocolo: Id
100
- }
101
- rules {
102
- usuario_id deve_ser valido
103
- papel_id deve_ser valido
104
- motivo deve_ser preenchido
105
- }
106
- effects {
107
- persistencia AtribuicaoPapel
108
- evento papel_revogado criticidade = alta
109
- auditoria revogacao_papel criticidade = alta
110
- }
111
- guarantees {
112
- protocolo existe
113
- }
114
- tests {
115
- caso "revoga papel" {
116
- given { usuario_id: "usr_1" papel_id: "papel_admin" motivo: "Saida da equipe" }
117
- expect { sucesso: verdadeiro }
118
- }
119
- }
120
- }
121
- }
1
+ module exemplos.permissao {
2
+ docs {
3
+ resumo: "Controle de acesso baseado em papeis e permissoes granulares."
4
+ }
5
+
6
+ entity Papel {
7
+ fields {
8
+ id: Id
9
+ nome: Texto
10
+ descricao: Texto
11
+ }
12
+ }
13
+
14
+ entity Permissao {
15
+ fields {
16
+ id: Id
17
+ recurso: Texto
18
+ acao: Texto
19
+ descricao: Texto
20
+ }
21
+ }
22
+
23
+ task atribuir_papel {
24
+ input {
25
+ usuario_id: Id required
26
+ papel_id: Id required
27
+ }
28
+ output {
29
+ atribuicao_id: Id
30
+ }
31
+ rules {
32
+ usuario_id deve_ser valido
33
+ papel_id deve_ser valido
34
+ }
35
+ effects {
36
+ consulta Usuario por usuario_id
37
+ consulta Papel por papel_id
38
+ persistencia AtribuicaoPapel
39
+ evento papel_atribuido criticidade = media
40
+ auditoria atribuicao_papel criticidade = alta
41
+ }
42
+ guarantees {
43
+ atribuicao_id existe
44
+ }
45
+ error {
46
+ usuario_nao_encontrado: "Usuario nao localizado."
47
+ papel_nao_encontrado: "Papel nao localizado."
48
+ atribuicao_duplicada: "Usuario ja possui este papel."
49
+ }
50
+ tests {
51
+ caso "atribui papel admin" {
52
+ given { usuario_id: "usr_1" papel_id: "papel_admin" }
53
+ expect { sucesso: verdadeiro }
54
+ }
55
+ }
56
+ }
57
+
58
+ task verificar_permissao {
59
+ input {
60
+ usuario_id: Id required
61
+ recurso: Texto required
62
+ acao: Texto required
63
+ }
64
+ output {
65
+ autorizado: Booleano
66
+ }
67
+ rules {
68
+ usuario_id deve_ser valido
69
+ recurso deve_ser preenchido
70
+ acao deve_ser preenchida
71
+ }
72
+ effects {
73
+ consulta AtribuicaoPapel por usuario_id
74
+ consulta PermissaoPapel por papel_id
75
+ auditoria verificacao_permissao
76
+ }
77
+ guarantees {
78
+ autorizado existe
79
+ }
80
+ tests {
81
+ caso "usuario autorizado" {
82
+ given { usuario_id: "usr_admin" recurso: "relatorios" acao: "exportar" }
83
+ expect { sucesso: verdadeiro }
84
+ }
85
+ caso "usuario sem permissao" {
86
+ given { usuario_id: "usr_basico" recurso: "admin" acao: "deletar" }
87
+ expect { sucesso: verdadeiro }
88
+ }
89
+ }
90
+ }
91
+
92
+ task revogar_papel {
93
+ input {
94
+ usuario_id: Id required
95
+ papel_id: Id required
96
+ motivo: Texto required
97
+ }
98
+ output {
99
+ protocolo: Id
100
+ }
101
+ rules {
102
+ usuario_id deve_ser valido
103
+ papel_id deve_ser valido
104
+ motivo deve_ser preenchido
105
+ }
106
+ effects {
107
+ persistencia AtribuicaoPapel
108
+ evento papel_revogado criticidade = alta
109
+ auditoria revogacao_papel criticidade = alta
110
+ }
111
+ guarantees {
112
+ protocolo existe
113
+ }
114
+ tests {
115
+ caso "revoga papel" {
116
+ given { usuario_id: "usr_1" papel_id: "papel_admin" motivo: "Saida da equipe" }
117
+ expect { sucesso: verdadeiro }
118
+ }
119
+ }
120
+ }
121
+ }