@semacode/cli 0.9.0 → 1.1.0

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 (46) hide show
  1. package/AGENTS.md +50 -0
  2. package/README.md +24 -3
  3. package/SEMA_BRIEF.curto.txt +9 -0
  4. package/SEMA_BRIEF.md +49 -0
  5. package/SEMA_BRIEF.micro.txt +7 -0
  6. package/SEMA_INDEX.json +501 -0
  7. package/dist/drift.d.ts +15 -0
  8. package/dist/drift.js +496 -5
  9. package/dist/drift.js.map +1 -1
  10. package/dist/importador.d.ts +1 -1
  11. package/dist/importador.js +681 -3
  12. package/dist/importador.js.map +1 -1
  13. package/dist/index.js +1578 -123
  14. package/dist/index.js.map +1 -1
  15. package/dist/projeto.js +49 -1
  16. package/dist/projeto.js.map +1 -1
  17. package/dist/tipos.d.ts +1 -1
  18. package/docs/AGENT_STARTER.md +40 -8
  19. package/docs/como-ensinar-a-sema-para-ia.md +17 -11
  20. package/docs/fluxo-pratico-ia-sema.md +42 -38
  21. package/docs/instalacao-e-primeiro-uso.md +196 -0
  22. package/docs/integracao-com-ia.md +228 -0
  23. package/docs/pagamento-ponta-a-ponta.md +155 -0
  24. package/docs/prompt-base-ia-sema.md +10 -3
  25. package/docs/sintaxe.md +267 -0
  26. package/exemplos/automacao.sema +107 -0
  27. package/exemplos/cadastro_usuario.sema +54 -0
  28. package/exemplos/calculadora.sema +78 -0
  29. package/exemplos/crud_simples.sema +89 -0
  30. package/exemplos/operacao_estrategia.sema +402 -0
  31. package/exemplos/pagamento.sema +222 -0
  32. package/exemplos/pagamento_dominio.sema +35 -0
  33. package/exemplos/testes_embutidos.sema +45 -0
  34. package/exemplos/tratamento_erro.sema +157 -0
  35. package/llms-full.txt +34 -0
  36. package/llms.txt +17 -0
  37. package/node_modules/@sema/gerador-dart/package.json +1 -1
  38. package/node_modules/@sema/gerador-python/dist/index.js +92 -10
  39. package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
  40. package/node_modules/@sema/gerador-python/package.json +1 -1
  41. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  42. package/node_modules/@sema/nucleo/package.json +1 -1
  43. package/node_modules/@sema/padroes/dist/index.js +47 -1
  44. package/node_modules/@sema/padroes/dist/index.js.map +1 -1
  45. package/node_modules/@sema/padroes/package.json +1 -1
  46. package/package.json +15 -7
@@ -0,0 +1,222 @@
1
+ module exemplos.pagamento {
2
+ docs {
3
+ resumo: "Vertical oficial de pagamento da Sema 0.5,usado como referencia de utilidade real controlada."
4
+ }
5
+
6
+ use exemplos.pagamento.dominio
7
+
8
+ task processar_pagamento {
9
+ input {
10
+ pagamento_id: Id required
11
+ valor: Decimal required
12
+ token: Texto required
13
+ }
14
+ output {
15
+ pagamento: Pagamento
16
+ status: StatusPagamento
17
+ }
18
+ rules {
19
+ valor > 0
20
+ token existe
21
+ token deve_ser valido
22
+ }
23
+ effects {
24
+ consulta gateway_pagamento criticidade = alta
25
+ persistencia Pagamento criticidade = alta
26
+ evento pagamento_autorizado criticidade = media
27
+ notificacao cliente comprovante_pagamento criticidade = media
28
+ auditoria pagamento criticidade = alta
29
+ }
30
+ state ciclo_pagamento {
31
+ transitions {
32
+ PENDENTE -> AUTORIZADO
33
+ AUTORIZADO -> PROCESSADO
34
+ }
35
+ }
36
+ guarantees {
37
+ pagamento existe
38
+ status em [AUTORIZADO, PROCESSADO]
39
+ pagamento.status == status
40
+ }
41
+ error {
42
+ autorizacao_negada: "A operacao foi recusada pelo gateway."
43
+ saldo_insuficiente: "O saldo nao cobre o valor da cobranca."
44
+ timeout_gateway: "O gateway nao respondeu em tempo habil."
45
+ }
46
+ tests {
47
+ caso "pagamento autorizado" {
48
+ given {
49
+ pagamento_id: "pag_1"
50
+ valor: 199.9
51
+ token: "tok_ok"
52
+ }
53
+
54
+ expect {
55
+ sucesso: verdadeiro
56
+ }
57
+ }
58
+ caso "pagamento recusado por autorizacao" {
59
+ given {
60
+ pagamento_id: "pag_erro"
61
+ valor: 10
62
+ token: "tok_recusado"
63
+ }
64
+
65
+ expect {
66
+ sucesso: falso
67
+ }
68
+
69
+ error {
70
+ tipo: "autorizacao_negada"
71
+ }
72
+ }
73
+ caso "pagamento falha por timeout" {
74
+ given {
75
+ pagamento_id: "pag_timeout"
76
+ valor: 10
77
+ token: "tok_timeout"
78
+ }
79
+
80
+ expect {
81
+ sucesso: falso
82
+ }
83
+
84
+ error {
85
+ tipo: "timeout_gateway"
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ task confirmar_pagamento {
92
+ input {
93
+ pagamento_id: Id required
94
+ }
95
+ output {
96
+ status: StatusPagamento
97
+ }
98
+ rules {
99
+ pagamento_id existe
100
+ }
101
+ effects {
102
+ consulta gateway_pagamento criticidade = alta
103
+ persistencia Pagamento criticidade = alta
104
+ evento pagamento_confirmado criticidade = media
105
+ auditoria conciliacao_pagamento criticidade = alta
106
+ }
107
+ state ciclo_pagamento {
108
+ transitions {
109
+ AUTORIZADO -> PROCESSADO
110
+ }
111
+ }
112
+ guarantees {
113
+ status == PROCESSADO
114
+ }
115
+ tests {
116
+ caso "confirma pagamento autorizado" {
117
+ given {
118
+ pagamento_id: "pag_1"
119
+ }
120
+
121
+ expect {
122
+ sucesso: verdadeiro
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ task notificar_falha_pagamento {
129
+ input {
130
+ pagamento_id: Id required
131
+ motivo: Texto required
132
+ }
133
+ output {
134
+ protocolo_notificacao: Id
135
+ }
136
+ effects {
137
+ notificacao cliente falha_pagamento criticidade = alta
138
+ auditoria falha_pagamento criticidade = media
139
+ }
140
+ guarantees {
141
+ protocolo_notificacao existe
142
+ }
143
+ tests {
144
+ caso "notifica falha por recusa" {
145
+ given {
146
+ pagamento_id: "pag_erro"
147
+ motivo: "autorizacao_negada"
148
+ }
149
+
150
+ expect {
151
+ sucesso: verdadeiro
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ task registrar_timeout_pagamento {
158
+ input {
159
+ pagamento_id: Id required
160
+ }
161
+ output {
162
+ auditoria_id: Id
163
+ }
164
+ effects {
165
+ auditoria timeout_gateway criticidade = alta
166
+ persistencia incidente_pagamento criticidade = media
167
+ }
168
+ guarantees {
169
+ auditoria_id existe
170
+ }
171
+ tests {
172
+ caso "registra timeout" {
173
+ given {
174
+ pagamento_id: "pag_timeout"
175
+ }
176
+
177
+ expect {
178
+ sucesso: verdadeiro
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ flow orquestracao_pagamento {
185
+ pagamento_id: Id
186
+ valor: Decimal
187
+ token: Texto
188
+ 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
+ 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
191
+ etapa registrar_timeout usa registrar_timeout_pagamento com pagamento_id = pagamento_id depende_de autorizar
192
+ etapa registrar_falha usa registrar_timeout_pagamento com pagamento_id = pagamento_id depende_de autorizar
193
+ effects {
194
+ auditoria fluxo_pagamento criticidade = alta
195
+ evento pagamento_em_processamento criticidade = media
196
+ }
197
+ }
198
+
199
+ route processar_pagamento_publico {
200
+ metodo: POST
201
+ caminho: /pagamentos/processar
202
+ task: processar_pagamento
203
+ input {
204
+ pagamento_id: Id required
205
+ valor: Decimal required
206
+ token: Texto required
207
+ }
208
+ output {
209
+ pagamento: Pagamento required
210
+ status: StatusPagamento required
211
+ }
212
+ effects {
213
+ auditoria pagamento_publico criticidade = alta
214
+ evento pagamento_requisitado criticidade = media
215
+ }
216
+ error {
217
+ autorizacao_negada: "Erro publico quando o gateway recusa a operacao."
218
+ saldo_insuficiente: "Erro publico quando nao ha saldo suficiente."
219
+ timeout_gateway: "Erro publico quando o gateway nao responde."
220
+ }
221
+ }
222
+ }
@@ -0,0 +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
+ }
@@ -0,0 +1,45 @@
1
+ module exemplos.testes.embutidos {
2
+ task validar_documento {
3
+ input {
4
+ documento: Texto required
5
+ }
6
+ output {
7
+ valido: Booleano
8
+ motivo: Texto
9
+ }
10
+ rules {
11
+ documento deve_ser preenchido
12
+ }
13
+ effects {
14
+ auditoria validacao_documento
15
+ }
16
+ guarantees {
17
+ valido existe
18
+ motivo existe
19
+ }
20
+ tests {
21
+ caso "documento valido" {
22
+ given {
23
+ documento: 12345678900
24
+ }
25
+
26
+ expect {
27
+ sucesso: verdadeiro
28
+ }
29
+ }
30
+ caso "documento vazio" {
31
+ given {
32
+ documento: ""
33
+ }
34
+
35
+ expect {
36
+ sucesso: falso
37
+ }
38
+
39
+ error {
40
+ tipo: "entrada_invalida"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +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
+ }
package/llms-full.txt ADDED
@@ -0,0 +1,34 @@
1
+ Sema is an AI-first semantic language and tooling stack for explicit software intent, drift analysis, and safer intervention in live backend systems.
2
+
3
+ This repository is not optimized for human-first reading. It is optimized for AI agents that need compressed, canonical semantic context.
4
+
5
+ Canonical entrypoints in the repository root:
6
+ 1. `llms.txt`
7
+ 2. `SEMA_BRIEF.md`
8
+ 3. `SEMA_INDEX.json`
9
+ 4. `AGENTS.md`
10
+ 5. `README.md`
11
+ 6. `docs/AGENT_STARTER.md`
12
+
13
+ Capacity routing:
14
+ - small/free AI: `llms.txt` -> `SEMA_BRIEF.micro.txt` -> `SEMA_INDEX.json` -> `AGENTS.md`
15
+ - medium AI: `llms.txt` -> `SEMA_BRIEF.curto.txt` -> `SEMA_INDEX.json` -> `AGENTS.md` -> `README.md`
16
+ - large/tool-using AI: `llms-full.txt` -> `SEMA_BRIEF.md` -> `SEMA_INDEX.json` -> `AGENTS.md` -> `README.md`
17
+
18
+ Source-of-truth order:
19
+ 1. root Sema artifacts
20
+ 2. CLI JSON outputs
21
+ 3. official docs
22
+ 4. official examples
23
+ 5. raw implementation code
24
+
25
+ Useful commands:
26
+ - `sema resumo <arquivo-ou-pasta> --micro --para mudanca`
27
+ - `sema prompt-curto <arquivo-ou-pasta> --curto --para review`
28
+ - `sema drift <arquivo-ou-pasta> --json`
29
+ - `sema contexto-ia <arquivo.sema> --saida ./.tmp/contexto --json`
30
+ - `sema validar <arquivo-ou-pasta> --json`
31
+ - `sema verificar <arquivo-ou-pasta> --json`
32
+
33
+ Do not ask the model to infer semantics that are already available in Sema artifacts.
34
+ Do not start from raw source code if `SEMA_BRIEF`, `SEMA_INDEX`, `drift`, or `briefing` are available.
package/llms.txt ADDED
@@ -0,0 +1,17 @@
1
+ Sema is an AI-first semantic language and tooling stack for backend intent.
2
+
3
+ This repository is not human-first. Use the canonical AI entrypoints before raw code.
4
+
5
+ Read in this order:
6
+ 1. SEMA_BRIEF.micro.txt or SEMA_BRIEF.md
7
+ 2. SEMA_INDEX.json
8
+ 3. AGENTS.md
9
+ 4. README.md
10
+
11
+ Capacity routing:
12
+ - small models: llms.txt -> SEMA_BRIEF.micro.txt -> SEMA_INDEX.json
13
+ - medium models: llms.txt -> SEMA_BRIEF.curto.txt -> SEMA_INDEX.json -> README.md
14
+ - large models: llms-full.txt -> SEMA_BRIEF.md -> SEMA_INDEX.json -> README.md
15
+
16
+ Prefer Sema artifacts over raw source code when both exist.
17
+ Prefer `drift`, `briefing`, `ir`, and `diagnosticos` over guesswork.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-dart",
3
- "version": "0.9.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"
@@ -1,15 +1,84 @@
1
1
  import path from "node:path";
2
2
  import { descreverEstruturaModulo, mapearTipoParaPython, normalizarNomeModulo, normalizarNomeParaSimbolo, } from "@sema/padroes";
3
3
  const TIPOS_PRIMITIVOS_SEMA = new Set(["Texto", "Numero", "Inteiro", "Decimal", "Booleano", "Data", "DataHora", "Id", "Email", "Url", "Json", "Vazio"]);
4
+ function dividirTipoNoNivelRaiz(valor, separador) {
5
+ const partes = [];
6
+ let atual = "";
7
+ let profundidade = 0;
8
+ for (const caractere of valor) {
9
+ if (caractere === "<") {
10
+ profundidade += 1;
11
+ atual += caractere;
12
+ continue;
13
+ }
14
+ if (caractere === ">") {
15
+ profundidade = Math.max(0, profundidade - 1);
16
+ atual += caractere;
17
+ continue;
18
+ }
19
+ if (caractere === separador && profundidade === 0) {
20
+ if (atual.trim()) {
21
+ partes.push(atual.trim());
22
+ }
23
+ atual = "";
24
+ continue;
25
+ }
26
+ atual += caractere;
27
+ }
28
+ if (atual.trim()) {
29
+ partes.push(atual.trim());
30
+ }
31
+ return partes;
32
+ }
33
+ function coletarFolhasTipoPython(tipo) {
34
+ const limpo = tipo.trim();
35
+ if (!limpo) {
36
+ return [];
37
+ }
38
+ if (/^Opcional<.+>$/.test(limpo)) {
39
+ return coletarFolhasTipoPython(limpo.slice("Opcional<".length, -1));
40
+ }
41
+ const uniao = dividirTipoNoNivelRaiz(limpo, "|");
42
+ if (uniao.length > 1) {
43
+ return uniao.flatMap((item) => coletarFolhasTipoPython(item));
44
+ }
45
+ if (/^Lista<.+>$/.test(limpo)) {
46
+ return coletarFolhasTipoPython(limpo.slice("Lista<".length, -1));
47
+ }
48
+ if (/^Mapa<.+>$/.test(limpo)) {
49
+ return dividirTipoNoNivelRaiz(limpo.slice("Mapa<".length, -1), ",")
50
+ .flatMap((item) => coletarFolhasTipoPython(item));
51
+ }
52
+ return [limpo];
53
+ }
54
+ function mapearCampoParaPython(campo) {
55
+ let anotacao;
56
+ if (campo.cardinalidade === "lista") {
57
+ anotacao = `list[${mapearTipoParaPython(campo.tipoItem ?? campo.tipoBase)}]`;
58
+ }
59
+ else if (campo.cardinalidade === "mapa") {
60
+ anotacao = `dict[${mapearTipoParaPython(campo.chaveMapa ?? "Texto")}, ${mapearTipoParaPython(campo.valorMapa ?? "Json")}]`;
61
+ }
62
+ else if (campo.cardinalidade === "uniao") {
63
+ anotacao = campo.tiposAlternativos.map((tipo) => mapearTipoParaPython(tipo)).join(" | ");
64
+ }
65
+ else {
66
+ anotacao = mapearTipoParaPython(campo.tipoBase);
67
+ }
68
+ if (campo.opcional && !/\bNone\b/.test(anotacao)) {
69
+ return `${anotacao} | None`;
70
+ }
71
+ return anotacao;
72
+ }
4
73
  function gerarDataclass(nome, campos) {
5
74
  const linhas = campos.length === 0
6
75
  ? " pass"
7
76
  : campos.map((campo) => {
8
- const tipoBase = mapearTipoParaPython(campo.tipo);
77
+ const tipoBase = mapearCampoParaPython(campo);
9
78
  if (campo.modificadores.includes("required")) {
10
79
  return ` ${campo.nome}: ${tipoBase}`;
11
80
  }
12
- return ` ${campo.nome}: ${tipoBase} | None = None`;
81
+ return ` ${campo.nome}: ${/\bNone\b/.test(tipoBase) ? tipoBase : `${tipoBase} | None`} = None`;
13
82
  }).join("\n");
14
83
  return `@dataclass\nclass ${nome}:\n${linhas}\n`;
15
84
  }
@@ -39,8 +108,10 @@ function coletarTiposExternos(modulo) {
39
108
  ...modulo.states.flatMap((state) => state.campos),
40
109
  ];
41
110
  for (const campo of campos) {
42
- if (!TIPOS_PRIMITIVOS_SEMA.has(campo.tipo) && !locais.has(campo.tipo)) {
43
- referenciados.add(campo.tipo);
111
+ for (const tipo of coletarFolhasTipoPython(campo.tipo)) {
112
+ if (!TIPOS_PRIMITIVOS_SEMA.has(tipo) && !locais.has(tipo)) {
113
+ referenciados.add(tipo);
114
+ }
44
115
  }
45
116
  }
46
117
  return [...referenciados].sort((a, b) => a.localeCompare(b, "pt-BR"));
@@ -87,7 +158,18 @@ function resolverExpressaoPython(expressao, camposConhecidos, variavel) {
87
158
  return `(not ${resolverExpressaoPython(expressao.termo, camposConhecidos, variavel)})`;
88
159
  }
89
160
  }
90
- function valorPadraoPython(tipo, nomeCampo) {
161
+ function valorPadraoPython(campo) {
162
+ const tipo = campo.tipoBase;
163
+ const nomeCampo = campo.nome;
164
+ if (campo.cardinalidade === "lista") {
165
+ return "[]";
166
+ }
167
+ if (campo.cardinalidade === "mapa") {
168
+ return "{}";
169
+ }
170
+ if (campo.opcional) {
171
+ return "None";
172
+ }
91
173
  switch (tipo) {
92
174
  case "Texto":
93
175
  case "Id":
@@ -175,7 +257,7 @@ function paraPascalCase(valor) {
175
257
  }
176
258
  function gerarPreparacaoSaida(task) {
177
259
  const camposSaida = new Set(task.output.map((campo) => campo.nome));
178
- const argumentos = task.output.map((campo) => `${campo.nome}=${valorPadraoPython(campo.tipo, campo.nome)}`).join(", ");
260
+ const argumentos = task.output.map((campo) => `${campo.nome}=${valorPadraoPython(campo)}`).join(", ");
179
261
  const ajustes = [];
180
262
  for (const garantia of task.garantiasEstruturadas) {
181
263
  if (garantia.tipo === "pertencimento" && garantia.valores && camposSaida.has(garantia.alvo)) {
@@ -426,18 +508,18 @@ function gerarFastApiSchemas(modulo, caminhoContrato) {
426
508
  ];
427
509
  for (const task of modulo.tasks) {
428
510
  linhas.push(`class ${task.nome}EntradaSchema(BaseModel):
429
- ${task.input.length === 0 ? " pass" : task.input.map((campo) => ` ${campo.nome}: ${mapearTipoParaPython(campo.tipo)}`).join("\n")}
511
+ ${task.input.length === 0 ? " pass" : task.input.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
430
512
  `);
431
513
  linhas.push(`class ${task.nome}SaidaSchema(BaseModel):
432
- ${task.output.length === 0 ? " pass" : task.output.map((campo) => ` ${campo.nome}: ${mapearTipoParaPython(campo.tipo)}`).join("\n")}
514
+ ${task.output.length === 0 ? " pass" : task.output.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
433
515
  `);
434
516
  }
435
517
  for (const route of modulo.routes) {
436
518
  linhas.push(`class ${route.nome}EntradaPublicaSchema(BaseModel):
437
- ${route.inputPublico.length === 0 ? " pass" : route.inputPublico.map((campo) => ` ${campo.nome}: ${mapearTipoParaPython(campo.tipo)}`).join("\n")}
519
+ ${route.inputPublico.length === 0 ? " pass" : route.inputPublico.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
438
520
  `);
439
521
  linhas.push(`class ${route.nome}SaidaPublicaSchema(BaseModel):
440
- ${route.outputPublico.length === 0 ? " pass" : route.outputPublico.map((campo) => ` ${campo.nome}: ${mapearTipoParaPython(campo.tipo)}`).join("\n")}
522
+ ${route.outputPublico.length === 0 ? " pass" : route.outputPublico.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
441
523
  `);
442
524
  }
443
525
  return linhas.join("\n");