@mybuildex/pkg 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/acl/map.generated.js +25 -0
- package/dist/acl/map.generated.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/dist/network/context.d.ts +68 -0
- package/dist/network/context.js +189 -0
- package/dist/network/context.js.map +1 -0
- package/dist/network/plugin.d.ts +21 -0
- package/dist/network/plugin.js +179 -0
- package/dist/network/plugin.js.map +1 -0
- package/dist/network/replication.d.ts +86 -0
- package/dist/network/replication.js +328 -0
- package/dist/network/replication.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,6 +51,34 @@ createAuthMiddleware({
|
|
|
51
51
|
createTenantMiddleware({getTenantClient, defaultClient, strictTenant: true});
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
## 0.11.0 — governança de rede de escolas (matriz/filial)
|
|
55
|
+
|
|
56
|
+
Módulo novo, opt-in: API que não registra o plugin não muda nada. Veio da `v1_settings` sem mudança de comportamento (19/10/2026), para as outras APIs ligarem com uma linha.
|
|
57
|
+
|
|
58
|
+
- **`createNetworkPlugin({ttlMs, enabled, logger})`** — a escola é de rede quando o PRÓPRIO banco tem `configs.key = 'REDE'` com `TRUE` (gravada pelo core Go). Sem a flag o core nem é consultado. Com ela, o papel e as regras vêm do banco core (`my_builder_<env>_core`, por SQL cru qualificado no mesmo pool; env `CORE_DATABASE` sobrescreve):
|
|
59
|
+
- **filial** — cada ação (`read/add/edit/remove/restore/delete`) numa tabela do catálogo de módulos passa pelas `networks_policies`, **acima** da ACL: nega com 403 mesmo com a permissão do usuário. A ação sai da constante do router (`routeAcl.key` gravada pelo `useModuleAcl`) ou, sem ela, do método HTTP. A tabela é o segmento depois de `/v1/:id_school/`.
|
|
60
|
+
- **matriz** — pode tudo; o que grava nas tabelas do catálogo é replicado nas filiais com o mesmo id, numa transação única, no `onSend` (antes da resposta). Falha na réplica vira 500 com mensagem clara (a matriz já gravou, nenhuma filial foi alterada).
|
|
61
|
+
- **standalone** — sem flag, sem vínculo ou rede removida: nada muda.
|
|
62
|
+
- Core fora do ar numa escola de rede: 503 (fail-closed). Contexto em cache por escola (`NETWORK_CACHE_TTL_MS`, default 30 s). `NETWORK_GOVERNANCE=off` desliga tudo.
|
|
63
|
+
- **Ordem no `loadPlugins`:** depois do `createAclPlugin` (usa a `routeAcl` dele) e **antes** do `createCompressPlugin` (o `onSend` da réplica pode trocar o corpo por erro).
|
|
64
|
+
- **Para o front:** `effectivePermissions(request.network ?? standaloneContext(id))` devolve `{tabela: {read, add, ...}}` — é o que o `GET /v1/:id_school/networks/effective` da `v1_settings` responde.
|
|
65
|
+
- Limitações (como antes): SQL cru na matriz não replica; escrita aninhada em relação só replica a tabela do model chamado; a réplica não entra no `audit_logs`.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import {createNetworkPlugin} from "@mybuildex/pkg";
|
|
69
|
+
|
|
70
|
+
const pluginNetwork = createNetworkPlugin();
|
|
71
|
+
// loadPlugins
|
|
72
|
+
await createAclPlugin({api: settings.PREFIX, mode: "enforce"})(fastify);
|
|
73
|
+
await pluginNetwork(fastify);
|
|
74
|
+
await pluginCors(fastify);
|
|
75
|
+
await pluginCompress(fastify);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 0.10.3 — ACL_MAP com split de pagamento
|
|
79
|
+
|
|
80
|
+
- **`ACL_MAP` regerado do front** com os recursos `pay_split_recipients` (ações do CRUD + `sync`, para o botão "Sincronizar" que grava o recebedor no gateway) e `pay_split_rules`. Sem eles a `v1_payments` em enforce nega as rotas novas para todo mundo (10/10/2026). Nenhuma mudança de código.
|
|
81
|
+
|
|
54
82
|
## 0.10.2 — `trace` resumido na resposta de erro
|
|
55
83
|
|
|
56
84
|
- **`createErrorHandler` devolve `{statusCode, message, trace}`.** `trace` é o resumo do erro REAL — `Nome: mensagem @ primeiro frame do stack`, numa linha, com no máximo 255 caracteres (`TRACE_MAX_CHARS`) — e vem mesmo quando `message` é a genérica "Erro interno no processamento". Motivo (10/10/2026): o upload de arquivo do produto respondia só a genérica e o que estava acontecendo era "The table `pay_products_files` does not exist" — isso só aparecia no Cloud Logging. Vale para todas as APIs ao subirem esta versão; `trace: false` desliga e `trace: <n>` troca o limite. `resumirTrace(error)` é exportado.
|
|
@@ -1340,6 +1340,31 @@ exports.ACL_MAP = {
|
|
|
1340
1340
|
"restore": ["full", "pay_products_types.restore", "tipos_produto.restaura"],
|
|
1341
1341
|
"trash": ["full", "pay_products_types.trash", "tipos_produto.lixeira"],
|
|
1342
1342
|
},
|
|
1343
|
+
"pay_split_recipients": {
|
|
1344
|
+
"add": ["full", "pay_split_recipients.add", "recebedores_split.adiciona"],
|
|
1345
|
+
"delete": ["full", "pay_split_recipients.delete", "recebedores_split.exclui"],
|
|
1346
|
+
"edit": ["full", "pay_split_recipients.edit", "recebedores_split.edita"],
|
|
1347
|
+
"find": ["full", "pay_split_recipients.find", "recebedores_split.detalha"],
|
|
1348
|
+
"list": ["full", "pay_split_recipients.list", "recebedores_split.lista"],
|
|
1349
|
+
"menu": ["full", "pay_split_recipients.menu", "recebedores_split.menu"],
|
|
1350
|
+
"paginate": ["full", "pay_split_recipients.paginate", "recebedores_split.pagina"],
|
|
1351
|
+
"remover": ["full", "pay_split_recipients.remove", "recebedores_split.remove"],
|
|
1352
|
+
"restore": ["full", "pay_split_recipients.restore", "recebedores_split.restaura"],
|
|
1353
|
+
"sync": ["full", "pay_split_recipients.sync", "recebedores_split.sincroniza"],
|
|
1354
|
+
"trash": ["full", "pay_split_recipients.trash", "recebedores_split.lixeira"],
|
|
1355
|
+
},
|
|
1356
|
+
"pay_split_rules": {
|
|
1357
|
+
"add": ["full", "pay_split_rules.add", "regras_split.adiciona"],
|
|
1358
|
+
"delete": ["full", "pay_split_rules.delete", "regras_split.exclui"],
|
|
1359
|
+
"edit": ["full", "pay_split_rules.edit", "regras_split.edita"],
|
|
1360
|
+
"find": ["full", "pay_split_rules.find", "regras_split.detalha"],
|
|
1361
|
+
"list": ["full", "pay_split_rules.list", "regras_split.lista"],
|
|
1362
|
+
"menu": ["full", "pay_split_rules.menu", "regras_split.menu"],
|
|
1363
|
+
"paginate": ["full", "pay_split_rules.paginate", "regras_split.pagina"],
|
|
1364
|
+
"remover": ["full", "pay_split_rules.remove", "regras_split.remove"],
|
|
1365
|
+
"restore": ["full", "pay_split_rules.restore", "regras_split.restaura"],
|
|
1366
|
+
"trash": ["full", "pay_split_rules.trash", "regras_split.lixeira"],
|
|
1367
|
+
},
|
|
1343
1368
|
"pay_status": {
|
|
1344
1369
|
"add": ["full", "pay_status.add", "status_pagamento.adiciona"],
|
|
1345
1370
|
"delete": ["full", "pay_status.delete", "status_pagamento.exclui"],
|