@oondemand/create-central-oon 0.3.7 → 0.3.9
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.
- package/README.md +54 -4
- package/bin/cli.js +59 -13
- package/docs/BACKEND_PATTERNS.md +87 -0
- package/docs/CHECKLIST_IMPLEMENTACAO.md +41 -0
- package/docs/CODEX.md +46 -0
- package/docs/COLLECTIONS_AND_PIPELINES.md +66 -0
- package/docs/CONNECTORS_AND_INTEGRATIONS.md +66 -0
- package/docs/DO_AND_DONT.md +27 -0
- package/docs/FRONTEND_PATTERNS.md +66 -0
- package/docs/OONCORE_ARCHITECTURE.md +50 -0
- package/docs/RBAC_SECURITY.md +35 -0
- package/package.json +6 -3
- package/src/index.js +203 -4
- package/templates/_base/README.md +20 -3
- package/templates/_base/backend/package.json +1 -1
- package/templates/_base/frontend/package.json +1 -1
- package/templates/_base/package.json +15 -0
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# @oondemand/create-central-oon
|
|
2
2
|
|
|
3
|
-
📖 **[Documentação completa → ooncoredoc.vercel.app](https://ooncoredoc.vercel.app)**
|
|
4
|
-
|
|
5
3
|
Gerador de **Centrais Oon**. Cria, a partir do nome da Central, um `backend/` de domínio e um `frontend/` declarativo prontos para consumir o Core (`@oondemand/oon-core-back` e `@oondemand/oon-core-front`).
|
|
6
4
|
|
|
5
|
+
> A documentação pública pode existir para consulta, mas a fonte de verdade para codificação assistida fica dentro deste pacote npm, versionada junto com o gerador.
|
|
6
|
+
|
|
7
7
|
Toda Central gerada nasce com o padrão visual e operacional consolidado na **Central Minexco**:
|
|
8
8
|
|
|
9
9
|
- identidade visual Oon/CST com Poppins, azul `#0474AF` e fundo `#F8F9FA`;
|
|
@@ -36,6 +36,51 @@ Aliases: o binário também responde por `scaffold-central-oon`.
|
|
|
36
36
|
| `--no-install` | Não roda `npm install` nos projetos gerados. |
|
|
37
37
|
| `--list` | Lista os templates e sai. |
|
|
38
38
|
|
|
39
|
+
## Documentação interna para Codex
|
|
40
|
+
|
|
41
|
+
O pacote inclui documentação canônica em `docs/`. Ela é publicada no npm junto com o gerador.
|
|
42
|
+
|
|
43
|
+
Ao criar uma Central, o CLI gera uma pasta `.ooncore/` com um cache local da documentação da versão instalada:
|
|
44
|
+
|
|
45
|
+
```txt
|
|
46
|
+
<central>/
|
|
47
|
+
└── .ooncore/
|
|
48
|
+
├── CODEX.md
|
|
49
|
+
├── context.generated.md
|
|
50
|
+
├── manifest.json
|
|
51
|
+
└── docs/
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
A pasta `.ooncore/` não é a fonte de verdade. Ela é apenas o contexto local para o Codex trabalhar sem depender de site externo.
|
|
55
|
+
|
|
56
|
+
### Sincronizar documentação local
|
|
57
|
+
|
|
58
|
+
Na raiz da Central:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run ooncore:docs
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
ou diretamente:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx create-central-oon docs --sync
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Verificar se está atualizada
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run ooncore:docs:check
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
ou diretamente:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx create-central-oon docs --check
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
O check compara a versão e o hash da documentação local com a versão instalada do pacote.
|
|
83
|
+
|
|
39
84
|
## Templates funcionais
|
|
40
85
|
|
|
41
86
|
Todos utilizam o mesmo frontend padrão Minexco.
|
|
@@ -55,6 +100,8 @@ Todos utilizam o mesmo frontend padrão Minexco.
|
|
|
55
100
|
```txt
|
|
56
101
|
<central>/
|
|
57
102
|
├── README.md
|
|
103
|
+
├── package.json # scripts de sync/check da documentação OonCore
|
|
104
|
+
├── .ooncore/ # cache local gerado a partir do pacote instalado
|
|
58
105
|
├── backend/ # consome @oondemand/oon-core-back
|
|
59
106
|
│ ├── central.config.js # identidade + módulos + paths de domínio
|
|
60
107
|
│ ├── central.manifest.json # valores de deploy (render no Core)
|
|
@@ -70,8 +117,11 @@ Todos utilizam o mesmo frontend padrão Minexco.
|
|
|
70
117
|
## Próximos passos após gerar
|
|
71
118
|
|
|
72
119
|
```bash
|
|
73
|
-
cd <central
|
|
74
|
-
|
|
120
|
+
cd <central>
|
|
121
|
+
npm run ooncore:docs:check
|
|
122
|
+
|
|
123
|
+
cd backend && cp .env.example .env && npm run dev
|
|
124
|
+
cd ../frontend && cp .env.example .env && npm run dev
|
|
75
125
|
```
|
|
76
126
|
|
|
77
127
|
Evoluir a Central significa criar models em `backend/src/models` e declarar as telas em `frontend/central.ui.json`. Menu, rotas, datagrids, formulários e esteiras são montados pelo Core mantendo o padrão Minexco.
|
package/bin/cli.js
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* CLI do create-central-oon
|
|
5
|
+
* CLI do create-central-oon.
|
|
6
6
|
*
|
|
7
7
|
* npx create-central-oon <nome-da-central> [opções]
|
|
8
|
+
* npx create-central-oon docs --sync
|
|
9
|
+
* npx create-central-oon docs --check
|
|
8
10
|
*
|
|
9
11
|
* Opções:
|
|
10
12
|
* --template=<t> Template inicial (default: basic). Veja --list.
|
|
@@ -12,26 +14,62 @@
|
|
|
12
14
|
* --force Sobrescreve pasta existente.
|
|
13
15
|
* --no-install Não roda npm install nos projetos gerados.
|
|
14
16
|
* --list Lista os templates disponíveis e sai.
|
|
17
|
+
*
|
|
18
|
+
* Documentação:
|
|
19
|
+
* docs --sync Gera/atualiza .ooncore/ com a documentação da versão instalada.
|
|
20
|
+
* docs --check Valida se .ooncore/ está sincronizado com a versão instalada.
|
|
15
21
|
*/
|
|
16
22
|
|
|
17
|
-
const { run, listTemplates } = require("../src/index");
|
|
23
|
+
const { run, listTemplates, syncDocs, checkDocs } = require("../src/index");
|
|
18
24
|
|
|
19
25
|
function parseArgs(argv) {
|
|
20
|
-
const opts = {
|
|
26
|
+
const opts = {
|
|
27
|
+
command: null,
|
|
28
|
+
template: "basic",
|
|
29
|
+
here: false,
|
|
30
|
+
force: false,
|
|
31
|
+
install: true,
|
|
32
|
+
list: false,
|
|
33
|
+
docsSync: false,
|
|
34
|
+
docsCheck: false,
|
|
35
|
+
};
|
|
21
36
|
const positionals = [];
|
|
22
|
-
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
39
|
+
const arg = argv[i];
|
|
40
|
+
|
|
23
41
|
if (arg === "--here") opts.here = true;
|
|
24
42
|
else if (arg === "--force") opts.force = true;
|
|
25
43
|
else if (arg === "--no-install") opts.install = false;
|
|
26
44
|
else if (arg === "--list") opts.list = true;
|
|
45
|
+
else if (arg === "--sync") opts.docsSync = true;
|
|
46
|
+
else if (arg === "--check") opts.docsCheck = true;
|
|
27
47
|
else if (arg.startsWith("--template=")) opts.template = arg.slice("--template=".length);
|
|
28
|
-
else if (arg === "--template")
|
|
29
|
-
|
|
48
|
+
else if (arg === "--template") {
|
|
49
|
+
opts.template = argv[i + 1];
|
|
50
|
+
i += 1;
|
|
51
|
+
} else if (!arg.startsWith("-")) {
|
|
52
|
+
positionals.push(arg);
|
|
53
|
+
}
|
|
30
54
|
}
|
|
31
|
-
|
|
55
|
+
|
|
56
|
+
if (positionals[0] === "docs") {
|
|
57
|
+
opts.command = "docs";
|
|
58
|
+
} else {
|
|
59
|
+
opts.name = positionals[0];
|
|
60
|
+
}
|
|
61
|
+
|
|
32
62
|
return opts;
|
|
33
63
|
}
|
|
34
64
|
|
|
65
|
+
function printUsage() {
|
|
66
|
+
console.error("Uso:");
|
|
67
|
+
console.error(" npx create-central-oon <nome-da-central> [--template=basic]");
|
|
68
|
+
console.error(" npx create-central-oon --list");
|
|
69
|
+
console.error(" npx create-central-oon docs --sync");
|
|
70
|
+
console.error(" npx create-central-oon docs --check");
|
|
71
|
+
}
|
|
72
|
+
|
|
35
73
|
async function main() {
|
|
36
74
|
const opts = parseArgs(process.argv.slice(2));
|
|
37
75
|
|
|
@@ -41,13 +79,21 @@ async function main() {
|
|
|
41
79
|
process.exit(0);
|
|
42
80
|
}
|
|
43
81
|
|
|
44
|
-
if (!opts.name) {
|
|
45
|
-
console.error("Uso: npx create-central-oon <nome-da-central> [--template=basic]");
|
|
46
|
-
console.error(" npx create-central-oon --list");
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
82
|
try {
|
|
83
|
+
if (opts.command === "docs") {
|
|
84
|
+
if (opts.docsCheck) {
|
|
85
|
+
checkDocs();
|
|
86
|
+
} else {
|
|
87
|
+
syncDocs();
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!opts.name) {
|
|
93
|
+
printUsage();
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
51
97
|
await run(opts);
|
|
52
98
|
} catch (err) {
|
|
53
99
|
console.error("\n✖", err.message);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Padrões Backend
|
|
2
|
+
|
|
3
|
+
O backend da Central deve conter apenas domínio e extensões. Boot, infraestrutura, CRUD padrão, autenticação, RBAC e metadata pertencem ao `@oondemand/oon-core-back`.
|
|
4
|
+
|
|
5
|
+
## Estrutura esperada
|
|
6
|
+
|
|
7
|
+
```txt
|
|
8
|
+
backend/
|
|
9
|
+
├── central.config.js
|
|
10
|
+
├── central.manifest.json
|
|
11
|
+
└── src/
|
|
12
|
+
├── models/
|
|
13
|
+
├── validations/
|
|
14
|
+
├── triggers/
|
|
15
|
+
├── hooks/
|
|
16
|
+
├── mappings/
|
|
17
|
+
├── documents/
|
|
18
|
+
├── pipelines/
|
|
19
|
+
├── integrations/
|
|
20
|
+
├── routes/
|
|
21
|
+
├── controllers/
|
|
22
|
+
└── services/
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Models
|
|
26
|
+
|
|
27
|
+
Use models para declarar entidades de negócio. Cada model deve ser pequeno, com nomes claros e campos compatíveis com as telas e integrações.
|
|
28
|
+
|
|
29
|
+
Boas práticas:
|
|
30
|
+
|
|
31
|
+
- use campos explícitos;
|
|
32
|
+
- defina tipos, obrigatoriedade e enums quando aplicável;
|
|
33
|
+
- preserve campos de status para esteiras;
|
|
34
|
+
- evite regras complexas diretamente no schema;
|
|
35
|
+
- evite dependência direta de frontend.
|
|
36
|
+
|
|
37
|
+
## Validations
|
|
38
|
+
|
|
39
|
+
Use validations para regras de negócio síncronas e mensagens claras para o usuário.
|
|
40
|
+
|
|
41
|
+
Exemplos:
|
|
42
|
+
|
|
43
|
+
- campo obrigatório condicional;
|
|
44
|
+
- status permitido para transição;
|
|
45
|
+
- valor mínimo/máximo;
|
|
46
|
+
- combinação inválida de campos;
|
|
47
|
+
- bloqueio por permissão ou perfil.
|
|
48
|
+
|
|
49
|
+
## Triggers e hooks
|
|
50
|
+
|
|
51
|
+
Use triggers e hooks para efeitos controlados depois ou antes de alterações.
|
|
52
|
+
|
|
53
|
+
Exemplos:
|
|
54
|
+
|
|
55
|
+
- criar ticket de integração;
|
|
56
|
+
- recalcular campos derivados;
|
|
57
|
+
- gerar histórico operacional;
|
|
58
|
+
- disparar conector;
|
|
59
|
+
- atualizar etapa da esteira.
|
|
60
|
+
|
|
61
|
+
Regras:
|
|
62
|
+
|
|
63
|
+
- trigger não deve esconder regra crítica sem validação;
|
|
64
|
+
- evite efeitos irreversíveis sem log;
|
|
65
|
+
- integração externa deve passar por camada de integração/conector;
|
|
66
|
+
- falhas de integração devem gerar status rastreável, não quebrar silenciosamente o processo.
|
|
67
|
+
|
|
68
|
+
## Rotas customizadas
|
|
69
|
+
|
|
70
|
+
Crie rotas customizadas somente quando o CRUD/metadata do Core não resolver.
|
|
71
|
+
|
|
72
|
+
Toda rota customizada deve ter:
|
|
73
|
+
|
|
74
|
+
- autenticação;
|
|
75
|
+
- verificação de permissão;
|
|
76
|
+
- validação de entrada;
|
|
77
|
+
- tratamento de erro;
|
|
78
|
+
- resposta padronizada;
|
|
79
|
+
- ausência de segredo hardcoded.
|
|
80
|
+
|
|
81
|
+
## Serviços
|
|
82
|
+
|
|
83
|
+
Use `services/` para regras reutilizáveis. Evite controllers grandes.
|
|
84
|
+
|
|
85
|
+
## Segurança
|
|
86
|
+
|
|
87
|
+
Nunca confie no frontend para permissão, tenant, app ou perfil. O backend deve validar tudo que altera dados, dispara integrações ou expõe informações sensíveis.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Checklist de Implementação
|
|
2
|
+
|
|
3
|
+
Use este checklist antes de concluir qualquer tarefa de codificação em uma Central Oon.
|
|
4
|
+
|
|
5
|
+
## Contexto
|
|
6
|
+
|
|
7
|
+
- [ ] Rodei `npm run ooncore:docs:check`.
|
|
8
|
+
- [ ] Rodei `npm run ooncore:docs` se havia documentação desatualizada.
|
|
9
|
+
- [ ] Li `.ooncore/context.generated.md`.
|
|
10
|
+
- [ ] Entendi qual recurso do Core já resolve parte da necessidade.
|
|
11
|
+
|
|
12
|
+
## Backend
|
|
13
|
+
|
|
14
|
+
- [ ] Usei model, validation, trigger, hook, mapping ou integration quando aplicável.
|
|
15
|
+
- [ ] Evitei recriar CRUD.
|
|
16
|
+
- [ ] Validei entrada.
|
|
17
|
+
- [ ] Validei permissão no backend.
|
|
18
|
+
- [ ] Tratei erros.
|
|
19
|
+
- [ ] Não hardcodei segredos.
|
|
20
|
+
- [ ] Mantive rastreabilidade.
|
|
21
|
+
|
|
22
|
+
## Frontend
|
|
23
|
+
|
|
24
|
+
- [ ] Usei `central.ui.json` antes de criar componente customizado.
|
|
25
|
+
- [ ] Evitei recriar shell, rotas, menu, datagrid ou form.
|
|
26
|
+
- [ ] Usei override apenas quando necessário.
|
|
27
|
+
- [ ] Não coloquei regra crítica apenas no frontend.
|
|
28
|
+
|
|
29
|
+
## Integrações
|
|
30
|
+
|
|
31
|
+
- [ ] Usei camada de integração/conector.
|
|
32
|
+
- [ ] Modelei mapping.
|
|
33
|
+
- [ ] Registrei status de integração.
|
|
34
|
+
- [ ] Normalizei erros externos.
|
|
35
|
+
- [ ] Não expus credenciais.
|
|
36
|
+
|
|
37
|
+
## Entrega
|
|
38
|
+
|
|
39
|
+
- [ ] A Central continua atualizável com novas versões do Core.
|
|
40
|
+
- [ ] A alteração é pequena, coesa e aderente à arquitetura.
|
|
41
|
+
- [ ] O comportamento esperado está documentado no README ou no próprio módulo quando necessário.
|
package/docs/CODEX.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# CODEX.md — Regras de Codificação OonCore
|
|
2
|
+
|
|
3
|
+
Este arquivo é a porta de entrada para o Codex codificar uma Central Oon.
|
|
4
|
+
|
|
5
|
+
A fonte de verdade desta documentação é a versão instalada do pacote `@oondemand/create-central-oon`. A pasta `.ooncore/` gerada em cada Central é apenas um cache local, criado por `create-central-oon docs --sync`.
|
|
6
|
+
|
|
7
|
+
## Antes de codificar
|
|
8
|
+
|
|
9
|
+
1. Rode `npm run ooncore:docs:check` na raiz da Central.
|
|
10
|
+
2. Se estiver desatualizado, rode `npm run ooncore:docs`.
|
|
11
|
+
3. Leia `.ooncore/context.generated.md`.
|
|
12
|
+
4. Identifique o recurso do Core que resolve a necessidade antes de criar código customizado.
|
|
13
|
+
|
|
14
|
+
## Princípios obrigatórios
|
|
15
|
+
|
|
16
|
+
- Escreva apenas o domínio da Central.
|
|
17
|
+
- Use `@oondemand/oon-core-back` para boot, autenticação, RBAC, CRUD, metadata, auditoria e padrões de API.
|
|
18
|
+
- Use `@oondemand/oon-core-front` para shell, rotas, menu, datagrid, formulários, badges, ações e renderização por metadata.
|
|
19
|
+
- Não recrie infraestrutura que já existe no Core.
|
|
20
|
+
- Não crie autenticação paralela.
|
|
21
|
+
- Não duplique RBAC no frontend.
|
|
22
|
+
- Não hardcode tenant, app, usuário, perfil, permissões, URLs sensíveis ou segredos.
|
|
23
|
+
- Não exponha chaves em código, templates ou documentação gerada.
|
|
24
|
+
- Não altere arquivos gerados do Core se houver extensão declarativa disponível.
|
|
25
|
+
- Prefira models, validations, triggers, hooks, mappings, documents, pipelines, integrations e overrides declarativos.
|
|
26
|
+
|
|
27
|
+
## Ordem de decisão
|
|
28
|
+
|
|
29
|
+
Ao implementar uma necessidade, siga esta ordem:
|
|
30
|
+
|
|
31
|
+
1. Configuração existente do Core.
|
|
32
|
+
2. Declaração em `central.config.js` ou `central.ui.json`.
|
|
33
|
+
3. Model, validation, trigger, hook ou mapping no backend da Central.
|
|
34
|
+
4. Override local pequeno e isolado.
|
|
35
|
+
5. Código customizado somente quando o Core não oferecer extensão adequada.
|
|
36
|
+
|
|
37
|
+
## Entrega segura
|
|
38
|
+
|
|
39
|
+
Toda alteração deve manter:
|
|
40
|
+
|
|
41
|
+
- rastreabilidade;
|
|
42
|
+
- validação de entrada;
|
|
43
|
+
- RBAC no backend;
|
|
44
|
+
- ausência de segredo hardcoded;
|
|
45
|
+
- separação entre domínio da Central e infraestrutura do Core;
|
|
46
|
+
- compatibilidade com atualização futura dos pacotes `@oondemand/*`.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Coleções, Documentos e Esteiras
|
|
2
|
+
|
|
3
|
+
Coleções, documentos e esteiras são a base operacional da Central Oon.
|
|
4
|
+
|
|
5
|
+
## Coleções
|
|
6
|
+
|
|
7
|
+
Use coleções para entidades de negócio:
|
|
8
|
+
|
|
9
|
+
- clientes;
|
|
10
|
+
- fornecedores;
|
|
11
|
+
- pedidos;
|
|
12
|
+
- pagamentos;
|
|
13
|
+
- documentos fiscais;
|
|
14
|
+
- serviços tomados;
|
|
15
|
+
- serviços prestados;
|
|
16
|
+
- integrações;
|
|
17
|
+
- tickets operacionais.
|
|
18
|
+
|
|
19
|
+
Cada coleção deve ter:
|
|
20
|
+
|
|
21
|
+
- model no backend;
|
|
22
|
+
- metadata para CRUD;
|
|
23
|
+
- campos de status quando participar de esteira;
|
|
24
|
+
- validações de negócio;
|
|
25
|
+
- configuração de tela no frontend.
|
|
26
|
+
|
|
27
|
+
## Documentos
|
|
28
|
+
|
|
29
|
+
Use documentos para entidades que exigem governança documental, aprovação, anexos ou histórico específico.
|
|
30
|
+
|
|
31
|
+
Exemplos:
|
|
32
|
+
|
|
33
|
+
- NF;
|
|
34
|
+
- contrato;
|
|
35
|
+
- proposta;
|
|
36
|
+
- comprovante;
|
|
37
|
+
- ordem de serviço;
|
|
38
|
+
- pedido de compra.
|
|
39
|
+
|
|
40
|
+
## Esteiras de processo
|
|
41
|
+
|
|
42
|
+
Use esteiras para fluxos operacionais com etapas claras.
|
|
43
|
+
|
|
44
|
+
Boas práticas:
|
|
45
|
+
|
|
46
|
+
- status/etapa deve estar no backend;
|
|
47
|
+
- transições devem ser validadas;
|
|
48
|
+
- ações devem registrar usuário e data;
|
|
49
|
+
- exceções devem ter status próprio;
|
|
50
|
+
- cada etapa deve representar uma decisão operacional real.
|
|
51
|
+
|
|
52
|
+
## Esteiras de integração
|
|
53
|
+
|
|
54
|
+
Use esteiras de integração para acompanhar comunicação com sistemas externos.
|
|
55
|
+
|
|
56
|
+
Estados recomendados:
|
|
57
|
+
|
|
58
|
+
- pendente;
|
|
59
|
+
- em processamento;
|
|
60
|
+
- enviado;
|
|
61
|
+
- concluído;
|
|
62
|
+
- falha;
|
|
63
|
+
- aguardando retry;
|
|
64
|
+
- cancelado.
|
|
65
|
+
|
|
66
|
+
Integrações não devem ser caixas-pretas. O usuário operacional precisa enxergar o que aconteceu, qual erro ocorreu e qual ação pode ser tomada.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Conectores e Integrações
|
|
2
|
+
|
|
3
|
+
Toda integração deve ser modelada como um processo rastreável, não como chamada solta dentro de controller.
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Transformar cada integração em:
|
|
8
|
+
|
|
9
|
+
```txt
|
|
10
|
+
configuração + mapping + execução + status + rastreabilidade
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Estrutura recomendada
|
|
14
|
+
|
|
15
|
+
```txt
|
|
16
|
+
backend/src/integrations/
|
|
17
|
+
├── <sistema>/
|
|
18
|
+
│ ├── client.js
|
|
19
|
+
│ ├── mappings/
|
|
20
|
+
│ ├── services/
|
|
21
|
+
│ └── README.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Client
|
|
25
|
+
|
|
26
|
+
O client deve concentrar:
|
|
27
|
+
|
|
28
|
+
- URL base;
|
|
29
|
+
- autenticação;
|
|
30
|
+
- headers;
|
|
31
|
+
- timeout;
|
|
32
|
+
- retry técnico;
|
|
33
|
+
- normalização de erro.
|
|
34
|
+
|
|
35
|
+
Não coloque regra de negócio no client.
|
|
36
|
+
|
|
37
|
+
## Mapping
|
|
38
|
+
|
|
39
|
+
Mappings devem transformar dados entre a Central e o sistema externo.
|
|
40
|
+
|
|
41
|
+
Regras:
|
|
42
|
+
|
|
43
|
+
- mapping deve ser explícito;
|
|
44
|
+
- campos obrigatórios devem ser validados antes do envio;
|
|
45
|
+
- resposta externa deve ser normalizada;
|
|
46
|
+
- erros devem ser compreensíveis para operação.
|
|
47
|
+
|
|
48
|
+
## Esteira de integração
|
|
49
|
+
|
|
50
|
+
Toda integração relevante deve gerar registro operacional com:
|
|
51
|
+
|
|
52
|
+
- origem;
|
|
53
|
+
- destino;
|
|
54
|
+
- payload resumido ou referência;
|
|
55
|
+
- status;
|
|
56
|
+
- tentativas;
|
|
57
|
+
- erro normalizado;
|
|
58
|
+
- data/hora;
|
|
59
|
+
- usuário ou processo responsável.
|
|
60
|
+
|
|
61
|
+
## Segurança
|
|
62
|
+
|
|
63
|
+
- Nunca versionar app key, secret, token ou credencial.
|
|
64
|
+
- Não logar payloads sensíveis sem necessidade.
|
|
65
|
+
- Não expor credenciais no frontend.
|
|
66
|
+
- Usar `.env` e configuração de ambiente.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Do and Don't
|
|
2
|
+
|
|
3
|
+
## Faça
|
|
4
|
+
|
|
5
|
+
- Use o Core antes de criar código novo.
|
|
6
|
+
- Modele o domínio com clareza.
|
|
7
|
+
- Prefira configuração e metadata.
|
|
8
|
+
- Escreva validações explícitas.
|
|
9
|
+
- Mantenha regras críticas no backend.
|
|
10
|
+
- Use esteiras para processos com status.
|
|
11
|
+
- Use conectores para integrações.
|
|
12
|
+
- Registre erros de forma operacional.
|
|
13
|
+
- Mantenha compatibilidade com atualização dos pacotes.
|
|
14
|
+
- Atualize `.ooncore/` com `npm run ooncore:docs`.
|
|
15
|
+
|
|
16
|
+
## Não faça
|
|
17
|
+
|
|
18
|
+
- Não recrie CRUD.
|
|
19
|
+
- Não recrie autenticação.
|
|
20
|
+
- Não duplique RBAC no frontend.
|
|
21
|
+
- Não criar um frontend inteiro se um override resolve.
|
|
22
|
+
- Não chamar APIs externas direto de qualquer lugar.
|
|
23
|
+
- Não hardcode tenant, app, usuário, URL sensível ou segredo.
|
|
24
|
+
- Não colocar regra crítica apenas no frontend.
|
|
25
|
+
- Não ignorar logs e rastreabilidade.
|
|
26
|
+
- Não editar `.ooncore/context.generated.md` manualmente.
|
|
27
|
+
- Não depender de documentação externa para codificar a arquitetura.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Padrões Frontend
|
|
2
|
+
|
|
3
|
+
O frontend da Central deve ser declarativo. Shell, providers, rotas, menu, datagrid, formulários, documentos e esteiras pertencem ao `@oondemand/oon-core-front`.
|
|
4
|
+
|
|
5
|
+
## Estrutura esperada
|
|
6
|
+
|
|
7
|
+
```txt
|
|
8
|
+
frontend/
|
|
9
|
+
├── central.ui.json
|
|
10
|
+
└── src/
|
|
11
|
+
├── main.tsx
|
|
12
|
+
├── collections/
|
|
13
|
+
├── documents/
|
|
14
|
+
├── pipelines/
|
|
15
|
+
├── dashboards/
|
|
16
|
+
└── overrides/
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## central.ui.json
|
|
20
|
+
|
|
21
|
+
Use `central.ui.json` como entrada principal para declarar:
|
|
22
|
+
|
|
23
|
+
- menu;
|
|
24
|
+
- coleções;
|
|
25
|
+
- campos exibidos;
|
|
26
|
+
- filtros;
|
|
27
|
+
- ações;
|
|
28
|
+
- formulários;
|
|
29
|
+
- documentos;
|
|
30
|
+
- esteiras;
|
|
31
|
+
- dashboards;
|
|
32
|
+
- agrupamentos.
|
|
33
|
+
|
|
34
|
+
## Regras
|
|
35
|
+
|
|
36
|
+
- Não recrie layout completo se o Core já renderiza.
|
|
37
|
+
- Não duplique chamada REST manual se o SDK do Core já atende.
|
|
38
|
+
- Não coloque regra de permissão apenas no frontend.
|
|
39
|
+
- Não hardcode endpoints quando a metadata puder fornecer.
|
|
40
|
+
- Não crie variações visuais fora do padrão sem necessidade real.
|
|
41
|
+
- Use overrides pequenos, específicos e documentados.
|
|
42
|
+
|
|
43
|
+
## Overrides
|
|
44
|
+
|
|
45
|
+
Overrides são permitidos para:
|
|
46
|
+
|
|
47
|
+
- campo especial;
|
|
48
|
+
- ação específica;
|
|
49
|
+
- card customizado;
|
|
50
|
+
- cabeçalho customizado;
|
|
51
|
+
- dashboard customizado;
|
|
52
|
+
- integração visual pontual.
|
|
53
|
+
|
|
54
|
+
Overrides não devem virar uma reimplementação do Core.
|
|
55
|
+
|
|
56
|
+
## Experiência padrão
|
|
57
|
+
|
|
58
|
+
A Central deve manter o padrão OonCore:
|
|
59
|
+
|
|
60
|
+
- navegação consistente;
|
|
61
|
+
- datagrids densos;
|
|
62
|
+
- formulários claros;
|
|
63
|
+
- feedback visual;
|
|
64
|
+
- status por badges;
|
|
65
|
+
- ações rastreáveis;
|
|
66
|
+
- responsividade.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Arquitetura OonCore
|
|
2
|
+
|
|
3
|
+
O OonCore é a base para criar Centrais operacionais sob demanda com arquitetura padronizada, segura e evolutiva.
|
|
4
|
+
|
|
5
|
+
A Central gerada não deve nascer como um sistema completo do zero. Ela deve nascer como uma camada de domínio que consome os recursos do Core.
|
|
6
|
+
|
|
7
|
+
## Separação de responsabilidades
|
|
8
|
+
|
|
9
|
+
```txt
|
|
10
|
+
Central
|
|
11
|
+
├── backend/ domínio, regras, validações, integrações e esteiras
|
|
12
|
+
└── frontend/ declaração de telas, coleções, documentos e overrides
|
|
13
|
+
|
|
14
|
+
OonCore Back
|
|
15
|
+
├── boot Express
|
|
16
|
+
├── Mongo/Mongoose
|
|
17
|
+
├── autenticação
|
|
18
|
+
├── RBAC
|
|
19
|
+
├── CRUD metadata-driven
|
|
20
|
+
├── auditoria
|
|
21
|
+
├── triggers/hooks
|
|
22
|
+
└── APIs padrão
|
|
23
|
+
|
|
24
|
+
OonCore Front
|
|
25
|
+
├── shell React
|
|
26
|
+
├── providers
|
|
27
|
+
├── roteamento
|
|
28
|
+
├── menu
|
|
29
|
+
├── datagrid
|
|
30
|
+
├── formulários
|
|
31
|
+
├── documentos
|
|
32
|
+
├── esteiras
|
|
33
|
+
└── SDK REST
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Modelo mini-monolítico
|
|
37
|
+
|
|
38
|
+
Cada Central começa como um mini-monolito de negócio: pequeno, coeso, isolado e capaz de entregar valor rapidamente. Quando uma parte do domínio se tornar reutilizável, crítica ou independente, ela pode evoluir para conector, serviço compartilhado ou micro-serviço.
|
|
39
|
+
|
|
40
|
+
## Fonte de verdade
|
|
41
|
+
|
|
42
|
+
- Dados e regras ficam no backend.
|
|
43
|
+
- Metadata operacional é exposta pelo backend.
|
|
44
|
+
- Frontend renderiza a experiência a partir da metadata.
|
|
45
|
+
- Permissões são decididas no backend.
|
|
46
|
+
- Integrações são tratadas como conectores, mappings, triggers e esteiras de integração.
|
|
47
|
+
|
|
48
|
+
## Objetivo do Codex
|
|
49
|
+
|
|
50
|
+
O Codex deve acelerar a construção da Central usando a arquitetura existente. O objetivo não é gerar um app genérico, mas sim completar a camada de domínio com segurança e aderência ao Core.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# RBAC e Segurança
|
|
2
|
+
|
|
3
|
+
A segurança da Central deve ser aplicada no backend. O frontend pode ocultar ou exibir ações, mas não é a fonte de decisão.
|
|
4
|
+
|
|
5
|
+
## Regras obrigatórias
|
|
6
|
+
|
|
7
|
+
- Toda operação sensível deve validar usuário autenticado.
|
|
8
|
+
- Toda alteração de dados deve validar permissão.
|
|
9
|
+
- Toda ação de integração deve validar permissão e contexto.
|
|
10
|
+
- Nunca confiar em `tenantId`, `appId`, `perfil` ou `roles` enviados livremente pelo frontend.
|
|
11
|
+
- Segredos devem vir de variáveis de ambiente ou vault equivalente.
|
|
12
|
+
- Logs não devem expor tokens, senhas, app keys ou dados sensíveis desnecessários.
|
|
13
|
+
|
|
14
|
+
## RBAC
|
|
15
|
+
|
|
16
|
+
Use o RBAC do Core para:
|
|
17
|
+
|
|
18
|
+
- controlar acesso por app;
|
|
19
|
+
- controlar perfis;
|
|
20
|
+
- controlar ações;
|
|
21
|
+
- filtrar funcionalidades;
|
|
22
|
+
- proteger rotas;
|
|
23
|
+
- permitir evolução de permissões sem reconstruir telas.
|
|
24
|
+
|
|
25
|
+
## Checklist de segurança para Codex
|
|
26
|
+
|
|
27
|
+
Antes de concluir uma alteração, confirme:
|
|
28
|
+
|
|
29
|
+
- Existe validação de entrada?
|
|
30
|
+
- Existe validação de permissão no backend?
|
|
31
|
+
- Existe tratamento de erro?
|
|
32
|
+
- A operação gera rastreabilidade?
|
|
33
|
+
- Algum segredo foi colocado no código?
|
|
34
|
+
- Algum dado sensível foi exposto no frontend?
|
|
35
|
+
- O comportamento funciona para múltiplos usuários e múltiplos apps?
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oondemand/create-central-oon",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/oondemand/oon-platform.git",
|
|
7
7
|
"directory": "packages/create-central-oon"
|
|
8
8
|
},
|
|
9
|
-
"description": "Gerador de Centrais Oon com backend declarativo
|
|
9
|
+
"description": "Gerador de Centrais Oon com backend declarativo, frontend padrão e documentação interna OonCore para Codex.",
|
|
10
10
|
"main": "src/index.js",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": "./src/index.js"
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"bin",
|
|
20
20
|
"src",
|
|
21
21
|
"templates",
|
|
22
|
+
"docs",
|
|
22
23
|
"README.md"
|
|
23
24
|
],
|
|
24
25
|
"engines": {
|
|
@@ -30,7 +31,9 @@
|
|
|
30
31
|
"central",
|
|
31
32
|
"scaffold",
|
|
32
33
|
"create",
|
|
33
|
-
"generator"
|
|
34
|
+
"generator",
|
|
35
|
+
"codex",
|
|
36
|
+
"docs"
|
|
34
37
|
],
|
|
35
38
|
"license": "SEE LICENSE IN LICENSE",
|
|
36
39
|
"publishConfig": {
|
package/src/index.js
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require("node:fs");
|
|
4
4
|
const path = require("node:path");
|
|
5
|
+
const crypto = require("node:crypto");
|
|
5
6
|
const { spawnSync } = require("node:child_process");
|
|
6
7
|
const { copyTemplate } = require("./render");
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
+
const PACKAGE_ROOT = path.join(__dirname, "..");
|
|
10
|
+
const TEMPLATES_DIR = path.join(PACKAGE_ROOT, "templates");
|
|
11
|
+
const DOCS_DIR = path.join(PACKAGE_ROOT, "docs");
|
|
9
12
|
|
|
10
13
|
const TEMPLATES = [
|
|
11
14
|
{ id: "basic", description: "Central mínima com uma coleção dinâmica (Pessoa)." },
|
|
@@ -52,6 +55,183 @@ function npmInstall(dir) {
|
|
|
52
55
|
return !r.status && !r.error;
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
function readPackageVersion() {
|
|
59
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8"));
|
|
60
|
+
return pkg.version;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function listDocFiles(dir = DOCS_DIR, prefix = "") {
|
|
64
|
+
if (!fs.existsSync(dir)) return [];
|
|
65
|
+
const files = [];
|
|
66
|
+
|
|
67
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
68
|
+
const relative = path.join(prefix, entry.name);
|
|
69
|
+
const absolute = path.join(dir, entry.name);
|
|
70
|
+
|
|
71
|
+
if (entry.isDirectory()) {
|
|
72
|
+
files.push(...listDocFiles(absolute, relative));
|
|
73
|
+
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
74
|
+
files.push(relative);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return files.sort((a, b) => a.localeCompare(b));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function docsHash(files = listDocFiles()) {
|
|
82
|
+
const hash = crypto.createHash("sha256");
|
|
83
|
+
for (const file of files) {
|
|
84
|
+
const normalized = file.split(path.sep).join("/");
|
|
85
|
+
hash.update(normalized);
|
|
86
|
+
hash.update("\n");
|
|
87
|
+
hash.update(fs.readFileSync(path.join(DOCS_DIR, file)));
|
|
88
|
+
hash.update("\n");
|
|
89
|
+
}
|
|
90
|
+
return hash.digest("hex");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function resolveCentralRoot(cwd = process.cwd()) {
|
|
94
|
+
const current = path.resolve(cwd);
|
|
95
|
+
const parent = path.dirname(current);
|
|
96
|
+
|
|
97
|
+
if (fs.existsSync(path.join(current, "backend")) && fs.existsSync(path.join(current, "frontend"))) {
|
|
98
|
+
return current;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
["backend", "frontend"].includes(path.basename(current)) &&
|
|
103
|
+
fs.existsSync(path.join(parent, "backend")) &&
|
|
104
|
+
fs.existsSync(path.join(parent, "frontend"))
|
|
105
|
+
) {
|
|
106
|
+
return parent;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return current;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function removeDir(dir) {
|
|
113
|
+
if (fs.existsSync(dir)) fs.rmSync(dir, { recursive: true, force: true });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function copyDocs(srcDir, destDir) {
|
|
117
|
+
if (!fs.existsSync(srcDir)) {
|
|
118
|
+
throw new Error(`Diretório de documentação não encontrado: ${srcDir}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
122
|
+
|
|
123
|
+
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
124
|
+
const from = path.join(srcDir, entry.name);
|
|
125
|
+
const to = path.join(destDir, entry.name);
|
|
126
|
+
|
|
127
|
+
if (entry.isDirectory()) {
|
|
128
|
+
copyDocs(from, to);
|
|
129
|
+
} else if (entry.isFile()) {
|
|
130
|
+
fs.copyFileSync(from, to);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function buildContext(files = listDocFiles()) {
|
|
136
|
+
const header = [
|
|
137
|
+
"# OonCore Contexto Consolidado para Codex",
|
|
138
|
+
"",
|
|
139
|
+
"> Arquivo gerado automaticamente por `create-central-oon docs --sync`.",
|
|
140
|
+
"> Não edite manualmente. A fonte de verdade está no pacote `@oondemand/create-central-oon` instalado.",
|
|
141
|
+
"",
|
|
142
|
+
"Este contexto consolida as regras mínimas para codificar Centrais Oon com segurança, usando o máximo dos recursos do OonCore.",
|
|
143
|
+
"",
|
|
144
|
+
].join("\n");
|
|
145
|
+
|
|
146
|
+
const sections = files
|
|
147
|
+
.map((file) => {
|
|
148
|
+
const normalized = file.split(path.sep).join("/");
|
|
149
|
+
const content = fs.readFileSync(path.join(DOCS_DIR, file), "utf8").trim();
|
|
150
|
+
return [
|
|
151
|
+
"---",
|
|
152
|
+
"",
|
|
153
|
+
`<!-- source: ${normalized} -->`,
|
|
154
|
+
"",
|
|
155
|
+
content,
|
|
156
|
+
"",
|
|
157
|
+
].join("\n");
|
|
158
|
+
})
|
|
159
|
+
.join("\n");
|
|
160
|
+
|
|
161
|
+
return `${header}\n${sections}`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function buildManifest(files = listDocFiles()) {
|
|
165
|
+
return {
|
|
166
|
+
source: "@oondemand/create-central-oon",
|
|
167
|
+
version: readPackageVersion(),
|
|
168
|
+
generatedAt: new Date().toISOString(),
|
|
169
|
+
docsMode: "generated-cache",
|
|
170
|
+
docsHash: docsHash(files),
|
|
171
|
+
files: files.map((file) => file.split(path.sep).join("/")),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function syncDocs(opts = {}) {
|
|
176
|
+
const root = resolveCentralRoot(opts.cwd);
|
|
177
|
+
const outDir = path.join(root, ".ooncore");
|
|
178
|
+
const docsOutDir = path.join(outDir, "docs");
|
|
179
|
+
const files = listDocFiles();
|
|
180
|
+
|
|
181
|
+
if (!files.length) {
|
|
182
|
+
throw new Error("Nenhum arquivo .md encontrado em packages/create-central-oon/docs.");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
186
|
+
removeDir(docsOutDir);
|
|
187
|
+
copyDocs(DOCS_DIR, docsOutDir);
|
|
188
|
+
|
|
189
|
+
const codexSource = path.join(DOCS_DIR, "CODEX.md");
|
|
190
|
+
if (fs.existsSync(codexSource)) {
|
|
191
|
+
fs.copyFileSync(codexSource, path.join(outDir, "CODEX.md"));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
fs.writeFileSync(path.join(outDir, "context.generated.md"), buildContext(files));
|
|
195
|
+
fs.writeFileSync(path.join(outDir, "manifest.json"), `${JSON.stringify(buildManifest(files), null, 2)}\n`);
|
|
196
|
+
|
|
197
|
+
console.log(`✔ Documentação OonCore sincronizada em ${path.relative(process.cwd(), outDir) || ".ooncore"}`);
|
|
198
|
+
console.log(` Versão: ${readPackageVersion()}`);
|
|
199
|
+
console.log(` Arquivos: ${files.length}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function checkDocs(opts = {}) {
|
|
203
|
+
const root = resolveCentralRoot(opts.cwd);
|
|
204
|
+
const manifestPath = path.join(root, ".ooncore", "manifest.json");
|
|
205
|
+
const version = readPackageVersion();
|
|
206
|
+
const files = listDocFiles();
|
|
207
|
+
const currentHash = docsHash(files);
|
|
208
|
+
|
|
209
|
+
if (!fs.existsSync(manifestPath)) {
|
|
210
|
+
throw new Error("Documentação OonCore local não encontrada. Rode `npm run ooncore:docs`.");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
214
|
+
const problems = [];
|
|
215
|
+
|
|
216
|
+
if (manifest.source !== "@oondemand/create-central-oon") {
|
|
217
|
+
problems.push(`fonte esperada @oondemand/create-central-oon, encontrada ${manifest.source || "(vazia)"}`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (manifest.version !== version) {
|
|
221
|
+
problems.push(`versão local ${manifest.version || "(vazia)"} diferente da instalada ${version}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (manifest.docsHash !== currentHash) {
|
|
225
|
+
problems.push("hash da documentação local diferente da documentação instalada");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (problems.length) {
|
|
229
|
+
throw new Error(`Documentação OonCore desatualizada:\n- ${problems.join("\n- ")}\nRode \`npm run ooncore:docs\`.`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
console.log(`✔ Documentação OonCore atualizada (versão ${version}).`);
|
|
233
|
+
}
|
|
234
|
+
|
|
55
235
|
async function run(opts) {
|
|
56
236
|
const template = TEMPLATES.find((t) => t.id === opts.template);
|
|
57
237
|
if (!template) {
|
|
@@ -81,13 +261,19 @@ async function run(opts) {
|
|
|
81
261
|
// 2. Overlay do template escolhido (vence sobre o _base).
|
|
82
262
|
copyTemplate(path.join(TEMPLATES_DIR, template.id), targetDir, tokens);
|
|
83
263
|
|
|
264
|
+
// 3. Contexto local para Codex derivado da documentação da versão instalada.
|
|
265
|
+
syncDocs({ cwd: targetDir });
|
|
266
|
+
|
|
84
267
|
console.log("✔ Arquivos gerados.");
|
|
85
268
|
|
|
86
269
|
if (opts.install) {
|
|
87
270
|
console.log("\n📦 Instalando dependências (best-effort)...");
|
|
271
|
+
const rootOk = fs.existsSync(path.join(targetDir, "package.json"))
|
|
272
|
+
? npmInstall(targetDir)
|
|
273
|
+
: true;
|
|
88
274
|
const backOk = npmInstall(path.join(targetDir, "backend"));
|
|
89
275
|
const frontOk = npmInstall(path.join(targetDir, "frontend"));
|
|
90
|
-
if (!backOk || !frontOk) {
|
|
276
|
+
if (!rootOk || !backOk || !frontOk) {
|
|
91
277
|
console.warn(
|
|
92
278
|
"\n⚠ npm install falhou em um dos projetos (esperado se os pacotes @oondemand/* ainda não foram publicados). Rode manualmente depois."
|
|
93
279
|
);
|
|
@@ -103,7 +289,11 @@ function printNextSteps(tokens, opts) {
|
|
|
103
289
|
✅ Central "${tokens.name}" pronta.
|
|
104
290
|
|
|
105
291
|
Próximos passos:
|
|
106
|
-
${cd} #
|
|
292
|
+
${cd} # Sincronizar/validar documentação local do Core para Codex
|
|
293
|
+
npm run ooncore:docs
|
|
294
|
+
npm run ooncore:docs:check
|
|
295
|
+
|
|
296
|
+
# Backend (só domínio — models/validations/triggers/...)
|
|
107
297
|
cd backend && cp .env.example .env && npm run dev
|
|
108
298
|
|
|
109
299
|
# Frontend (só declaração — central.ui.json)
|
|
@@ -114,4 +304,13 @@ Edite backend/src/models e frontend/central.ui.json para evoluir a Central.
|
|
|
114
304
|
`);
|
|
115
305
|
}
|
|
116
306
|
|
|
117
|
-
module.exports = {
|
|
307
|
+
module.exports = {
|
|
308
|
+
run,
|
|
309
|
+
listTemplates,
|
|
310
|
+
toSlug,
|
|
311
|
+
toPascal,
|
|
312
|
+
toTitle,
|
|
313
|
+
syncDocs,
|
|
314
|
+
checkDocs,
|
|
315
|
+
resolveCentralRoot,
|
|
316
|
+
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# __NAME__
|
|
2
2
|
|
|
3
|
-
Central Oon gerada com `create-central-oon`. É composta por dois projetos
|
|
4
|
-
mínimos que consomem o Core:
|
|
3
|
+
Central Oon gerada com `create-central-oon`. É composta por dois projetos mínimos que consomem o Core:
|
|
5
4
|
|
|
6
5
|
- **backend/** — só domínio (`src/models`, `validations`, `triggers`, …).
|
|
7
6
|
Sobe com `oonCore-back dev`. Toda a infra (boot, db, auth, RBAC, metadata,
|
|
@@ -10,9 +9,26 @@ mínimos que consomem o Core:
|
|
|
10
9
|
dev`. Shell, providers, roteamento, auth e telas vêm do
|
|
11
10
|
`@oondemand/oon-core-front`, renderizados a partir do `/core/metadata` do back.
|
|
12
11
|
|
|
12
|
+
## Documentação local do OonCore
|
|
13
|
+
|
|
14
|
+
A pasta `.ooncore/` é gerada automaticamente a partir da versão instalada do pacote `@oondemand/create-central-oon`.
|
|
15
|
+
|
|
16
|
+
Ela serve como contexto local para o Codex codificar sem depender de site externo.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run ooncore:docs # sincroniza .ooncore/
|
|
20
|
+
npm run ooncore:docs:check # valida versão/hash da documentação local
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Não edite `.ooncore/context.generated.md` manualmente. Atualize o pacote e rode o sync.
|
|
24
|
+
|
|
13
25
|
## Rodando
|
|
14
26
|
|
|
15
27
|
```bash
|
|
28
|
+
# raiz da Central
|
|
29
|
+
npm install
|
|
30
|
+
npm run ooncore:docs:check
|
|
31
|
+
|
|
16
32
|
# backend
|
|
17
33
|
cd backend && cp .env.example .env && npm install && npm run dev
|
|
18
34
|
|
|
@@ -24,4 +40,5 @@ cd frontend && cp .env.example .env && npm install && npm run dev
|
|
|
24
40
|
|
|
25
41
|
1. Crie models em `backend/src/models` (só schema + CRUD).
|
|
26
42
|
2. Declare as telas em `frontend/central.ui.json` (coleções/esteiras/documentos).
|
|
27
|
-
3.
|
|
43
|
+
3. Use validations, triggers, hooks, mappings e integrations para regras e processos.
|
|
44
|
+
4. O resto — grid, form, rotas, menu — é montado pelo Core automaticamente.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"sync:metadata": "oonCore-front sync:metadata"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@oondemand/oon-core-front": "^0.3.
|
|
13
|
+
"@oondemand/oon-core-front": "^0.3.9",
|
|
14
14
|
"@chakra-ui/react": "^3.13.0",
|
|
15
15
|
"@emotion/react": "^11.14.0",
|
|
16
16
|
"@tanstack/react-query": "^5.65.0",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__SLUG__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Central Oon __NAME__ gerada com create-central-oon.",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"ooncore:docs": "create-central-oon docs --sync",
|
|
8
|
+
"ooncore:docs:check": "create-central-oon docs --check",
|
|
9
|
+
"dev:backend": "npm run dev --prefix backend",
|
|
10
|
+
"dev:frontend": "npm run dev --prefix frontend"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@oondemand/create-central-oon": "^0.3.8"
|
|
14
|
+
}
|
|
15
|
+
}
|