@oondemand/create-central-oon 0.6.2 → 0.6.3
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 +34 -32
- package/docs/AGENTS.md +22 -12
- package/docs/AGENT_WORKFLOW.md +15 -8
- package/docs/BACKEND_API.md +10 -2
- package/docs/CAPABILITIES.md +7 -7
- package/docs/CHECKLIST_IMPLEMENTACAO.md +21 -11
- package/docs/OON_APP_AGENT_GUIDE.md +72 -0
- package/docs/PDF_RENDERING.md +157 -0
- package/docs/TRANSACTIONAL_EMAIL.md +111 -0
- package/package.json +1 -1
- package/schemas/central.app.schema.json +64 -0
- package/templates/_base/README.md +25 -10
- package/templates/_base/backend/package.json +1 -1
- package/templates/_base/frontend/package.json +1 -1
- package/templates/_base/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @oondemand/create-central-oon
|
|
2
2
|
|
|
3
|
-
Gerador estrutural de Apps Oon. Ele cria backend e frontend code-first prontos
|
|
4
|
-
para consumir `@oondemand/oon-core-back` e `@oondemand/oon-core-front`.
|
|
3
|
+
Gerador estrutural de Apps Oon. Ele cria backend e frontend code-first prontos para consumir `@oondemand/oon-core-back` e `@oondemand/oon-core-front` e inclui a documentação pública versionada necessária para Agents.
|
|
5
4
|
|
|
6
5
|
## Uso
|
|
7
6
|
|
|
8
7
|
```bash
|
|
9
|
-
npx create-central-oon central-
|
|
8
|
+
npx --yes --package @oondemand/create-central-oon@0.6 create-central-oon central-exemplo
|
|
10
9
|
```
|
|
11
10
|
|
|
12
|
-
O gerador possui uma única base `_base`. Não há seleção ou catálogo de
|
|
13
|
-
templates funcionais. O binário também responde por `scaffold-central-oon`.
|
|
11
|
+
O gerador possui uma única base `_base`. Não há seleção ou catálogo de templates funcionais. O binário também responde por `scaffold-central-oon`.
|
|
14
12
|
|
|
15
13
|
## Contrato `central.app.json`
|
|
16
14
|
|
|
@@ -22,8 +20,11 @@ templates funcionais. O binário também responde por `scaffold-central-oon`.
|
|
|
22
20
|
"name": "Central Exemplo",
|
|
23
21
|
"slug": "central-exemplo",
|
|
24
22
|
"appKind": "member-central",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
23
|
+
"tenancyModel": "single_tenant",
|
|
24
|
+
"availability": "licensed",
|
|
25
|
+
"accessMode": "explicit_users",
|
|
26
|
+
"authorizationMode": "rbac",
|
|
27
|
+
"deploymentMode": "dedicated",
|
|
27
28
|
"modules": {
|
|
28
29
|
"collections": false,
|
|
29
30
|
"documents": false,
|
|
@@ -33,28 +34,30 @@ templates funcionais. O binário também responde por `scaffold-central-oon`.
|
|
|
33
34
|
},
|
|
34
35
|
"capabilities": [],
|
|
35
36
|
"compatibility": {
|
|
36
|
-
"core": {
|
|
37
|
-
"minVersion": "0.6.0",
|
|
38
|
-
"maxVersionExclusive": "0.7.0"
|
|
39
|
-
}
|
|
37
|
+
"core": { "minVersion": "0.6.0" }
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
```
|
|
43
41
|
|
|
44
|
-
O manifesto contém identidade, política de acesso,
|
|
45
|
-
compatibilidade. Rotas, menus, páginas, componentes, layouts e temas ficam no
|
|
46
|
-
código do frontend, para qualquer `appKind`.
|
|
42
|
+
O manifesto contém identidade, política de acesso, capabilities funcionais e compatibilidade. Dependências de infraestrutura de publicação ficam em `oon.deploy.json`. Rotas, menus, páginas, componentes, layouts e temas ficam no código do frontend.
|
|
47
43
|
|
|
48
44
|
## Estrutura gerada
|
|
49
45
|
|
|
50
46
|
```txt
|
|
51
47
|
<app>/
|
|
48
|
+
├── .ooncore/
|
|
49
|
+
│ ├── AGENTS.md
|
|
50
|
+
│ ├── CODEX.md
|
|
51
|
+
│ ├── manifest.json
|
|
52
|
+
│ ├── context.generated.md
|
|
53
|
+
│ └── docs/
|
|
52
54
|
├── central.app.json
|
|
55
|
+
├── oon.deploy.json
|
|
53
56
|
├── package.json
|
|
54
57
|
├── backend/
|
|
55
58
|
│ ├── central.config.js
|
|
56
|
-
│ ├── central.
|
|
57
|
-
│ └── src/{validations,triggers,hooks,mappings,rules}/
|
|
59
|
+
│ ├── central.manifest.json
|
|
60
|
+
│ └── src/{models,validations,triggers,hooks,mappings,rules,routes,services}/
|
|
58
61
|
└── frontend/
|
|
59
62
|
└── src/
|
|
60
63
|
├── main.tsx
|
|
@@ -65,29 +68,28 @@ código do frontend, para qualquer `appKind`.
|
|
|
65
68
|
└── layouts/
|
|
66
69
|
```
|
|
67
70
|
|
|
68
|
-
O bootstrap
|
|
69
|
-
`defineOonApp`, `defineOonRoutes` e `defineOonNavigation`.
|
|
71
|
+
Um domínio declarativo pode adicionar `backend/central.domain.json` conforme seu contrato; ele não faz parte da base neutra. O bootstrap chama `startOonApp(app)` e a composição usa `defineOonApp`, `defineOonRoutes` e `defineOonNavigation`.
|
|
70
72
|
|
|
71
|
-
##
|
|
73
|
+
## Contrato para Agents
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
npm run ooncore:conformance
|
|
75
|
-
npx create-central-oon conformance --json
|
|
76
|
-
```
|
|
75
|
+
A documentação em `.ooncore/` é autocontida. Um Agent deve conseguir criar e customizar o App sem ler o monorepo do OonCore, `node_modules`, outros Apps ou documentação privada.
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
guards de segurança e imports internos, e rejeita código remoto, segredos no
|
|
80
|
-
bundle e dependências fora do frontend.
|
|
77
|
+
Comece por:
|
|
81
78
|
|
|
82
|
-
|
|
79
|
+
1. `.ooncore/AGENTS.md`;
|
|
80
|
+
2. `.ooncore/docs/OON_APP_AGENT_GUIDE.md`;
|
|
81
|
+
3. `.ooncore/docs/CAPABILITIES.md`;
|
|
82
|
+
4. o contrato dedicado apontado para a tarefa.
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
Se faltar informação pública, registre a lacuna; não deduza APIs por implementação interna.
|
|
85
|
+
|
|
86
|
+
## Conformidade
|
|
86
87
|
|
|
87
88
|
```bash
|
|
88
|
-
npm run ooncore:docs
|
|
89
89
|
npm run ooncore:docs:check
|
|
90
|
+
npm run ooncore:conformance
|
|
91
|
+
npm run check
|
|
92
|
+
npm test
|
|
90
93
|
```
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
A verificação exige schema v2 e bootstrap code-first, protege rotas reservadas, guards de segurança e imports internos, e rejeita código remoto, segredos no bundle e dependências fora do frontend.
|
package/docs/AGENTS.md
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
# OonCore — entrada canônica para IA/Agents
|
|
2
2
|
|
|
3
|
-
Este arquivo é o contrato inicial neutro para Codex, ChatGPT, Kimi, Manus e outros Agents que alterem uma Central Oon.
|
|
3
|
+
Este arquivo é o contrato inicial neutro para Codex, ChatGPT, Kimi, Manus e outros Agents que criem ou alterem uma Central Oon.
|
|
4
|
+
|
|
5
|
+
## Contrato de autonomia
|
|
6
|
+
|
|
7
|
+
O Agent deve trabalhar em modo **closed-book**: a árvore do App gerado, incluindo `.ooncore/`, é suficiente. Código-fonte do OonCore, `node_modules`, repositórios de outros Apps e documentação privada não são contratos de extensão e não devem ser usados para descobrir comportamento suportado.
|
|
8
|
+
|
|
9
|
+
Se a documentação distribuída não responder à tarefa, pare e registre a lacuna. Não invente API nem contorne a fronteira pública.
|
|
4
10
|
|
|
5
11
|
## Ordem de leitura
|
|
6
12
|
|
|
7
13
|
1. Leia primeiro o `AGENTS.md` da raiz do projeto consumidor, quando existir.
|
|
8
14
|
2. Confirme `schemaVersion`, `version`, `docsHash` e `entrypointsHash` em `.ooncore/manifest.json`.
|
|
9
15
|
3. Rode `npm run ooncore:docs:check`; se falhar, rode `npm run ooncore:docs` e verifique novamente.
|
|
10
|
-
4.
|
|
11
|
-
5.
|
|
12
|
-
6. Leia
|
|
16
|
+
4. Leia [OON_APP_AGENT_GUIDE.md](OON_APP_AGENT_GUIDE.md).
|
|
17
|
+
5. Consulte [CAPABILITIES.md](CAPABILITIES.md) antes de criar código.
|
|
18
|
+
6. Leia os contratos de backend, frontend, runtime, RBAC ou capability indicados abaixo.
|
|
19
|
+
7. Leia a documentação de domínio do projeto consumidor.
|
|
13
20
|
|
|
14
21
|
O `AGENTS.md` da raiz pertence ao projeto e nunca pode ser sobrescrito pelo scaffold ou pelo sync do Core.
|
|
15
22
|
|
|
@@ -17,13 +24,16 @@ O `AGENTS.md` da raiz pertence ao projeto e nunca pode ser sobrescrito pelo scaf
|
|
|
17
24
|
|
|
18
25
|
| Tarefa | Leitura obrigatória |
|
|
19
26
|
|---|---|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
+
| Criar um App ou definir onde customizar | [OON_APP_AGENT_GUIDE.md](OON_APP_AGENT_GUIDE.md), [CAPABILITIES.md](CAPABILITIES.md) |
|
|
28
|
+
| Domínio, models, validações e fórmulas | [BACKEND_API.md](BACKEND_API.md), [BACKEND_DOMAIN_MANIFEST.md](BACKEND_DOMAIN_MANIFEST.md), [BACKEND_PATTERNS.md](BACKEND_PATTERNS.md), [REACTIVE_DOMAIN_FORMULAS.md](REACTIVE_DOMAIN_FORMULAS.md) |
|
|
29
|
+
| CRUD, metadata e UI | [METADATA_CRUD_UI.md](METADATA_CRUD_UI.md), [FRONTEND_API.md](FRONTEND_API.md), [FRONTEND_CODE_FIRST.md](FRONTEND_CODE_FIRST.md) |
|
|
30
|
+
| Auth, ativação, tenant ou permissões | [AUTH_ACTIVATION_RBAC.md](AUTH_ACTIVATION_RBAC.md), [RBAC_SECURITY.md](RBAC_SECURITY.md), [DO_AND_DONT.md](DO_AND_DONT.md) |
|
|
31
|
+
| Renderizar, visualizar ou baixar PDF | [PDF_RENDERING.md](PDF_RENDERING.md), [BACKEND_API.md](BACKEND_API.md), [FRONTEND_API.md](FRONTEND_API.md) |
|
|
32
|
+
| Configurar templates ou enviar e-mail | [TRANSACTIONAL_EMAIL.md](TRANSACTIONAL_EMAIL.md), [RBAC_SECURITY.md](RBAC_SECURITY.md) |
|
|
33
|
+
| Execução local | [RUNTIME_MODES.md](RUNTIME_MODES.md), [LOCAL_DEVELOPMENT.md](LOCAL_DEVELOPMENT.md), [LOCAL_SECURITY_BOUNDARY.md](LOCAL_SECURITY_BOUNDARY.md) |
|
|
34
|
+
| Rotas, hooks, jobs e filas | [ROUTES_HOOKS_WORKERS.md](ROUTES_HOOKS_WORKERS.md), [BACKEND_PATTERNS.md](BACKEND_PATTERNS.md) |
|
|
35
|
+
| Upgrade do Core | [CORE_UPGRADE.md](CORE_UPGRADE.md), [TESTING_CONFORMANCE.md](TESTING_CONFORMANCE.md), [releases/0.6.0.md](releases/0.6.0.md) |
|
|
36
|
+
| UX avançada | [ADVANCED_UX_PATTERNS.md](ADVANCED_UX_PATTERNS.md), [DETAIL_MODAL_AND_RELATED_GRIDS.md](DETAIL_MODAL_AND_RELATED_GRIDS.md), [PORTAL_COCKPIT_PATTERNS.md](PORTAL_COCKPIT_PATTERNS.md) |
|
|
27
37
|
|
|
28
38
|
## Fronteira obrigatória
|
|
29
39
|
|
|
@@ -43,4 +53,4 @@ npm run check
|
|
|
43
53
|
npm test
|
|
44
54
|
```
|
|
45
55
|
|
|
46
|
-
|
|
56
|
+
Uma entrega que depende da leitura de fonte privada ou de outro App não está concluída: registre a lacuna na documentação distribuída.
|
package/docs/AGENT_WORKFLOW.md
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# Fluxo de trabalho para Agents
|
|
2
2
|
|
|
3
|
-
1. **
|
|
4
|
-
2. **
|
|
5
|
-
3. **
|
|
6
|
-
4. **
|
|
7
|
-
5. **
|
|
8
|
-
6. **
|
|
9
|
-
7. **
|
|
3
|
+
1. **Gerar:** para um App novo, siga [OON_APP_AGENT_GUIDE.md](OON_APP_AGENT_GUIDE.md) e confirme que `.ooncore/` foi criada.
|
|
4
|
+
2. **Descobrir:** leia `AGENTS.md`, o manifesto documental e [CAPABILITIES.md](CAPABILITIES.md).
|
|
5
|
+
3. **Classificar:** separe contrato do Core, domínio da Central e recurso exclusivo da plataforma.
|
|
6
|
+
4. **Escolher extensão:** manifesto → validation/trigger/hook/mapping → renderer/rota pequena → código customizado somente se necessário.
|
|
7
|
+
5. **Implementar:** use exports públicos documentados; preserve segurança, tenant, auditoria e idempotência.
|
|
8
|
+
6. **Executar local:** `npm run dev`, sem cadastro ou conexão com a plataforma; capabilities de plataforma falham fechado.
|
|
9
|
+
7. **Validar:** docs check, conformance, testes, typecheck e provas específicas do projeto.
|
|
10
|
+
8. **Relatar:** arquivos, contratos usados, riscos, limitações e evidências.
|
|
11
|
+
|
|
12
|
+
## Regra closed-book
|
|
13
|
+
|
|
14
|
+
Mantenha os três pacotes OonCore na linha 0.6.x declarada pelo App e sincronize `.ooncore` após qualquer atualização.
|
|
15
|
+
|
|
16
|
+
Trabalhe somente com o App e sua `.ooncore/`. Não leia fonte privada, `node_modules` ou outros Apps para descobrir como usar o Core. Se faltar assinatura, declaração, exemplo, erro ou limite necessário, interrompa essa parte e registre a lacuna documental.
|
|
10
17
|
|
|
11
18
|
Prompt operacional:
|
|
12
19
|
|
|
13
|
-
>
|
|
20
|
+
> Crie ou atualize o Oon App usando exclusivamente a documentação versionada em `.ooncore`. Preserve o domínio e o AGENTS.md do projeto, consulte o catálogo e os contratos públicos de back, front e capabilities, use apenas extensões suportadas, execute os gates e homologue em `127.0.0.1` sem conexão com a plataforma. Não leia fonte privada ou outros Apps e não crie autenticação, ativação, RBAC, CRUD, shell ou infraestrutura paralelos.
|
package/docs/BACKEND_API.md
CHANGED
|
@@ -29,8 +29,16 @@ Erros de manifesto carregam `code`, `statusCode` e `issues[]` com `path` e `mess
|
|
|
29
29
|
|
|
30
30
|
## Capabilities
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
O namespace público `capabilities` contém:
|
|
33
|
+
|
|
34
|
+
- `capabilities.pdf.render(input, context): Promise<Buffer>`; contrato completo em [PDF_RENDERING.md](PDF_RENDERING.md);
|
|
35
|
+
- alias compatível `capabilities.pdfRendering.render`;
|
|
36
|
+
- `capabilities.transactionalEmail.send(input, context)` e operações administrativas; contrato completo em [TRANSACTIONAL_EMAIL.md](TRANSACTIONAL_EMAIL.md);
|
|
37
|
+
- `PdfRenderingError` e `TransactionalEmailError` para normalização específica.
|
|
38
|
+
|
|
39
|
+
O App nunca configura URL, credencial interna ou implementação de uma capability. A única exceção é a injeção de dublês documentada para testes automatizados.
|
|
40
|
+
|
|
41
|
+
`operationalRequestHeaders(options)` produz headers de identidade do Deployment. Retorna `LOCAL_OPERATION_NOT_SUPPORTED` no runtime local; nunca improvise identidade local.
|
|
34
42
|
|
|
35
43
|
## Runtime local
|
|
36
44
|
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# Catálogo de capacidades do OonCore
|
|
2
2
|
|
|
3
|
-
Consulte este catálogo antes de criar infraestrutura ou componentes customizados.
|
|
3
|
+
Consulte este catálogo antes de criar infraestrutura ou componentes customizados. Para capabilities nativas, o guia dedicado é leitura obrigatória.
|
|
4
4
|
|
|
5
5
|
| Capacidade | Backend | Frontend | Declaração/extensão | Local | Plataforma |
|
|
6
6
|
|---|---|---|---|---|---|
|
|
7
|
-
| Models e CRUD | `defineModel`, domain manifest, `/core/*` | `CoreCollection`, hooks de API | `central.domain.json
|
|
7
|
+
| Models e CRUD | `defineModel`, domain manifest, `/core/*` | `CoreCollection`, hooks de API | `central.domain.json` ou composição code-first | Sim | Sim |
|
|
8
8
|
| Metadata | registry e `/core/metadata` | `useCoreMetadata`, renderers | models/domain manifest | Sim | Sim |
|
|
9
9
|
| Validações e fórmulas | `defineValidation`, domain rules | prévia reativa | domain manifest/validation | Sim | Sim |
|
|
10
|
-
| Esteiras | process manifest/runtime | `CorePipeline` | `central.process.json`, UI
|
|
10
|
+
| Esteiras | process manifest/runtime | `CorePipeline` | `central.process.json`, UI code-first | Sim | Sim |
|
|
11
11
|
| Documentos | `defineDocument` | `CoreDocument` | UI/domain manifest | Sim | Sim |
|
|
12
|
-
| Dashboards | agregações e rotas | `CoreDashboard` | UI
|
|
12
|
+
| Dashboards | agregações e rotas | `CoreDashboard` | UI code-first | Sim | Sim |
|
|
13
13
|
| RBAC | policy, middleware e `requirePermission` | `PermissionGate`, `can` | `central.app.json` | Simulação declarada | Identidade real |
|
|
14
14
|
| Tenant e escopo | access context e scope helpers | `TenantProvider` | `central.app.json` | Contexto técnico | Contexto autorizado |
|
|
15
15
|
| Auditoria | CRUD e request context | headers do SDK | automática/extensão | Local | Operacional |
|
|
16
16
|
| Rotas customizadas | `defineRoutes` | página/ação declarada | `backend/src/routes` | Sim | Sim |
|
|
17
17
|
| Jobs e workers | process workers | status operacional | manifestos/hooks | Sim | Sim |
|
|
18
|
-
| E-mail transacional |
|
|
19
|
-
| PDF |
|
|
18
|
+
| E-mail transacional | `capabilities.transactionalEmail` | `CoreTransactionalEmail` | [TRANSACTIONAL_EMAIL.md](TRANSACTIONAL_EMAIL.md) | Fail-closed/dublê de teste | Implementação resolvida pelo Core |
|
|
19
|
+
| PDF | `capabilities.pdf.render` | `useOonApi`/download | [PDF_RENDERING.md](PDF_RENDERING.md) | Fail-closed/dublê de teste | Implementação resolvida pelo runtime |
|
|
20
20
|
| Publicação/promoção | contratos de delivery | indisponível no App | CLI/ponte pública | Não | Sim |
|
|
21
21
|
| Runtime local | sessão e guardas locais | bootstrap/cookie/banner | `OON_RUNTIME_MODE=local` | Sim | Não aplicável |
|
|
22
22
|
|
|
23
|
-
Para cada capacidade, use o manifesto quando houver contrato declarativo
|
|
23
|
+
Para cada capacidade, use o manifesto quando houver contrato declarativo e código da Central apenas nos pontos de extensão documentados. Se uma capability não possuir guia dedicado suficiente, registre uma lacuna; não descubra o contrato lendo fonte privada ou outro repositório.
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Use este checklist antes de concluir qualquer tarefa de codificação em uma Central Oon.
|
|
4
4
|
|
|
5
|
-
## Contexto
|
|
5
|
+
## Contexto e documentação
|
|
6
6
|
|
|
7
7
|
- [ ] Rodei `npm run ooncore:docs:check`.
|
|
8
8
|
- [ ] Rodei `npm run ooncore:docs` se havia documentação desatualizada.
|
|
9
|
-
- [ ] Li `.ooncore/
|
|
9
|
+
- [ ] Li `.ooncore/AGENTS.md` e o guia de autoria.
|
|
10
|
+
- [ ] Consultei o catálogo e o contrato dedicado de cada capability usada.
|
|
11
|
+
- [ ] Trabalhei somente com a árvore do App e `.ooncore/`, sem fonte privada, `node_modules` ou outros Apps.
|
|
12
|
+
- [ ] Registrei qualquer lacuna em vez de inventar API ou infraestrutura.
|
|
10
13
|
- [ ] Entendi qual recurso do Core já resolve parte da necessidade.
|
|
11
14
|
|
|
12
15
|
## Backend
|
|
@@ -15,27 +18,34 @@ Use este checklist antes de concluir qualquer tarefa de codificação em uma Cen
|
|
|
15
18
|
- [ ] Evitei recriar CRUD.
|
|
16
19
|
- [ ] Validei entrada.
|
|
17
20
|
- [ ] Validei permissão no backend.
|
|
18
|
-
- [ ]
|
|
19
|
-
- [ ]
|
|
20
|
-
- [ ]
|
|
21
|
+
- [ ] Propaguei tenant, correlação, cancelamento e idempotência quando aplicáveis.
|
|
22
|
+
- [ ] Tratei erros pelo contrato público.
|
|
23
|
+
- [ ] Não hardcodei segredos, endpoints internos ou implementations.
|
|
24
|
+
- [ ] Mantive rastreabilidade sem registrar conteúdo sensível.
|
|
21
25
|
|
|
22
26
|
## Frontend
|
|
23
27
|
|
|
24
28
|
- [ ] Defini o App com `defineOonApp` e `startOonApp`.
|
|
25
29
|
- [ ] Reutilizei shell, guards, primitives e padrões públicos do Core.
|
|
26
30
|
- [ ] Mantive rotas, navegação, páginas, layouts e temas no código do App.
|
|
31
|
+
- [ ] Usei `useOonApi` para chamadas autenticadas e respostas binárias.
|
|
27
32
|
- [ ] Não coloquei regra crítica apenas no frontend.
|
|
28
33
|
|
|
29
|
-
## Integrações
|
|
34
|
+
## Integrações e capabilities
|
|
30
35
|
|
|
31
|
-
- [ ]
|
|
32
|
-
- [ ]
|
|
33
|
-
- [ ]
|
|
34
|
-
- [ ] Normalizei erros externos
|
|
36
|
+
- [ ] Fiz a declaração no manifesto indicado pelo guia.
|
|
37
|
+
- [ ] Usei camada de integração/capability pública.
|
|
38
|
+
- [ ] Modelei mapping e status operacional quando necessário.
|
|
39
|
+
- [ ] Normalizei erros externos e respeitei `retryable`.
|
|
40
|
+
- [ ] O runtime local falha fechado ou usa dublê somente no teste.
|
|
35
41
|
- [ ] Não expus credenciais.
|
|
36
42
|
|
|
37
43
|
## Entrega
|
|
38
44
|
|
|
45
|
+
- [ ] `npm run ooncore:docs:check` passou.
|
|
46
|
+
- [ ] `npm run ooncore:conformance` passou.
|
|
47
|
+
- [ ] `npm run check` e `npm test` passaram.
|
|
48
|
+
- [ ] Provei o fluxo específico do usuário.
|
|
39
49
|
- [ ] A Central continua atualizável com novas versões do Core.
|
|
40
50
|
- [ ] A alteração é pequena, coesa e aderente à arquitetura.
|
|
41
|
-
- [ ] O comportamento
|
|
51
|
+
- [ ] O comportamento específico do App está documentado sem duplicar contrato do Core.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Criar e customizar um Oon App com um Agent
|
|
2
|
+
|
|
3
|
+
Este é o roteiro canônico de autoria. O contrato de aceite é **closed-book**: o Agent recebe somente a árvore do App gerado, incluindo `.ooncore/`, e não precisa consultar o código-fonte do OonCore, repositórios de outros Apps ou documentação privada.
|
|
4
|
+
|
|
5
|
+
## 1. Gerar a base
|
|
6
|
+
|
|
7
|
+
Em um diretório vazio:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx --yes --package @oondemand/create-central-oon@0.6 create-central-oon meu-app --no-install
|
|
11
|
+
cd meu-app
|
|
12
|
+
npm install
|
|
13
|
+
npm run ooncore:docs:check
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
O gerador cria backend, frontend, manifestos, gates e a documentação versionada em `.ooncore/`. Não copie arquivos de outro App para iniciar uma Central.
|
|
17
|
+
|
|
18
|
+
## 2. Ler antes de alterar
|
|
19
|
+
|
|
20
|
+
1. Leia `.ooncore/AGENTS.md`.
|
|
21
|
+
2. Confira `.ooncore/manifest.json` e rode `npm run ooncore:docs:check`.
|
|
22
|
+
3. Consulte [CAPABILITIES.md](CAPABILITIES.md).
|
|
23
|
+
4. Abra somente os contratos indicados para a tarefa.
|
|
24
|
+
5. Leia o `AGENTS.md` da raiz, quando o projeto possuir regras próprias.
|
|
25
|
+
|
|
26
|
+
Se a resposta não estiver nesses arquivos, pare e registre uma lacuna documental. Não deduza contrato lendo `node_modules`, `src/` privado ou outros repositórios.
|
|
27
|
+
|
|
28
|
+
## 3. Separar os contratos
|
|
29
|
+
|
|
30
|
+
| Necessidade | Local correto |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Identidade, tipo do App, tenant, acesso, módulos e RBAC | `central.app.json` |
|
|
33
|
+
| Recursos exigidos do ambiente de publicação | `oon.deploy.json` |
|
|
34
|
+
| Models e regras de domínio | `backend/src` ou `backend/central.domain.json`, quando o contrato declarativo for adotado |
|
|
35
|
+
| Rotas e serviços específicos | `backend/src/routes` e `backend/src/services` |
|
|
36
|
+
| Rotas, navegação, páginas, tema e experiência | `frontend/src/app`, `frontend/src/pages` e `frontend/src/components` |
|
|
37
|
+
| Auth, ativação, shell, CRUD, metadata e infraestrutura | OonCore; não reimplementar |
|
|
38
|
+
|
|
39
|
+
`central.app.json` e `oon.deploy.json` têm finalidades diferentes. Uma capability funcional do App pode exigir declaração no primeiro; uma dependência de infraestrutura, como renderização de PDF, é declarada no segundo. Siga o guia da capability.
|
|
40
|
+
|
|
41
|
+
## 4. Customizar
|
|
42
|
+
|
|
43
|
+
- Domínio: use [BACKEND_API.md](BACKEND_API.md), [BACKEND_DOMAIN_MANIFEST.md](BACKEND_DOMAIN_MANIFEST.md) e [BACKEND_PATTERNS.md](BACKEND_PATTERNS.md).
|
|
44
|
+
- Frontend: use [FRONTEND_CODE_FIRST.md](FRONTEND_CODE_FIRST.md), [FRONTEND_API.md](FRONTEND_API.md) e os padrões de UI indicados no catálogo.
|
|
45
|
+
- Segurança: declare permissões em `central.app.json`, aplique `requirePermission` no backend e use guards públicos no frontend.
|
|
46
|
+
- Capabilities: abra o contrato dedicado antes de declarar ou consumir.
|
|
47
|
+
- Runtime local: preserve o comportamento fail-closed descrito em [LOCAL_SECURITY_BOUNDARY.md](LOCAL_SECURITY_BOUNDARY.md).
|
|
48
|
+
|
|
49
|
+
Crie apenas código de negócio. URLs internas, credenciais, registries, transports e detalhes de implementação não pertencem ao App.
|
|
50
|
+
|
|
51
|
+
## 5. Validar
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm run ooncore:docs:check
|
|
55
|
+
npm run ooncore:conformance
|
|
56
|
+
npm run check
|
|
57
|
+
npm test
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Além dos gates, prove o fluxo de usuário da tarefa. Para respostas binárias, valide tipo, assinatura e download; para mutações, valide permissão, tenant, idempotência e erros.
|
|
61
|
+
|
|
62
|
+
## Critério final do Agent
|
|
63
|
+
|
|
64
|
+
O relato de entrega deve informar:
|
|
65
|
+
|
|
66
|
+
- contratos públicos consultados;
|
|
67
|
+
- manifestos e pontos de extensão alterados;
|
|
68
|
+
- testes e gates executados;
|
|
69
|
+
- limitações do runtime local;
|
|
70
|
+
- qualquer lacuna documental encontrada.
|
|
71
|
+
|
|
72
|
+
Citar fonte privada como requisito de implementação significa que a tarefa ainda não atende a este contrato.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Renderização de PDF
|
|
2
|
+
|
|
3
|
+
Use esta capability para transformar HTML em um `Buffer` PDF sem conhecer endpoint, credencial ou implementação do serviço. Requer OonCore `0.6.0` ou superior.
|
|
4
|
+
|
|
5
|
+
## Declaração
|
|
6
|
+
|
|
7
|
+
Declare a dependência de infraestrutura em `oon.deploy.json`:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"capabilities": {
|
|
12
|
+
"pdfRendering": {
|
|
13
|
+
"required": true,
|
|
14
|
+
"minVersion": "1.0.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Não adicione URL, usuário, senha ou implementation reference. O runtime resolve esses valores na publicação. Esta declaração não pertence ao array `capabilities` de `central.app.json`.
|
|
21
|
+
|
|
22
|
+
## API pública do backend
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
const {
|
|
26
|
+
capabilities,
|
|
27
|
+
defineRoutes,
|
|
28
|
+
GenericError,
|
|
29
|
+
requirePermission,
|
|
30
|
+
} = require("@oondemand/oon-core-back");
|
|
31
|
+
|
|
32
|
+
defineRoutes("/pdf", (router) => {
|
|
33
|
+
router.private.post(
|
|
34
|
+
"/render",
|
|
35
|
+
requirePermission("pdf.render"),
|
|
36
|
+
async (req, res) => {
|
|
37
|
+
if (typeof req.body?.html !== "string" || !req.body.html.trim()) {
|
|
38
|
+
throw new GenericError("Informe o HTML.", {
|
|
39
|
+
statusCode: 422,
|
|
40
|
+
code: "PDF_HTML_REQUIRED",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const abort = () => controller.abort();
|
|
46
|
+
req.once("aborted", abort);
|
|
47
|
+
res.once("close", abort);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const pdf = await capabilities.pdf.render(
|
|
51
|
+
{
|
|
52
|
+
html: req.body.html,
|
|
53
|
+
format: req.body.format || "A4",
|
|
54
|
+
printBackground: true,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
...req.accessContext,
|
|
58
|
+
correlationId: req.id,
|
|
59
|
+
environment: process.env.APP_ENVIRONMENT,
|
|
60
|
+
signal: controller.signal,
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
res.type("application/pdf");
|
|
65
|
+
res.set("Content-Disposition", 'attachment; filename="documento.pdf"');
|
|
66
|
+
res.send(pdf);
|
|
67
|
+
} finally {
|
|
68
|
+
req.off("aborted", abort);
|
|
69
|
+
res.off("close", abort);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Declare `pdf.render` em `rbac.permissions` e conceda-a somente aos papéis necessários. O backend continua sendo a autoridade de permissão e tenant.
|
|
77
|
+
|
|
78
|
+
A assinatura é:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
capabilities.pdf.render(input, context): Promise<Buffer>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| Campo de `input` | Tipo | Regra/default |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `html` | string | obrigatório; máximo padrão de 2 MiB |
|
|
87
|
+
| `format` | `A3 \| A4 \| A5 \| Letter \| Legal` | `A4` |
|
|
88
|
+
| `landscape` | boolean | `false` |
|
|
89
|
+
| `marginTop`, `marginBottom`, `marginLeft`, `marginRight` | number | polegadas, de 0 a 4; `0.39` |
|
|
90
|
+
| `printBackground` | boolean | `true` |
|
|
91
|
+
| `timeoutMs` | number | mínimo 1.000 ms; padrão 30.000 ms; máximo do runtime, padrão 60.000 ms |
|
|
92
|
+
|
|
93
|
+
O `context` pode carregar `tenantId`, `appCode`, `environment`, `operationId`, `correlationId`/`requestId`, `signal` e, somente em testes, `fetchImpl`. A saída deve começar com `%PDF-` e tem limite padrão de 20 MiB.
|
|
94
|
+
|
|
95
|
+
## Preview e download no frontend
|
|
96
|
+
|
|
97
|
+
Preview do HTML deve usar iframe sem privilégios:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
<iframe title="Prévia" sandbox="" srcDoc={html} />
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Para gerar e baixar usando o cliente autenticado do Core:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import { useOonApi } from "@oondemand/oon-core-front";
|
|
107
|
+
|
|
108
|
+
function DownloadPdfButton({ html }: { html: string }) {
|
|
109
|
+
const { http } = useOonApi();
|
|
110
|
+
|
|
111
|
+
async function download() {
|
|
112
|
+
const response = await http.post(
|
|
113
|
+
"/pdf/render",
|
|
114
|
+
{ html, format: "A4" },
|
|
115
|
+
{ responseType: "blob" },
|
|
116
|
+
);
|
|
117
|
+
const url = URL.createObjectURL(response.data);
|
|
118
|
+
const link = document.createElement("a");
|
|
119
|
+
link.href = url;
|
|
120
|
+
link.download = "documento.pdf";
|
|
121
|
+
link.click();
|
|
122
|
+
URL.revokeObjectURL(url);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return <button onClick={download}>Gerar PDF</button>;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Nunca envie a geração diretamente a um endpoint de infraestrutura pelo navegador.
|
|
130
|
+
|
|
131
|
+
## Erros
|
|
132
|
+
|
|
133
|
+
`PdfRenderingError` expõe `code`, `statusCode`, `retryable` e detalhes sanitizados.
|
|
134
|
+
|
|
135
|
+
| Código | Retry | Significado |
|
|
136
|
+
|---|---:|---|
|
|
137
|
+
| `PDF_RENDERING_INVALID_INPUT` | não | HTML vazio ou acima do limite |
|
|
138
|
+
| `PDF_RENDERING_INVALID_OPTIONS` | não | formato, margem ou opção inválida |
|
|
139
|
+
| `PDF_RENDERING_UNAVAILABLE` | sim | capability não resolvida no ambiente |
|
|
140
|
+
| `PDF_RENDERING_CREDENTIAL_UNAVAILABLE` | sim | credencial interna não injetada |
|
|
141
|
+
| `PDF_RENDERING_IMPLEMENTATION_ERROR` | sim | implementação respondeu com falha |
|
|
142
|
+
| `PDF_RENDERING_TIMEOUT` | sim | prazo excedido ou sinal abortado |
|
|
143
|
+
| `PDF_RENDERING_SATURATED` | sim | concorrência/fila excedida |
|
|
144
|
+
| `PDF_RENDERING_TRANSPORT_ERROR` | sim | falha transitória de transporte |
|
|
145
|
+
| `PDF_RENDERING_INVALID_OUTPUT` | sim | saída inválida ou acima do limite |
|
|
146
|
+
|
|
147
|
+
Use retentativas apenas quando `error.retryable === true`, com backoff e idempotência na operação chamadora.
|
|
148
|
+
|
|
149
|
+
## Segurança e runtime local
|
|
150
|
+
|
|
151
|
+
- trate HTML do usuário como não confiável; sanitize no App e use interpolação escapada;
|
|
152
|
+
- prefira HTML autocontido; recursos remotos tornam o resultado não determinístico e podem ser bloqueados;
|
|
153
|
+
- nunca inclua segredos, tokens ou credenciais no HTML;
|
|
154
|
+
- não registre HTML nem bytes do PDF; registre correlação, duração, tamanhos e código de erro;
|
|
155
|
+
- propague cancelamento do request por `AbortSignal`;
|
|
156
|
+
- no runtime local, a capability falha fechado com `PDF_RENDERING_UNAVAILABLE` quando não resolvida;
|
|
157
|
+
- em testes automatizados, um transport fake pode ser injetado por `capabilities.configurePdfRendering` e deve devolver bytes iniciados por `%PDF-`; não gere um “PDF” textual falso no código do App.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# E-mail transacional
|
|
2
|
+
|
|
3
|
+
A capability `core.transactional-email` fornece configuração protegida, templates versionados, preview, envio idempotente, fila, retentativas e painel administrativo. Requer OonCore `0.6.0` ou superior.
|
|
4
|
+
|
|
5
|
+
## Declaração funcional
|
|
6
|
+
|
|
7
|
+
Em `central.app.json`:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"capabilities": ["core.transactional-email"],
|
|
12
|
+
"capabilitySettings": {
|
|
13
|
+
"core.transactional-email": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"scopePolicy": "tenant_override",
|
|
16
|
+
"retentionDays": 30,
|
|
17
|
+
"attachmentsPolicy": { "allowed": false },
|
|
18
|
+
"templates": [
|
|
19
|
+
{
|
|
20
|
+
"code": "confirmacao",
|
|
21
|
+
"definition": "./emails/confirmacao.json",
|
|
22
|
+
"initialStatus": "active"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`scopePolicy` aceita `app_only`, `tenant_required` ou `tenant_override`. `retentionDays` aceita 1 a 90. Nesta linha do Core, anexos não são permitidos.
|
|
31
|
+
|
|
32
|
+
A definição referenciada contém:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"code": "confirmacao",
|
|
37
|
+
"name": "Confirmação",
|
|
38
|
+
"subject": "Olá, {{nome}}",
|
|
39
|
+
"htmlContent": "<p>Olá, {{nome}}.</p>",
|
|
40
|
+
"textContent": "Olá, {{nome}}.",
|
|
41
|
+
"variablesSchema": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"additionalProperties": false,
|
|
44
|
+
"required": ["nome"],
|
|
45
|
+
"properties": { "nome": { "type": "string" } }
|
|
46
|
+
},
|
|
47
|
+
"locale": "pt-BR",
|
|
48
|
+
"initialStatus": "active",
|
|
49
|
+
"attachmentsPolicy": { "allowed": false }
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Templates usam somente interpolação Handlebars escapada. Blocos, helpers, subexpressões, triple-stache e conteúdo remoto executável não são aceitos.
|
|
54
|
+
|
|
55
|
+
## Envio no backend
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const { capabilities } = require("@oondemand/oon-core-back");
|
|
59
|
+
|
|
60
|
+
async function enviarConfirmacao({ email, nome, idempotencyKey }, req) {
|
|
61
|
+
return capabilities.transactionalEmail.send(
|
|
62
|
+
{
|
|
63
|
+
templateCode: "confirmacao",
|
|
64
|
+
to: email,
|
|
65
|
+
variables: { nome },
|
|
66
|
+
idempotencyKey,
|
|
67
|
+
correlationId: req.id,
|
|
68
|
+
maxAttempts: 5,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
...req.accessContext,
|
|
72
|
+
userId: req.accessContext?.userId,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`idempotencyKey` é obrigatória. O retorno é `{ dispatchId, status, correlationId }`; `status` é `accepted` ou `duplicate`. Não trate `accepted` como entrega confirmada.
|
|
79
|
+
|
|
80
|
+
Outras operações públicas do namespace `capabilities.transactionalEmail` incluem preview e versionamento de templates, consulta de dispatches e retry de dead letter. Para administração interativa, prefira o componente do Core.
|
|
81
|
+
|
|
82
|
+
## Painel administrativo
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { CoreTransactionalEmail } from "@oondemand/oon-core-front";
|
|
86
|
+
|
|
87
|
+
export function EmailPage() {
|
|
88
|
+
return <CoreTransactionalEmail />;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Proteja a rota e declare/conceda apenas as permissões necessárias:
|
|
93
|
+
|
|
94
|
+
- `transactional-email.config.read`
|
|
95
|
+
- `transactional-email.config.manage`
|
|
96
|
+
- `transactional-email.templates.read`
|
|
97
|
+
- `transactional-email.templates.manage`
|
|
98
|
+
- `transactional-email.dispatches.read`
|
|
99
|
+
- `transactional-email.dispatches.retry`
|
|
100
|
+
|
|
101
|
+
O componente usa as rotas autenticadas em `/core/transactional-email/*`. Credenciais são inseridas pela tela protegida e armazenadas pelo Core; nunca as coloque no manifesto, frontend, repositório ou log.
|
|
102
|
+
|
|
103
|
+
## Segurança e operação
|
|
104
|
+
|
|
105
|
+
- o backend resolve app e tenant a partir do contexto validado;
|
|
106
|
+
- `tenant_required` exige tenant; `tenant_override` usa configuração do tenant quando houver e recua para a do App;
|
|
107
|
+
- destinatários e variáveis são validados antes de enfileirar;
|
|
108
|
+
- payload protegido tem retenção limitada; listagens não retornam o payload protegido;
|
|
109
|
+
- erros usam `TransactionalEmailError` e códigos `EMAIL_*` sanitizados;
|
|
110
|
+
- no runtime local, falhe fechado até a capability e seu secret store/configuração estarem disponíveis;
|
|
111
|
+
- testes devem substituir a fronteira externa; não envie e-mail real e não grave credenciais de teste.
|
package/package.json
CHANGED
|
@@ -220,6 +220,70 @@
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
+
},
|
|
224
|
+
"capabilitySettings": {
|
|
225
|
+
"type": "object",
|
|
226
|
+
"additionalProperties": false,
|
|
227
|
+
"properties": {
|
|
228
|
+
"core.transactional-email": {
|
|
229
|
+
"type": "object",
|
|
230
|
+
"additionalProperties": false,
|
|
231
|
+
"required": [
|
|
232
|
+
"enabled",
|
|
233
|
+
"scopePolicy",
|
|
234
|
+
"templates"
|
|
235
|
+
],
|
|
236
|
+
"properties": {
|
|
237
|
+
"enabled": {
|
|
238
|
+
"type": "boolean"
|
|
239
|
+
},
|
|
240
|
+
"scopePolicy": {
|
|
241
|
+
"enum": [
|
|
242
|
+
"app_only",
|
|
243
|
+
"tenant_required",
|
|
244
|
+
"tenant_override"
|
|
245
|
+
]
|
|
246
|
+
},
|
|
247
|
+
"retentionDays": {
|
|
248
|
+
"type": "integer",
|
|
249
|
+
"minimum": 1,
|
|
250
|
+
"maximum": 90
|
|
251
|
+
},
|
|
252
|
+
"attachmentsPolicy": {
|
|
253
|
+
"type": "object"
|
|
254
|
+
},
|
|
255
|
+
"templates": {
|
|
256
|
+
"type": "array",
|
|
257
|
+
"items": {
|
|
258
|
+
"type": "object",
|
|
259
|
+
"additionalProperties": false,
|
|
260
|
+
"required": [
|
|
261
|
+
"code",
|
|
262
|
+
"definition",
|
|
263
|
+
"initialStatus"
|
|
264
|
+
],
|
|
265
|
+
"properties": {
|
|
266
|
+
"code": {
|
|
267
|
+
"type": "string",
|
|
268
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
269
|
+
},
|
|
270
|
+
"definition": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"minLength": 1,
|
|
273
|
+
"pattern": "^(?![\\\\/])(?!.*(?:^|[\\\\/])\\.\\.(?:[\\\\/]|$)).+$"
|
|
274
|
+
},
|
|
275
|
+
"initialStatus": {
|
|
276
|
+
"enum": [
|
|
277
|
+
"draft",
|
|
278
|
+
"active"
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
223
287
|
}
|
|
224
288
|
},
|
|
225
289
|
"allOf": [
|
|
@@ -2,14 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
App Oon code-first gerado com `create-central-oon`.
|
|
4
4
|
|
|
5
|
+
## Comece aqui
|
|
6
|
+
|
|
7
|
+
A pasta `.ooncore/` contém o contrato público versionado para criar e customizar este App. Um Agent deve usar somente esta árvore do projeto: não é necessário consultar fonte privada do OonCore, `node_modules` ou outros Apps.
|
|
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
|
+
|
|
5
16
|
## Fronteira arquitetural
|
|
6
17
|
|
|
7
|
-
- `central.app.json` declara identidade, `appKind`, módulos, capabilities e compatibilidade
|
|
8
|
-
- `
|
|
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;
|
|
9
22
|
- `frontend/src/app` compõe rotas, navegação, layouts e temas;
|
|
10
23
|
- `frontend/src/{pages,components,features}` contém a experiência local;
|
|
11
|
-
- `backend/central.config.js` fica reservado a extensões
|
|
12
|
-
- `frontend/src/main.tsx` chama
|
|
24
|
+
- `backend/central.config.js` fica reservado a extensões documentadas de runtime;
|
|
25
|
+
- `frontend/src/main.tsx` chama `startOonApp`.
|
|
13
26
|
|
|
14
27
|
Autenticação, guards, shell, RBAC, metadata, CRUD e infraestrutura pertencem ao OonCore.
|
|
15
28
|
|
|
@@ -20,9 +33,10 @@ npm run ooncore:docs # sincroniza .ooncore/
|
|
|
20
33
|
npm run ooncore:docs:check # valida versão/hash do cache local
|
|
21
34
|
npm run ooncore:conformance # valida a fronteira da Central
|
|
22
35
|
npm run check # executa os gates locais
|
|
36
|
+
npm test
|
|
23
37
|
```
|
|
24
38
|
|
|
25
|
-
|
|
39
|
+
`.ooncore/` é um cache regenerável da documentação publicada no pacote. Não edite `context.generated.md` manualmente; versione a pasta junto com o App para que humanos e Agents recebam o mesmo contrato.
|
|
26
40
|
|
|
27
41
|
## Rodando
|
|
28
42
|
|
|
@@ -35,13 +49,14 @@ cp frontend/.env.example frontend/.env
|
|
|
35
49
|
npm run dev
|
|
36
50
|
```
|
|
37
51
|
|
|
38
|
-
O comando inicia backend e frontend exclusivamente em loopback, abre uma sessão local aleatória e não consulta nem cria recursos na plataforma. Não implemente autenticação ou
|
|
52
|
+
O comando inicia backend e frontend exclusivamente em loopback, abre uma sessão local aleatória e não consulta nem cria recursos na plataforma. Capabilities de plataforma falham fechado quando não resolvidas. Não implemente autenticação, ativação ou infraestrutura paralela.
|
|
39
53
|
|
|
40
54
|
## Evoluindo a Central
|
|
41
55
|
|
|
42
|
-
1.
|
|
43
|
-
2. Crie rotas, páginas, componentes, layouts e temas
|
|
44
|
-
3.
|
|
45
|
-
4.
|
|
56
|
+
1. Modele o domínio por exports públicos em `backend/src` ou adote o manifesto declarativo conforme `BACKEND_DOMAIN_MANIFEST.md`.
|
|
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.
|
|
46
61
|
|
|
47
62
|
O OonCore fornece a fundação; o App implementa sua experiência e seu domínio.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"sync:metadata": "oonCore-front sync:metadata"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@oondemand/oon-core-front": "^0.6.
|
|
14
|
+
"@oondemand/oon-core-front": "^0.6.3",
|
|
15
15
|
"@chakra-ui/react": "^3.13.0",
|
|
16
16
|
"@emotion/react": "^11.14.0",
|
|
17
17
|
"@tanstack/react-query": "^5.65.0",
|