@oondemand/create-central-oon 0.7.4 → 0.7.6
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 +18 -14
- package/bin/cli.js +12 -2
- package/docs/AGENTS.md +12 -56
- package/docs/AGENT_WORKFLOW.md +8 -15
- package/docs/BACKEND_API.md +5 -5
- package/docs/BACKEND_DOMAIN_MANIFEST.md +1 -1
- package/docs/CAPABILITIES.md +11 -3
- package/docs/CHECKLIST_IMPLEMENTACAO.md +4 -5
- package/docs/CORE_UPGRADE.md +17 -14
- package/docs/ERRORS.md +1 -1
- package/docs/EXECUTABLE_EXAMPLE.md +42 -0
- package/docs/NATIVE_RESOURCES.md +94 -0
- package/docs/OON_APP_AGENT_GUIDE.md +26 -45
- package/docs/PDF_RENDERING.md +2 -3
- package/docs/PUBLIC_CONTRACTS.md +124 -0
- package/docs/RBAC_SECURITY.md +1 -1
- package/docs/ROUTES_HOOKS_WORKERS.md +19 -8
- package/docs/SECRETS.md +54 -0
- package/docs/TASK_EXAMPLES.md +134 -0
- package/docs/TASK_INDEX.md +36 -0
- package/docs/TESTING_CONFORMANCE.md +12 -19
- package/docs/TRANSACTIONAL_EMAIL.md +1 -1
- package/examples/first-journey/FIRST_JOURNEY.md +27 -0
- package/examples/first-journey/backend/central.domain.json +141 -0
- package/examples/first-journey/backend/central.process.json +105 -0
- package/examples/first-journey/backend/emails/confirmacao.json +12 -0
- package/examples/first-journey/backend/src/models/Documento.js +9 -0
- package/examples/first-journey/backend/src/models/Pessoa.js +6 -0
- package/examples/first-journey/backend/src/routes/integracao.js +23 -0
- package/examples/first-journey/backend/src/routes/jornada.js +10 -0
- package/examples/first-journey/backend/src/routes/recursos.js +26 -0
- package/examples/first-journey/backend/src/routes/segredos.js +27 -0
- package/examples/first-journey/backend/src/services/confirmacao.js +11 -0
- package/examples/first-journey/frontend/src/pages/JourneyPage.tsx +32 -0
- package/examples/first-journey/frontend/src/pages/NativeResourcesPage.tsx +50 -0
- package/examples/first-journey/frontend/src/pages/SecretsPage.tsx +31 -0
- package/package.json +3 -2
- package/schemas/central.app.schema.json +12 -0
- package/src/doctor.js +90 -0
- package/src/example.js +39 -0
- package/src/index.js +31 -16
- package/templates/_base/README.md +17 -46
- package/templates/_base/backend/package.json +1 -1
- package/templates/_base/frontend/package.json +1 -1
- package/templates/_base/frontend/src/app/app.tsx +2 -2
- package/templates/_base/frontend/src/pages/HomePage.tsx +3 -3
- package/templates/_base/package.json +2 -2
package/src/example.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { resolveCentralRoot } = require("./index");
|
|
5
|
+
const { listFiles } = require("./conformance");
|
|
6
|
+
|
|
7
|
+
// Explicit opt-in after generating the canonical base. Never overwrite an App.
|
|
8
|
+
function installExample({ cwd = process.cwd() } = {}) {
|
|
9
|
+
const root = resolveCentralRoot(cwd);
|
|
10
|
+
const source = path.join(__dirname, "../examples/first-journey");
|
|
11
|
+
const files = listFiles(source);
|
|
12
|
+
const manifestPath = path.join(root, "central.app.json");
|
|
13
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
14
|
+
if (manifest.tenancyModel !== "single_tenant" || manifest.deploymentMode !== "dedicated") throw new Error("Exemplo requer single_tenant dedicado da base oficial.");
|
|
15
|
+
for (const file of files) {
|
|
16
|
+
if (fs.existsSync(path.join(root, file))) throw new Error(`Exemplo não sobrescreve ${file}. Use um App recém-gerado.`);
|
|
17
|
+
}
|
|
18
|
+
const composition = ["routes.tsx", "navigation.ts"];
|
|
19
|
+
for (const name of composition) {
|
|
20
|
+
const relative = `frontend/src/app/${name}`;
|
|
21
|
+
const base = fs.readFileSync(path.join(__dirname, "../templates/_base", relative), "utf8");
|
|
22
|
+
if (fs.readFileSync(path.join(root, relative), "utf8") !== base) throw new Error(`Exemplo requer composição original: ${relative}. Nenhum arquivo foi alterado.`);
|
|
23
|
+
}
|
|
24
|
+
manifest.capabilities = [...new Set([...manifest.capabilities, "core.secrets"])];
|
|
25
|
+
manifest.capabilitySettings = { ...manifest.capabilitySettings, "core.secrets": { enabled: true } };
|
|
26
|
+
const permissions = ["segredos.manage", "pessoas.read", "pessoas.write", "tickets.read", "tickets.write", "jornada.write", "integracao.test", "contratos.read", "contratos.write", "parcelas.read", "parcelas.write", "documentos.read", "documentos.write", "pdf.render"];
|
|
27
|
+
manifest.rbac.permissions = [...new Set([...manifest.rbac.permissions, ...permissions])];
|
|
28
|
+
for (const file of files) {
|
|
29
|
+
fs.mkdirSync(path.dirname(path.join(root, file)), { recursive: true });
|
|
30
|
+
fs.copyFileSync(path.join(source, file), path.join(root, file));
|
|
31
|
+
}
|
|
32
|
+
const routes = path.join(root, "frontend/src/app/routes.tsx");
|
|
33
|
+
fs.writeFileSync(routes, fs.readFileSync(routes, "utf8").replace('import { HomePage }', 'import { SecretsPage } from "../pages/SecretsPage";\nimport { NativeResourcesPage } from "../pages/NativeResourcesPage";\nimport { JourneyPage } from "../pages/JourneyPage";\nimport { HomePage }').replace(' { path: "/", component: HomePage },', ' { path: "/", component: HomePage },\n { path: "/jornada", component: JourneyPage },\n { path: "/recursos", component: NativeResourcesPage },\n { path: "/segredos", component: SecretsPage },'));
|
|
34
|
+
const navigation = path.join(root, "frontend/src/app/navigation.ts");
|
|
35
|
+
fs.writeFileSync(navigation, fs.readFileSync(navigation, "utf8").replace(' { label: "Início", href: "/", order: 10 },', ' { label: "Início", href: "/", order: 10 },\n { label: "Primeira jornada", href: "/jornada", order: 20 },\n { label: "Recursos nativos", href: "/recursos", order: 30 },\n { label: "Segredos", href: "/segredos", order: 40 },'));
|
|
36
|
+
fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
37
|
+
console.log("Exemplo instalado em /jornada, com navegação, endpoints e permissões. Siga FIRST_JOURNEY.md.");
|
|
38
|
+
}
|
|
39
|
+
module.exports = { installExample };
|
package/src/index.js
CHANGED
|
@@ -47,6 +47,21 @@ function readPackageVersion() {
|
|
|
47
47
|
return pkg.version;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
// Documentation examples follow the installed release, including docs sync/check.
|
|
51
|
+
// Hash the rendered bytes so consumers can verify the exact generated cache.
|
|
52
|
+
function renderDoc(content) {
|
|
53
|
+
const version = readPackageVersion();
|
|
54
|
+
const [major, minor] = version.split(".").map(Number);
|
|
55
|
+
return content
|
|
56
|
+
.replace(/__OONCORE_VERSION__/g, version)
|
|
57
|
+
.replace(/__OONCORE_LINE__/g, `${major}.${minor}`)
|
|
58
|
+
.replace(/__OONCORE_RANGE__/g, `>=${major}.${minor}.0 <${major}.${minor + 1}.0`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function readDoc(file) {
|
|
62
|
+
return renderDoc(fs.readFileSync(path.join(DOCS_DIR, file), "utf8"));
|
|
63
|
+
}
|
|
64
|
+
|
|
50
65
|
function listDocFiles(dir = DOCS_DIR, prefix = "") {
|
|
51
66
|
if (!fs.existsSync(dir)) return [];
|
|
52
67
|
const files = [];
|
|
@@ -71,7 +86,7 @@ function docsHash(files = listDocFiles()) {
|
|
|
71
86
|
const normalized = file.split(path.sep).join("/");
|
|
72
87
|
hash.update(normalized);
|
|
73
88
|
hash.update("\n");
|
|
74
|
-
hash.update(
|
|
89
|
+
hash.update(readDoc(file));
|
|
75
90
|
hash.update("\n");
|
|
76
91
|
}
|
|
77
92
|
return hash.digest("hex");
|
|
@@ -95,9 +110,9 @@ function rootAgentEntrypoint() {
|
|
|
95
110
|
return [
|
|
96
111
|
"# OonCore — entrada para IA/Agents",
|
|
97
112
|
"",
|
|
98
|
-
"Leia
|
|
113
|
+
"Leia a entrada curta em [docs/AGENTS.md](docs/AGENTS.md) e consulte apenas a tarefa necessária.",
|
|
99
114
|
"",
|
|
100
|
-
"
|
|
115
|
+
"Execute \`npm run check\` para validar cache e conformidade; regenere o cache somente pelo comando oficial.",
|
|
101
116
|
"",
|
|
102
117
|
].join("\n");
|
|
103
118
|
}
|
|
@@ -105,7 +120,7 @@ function rootAgentEntrypoint() {
|
|
|
105
120
|
function entrypointContents(files = listDocFiles()) {
|
|
106
121
|
return {
|
|
107
122
|
"AGENTS.md": rootAgentEntrypoint(),
|
|
108
|
-
"CODEX.md":
|
|
123
|
+
"CODEX.md": readDoc("CODEX.md"),
|
|
109
124
|
"context.generated.md": buildContext(files),
|
|
110
125
|
};
|
|
111
126
|
}
|
|
@@ -168,7 +183,9 @@ function copyDocs(srcDir, destDir) {
|
|
|
168
183
|
if (entry.isDirectory()) {
|
|
169
184
|
copyDocs(from, to);
|
|
170
185
|
} else if (entry.isFile()) {
|
|
171
|
-
fs.
|
|
186
|
+
fs.writeFileSync(to, entry.name.endsWith(".md")
|
|
187
|
+
? renderDoc(fs.readFileSync(from, "utf8"))
|
|
188
|
+
: fs.readFileSync(from));
|
|
172
189
|
}
|
|
173
190
|
}
|
|
174
191
|
}
|
|
@@ -180,14 +197,14 @@ function buildContext(files = listDocFiles()) {
|
|
|
180
197
|
"> Arquivo gerado automaticamente por `create-central-oon docs sync`.",
|
|
181
198
|
"> Não edite manualmente. A fonte de verdade está no pacote `@oondemand/create-central-oon` instalado.",
|
|
182
199
|
"",
|
|
183
|
-
"
|
|
200
|
+
"Compilação opcional para consulta. Comece por docs/OON_APP_AGENT_GUIDE.md e docs/TASK_INDEX.md; não é necessário ler este arquivo inteiro.",
|
|
184
201
|
"",
|
|
185
202
|
].join("\n");
|
|
186
203
|
|
|
187
204
|
const sections = files
|
|
188
205
|
.map((file) => {
|
|
189
206
|
const normalized = file.split(path.sep).join("/");
|
|
190
|
-
const content =
|
|
207
|
+
const content = readDoc(file).trim();
|
|
191
208
|
return [
|
|
192
209
|
"---",
|
|
193
210
|
"",
|
|
@@ -232,7 +249,7 @@ function syncDocs(opts = {}) {
|
|
|
232
249
|
|
|
233
250
|
fs.writeFileSync(path.join(outDir, "AGENTS.md"), rootAgentEntrypoint());
|
|
234
251
|
const codexSource = path.join(DOCS_DIR, "CODEX.md");
|
|
235
|
-
if (fs.existsSync(codexSource)) fs.
|
|
252
|
+
if (fs.existsSync(codexSource)) fs.writeFileSync(path.join(outDir, "CODEX.md"), readDoc("CODEX.md"));
|
|
236
253
|
|
|
237
254
|
fs.writeFileSync(path.join(outDir, "context.generated.md"), buildContext(files));
|
|
238
255
|
fs.writeFileSync(path.join(outDir, "manifest.json"), `${JSON.stringify(buildManifest(files), null, 2)}\n`);
|
|
@@ -299,7 +316,7 @@ function checkDocs(opts = {}) {
|
|
|
299
316
|
throw new Error(`Documentação OonCore desatualizada:\n- ${problems.join("\n- ")}\nRode \`npm run ooncore:docs\`.`);
|
|
300
317
|
}
|
|
301
318
|
|
|
302
|
-
console.log(`✔ Documentação OonCore atualizada (versão ${version}).`);
|
|
319
|
+
if (!opts.quiet) console.log(`✔ Documentação OonCore atualizada (versão ${version}).`);
|
|
303
320
|
}
|
|
304
321
|
|
|
305
322
|
async function run(opts) {
|
|
@@ -350,15 +367,13 @@ function printNextSteps(tokens, opts) {
|
|
|
350
367
|
✅ Central "${tokens.name}" pronta.
|
|
351
368
|
|
|
352
369
|
Próximos passos:
|
|
353
|
-
${cd} #
|
|
354
|
-
|
|
355
|
-
npm run ooncore:docs:check
|
|
356
|
-
|
|
357
|
-
# Runtime local desconectado (backend + frontend)
|
|
370
|
+
${cd} # Instale as dependências se usou --no-install ou se a instalação falhou.
|
|
371
|
+
# Configure MongoDB e os .env conforme README.md.
|
|
358
372
|
npm run dev
|
|
359
373
|
|
|
360
|
-
|
|
361
|
-
|
|
374
|
+
Siga .ooncore/docs/OON_APP_AGENT_GUIDE.md: gerar, executar, implementar uma
|
|
375
|
+
jornada, validar e publicar pelo fluxo existente. Para alterar, consulte
|
|
376
|
+
.ooncore/docs/TASK_INDEX.md. npm run check valida cache e conformidade.
|
|
362
377
|
`);
|
|
363
378
|
}
|
|
364
379
|
|
|
@@ -1,62 +1,33 @@
|
|
|
1
1
|
# __NAME__
|
|
2
2
|
|
|
3
|
-
App Oon code-first gerado com `create-central-oon`.
|
|
3
|
+
App Oon code-first gerado com `create-central-oon`. Comece pela entrada curta `.ooncore/AGENTS.md` e pelo roteiro `.ooncore/docs/OON_APP_AGENT_GUIDE.md`; escolha referências em `.ooncore/docs/TASK_INDEX.md` conforme a tarefa. Não é necessário ler o contexto consolidado nem fonte privada.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Executar
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
1. Leia `.ooncore/AGENTS.md`.
|
|
10
|
-
2. Rode `npm run ooncore:docs:check`.
|
|
11
|
-
3. Siga `.ooncore/docs/OON_APP_AGENT_GUIDE.md`.
|
|
12
|
-
4. Consulte `.ooncore/docs/CAPABILITIES.md` e o guia específico da tarefa.
|
|
13
|
-
|
|
14
|
-
Se faltar um contrato, registre a lacuna documental em vez de inventar API ou infraestrutura.
|
|
15
|
-
|
|
16
|
-
## Fronteira arquitetural
|
|
17
|
-
|
|
18
|
-
- `central.app.json` declara identidade, `appKind`, tenant, acesso, módulos, capabilities funcionais e compatibilidade;
|
|
19
|
-
- `oon.deploy.json` declara runtime e dependências de infraestrutura da publicação;
|
|
20
|
-
- `backend/src/models` e demais extensões code-first contêm o domínio;
|
|
21
|
-
- `backend/central.domain.json` é opcional quando o projeto adota o contrato declarativo documentado;
|
|
22
|
-
- `frontend/src/app` compõe rotas, navegação, layouts e temas;
|
|
23
|
-
- `frontend/src/{pages,components,features}` contém a experiência local;
|
|
24
|
-
- `backend/central.config.js` fica reservado a extensões documentadas de runtime;
|
|
25
|
-
- `frontend/src/main.tsx` chama `startOonApp`.
|
|
26
|
-
|
|
27
|
-
Autenticação, guards, shell, RBAC, metadata, CRUD e infraestrutura pertencem ao OonCore.
|
|
28
|
-
|
|
29
|
-
## Documentação e conformidade
|
|
7
|
+
Requer Node compatível com os pacotes e MongoDB local. Ajuste `MONGO_URI` para um banco de desenvolvimento.
|
|
30
8
|
|
|
31
9
|
```bash
|
|
32
|
-
npm
|
|
33
|
-
npm
|
|
34
|
-
npm
|
|
35
|
-
|
|
36
|
-
|
|
10
|
+
npm install
|
|
11
|
+
npm install --prefix backend
|
|
12
|
+
npm install --prefix frontend
|
|
13
|
+
cp backend/.env.example backend/.env
|
|
14
|
+
cp frontend/.env.example frontend/.env
|
|
15
|
+
npm run dev
|
|
37
16
|
```
|
|
38
17
|
|
|
39
|
-
|
|
18
|
+
O runtime local funciona em loopback com sessão técnica; não cadastra recursos na Plataforma. Capabilities dependentes da Plataforma falham fechado quando indisponíveis.
|
|
19
|
+
|
|
20
|
+
## Entregar a primeira jornada
|
|
40
21
|
|
|
41
|
-
|
|
22
|
+
Implemente página, navegação, endpoint e permissão usando `.ooncore/docs/PUBLIC_CONTRACTS.md`. Domínio fica em `backend/src`; `backend/central.domain.json` é opcional. Composição de UX fica em `frontend/src/app` e `frontend/src/pages`. `central.app.json` declara identidade e acesso; `oon.deploy.json` declara requisitos de publicação.
|
|
42
23
|
|
|
43
24
|
```bash
|
|
44
|
-
npm install
|
|
45
25
|
npm run check
|
|
46
|
-
|
|
47
|
-
cp backend/.env.example backend/.env
|
|
48
|
-
cp frontend/.env.example frontend/.env
|
|
49
|
-
npm run dev
|
|
26
|
+
npm run build --prefix frontend
|
|
50
27
|
```
|
|
51
28
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## Evoluindo a Central
|
|
29
|
+
`check` inclui cache documental e conformance. Execute os testes relevantes quando declarados; a base neutra não contém script raiz `test`. Prove a jornada, versione código/manifestos/lockfiles/cache e publique pelo fluxo existente do Workspace/Plataforma. Registre o commit e a validação autenticada em Dev. Build, publicação e homologação são estados distintos.
|
|
55
30
|
|
|
56
|
-
|
|
57
|
-
2. Crie rotas, páginas, componentes, layouts e temas nos pontos documentados.
|
|
58
|
-
3. Declare capabilities no manifesto indicado pelo guia dedicado.
|
|
59
|
-
4. Use validações, triggers, hooks, mappings e regras somente para comportamento específico do negócio.
|
|
60
|
-
5. Execute `npm run check` e `npm test` antes de abrir o PR.
|
|
31
|
+
Lacuna documental: registre, use extensão pública adequada no App e continue as partes independentes; não invente APIs nem remova autenticação, autorização ou isolamento. POC não exige roadmap completo nem matriz final de perfis. Não reimplemente nem homologue novamente os serviços já homologados da Plataforma.
|
|
61
32
|
|
|
62
|
-
|
|
33
|
+
`.ooncore/` é cache gerado: atualize a fonte do pacote e use `npm run ooncore:docs`; nunca edite manualmente. Upgrade coordenado está em `.ooncore/docs/CORE_UPGRADE.md`.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"sync:metadata": "oonCore-front sync:metadata"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@oondemand/oon-core-front": "^0.7.
|
|
14
|
+
"@oondemand/oon-core-front": "^0.7.6",
|
|
15
15
|
"@chakra-ui/react": "^3.13.0",
|
|
16
16
|
"@emotion/react": "^11.14.0",
|
|
17
17
|
"@tanstack/react-query": "^5.65.0",
|
|
@@ -18,8 +18,8 @@ export const app = defineOonApp({
|
|
|
18
18
|
meusAppsUrl: import.meta.env.DEV ? undefined : import.meta.env.VITE_MEUS_APPS_URL,
|
|
19
19
|
},
|
|
20
20
|
runtimeMode: import.meta.env.DEV ? "local" : "platform",
|
|
21
|
-
routes,
|
|
22
|
-
navigation,
|
|
21
|
+
routes: [...routes],
|
|
22
|
+
navigation: [...navigation],
|
|
23
23
|
theme,
|
|
24
24
|
shell: { shell: "default" },
|
|
25
25
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Stack, Text } from "@chakra-ui/react";
|
|
2
|
-
import {
|
|
2
|
+
import { CorePageHeader, CoreStatusPanel, CoreSummaryCards } from "@oondemand/oon-core-front/ui";
|
|
3
3
|
|
|
4
4
|
export function HomePage() {
|
|
5
5
|
return (
|
|
6
|
-
<
|
|
6
|
+
<Stack gap={6} p={6}>
|
|
7
7
|
<CorePageHeader
|
|
8
8
|
title="Boas-vindas ao __NAME__"
|
|
9
9
|
description="A fundação técnica está pronta para receber a experiência e o domínio do app."
|
|
@@ -20,6 +20,6 @@ export function HomePage() {
|
|
|
20
20
|
/>
|
|
21
21
|
<Text color="text.muted">Menus, rotas, layouts e temas ficam em src/app e podem combinar componentes locais com blocos públicos do OonCore.</Text>
|
|
22
22
|
</Stack>
|
|
23
|
-
</
|
|
23
|
+
</Stack>
|
|
24
24
|
);
|
|
25
25
|
}
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"ooncore:docs": "create-central-oon docs sync",
|
|
8
8
|
"ooncore:docs:check": "create-central-oon docs check",
|
|
9
9
|
"ooncore:conformance": "create-central-oon conformance",
|
|
10
|
-
"check": "
|
|
10
|
+
"check": "create-central-oon doctor",
|
|
11
11
|
"dev": "create-central-oon dev",
|
|
12
12
|
"dev:backend": "npm run dev --prefix backend",
|
|
13
13
|
"dev:frontend": "npm run dev --prefix frontend"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@oondemand/create-central-oon": "0.7.
|
|
16
|
+
"@oondemand/create-central-oon": "0.7.6"
|
|
17
17
|
}
|
|
18
18
|
}
|