@oondemand/create-central-oon 0.3.44 → 0.3.46
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 +88 -80
- package/bin/cli.js +30 -44
- package/package.json +11 -4
- package/schemas/central.app.schema.json +73 -0
- package/src/conformance.js +228 -0
- package/templates/_base/README.md +23 -22
- package/templates/_base/backend/central.config.js +4 -52
- package/templates/_base/backend/package.json +1 -1
- package/templates/_base/central.app.json +31 -0
- package/templates/_base/frontend/central.ui.json +1 -2
- package/templates/_base/frontend/package.json +1 -1
- package/templates/_base/frontend/src/main.tsx +4 -10
- package/templates/_base/frontend/vite.config.ts +4 -1
- package/templates/_base/package.json +3 -1
- package/templates/basic/frontend/central.ui.json +1 -2
- package/templates/documentos-fiscais/frontend/central.ui.json +1 -2
- package/templates/multi-moedas/frontend/central.ui.json +1 -2
- package/templates/omie-sidecar/frontend/central.ui.json +1 -2
- package/templates/pedidos-marketplace/frontend/central.ui.json +1 -2
- package/templates/servicos-prestados/frontend/central.ui.json +1 -2
- package/templates/servicos-tomados/frontend/central.ui.json +1 -2
package/README.md
CHANGED
|
@@ -1,133 +1,141 @@
|
|
|
1
1
|
# @oondemand/create-central-oon
|
|
2
2
|
|
|
3
|
-
Gerador de **Centrais Oon**. Cria
|
|
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
|
-
Toda Central gerada nasce com o padrão visual e operacional consolidado na **Central Minexco**:
|
|
8
|
-
|
|
9
|
-
- identidade visual Oon/CST com Poppins, azul `#0474AF` e fundo `#F8F9FA`;
|
|
10
|
-
- menu lateral compacto, responsivo e agrupado por seções;
|
|
11
|
-
- datagrids densos com busca, ordenação, paginação, badges e ações;
|
|
12
|
-
- formulários em diálogo, duas colunas e validação detalhada por campo;
|
|
13
|
-
- campos relacionados com seleção pesquisável;
|
|
14
|
-
- esteiras horizontais com colunas `#E8ECEF` e cartões operacionais brancos.
|
|
15
|
-
|
|
16
|
-
O padrão fica no `@oondemand/oon-core-front`; os templates funcionais apenas declaram domínio, coleções, documentos e esteiras. Assim, não é necessário copiar ou manter um frontend diferente para cada Central.
|
|
3
|
+
Gerador de **Centrais Oon declarativas**. Cria backend e frontend prontos para consumir `@oondemand/oon-core-back` e `@oondemand/oon-core-front`, sem copiar shell, autenticação, páginas genéricas ou infraestrutura para a Central.
|
|
17
4
|
|
|
18
5
|
## Uso
|
|
19
6
|
|
|
20
7
|
```bash
|
|
21
8
|
npx create-central-oon central-transtour
|
|
22
|
-
npx create-central-oon central-transtour --template=
|
|
23
|
-
npx create-central-oon "Minha Loja" --template=multi-moedas --no-install
|
|
9
|
+
npx create-central-oon central-transtour --template=servicos-tomados
|
|
24
10
|
npx create-central-oon --list
|
|
25
11
|
```
|
|
26
12
|
|
|
27
13
|
Aliases: o binário também responde por `scaffold-central-oon`.
|
|
28
14
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
15
|
+
## Contrato `central.app.json`
|
|
16
|
+
|
|
17
|
+
Toda Central gerada possui um manifesto raiz com identidade e capabilities:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"$schema": "./node_modules/@oondemand/create-central-oon/schemas/central.app.schema.json",
|
|
22
|
+
"schemaVersion": 1,
|
|
23
|
+
"id": "central-exemplo",
|
|
24
|
+
"name": "Central Exemplo",
|
|
25
|
+
"slug": "central-exemplo",
|
|
26
|
+
"appKind": "member-central",
|
|
27
|
+
"modules": {
|
|
28
|
+
"collections": true,
|
|
29
|
+
"documents": false,
|
|
30
|
+
"pipelines": false,
|
|
31
|
+
"integrations": false,
|
|
32
|
+
"omie": false,
|
|
33
|
+
"assistants": false,
|
|
34
|
+
"currencies": false
|
|
35
|
+
},
|
|
36
|
+
"capabilities": ["core.collections"],
|
|
37
|
+
"compatibility": {
|
|
38
|
+
"core": {
|
|
39
|
+
"minVersion": "0.3.45",
|
|
40
|
+
"maxVersionExclusive": "0.4.0"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
O schema versionado é publicado no pacote em:
|
|
44
47
|
|
|
45
48
|
```txt
|
|
46
|
-
|
|
49
|
+
@oondemand/create-central-oon/schemas/central.app.schema.json
|
|
47
50
|
```
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
Responsabilidades do manifesto:
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
├── manifest.json
|
|
57
|
-
└── docs/
|
|
58
|
-
```
|
|
54
|
+
- identidade estável (`id`, `name`, `slug`);
|
|
55
|
+
- perfil arquitetural (`appKind`);
|
|
56
|
+
- módulos e capabilities habilitados;
|
|
57
|
+
- faixa compatível do OonCore;
|
|
58
|
+
- metadados declarativos de ativação.
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
`backend/central.config.js` fica reservado a extensões excepcionais de runtime. Em Centrais `member-central` e `portal-cockpit`, identidade, módulos e autenticação não podem ser reintroduzidos nesse arquivo. O token local de desenvolvimento é validado pelo próprio OonCore por `DEV_TOKEN`.
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
## Verificação de conformidade
|
|
63
63
|
|
|
64
64
|
Na raiz da Central:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
npm run ooncore:
|
|
67
|
+
npm run ooncore:conformance
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
ou
|
|
70
|
+
ou:
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
|
-
npx create-central-oon
|
|
73
|
+
npx create-central-oon conformance
|
|
74
|
+
npx create-central-oon conformance --json
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
O comando falha quando encontra, entre outros desvios:
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
- ausência ou incompatibilidade de `central.app.json`;
|
|
80
|
+
- transformações ou registries no bootstrap do frontend;
|
|
81
|
+
- páginas genéricas e extensões executáveis locais;
|
|
82
|
+
- identidade ou autenticação reintroduzida em `central.config.js`;
|
|
83
|
+
- models técnicos de integração;
|
|
84
|
+
- workers, runtimes, locks, clients Omie ou registries locais;
|
|
85
|
+
- patches de métodos do Mongoose;
|
|
86
|
+
- arquivos com extensões fora da allowlist.
|
|
87
|
+
|
|
88
|
+
A CI de uma Central deve executar o comando antes do build e da publicação.
|
|
89
|
+
|
|
90
|
+
## Documentação interna para Codex
|
|
81
91
|
|
|
82
|
-
|
|
92
|
+
O pacote inclui documentação canônica em `docs/`. Ao criar uma Central, o CLI gera `.ooncore/` como cache local da documentação da versão instalada.
|
|
83
93
|
|
|
84
94
|
```bash
|
|
85
|
-
|
|
95
|
+
npm run ooncore:docs
|
|
96
|
+
npm run ooncore:docs:check
|
|
86
97
|
```
|
|
87
98
|
|
|
88
|
-
|
|
99
|
+
A pasta `.ooncore/` não é fonte de verdade; ela pode ser regenerada a partir do pacote npm.
|
|
89
100
|
|
|
90
101
|
## Templates funcionais
|
|
91
102
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `documentos-fiscais` | Documento fiscal com aprovação (`CoreDocument`). |
|
|
102
|
-
| `multi-moedas` | `Moeda` + `Cotacao` com o módulo currencies. |
|
|
103
|
+
| Template | O que gera |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `basic` | Uma coleção dinâmica (`Pessoa`). |
|
|
106
|
+
| `omie-sidecar` | Estrutura declarativa inicial para mapping Omie. |
|
|
107
|
+
| `servicos-tomados` | Prestadores e esteira por status. |
|
|
108
|
+
| `servicos-prestados` | Clientes e esteira por etapa. |
|
|
109
|
+
| `pedidos-marketplace` | Catálogo e esteira de pedidos. |
|
|
110
|
+
| `documentos-fiscais` | Documento fiscal com aprovação. |
|
|
111
|
+
| `multi-moedas` | Moedas e cotações. |
|
|
103
112
|
|
|
104
113
|
## Estrutura gerada
|
|
105
114
|
|
|
106
115
|
```txt
|
|
107
116
|
<central>/
|
|
108
|
-
├──
|
|
109
|
-
├── package.json
|
|
110
|
-
├── .ooncore/
|
|
111
|
-
├── backend/
|
|
112
|
-
│ ├── central.config.js
|
|
113
|
-
│ ├── central.
|
|
114
|
-
│ └── src/{
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
└── src/
|
|
119
|
-
├── main.tsx # startFromManifest(manifest, { apiBaseUrl })
|
|
120
|
-
└── {collections,documents,pipelines,dashboards,overrides}/
|
|
117
|
+
├── central.app.json # identidade, appKind, módulos e capabilities
|
|
118
|
+
├── package.json # docs, conformance e comandos locais
|
|
119
|
+
├── .ooncore/ # cache regenerável da documentação
|
|
120
|
+
├── backend/
|
|
121
|
+
│ ├── central.config.js # somente extensão excepcional de runtime
|
|
122
|
+
│ ├── central.domain.json # domínio declarativo
|
|
123
|
+
│ └── src/{validations,triggers,hooks,mappings,rules}/
|
|
124
|
+
└── frontend/
|
|
125
|
+
├── central.ui.json # telas, formulários, grids e esteiras
|
|
126
|
+
└── src/main.tsx # bootstrap mínimo gerado
|
|
121
127
|
```
|
|
122
128
|
|
|
123
|
-
|
|
129
|
+
O bootstrap gerado importa `central.app.json` e `central.ui.json` e chama `startCentralFromManifest`. Não deve transformar manifestos, registrar componentes padrão nem conhecer regras de um cliente.
|
|
130
|
+
|
|
131
|
+
## Próximos passos
|
|
124
132
|
|
|
125
133
|
```bash
|
|
126
134
|
cd <central>
|
|
127
|
-
npm run
|
|
135
|
+
npm run check
|
|
128
136
|
|
|
129
|
-
cd backend
|
|
137
|
+
cd backend && cp .env.example .env && npm run dev
|
|
130
138
|
cd ../frontend && cp .env.example .env && npm run dev
|
|
131
139
|
```
|
|
132
140
|
|
|
133
|
-
Evoluir a Central significa
|
|
141
|
+
Evoluir a Central significa declarar domínio, UI, mappings e regras específicas. O OonCore implementa como a aplicação funciona.
|
package/bin/cli.js
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* CLI do create-central-oon.
|
|
6
|
-
*
|
|
7
|
-
* npx create-central-oon <nome-da-central> [opções]
|
|
8
|
-
* npx create-central-oon docs --sync
|
|
9
|
-
* npx create-central-oon docs --check
|
|
10
|
-
*
|
|
11
|
-
* Opções:
|
|
12
|
-
* --template=<t> Template inicial (default: basic). Veja --list.
|
|
13
|
-
* --here Gera na pasta atual em vez de criar <nome>/.
|
|
14
|
-
* --force Sobrescreve pasta existente.
|
|
15
|
-
* --no-install Não roda npm install nos projetos gerados.
|
|
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.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
4
|
const { run, listTemplates, syncDocs, checkDocs } = require("../src/index");
|
|
5
|
+
const { checkConformance } = require("../src/conformance");
|
|
24
6
|
|
|
25
7
|
function parseArgs(argv) {
|
|
26
8
|
const opts = {
|
|
@@ -32,33 +14,29 @@ function parseArgs(argv) {
|
|
|
32
14
|
list: false,
|
|
33
15
|
docsSync: false,
|
|
34
16
|
docsCheck: false,
|
|
17
|
+
json: false,
|
|
18
|
+
root: undefined,
|
|
35
19
|
};
|
|
36
20
|
const positionals = [];
|
|
37
21
|
|
|
38
22
|
for (let i = 0; i < argv.length; i += 1) {
|
|
39
23
|
const arg = argv[i];
|
|
40
|
-
|
|
41
24
|
if (arg === "--here") opts.here = true;
|
|
42
25
|
else if (arg === "--force") opts.force = true;
|
|
43
26
|
else if (arg === "--no-install") opts.install = false;
|
|
44
27
|
else if (arg === "--list") opts.list = true;
|
|
45
28
|
else if (arg === "--sync") opts.docsSync = true;
|
|
46
29
|
else if (arg === "--check") opts.docsCheck = true;
|
|
30
|
+
else if (arg === "--json") opts.json = true;
|
|
31
|
+
else if (arg.startsWith("--root=")) opts.root = arg.slice("--root=".length);
|
|
32
|
+
else if (arg === "--root") { opts.root = argv[i + 1]; i += 1; }
|
|
47
33
|
else if (arg.startsWith("--template=")) opts.template = arg.slice("--template=".length);
|
|
48
|
-
else if (arg === "--template") {
|
|
49
|
-
|
|
50
|
-
i += 1;
|
|
51
|
-
} else if (!arg.startsWith("-")) {
|
|
52
|
-
positionals.push(arg);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (positionals[0] === "docs") {
|
|
57
|
-
opts.command = "docs";
|
|
58
|
-
} else {
|
|
59
|
-
opts.name = positionals[0];
|
|
34
|
+
else if (arg === "--template") { opts.template = argv[i + 1]; i += 1; }
|
|
35
|
+
else if (!arg.startsWith("-")) positionals.push(arg);
|
|
60
36
|
}
|
|
61
37
|
|
|
38
|
+
if (["docs", "conformance"].includes(positionals[0])) opts.command = positionals[0];
|
|
39
|
+
else opts.name = positionals[0];
|
|
62
40
|
return opts;
|
|
63
41
|
}
|
|
64
42
|
|
|
@@ -66,34 +44,42 @@ function printUsage() {
|
|
|
66
44
|
console.error("Uso:");
|
|
67
45
|
console.error(" npx create-central-oon <nome-da-central> [--template=basic]");
|
|
68
46
|
console.error(" npx create-central-oon --list");
|
|
69
|
-
console.error(" npx create-central-oon docs --sync");
|
|
70
|
-
console.error(" npx create-central-oon
|
|
47
|
+
console.error(" npx create-central-oon docs --sync|--check");
|
|
48
|
+
console.error(" npx create-central-oon conformance [--root .] [--json]");
|
|
71
49
|
}
|
|
72
50
|
|
|
73
51
|
async function main() {
|
|
74
52
|
const opts = parseArgs(process.argv.slice(2));
|
|
75
|
-
|
|
76
53
|
if (opts.list) {
|
|
77
54
|
console.log("Templates disponíveis:\n");
|
|
78
|
-
for (const
|
|
79
|
-
|
|
55
|
+
for (const template of listTemplates()) {
|
|
56
|
+
console.log(` ${template.id.padEnd(20)} ${template.description}`);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
80
59
|
}
|
|
81
60
|
|
|
82
61
|
try {
|
|
83
62
|
if (opts.command === "docs") {
|
|
84
|
-
if (opts.docsCheck)
|
|
85
|
-
|
|
86
|
-
} else {
|
|
87
|
-
syncDocs();
|
|
88
|
-
}
|
|
63
|
+
if (opts.docsCheck) checkDocs();
|
|
64
|
+
else syncDocs();
|
|
89
65
|
return;
|
|
90
66
|
}
|
|
91
|
-
|
|
67
|
+
if (opts.command === "conformance") {
|
|
68
|
+
const result = checkConformance({ cwd: opts.root || process.cwd() });
|
|
69
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
70
|
+
else if (result.ok) console.log(`✔ Central conforme (${result.filesChecked} arquivos verificados).`);
|
|
71
|
+
else {
|
|
72
|
+
console.error("✖ Conformidade da Central reprovada:");
|
|
73
|
+
for (const issue of result.issues) {
|
|
74
|
+
console.error(` - [${issue.code}] ${issue.path}: ${issue.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
process.exit(result.ok ? 0 : 1);
|
|
78
|
+
}
|
|
92
79
|
if (!opts.name) {
|
|
93
80
|
printUsage();
|
|
94
81
|
process.exit(1);
|
|
95
82
|
}
|
|
96
|
-
|
|
97
83
|
await run(opts);
|
|
98
84
|
} catch (err) {
|
|
99
85
|
console.error("\n✖", err.message);
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oondemand/create-central-oon",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.46",
|
|
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
|
|
9
|
+
"description": "Gerador de Centrais Oon com contratos declarativos, guardrails de conformidade e documentação interna para Codex.",
|
|
10
10
|
"main": "src/index.js",
|
|
11
11
|
"exports": {
|
|
12
|
-
".": "./src/index.js"
|
|
12
|
+
".": "./src/index.js",
|
|
13
|
+
"./conformance": "./src/conformance.js",
|
|
14
|
+
"./schemas/central.app.schema.json": "./schemas/central.app.schema.json"
|
|
13
15
|
},
|
|
14
16
|
"bin": {
|
|
15
17
|
"create-central-oon": "bin/cli.js",
|
|
@@ -19,9 +21,13 @@
|
|
|
19
21
|
"bin",
|
|
20
22
|
"src",
|
|
21
23
|
"templates",
|
|
24
|
+
"schemas",
|
|
22
25
|
"docs",
|
|
23
26
|
"README.md"
|
|
24
27
|
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "node --test"
|
|
30
|
+
},
|
|
25
31
|
"engines": {
|
|
26
32
|
"node": ">=18"
|
|
27
33
|
},
|
|
@@ -33,7 +39,8 @@
|
|
|
33
39
|
"create",
|
|
34
40
|
"generator",
|
|
35
41
|
"codex",
|
|
36
|
-
"docs"
|
|
42
|
+
"docs",
|
|
43
|
+
"conformance"
|
|
37
44
|
],
|
|
38
45
|
"license": "SEE LICENSE IN LICENSE",
|
|
39
46
|
"publishConfig": {
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://schemas.oondemand.com.br/central.app.v1.schema.json",
|
|
4
|
+
"title": "Oon Central App Manifest",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"id",
|
|
10
|
+
"name",
|
|
11
|
+
"slug",
|
|
12
|
+
"appKind",
|
|
13
|
+
"modules",
|
|
14
|
+
"capabilities",
|
|
15
|
+
"compatibility"
|
|
16
|
+
],
|
|
17
|
+
"properties": {
|
|
18
|
+
"$schema": { "type": "string" },
|
|
19
|
+
"schemaVersion": { "const": 1 },
|
|
20
|
+
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*$" },
|
|
21
|
+
"name": { "type": "string", "minLength": 1 },
|
|
22
|
+
"slug": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
|
23
|
+
"appKind": {
|
|
24
|
+
"enum": ["root-central", "member-central", "portal-cockpit"]
|
|
25
|
+
},
|
|
26
|
+
"modules": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"properties": {
|
|
30
|
+
"collections": { "type": "boolean" },
|
|
31
|
+
"documents": { "type": "boolean" },
|
|
32
|
+
"pipelines": { "type": "boolean" },
|
|
33
|
+
"integrations": { "type": "boolean" },
|
|
34
|
+
"omie": { "type": "boolean" },
|
|
35
|
+
"assistants": { "type": "boolean" },
|
|
36
|
+
"currencies": { "type": "boolean" }
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"capabilities": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"uniqueItems": true,
|
|
42
|
+
"items": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"pattern": "^[a-z][a-z0-9]*(?:[._:-][a-z0-9][a-z0-9-]*)+$"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"compatibility": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": false,
|
|
50
|
+
"required": ["core"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"core": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": ["minVersion"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"minVersion": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$" },
|
|
58
|
+
"maxVersionExclusive": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$" }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"activation": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"properties": {
|
|
67
|
+
"enabled": { "type": "boolean" },
|
|
68
|
+
"configurationVersion": { "type": "integer", "minimum": 1 },
|
|
69
|
+
"fields": { "type": "array" }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
|
|
6
|
+
const IGNORED_DIRS = new Set([".git", ".ooncore", "node_modules", "dist", "build", "coverage"]);
|
|
7
|
+
const EXECUTABLE_EXTENSIONS = new Set([".js", ".cjs", ".mjs", ".ts", ".tsx", ".jsx"]);
|
|
8
|
+
const TECHNICAL_MODEL_NAMES = new Set([
|
|
9
|
+
"IntegrationExecution",
|
|
10
|
+
"IntegrationOutbox",
|
|
11
|
+
"IntegrationInbox",
|
|
12
|
+
"WebhookInbox",
|
|
13
|
+
"ExecutionHistory",
|
|
14
|
+
"ProviderRegistry",
|
|
15
|
+
"DistributedLock",
|
|
16
|
+
"OmieConfiguracao",
|
|
17
|
+
"OmieCategoria",
|
|
18
|
+
"OmieContaCorrente",
|
|
19
|
+
"OmieBaixaPagamento",
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
function normalize(relativePath) {
|
|
23
|
+
return relativePath.split(path.sep).join("/");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function listFiles(root, current = root) {
|
|
27
|
+
const files = [];
|
|
28
|
+
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
29
|
+
if (entry.isDirectory() && IGNORED_DIRS.has(entry.name)) continue;
|
|
30
|
+
const absolute = path.join(current, entry.name);
|
|
31
|
+
if (entry.isDirectory()) files.push(...listFiles(root, absolute));
|
|
32
|
+
else if (entry.isFile()) files.push(normalize(path.relative(root, absolute)));
|
|
33
|
+
}
|
|
34
|
+
return files.sort();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function readText(root, relativePath) {
|
|
38
|
+
return fs.readFileSync(path.join(root, relativePath), "utf8");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function addIssue(issues, code, file, message) {
|
|
42
|
+
issues.push({ code, path: file, message });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function fallbackValidateAppManifest(manifest) {
|
|
46
|
+
const required = ["schemaVersion", "id", "name", "slug", "appKind", "modules", "capabilities", "compatibility"];
|
|
47
|
+
const missing = required.filter((key) => manifest?.[key] === undefined);
|
|
48
|
+
if (missing.length) throw new Error(`campos obrigatórios ausentes: ${missing.join(", ")}.`);
|
|
49
|
+
if (manifest.schemaVersion !== 1) throw new Error("schemaVersion deve ser 1.");
|
|
50
|
+
if (!Array.isArray(manifest.capabilities)) throw new Error("capabilities deve ser uma lista.");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function validateAppManifest(root, manifest) {
|
|
54
|
+
try {
|
|
55
|
+
const entry = require.resolve("@oondemand/oon-core-back", {
|
|
56
|
+
paths: [path.join(root, "backend"), root, __dirname],
|
|
57
|
+
});
|
|
58
|
+
const core = require(entry);
|
|
59
|
+
if (typeof core.validateAppManifest === "function") {
|
|
60
|
+
core.validateAppManifest(manifest);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error?.code !== "MODULE_NOT_FOUND") throw error;
|
|
65
|
+
}
|
|
66
|
+
fallbackValidateAppManifest(manifest);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function checkAppManifest(root, issues) {
|
|
70
|
+
const file = "central.app.json";
|
|
71
|
+
const absolute = path.join(root, file);
|
|
72
|
+
if (!fs.existsSync(absolute)) {
|
|
73
|
+
addIssue(issues, "APP_MANIFEST_REQUIRED", file, "central.app.json é obrigatório.");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
validateAppManifest(root, JSON.parse(readText(root, file)));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
const details = error?.issues?.length
|
|
80
|
+
? error.issues.map((item) => `${item.path}: ${item.message}`).join("; ")
|
|
81
|
+
: error.message;
|
|
82
|
+
addIssue(issues, "APP_MANIFEST_INVALID", file, details);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function checkBootstrap(root, files, issues) {
|
|
87
|
+
const file = files.find((candidate) => /^frontend\/src\/main\.(?:t|j)sx?$/.test(candidate));
|
|
88
|
+
if (!file) {
|
|
89
|
+
addIssue(issues, "FRONTEND_BOOTSTRAP_REQUIRED", "frontend/src/main.tsx", "bootstrap gerado não encontrado.");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const source = readText(root, file);
|
|
93
|
+
if (!/\bstart(?:Central)?FromManifest\b/.test(source)) {
|
|
94
|
+
addIssue(
|
|
95
|
+
issues,
|
|
96
|
+
"FRONTEND_BOOTSTRAP_INVALID",
|
|
97
|
+
file,
|
|
98
|
+
"deve iniciar o Core com startCentralFromManifest.",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
const forbidden = [
|
|
102
|
+
/structuredClone\s*\(/,
|
|
103
|
+
/\b(?:configure|prepare|transform)[A-Z_a-z0-9]*\s*\(/,
|
|
104
|
+
/\b(?:registry|pageComponents|cellRenderers|fieldRenderers|cardRenderers|layoutSlots)\b/,
|
|
105
|
+
/\.find\s*\(/,
|
|
106
|
+
/\.push\s*\(/,
|
|
107
|
+
/Object\.assign\s*\(/,
|
|
108
|
+
];
|
|
109
|
+
for (const pattern of forbidden) {
|
|
110
|
+
if (pattern.test(source)) {
|
|
111
|
+
addIssue(issues, "FRONTEND_BOOTSTRAP_TRANSFORM", file, `transform local detectado: ${pattern}.`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const localImports = [...source.matchAll(/from\s+["'](\.\.?\/[^"']+)["']/g)]
|
|
115
|
+
.map((match) => match[1])
|
|
116
|
+
.filter((value) => !value.endsWith(".json"));
|
|
117
|
+
if (localImports.length) {
|
|
118
|
+
addIssue(
|
|
119
|
+
issues,
|
|
120
|
+
"FRONTEND_BOOTSTRAP_LOCAL_CODE",
|
|
121
|
+
file,
|
|
122
|
+
`imports locais executáveis não permitidos: ${localImports.join(", ")}.`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const extraFrontendSources = files.filter(
|
|
127
|
+
(candidate) => candidate.startsWith("frontend/src/")
|
|
128
|
+
&& candidate !== file
|
|
129
|
+
&& candidate !== "frontend/src/vite-env.d.ts",
|
|
130
|
+
);
|
|
131
|
+
for (const extra of extraFrontendSources) {
|
|
132
|
+
addIssue(issues, "FRONTEND_LOCAL_EXTENSION", extra, "frontend declarativo deve manter somente o bootstrap gerado.");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function checkCentralConfig(root, files, issues) {
|
|
137
|
+
const file = files.find((candidate) => candidate === "backend/central.config.js");
|
|
138
|
+
if (!file) return;
|
|
139
|
+
const source = readText(root, file);
|
|
140
|
+
const forbiddenKeys = ["name", "slug", "appKind", "appCode", "appCodigo", "ecosystem", "activation", "modules", "capabilities", "auth"];
|
|
141
|
+
for (const key of forbiddenKeys) {
|
|
142
|
+
if (new RegExp(`\\b${key}\\s*:`).test(source)) {
|
|
143
|
+
addIssue(
|
|
144
|
+
issues,
|
|
145
|
+
"CENTRAL_CONFIG_BOUNDARY",
|
|
146
|
+
file,
|
|
147
|
+
`${key} deve ser declarado em central.app.json ou fornecido pelo Core.`,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function checkDomainManifest(root, issues) {
|
|
154
|
+
const file = "backend/central.domain.json";
|
|
155
|
+
if (!fs.existsSync(path.join(root, file))) return;
|
|
156
|
+
try {
|
|
157
|
+
const manifest = JSON.parse(readText(root, file));
|
|
158
|
+
for (const model of manifest.models || []) {
|
|
159
|
+
if (TECHNICAL_MODEL_NAMES.has(model.name) || /(?:Outbox|Inbox|Execution|Provider|Lock|Webhook|Omie)/i.test(model.name)) {
|
|
160
|
+
addIssue(issues, "TECHNICAL_MODEL", file, `model técnica não permitida na Central: ${model.name}.`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
addIssue(issues, "DOMAIN_MANIFEST_INVALID", file, error.message);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function checkExecutableFiles(root, files, issues) {
|
|
169
|
+
const suspiciousPath = /(?:^|\/)(?:workers?|runtime|registr(?:y|ies)|clients?|patches?|infrastructure|infra)(?:\/|\.)/i;
|
|
170
|
+
const omieClient = /(?:^|\/)(?:omie[-_.]?(?:client|http|service)|clients?\/omie)(?:\.|\/)/i;
|
|
171
|
+
const genericPage = /^frontend\/src\/(?:pages|components)\/(?:Core|Integration|Integracao|Settings|Configurac)/i;
|
|
172
|
+
const mongoosePatch = /mongoose\.(?:Model|Query|Document)\.prototype|\.prototype\.(?:save|updateOne|findOneAndUpdate)\s*=|patchMongoose/i;
|
|
173
|
+
const registryCode = /\b(?:pageComponents|cellRenderers|fieldRenderers|cardRenderers|actionRenderers|layoutSlots)\b/;
|
|
174
|
+
|
|
175
|
+
for (const file of files) {
|
|
176
|
+
if (!EXECUTABLE_EXTENSIONS.has(path.extname(file))) continue;
|
|
177
|
+
if (suspiciousPath.test(file)) addIssue(issues, "GENERIC_RUNTIME", file, "runtime/worker/registry local não permitido.");
|
|
178
|
+
if (omieClient.test(file)) addIssue(issues, "OMIE_CLIENT", file, "cliente Omie deve pertencer ao adaptador nativo do Core.");
|
|
179
|
+
if (genericPage.test(file)) addIssue(issues, "GENERIC_PAGE", file, "página genérica deve pertencer ao OonCore.");
|
|
180
|
+
|
|
181
|
+
const source = readText(root, file);
|
|
182
|
+
if (mongoosePatch.test(source)) addIssue(issues, "MONGOOSE_PATCH", file, "patch de Mongoose não permitido na Central.");
|
|
183
|
+
if (file !== "frontend/src/main.tsx" && file.startsWith("frontend/") && registryCode.test(source)) {
|
|
184
|
+
addIssue(issues, "LOCAL_REGISTRY", file, "registry de componentes padrão não permitido na Central.");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function checkAllowedExtensions(files, issues) {
|
|
190
|
+
const allowed = new Set([
|
|
191
|
+
"", ".json", ".md", ".txt", ".yml", ".yaml", ".js", ".cjs", ".mjs", ".ts", ".tsx", ".jsx",
|
|
192
|
+
".html", ".css", ".svg", ".png", ".jpg", ".jpeg", ".webp", ".ico", ".env", ".example", ".sh",
|
|
193
|
+
]);
|
|
194
|
+
for (const file of files) {
|
|
195
|
+
const base = path.basename(file);
|
|
196
|
+
if (base.startsWith(".env")) continue;
|
|
197
|
+
const extension = path.extname(file).toLowerCase();
|
|
198
|
+
if (!allowed.has(extension)) addIssue(issues, "FILE_EXTENSION", file, `extensão não permitida: ${extension || "(sem extensão)"}.`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function checkConformance({ cwd = process.cwd() } = {}) {
|
|
203
|
+
const root = path.resolve(cwd);
|
|
204
|
+
const files = listFiles(root);
|
|
205
|
+
const issues = [];
|
|
206
|
+
checkAppManifest(root, issues);
|
|
207
|
+
checkBootstrap(root, files, issues);
|
|
208
|
+
checkCentralConfig(root, files, issues);
|
|
209
|
+
checkDomainManifest(root, issues);
|
|
210
|
+
checkExecutableFiles(root, files, issues);
|
|
211
|
+
checkAllowedExtensions(files, issues);
|
|
212
|
+
return { ok: issues.length === 0, root, filesChecked: files.length, issues };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function assertConformance(options = {}) {
|
|
216
|
+
const result = checkConformance(options);
|
|
217
|
+
if (!result.ok) {
|
|
218
|
+
const error = new Error(
|
|
219
|
+
`Conformidade da Central reprovada:\n${result.issues.map((issue) => `- [${issue.code}] ${issue.path}: ${issue.message}`).join("\n")}`,
|
|
220
|
+
);
|
|
221
|
+
error.code = "OON_CONFORMANCE_FAILED";
|
|
222
|
+
error.issues = result.issues;
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = { checkConformance, assertConformance, listFiles };
|
|
@@ -1,44 +1,45 @@
|
|
|
1
1
|
# __NAME__
|
|
2
2
|
|
|
3
|
-
Central Oon gerada com `create-central-oon`.
|
|
3
|
+
Central Oon declarativa gerada com `create-central-oon`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
Sobe com `oonCore-back dev`. Toda a infra (boot, db, auth, RBAC, metadata,
|
|
7
|
-
CRUD, deploy) vem do `@oondemand/oon-core-back`.
|
|
8
|
-
- **frontend/** — só declaração (`central.ui.json`). Sobe com `oonCore-front
|
|
9
|
-
dev`. Shell, providers, roteamento, auth e telas vêm do
|
|
10
|
-
`@oondemand/oon-core-front`, renderizados a partir do `/core/metadata` do back.
|
|
5
|
+
## Fronteira arquitetural
|
|
11
6
|
|
|
12
|
-
|
|
7
|
+
- `central.app.json` declara identidade, `appKind`, módulos, capabilities e compatibilidade com o OonCore;
|
|
8
|
+
- `backend/central.domain.json` declara models e regras do domínio;
|
|
9
|
+
- `frontend/central.ui.json` declara telas, formulários, grids e esteiras;
|
|
10
|
+
- `backend/central.config.js` fica reservado a extensões excepcionais de runtime;
|
|
11
|
+
- `frontend/src/main.tsx` é um bootstrap gerado e não deve transformar manifestos.
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
Autenticação, shell, roteamento, RBAC, metadata, CRUD, páginas genéricas e infraestrutura pertencem ao OonCore.
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
## Documentação e conformidade
|
|
17
16
|
|
|
18
17
|
```bash
|
|
19
18
|
npm run ooncore:docs # sincroniza .ooncore/
|
|
20
|
-
npm run ooncore:docs:check # valida versão/hash
|
|
19
|
+
npm run ooncore:docs:check # valida versão/hash do cache local
|
|
20
|
+
npm run ooncore:conformance # valida a fronteira da Central
|
|
21
|
+
npm run check # executa os gates locais
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
A pasta `.ooncore/` é um cache regenerável da documentação publicada no pacote. Não edite `context.generated.md` manualmente.
|
|
24
25
|
|
|
25
26
|
## Rodando
|
|
26
27
|
|
|
27
28
|
```bash
|
|
28
|
-
# raiz da Central
|
|
29
29
|
npm install
|
|
30
|
-
npm run
|
|
30
|
+
npm run check
|
|
31
31
|
|
|
32
|
-
# backend
|
|
33
32
|
cd backend && cp .env.example .env && npm install && npm run dev
|
|
34
|
-
|
|
35
|
-
# frontend (noutro terminal)
|
|
36
|
-
cd frontend && cp .env.example .env && npm install && npm run dev
|
|
33
|
+
cd ../frontend && cp .env.example .env && npm install && npm run dev
|
|
37
34
|
```
|
|
38
35
|
|
|
36
|
+
Em desenvolvimento, configure o mesmo valor em `DEV_TOKEN` no backend e `VITE_DEV_TOKEN` no frontend. A validação do token local é fornecida pelo Core; não implemente `auth.verifyToken` na Central.
|
|
37
|
+
|
|
39
38
|
## Evoluindo a Central
|
|
40
39
|
|
|
41
|
-
1.
|
|
42
|
-
2. Declare
|
|
43
|
-
3. Use
|
|
44
|
-
4.
|
|
40
|
+
1. Declare domínio e fórmulas em `backend/central.domain.json`.
|
|
41
|
+
2. Declare telas em `frontend/central.ui.json`.
|
|
42
|
+
3. Use validações, triggers, hooks, mappings e regras somente para comportamento específico do negócio.
|
|
43
|
+
4. Execute `npm run check` antes de abrir o PR.
|
|
44
|
+
|
|
45
|
+
O OonCore implementa como a aplicação funciona; a Central declara o que pertence ao negócio.
|
|
@@ -1,54 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Extensões exclusivamente de runtime da Central __NAME__.
|
|
3
|
+
* Identidade, appKind, módulos, capabilities e ativação vivem em
|
|
4
|
+
* ../central.app.json. Autenticação local é fornecida pelo OonCore.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
// Em desenvolvimento, aceita o DEV_TOKEN sem chamar o Meus Apps.
|
|
8
|
-
// Para usar: acesse http://localhost:5173/?code=<DEV_TOKEN>
|
|
9
|
-
const devAuth =
|
|
10
|
-
process.env.NODE_ENV === "development" && process.env.DEV_TOKEN
|
|
11
|
-
? {
|
|
12
|
-
verifyToken: async (token) => {
|
|
13
|
-
if (token !== process.env.DEV_TOKEN) {
|
|
14
|
-
const err = new Error("Token inválido.");
|
|
15
|
-
err.statusCode = 401;
|
|
16
|
-
throw err;
|
|
17
|
-
}
|
|
18
|
-
return { tipo: "admin", nome: "Dev Local", email: "dev@local" };
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
: undefined;
|
|
22
|
-
|
|
23
|
-
module.exports = {
|
|
24
|
-
ecosystem: { role: "member" },
|
|
25
|
-
activation: { enabled: true, configurationVersion: 1, fields: [] },
|
|
26
|
-
name: "__NAME__",
|
|
27
|
-
slug: "__SLUG__",
|
|
28
|
-
|
|
29
|
-
auth: devAuth,
|
|
30
|
-
|
|
31
|
-
// Módulos opinativos do Core ligados nesta Central.
|
|
32
|
-
modules: {
|
|
33
|
-
collections: true,
|
|
34
|
-
documents: false,
|
|
35
|
-
pipelines: false,
|
|
36
|
-
integrations: false,
|
|
37
|
-
omie: false,
|
|
38
|
-
assistants: false,
|
|
39
|
-
currencies: false,
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
// Paths de domínio (carregados por convenção pelo Core no boot).
|
|
43
|
-
domain: {
|
|
44
|
-
models: "src/models",
|
|
45
|
-
validations: "src/validations",
|
|
46
|
-
triggers: "src/triggers",
|
|
47
|
-
hooks: "src/hooks",
|
|
48
|
-
mappings: "src/mappings",
|
|
49
|
-
documents: "src/documents",
|
|
50
|
-
pipelines: "src/pipelines",
|
|
51
|
-
integrations: "src/integrations",
|
|
52
|
-
routes: "src/routes",
|
|
53
|
-
},
|
|
54
|
-
};
|
|
6
|
+
module.exports = {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/@oondemand/create-central-oon/schemas/central.app.schema.json",
|
|
3
|
+
"schemaVersion": 1,
|
|
4
|
+
"id": "__SLUG__",
|
|
5
|
+
"name": "__NAME__",
|
|
6
|
+
"slug": "__SLUG__",
|
|
7
|
+
"appKind": "member-central",
|
|
8
|
+
"modules": {
|
|
9
|
+
"collections": true,
|
|
10
|
+
"documents": false,
|
|
11
|
+
"pipelines": false,
|
|
12
|
+
"integrations": false,
|
|
13
|
+
"omie": false,
|
|
14
|
+
"assistants": false,
|
|
15
|
+
"currencies": false
|
|
16
|
+
},
|
|
17
|
+
"capabilities": [
|
|
18
|
+
"core.collections"
|
|
19
|
+
],
|
|
20
|
+
"compatibility": {
|
|
21
|
+
"core": {
|
|
22
|
+
"minVersion": "0.3.45",
|
|
23
|
+
"maxVersionExclusive": "0.4.0"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"activation": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"configurationVersion": 1,
|
|
29
|
+
"fields": []
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -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.46",
|
|
14
14
|
"@chakra-ui/react": "^3.13.0",
|
|
15
15
|
"@emotion/react": "^11.14.0",
|
|
16
16
|
"@tanstack/react-query": "^5.65.0",
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { startCentralFromManifest } from "@oondemand/oon-core-front";
|
|
2
|
+
import app from "../../central.app.json";
|
|
3
|
+
import ui from "../central.ui.json";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
* Toda a Central __NAME__ inicia por aqui. Sem providers, router, auth, layout
|
|
6
|
-
* ou páginas — só o manifesto declarativo `central.ui.json`. O Core resolve as
|
|
7
|
-
* telas a partir do `/core/metadata` do backend.
|
|
8
|
-
*/
|
|
9
|
-
startFromManifest(manifest, {
|
|
5
|
+
startCentralFromManifest({ app, ui }, {
|
|
10
6
|
apiBaseUrl: import.meta.env.VITE_API_URL ?? "http://localhost:4000",
|
|
11
7
|
meusAppsUrl: import.meta.env.VITE_MEUS_APPS_URL,
|
|
12
|
-
// O valor só entra no bundle servido pelo Vite em modo de desenvolvimento.
|
|
13
|
-
// O backend continua validando se ele coincide com DEV_TOKEN.
|
|
14
8
|
devToken: import.meta.env.DEV ? (import.meta.env.VITE_DEV_TOKEN ?? "dev-local") : undefined,
|
|
15
9
|
});
|
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"ooncore:docs": "create-central-oon docs --sync",
|
|
8
8
|
"ooncore:docs:check": "create-central-oon docs --check",
|
|
9
|
+
"ooncore:conformance": "create-central-oon conformance",
|
|
10
|
+
"check": "npm run ooncore:docs:check && npm run ooncore:conformance",
|
|
9
11
|
"dev:backend": "npm run dev --prefix backend",
|
|
10
12
|
"dev:frontend": "npm run dev --prefix frontend"
|
|
11
13
|
},
|
|
12
14
|
"devDependencies": {
|
|
13
|
-
"@oondemand/create-central-oon": "
|
|
15
|
+
"@oondemand/create-central-oon": "0.3.45"
|
|
14
16
|
}
|
|
15
17
|
}
|