@maykonpaulo/maestro-server 0.1.1 → 0.1.2-rc.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.
Files changed (2) hide show
  1. package/README.md +564 -1
  2. package/package.json +5 -10
package/README.md CHANGED
@@ -1,6 +1,569 @@
1
1
  # @maykonpaulo/maestro-server
2
2
 
3
- > 📖 **[Guia completo — criar o admin de qualquer sistema com o Maestro](https://github.com/maykonpaulo/maestro/blob/main/docs/guia-criar-admin.md)** passo a passo, do zero ao admin no ar, para qualquer banco.
3
+ Este guia leva um programador do zero a um **painel administrativo governado** (listar,
4
+ filtrar, criar, editar, excluir, exportar, com RBAC e auditoria) sobre **o banco de dados de
5
+ qualquer sistema** — sem escrever CRUD por entidade.
6
+
7
+ > **O que é o Maestro?** Uma engine metadata-driven em TypeScript que você conecta a um banco
8
+ > existente para operá-lo com segurança, sem acesso direto ao banco. Você aponta para o banco,
9
+ > o Maestro descobre o schema (ou você declara), e ele entrega uma API REST + uma UI de admin
10
+ > genérica que se auto-monta. É **agnóstico de framework, de banco e de domínio**.
11
+
12
+ ---
13
+
14
+ ## Índice
15
+
16
+ 1. [Pré-requisitos](#1-pré-requisitos)
17
+ 2. [Escolha seu banco (providers)](#2-escolha-seu-banco-providers)
18
+ 3. [Instalação](#3-instalação)
19
+ 4. [Caminho A — Turnkey (recomendado)](#4-caminho-a--turnkey-recomendado)
20
+ 5. [Caminho B — Declarativo/curado](#5-caminho-b--declarativocurado)
21
+ 6. [Autenticação (`actorResolver`)](#6-autenticação-actorresolver)
22
+ 7. [Autorização (RBAC)](#7-autorização-rbac)
23
+ 8. [Auditoria](#8-auditoria)
24
+ 9. [Operações customizadas (ações de negócio)](#9-operações-customizadas-ações-de-negócio)
25
+ 10. [Campos: tipos, sensíveis, soft delete, relações](#10-campos-tipos-sensíveis-soft-delete-relações)
26
+ 11. [A UI de admin (`maestro-admin`)](#11-a-ui-de-admin-maestro-admin)
27
+ 12. [A API HTTP (para frontends próprios)](#12-a-api-http-para-frontends-próprios)
28
+ 13. [Referência rápida](#13-referência-rápida)
29
+ 14. [Produção: checklist e ressalvas](#14-produção-checklist-e-ressalvas)
30
+ 15. [Solução de problemas](#15-solução-de-problemas)
31
+ 16. [Pacotes e versões](#16-pacotes-e-versões)
32
+
33
+ ---
34
+
35
+ ## 1. Pré-requisitos
36
+
37
+ - **Node.js 18+** e um gerenciador de pacotes (`npm`, `pnpm` ou `yarn`).
38
+ - Acesso ao banco de dados do sistema que você quer administrar (string de conexão).
39
+ - Um mecanismo de autenticação seu (JWT, cookie de sessão, etc.) — o Maestro **não** faz auth;
40
+ ele consome o "ator" que você já autenticou.
41
+
42
+ ---
43
+
44
+ ## 2. Escolha seu banco (providers)
45
+
46
+ O Maestro fala com o banco através de um **provider**. Existem 9 pacotes oficiais publicados —
47
+ cada um implementa leitura de schema (introspecção), CRUD real e criação de coleção/tabela:
48
+
49
+ | Banco | Pacote |
50
+ |---|---|
51
+ | PostgreSQL · MySQL · SQLite · SQL Server | `@maykonpaulo/maestro-provider-sql` |
52
+ | MongoDB | `@maykonpaulo/maestro-provider-mongodb` |
53
+ | Redis | `@maykonpaulo/maestro-provider-redis` |
54
+ | Elasticsearch | `@maykonpaulo/maestro-provider-elasticsearch` |
55
+ | DynamoDB | `@maykonpaulo/maestro-provider-dynamodb` |
56
+ | Cassandra | `@maykonpaulo/maestro-provider-cassandra` |
57
+ | Couchbase | `@maykonpaulo/maestro-provider-couchbase` |
58
+ | Firestore | `@maykonpaulo/maestro-provider-firestore` |
59
+ | Neo4j | `@maykonpaulo/maestro-provider-neo4j` |
60
+
61
+ > Banco fora dessa lista? Você pode implementar a interface `DatasourceProvider` (6 métodos) —
62
+ > ver seção [Solução de problemas](#15-solução-de-problemas). Mas para qualquer um acima, é só instalar.
63
+
64
+ ---
65
+
66
+ ## 3. Instalação
67
+
68
+ Instale a **engine**, o **provider** do seu banco, o **servidor turnkey** e a **UI**:
69
+
70
+ ```bash
71
+ # engine + servidor + UI
72
+ npm i @maykonpaulo/maestro-core @maykonpaulo/maestro-server @maykonpaulo/maestro-admin
73
+
74
+ # provider do seu banco (exemplo: MongoDB)
75
+ npm i @maykonpaulo/maestro-provider-mongodb
76
+ ```
77
+
78
+ Troque o provider pelo do seu banco (ex.: `@maykonpaulo/maestro-provider-sql`).
79
+
80
+ ---
81
+
82
+ ## 4. Caminho A — Turnkey (recomendado)
83
+
84
+ **Aponte para o banco e tenha um admin completo, sem declarar entidade nenhuma.** O Maestro
85
+ introspecta o banco, transforma cada coleção/tabela em uma entidade administrável e sobe um
86
+ servidor REST. É o caminho mais rápido.
87
+
88
+ ### 4.1 Conectar o provider
89
+
90
+ Escolha a fábrica do seu banco (confira as opções exatas de conexão no README do provider):
91
+
92
+ ```ts
93
+ // MongoDB
94
+ import { createMongoProvider } from '@maykonpaulo/maestro-provider-mongodb';
95
+ const provider = createMongoProvider({ uri: process.env.MONGO_URL!, database: 'app' });
96
+
97
+ // PostgreSQL (mesma família: mysql/sqlite/mssql via `dialect`)
98
+ import { createSqlProvider } from '@maykonpaulo/maestro-provider-sql';
99
+ const provider = createSqlProvider({ dialect: 'postgres', connectionString: process.env.PG_URL! });
100
+ // sqlite: createSqlProvider({ dialect: 'sqlite', databasePath: './app.db' })
101
+ // mysql: createSqlProvider({ dialect: 'mysql', uri: process.env.MYSQL_URL! })
102
+
103
+ // Outros
104
+ import { createRedisProvider } from '@maykonpaulo/maestro-provider-redis';
105
+ const provider = createRedisProvider({ uri: 'redis://localhost:6379' });
106
+ // createElasticsearchProvider({ node, auth })
107
+ // createDynamoDbProvider({ region })
108
+ // createCassandraProvider({ contactPoints, localDataCenter, keyspace })
109
+ // createCouchbaseProvider({ connectionString, username, password, bucket })
110
+ // createFirestoreProvider({ projectId })
111
+ // createNeo4jProvider({ uri, username, password })
112
+ ```
113
+
114
+ ### 4.2 Construir o engine por introspecção
115
+
116
+ ```ts
117
+ import { createIntrospectedEngine } from '@maykonpaulo/maestro-server';
118
+
119
+ const engine = await createIntrospectedEngine({
120
+ provider,
121
+ access: 'full', // 'full' = list/detalhe/criar/editar/excluir/exportar
122
+ // 'readonly' = só navegar (sem risco de alterar)
123
+ });
124
+ ```
125
+
126
+ `createIntrospectedEngine` descobre toda coleção/tabela e habilita as capacidades de escrita
127
+ (o padrão do core seria só-leitura — este helper é o que liga o CRUD).
128
+
129
+ **Opções:**
130
+
131
+ | Opção | Descrição |
132
+ |---|---|
133
+ | `provider` | O provider conectado (obrigatório). |
134
+ | `access` | `'full'` (padrão) ou `'readonly'`. |
135
+ | `datasourceId` | id do datasource (padrão `'main'`). |
136
+ | `policies` | Política RBAC (ver §7). Padrão: papel `admin` com `['*']`. |
137
+ | `overrides` | Sobreposição curada (rótulos, campos, RBAC) mesclada sobre o schema descoberto. |
138
+ | `operations` | Operações customizadas (ver §9). |
139
+ | `audit` | Repositório de auditoria (ver §8). |
140
+
141
+ ### 4.3 Subir o servidor
142
+
143
+ ```ts
144
+ import { createMaestroServer } from '@maykonpaulo/maestro-server';
145
+
146
+ const server = createMaestroServer({ engine /*, actorResolver, cors, basePath */ });
147
+ await server.listen(3000);
148
+ // → REST admin para cada coleção em http://localhost:3000/entities/:colecao
149
+ ```
150
+
151
+ ### 4.4 Autenticação
152
+
153
+ Sem `actorResolver`, o servidor usa um resolver **só-dev** que concede um ator admin a toda
154
+ requisição. **Em produção, sempre passe o seu** — ver [§6](#6-autenticação-actorresolver).
155
+
156
+ ### 4.5 Subir a UI
157
+
158
+ A UI genérica lê `GET /metadata` e se auto-monta (navegação, tabela, detalhe, formulários)
159
+ para **todas** as entidades. Rodando como app:
160
+
161
+ ```bash
162
+ VITE_MAESTRO_API_URL=http://localhost:3000 \
163
+ npm --prefix node_modules/@maykonpaulo/maestro-admin run dev
164
+ # abra http://localhost:5173
165
+ ```
166
+
167
+ Ou embutida no seu app React — ver [§11](#11-a-ui-de-admin-maestro-admin).
168
+
169
+ ### 4.6 Servidor completo (copy-paste)
170
+
171
+ ```ts
172
+ // server.ts
173
+ import { createMongoProvider } from '@maykonpaulo/maestro-provider-mongodb';
174
+ import { createMaestroServer, createIntrospectedEngine } from '@maykonpaulo/maestro-server';
175
+ import { InMemoryAuditRepository, type RbacPolicy } from '@maykonpaulo/maestro-core';
176
+
177
+ const provider = createMongoProvider({ uri: process.env.MONGO_URL!, database: 'app' });
178
+
179
+ const policies: RbacPolicy = {
180
+ roles: {
181
+ admin: { id: 'admin', name: 'Admin', permissions: ['*'] },
182
+ viewer: { id: 'viewer', name: 'Viewer', permissions: ['entity.*.list', 'entity.*.detail'] },
183
+ },
184
+ };
185
+
186
+ const engine = await createIntrospectedEngine({
187
+ provider,
188
+ access: 'full',
189
+ policies,
190
+ audit: new InMemoryAuditRepository(), // troque por seu repositório em produção (§8)
191
+ });
192
+
193
+ const server = createMaestroServer({
194
+ engine,
195
+ actorResolver: async (req) => {
196
+ // derive o ator da SUA autenticação (JWT/cookie)
197
+ const token = String(req.headers['authorization'] ?? '').replace('Bearer ', '');
198
+ const user = await verifyJwt(token); // sua função
199
+ return { actor: { id: user.sub, type: 'user', roles: user.roles } };
200
+ },
201
+ });
202
+
203
+ await server.listen(3000);
204
+ console.log('Admin API em http://localhost:3000');
205
+ ```
206
+
207
+ ---
208
+
209
+ ## 5. Caminho B — Declarativo/curado
210
+
211
+ Quando quiser **rótulos bonitos, RBAC fino, tipos de campo explícitos e formulários controlados**,
212
+ declare as entidades. Você tem controle total; o Maestro monta o resto.
213
+
214
+ ### 5.1 Declarar entidades
215
+
216
+ ```ts
217
+ import { type DeclarativeConfig } from '@maykonpaulo/maestro-core';
218
+
219
+ const declarations: DeclarativeConfig = {
220
+ entities: [
221
+ {
222
+ entity: 'order', // = nome da tabela/coleção
223
+ label: 'Pedido',
224
+ pluralLabel: 'Pedidos',
225
+ fields: {
226
+ id: { type: 'string', primary: true },
227
+ code: { type: 'string', label: 'Código', required: true, searchable: true, sortable: true },
228
+ status: { type: 'enum', label: 'Status',
229
+ enumOptions: [
230
+ { value: 'open', label: 'Aberto' },
231
+ { value: 'paid', label: 'Pago' },
232
+ { value: 'canceled', label: 'Cancelado' },
233
+ ] },
234
+ total: { type: 'currency', label: 'Total', sortable: true },
235
+ paid: { type: 'boolean', label: 'Pago' },
236
+ createdAt: { type: 'datetime', label: 'Criado em', sortable: true },
237
+ notes: { type: 'text', label: 'Observações' },
238
+ },
239
+ // capacidades: liste o que este admin pode fazer nesta entidade
240
+ capabilities: { list: true, detail: true, create: true, update: true, delete: true, export: true },
241
+ },
242
+ ],
243
+ };
244
+ ```
245
+
246
+ ### 5.2 `createMaestro` + servir
247
+
248
+ ```ts
249
+ import { createMaestro } from '@maykonpaulo/maestro-core';
250
+ import { createMaestroServer } from '@maykonpaulo/maestro-server';
251
+
252
+ const engine = createMaestro({
253
+ datasources: { main: provider }, // o provider do seu banco (§4.1)
254
+ declarations,
255
+ policies, // RBAC (§7)
256
+ audit: myAuditRepository, // (§8)
257
+ operations: [cancelOrder], // ações customizadas (§9)
258
+ });
259
+
260
+ await createMaestroServer({ engine, actorResolver }).listen(3000);
261
+ ```
262
+
263
+ ### 5.3 A vs B (e híbrido)
264
+
265
+ - **A (introspecção):** o mais rápido; toda coleção vira entidade; schema inferido.
266
+ - **B (declarativo):** controle total; ideal para as entidades que os operadores mais usam.
267
+ - **Híbrido:** passe `overrides` (config declarativa) para `createIntrospectedEngine` — o Maestro
268
+ descobre tudo e aplica seus rótulos/regras por cima nas entidades que você curou.
269
+
270
+ ---
271
+
272
+ ## 6. Autenticação (`actorResolver`)
273
+
274
+ Autenticação é **responsabilidade sua**. O único ponto onde ela entra no Maestro é o
275
+ `actorResolver`, que converte cada requisição em um **`Actor`**:
276
+
277
+ ```ts
278
+ const server = createMaestroServer({
279
+ engine,
280
+ actorResolver: async (req) => {
281
+ const token = String(req.headers['authorization'] ?? '').replace('Bearer ', '');
282
+ const user = await verifyJwt(token); // SUA autenticação
283
+ return {
284
+ actor: {
285
+ id: user.sub,
286
+ type: 'user', // 'user' | 'system' | 'job' | 'integration' | 'ai-agent'
287
+ name: user.name,
288
+ email: user.email,
289
+ roles: user.roles, // dão as permissões (§7)
290
+ },
291
+ correlationId: String(req.headers['x-correlation-id'] ?? ''), // opcional (rastreio na auditoria)
292
+ };
293
+ },
294
+ });
295
+ ```
296
+
297
+ - **Omitir `actorResolver` = rodar sem autenticação** (o default `devActorResolver` concede admin a
298
+ todos). Nunca faça isso em produção.
299
+ - O `Actor` é passado a **toda** operação; o RBAC decide o que ele pode fazer.
300
+
301
+ ---
302
+
303
+ ## 7. Autorização (RBAC)
304
+
305
+ Você define **papéis** e as **permissões** de cada um. O ator recebe permissões pelos seus `roles`.
306
+
307
+ ```ts
308
+ import { type RbacPolicy } from '@maykonpaulo/maestro-core';
309
+
310
+ const policies: RbacPolicy = {
311
+ roles: {
312
+ admin: { id: 'admin', name: 'Admin', permissions: ['*'] },
313
+ operator: { id: 'operator', name: 'Operador', permissions: ['entity.order.*', 'operation.order.cancel'] },
314
+ viewer: { id: 'viewer', name: 'Leitura', permissions: ['entity.*.list', 'entity.*.detail', 'entity.*.export'] },
315
+ },
316
+ };
317
+ ```
318
+
319
+ **Formato das permissões:**
320
+
321
+ | Permissão | Concede |
322
+ |---|---|
323
+ | `entity.<entidade>.<capacidade>` | Uma ação em uma entidade. Capacidades: `list`, `detail`, `create`, `update`, `clone`, `delete`, `softDelete`, `restore`, `export`. |
324
+ | `operation.<opId>` | Executar uma operação customizada (§9). |
325
+ | `entity.order.*` | Tudo na entidade `order`. |
326
+ | `entity.*.list` | `list` em todas as entidades. |
327
+ | `*` | Tudo. |
328
+
329
+ Curinga: `*` (tudo) e `prefixo.*` (tudo abaixo do prefixo). Um `403` é retornado quando negado — a
330
+ UI trata isso como erro na tela, sem quebrar.
331
+
332
+ > **Importante:** as **capacidades** (o que a entidade permite) e o **RBAC** (o que o ator pode) são
333
+ > checados juntos. No modo introspecção `access: 'full'`, todas as capacidades ficam ligadas; o RBAC
334
+ > é quem restringe por papel.
335
+
336
+ ---
337
+
338
+ ## 8. Auditoria
339
+
340
+ Toda operação emite um evento de auditoria quando você fornece um `AuditRepository`. Para começar,
341
+ use o `InMemoryAuditRepository`; em produção, implemente o contrato gravando no seu store:
342
+
343
+ ```ts
344
+ import { type AuditRepository, type AuditEvent } from '@maykonpaulo/maestro-core';
345
+
346
+ class MyAuditRepository implements AuditRepository {
347
+ async record(event: AuditEvent): Promise<void> {
348
+ await db.collection('audit').insertOne(event); // grave onde quiser
349
+ }
350
+ async list(filter) { /* consulte por ator/ação/entidade/período/correlationId */ return []; }
351
+ }
352
+ ```
353
+
354
+ Cada evento inclui ação, ator, recurso, nível, `before`/`after` (em update/delete) e `correlationId`.
355
+
356
+ ---
357
+
358
+ ## 9. Operações customizadas (ações de negócio)
359
+
360
+ Além do CRUD, exponha **ações** (ex.: "cancelar pedido", "reenviar e-mail"). Elas aparecem como
361
+ botões (por linha / em massa / globais) e executam sua lógica com RBAC + auditoria:
362
+
363
+ ```ts
364
+ import { type OperationDef } from '@maykonpaulo/maestro-core';
365
+
366
+ const cancelOrder: OperationDef = {
367
+ id: 'order.cancel',
368
+ label: 'Cancelar pedido',
369
+ entity: 'order',
370
+ scope: 'record', // 'record' | 'bulk' | 'global'
371
+ requiredPermission: 'operation.order.cancel',
372
+ execute: async ({ record, input, actor }) => {
373
+ // sua lógica de negócio aqui
374
+ await paymentGateway.refund(record.id);
375
+ return { success: true, message: 'Pedido cancelado.' };
376
+ },
377
+ };
378
+
379
+ // registre no engine:
380
+ createMaestro({ /* ... */ operations: [cancelOrder] });
381
+ // ou createIntrospectedEngine({ /* ... */ operations: [cancelOrder] });
382
+ ```
383
+
384
+ Chamada HTTP: `POST /operations/order.cancel` com `{ entityId, record, input }`.
385
+
386
+ ---
387
+
388
+ ## 10. Campos: tipos, sensíveis, soft delete, relações
389
+
390
+ **Tipos de campo** (`type`): `string`, `text`, `number`, `integer`, `decimal`, `currency`,
391
+ `boolean`, `date`, `datetime`, `time`, `email`, `phone`, `url`, `document`, `uuid`, `enum`,
392
+ `json`, `relation`, `array`. A UI escolhe o controle certo por tipo (checkbox, número, select,
393
+ data, textarea/JSON…).
394
+
395
+ **Flags úteis por campo** (no modo declarativo): `required`, `readonly`, `primary`, `sensitive`,
396
+ `searchable`, `sortable`, `filterable`, `exportable`, `enumOptions` (para `enum`), `relationEntity`
397
+ (para `relation`).
398
+
399
+ - **`sensitive: true`** — mascara o valor (`***`) na exportação CSV e na UI. (Logging/`before`/`after`
400
+ continuam responsabilidade sua.)
401
+ - **Soft delete** — configure um campo que marca "inativo" (ex.: `active`/`deletedAt`). As
402
+ operações `softDelete`/`restore` passam a existir em vez de exclusão física.
403
+ - **Relações** — o Maestro não infere FK em bancos NoSQL; declare relações à mão quando quiser abas
404
+ de relacionamento no detalhe.
405
+ - **Campos cifrados (E2EE / zero-knowledge)** — se o seu backend cifra campos, eles chegam **opacos**;
406
+ a UI os exibe como estão e **nunca descriptografa**. Comece o admin pelas coleções não cifradas.
407
+
408
+ ---
409
+
410
+ ## 11. A UI de admin (`maestro-admin`)
411
+
412
+ A UI (React + Vite + Tailwind) lê `GET /metadata` e monta sozinha: navegação por entidade, tabela
413
+ (com busca/ordenação/paginação/filtros vindos do metadata), detalhe, e formulários de criar/editar.
414
+ Ela respeita as **capacidades** (esconde New/Edit/Delete quando desabilitados) e o **RBAC** (403 vira
415
+ erro na tela). **Uma tela, todas as entidades.**
416
+
417
+ ### App standalone
418
+
419
+ ```bash
420
+ VITE_MAESTRO_API_URL=http://localhost:3000 \
421
+ npm --prefix node_modules/@maykonpaulo/maestro-admin run dev # dev server
422
+ # ou build estático:
423
+ VITE_MAESTRO_API_URL=http://localhost:3000 \
424
+ npm --prefix node_modules/@maykonpaulo/maestro-admin run build:app
425
+ ```
426
+
427
+ `VITE_MAESTRO_ROLE=viewer` (ou `?role=viewer` na URL) define o header `X-Role` — útil para testar RBAC.
428
+
429
+ ### Embutida no seu app React
430
+
431
+ ```tsx
432
+ import { MaestroAdmin } from '@maykonpaulo/maestro-admin';
433
+ import '@maykonpaulo/maestro-admin/src/styles.css';
434
+
435
+ export function AdminPage() {
436
+ return (
437
+ <MaestroAdmin
438
+ apiUrl="http://localhost:3000"
439
+ headers={() => ({ Authorization: `Bearer ${getToken()}` })} // pode ser função (token fresco a cada request)
440
+ title="Admin"
441
+ />
442
+ );
443
+ }
444
+ ```
445
+
446
+ Também exportamos os blocos (`EntityList`, `EntityDetail`, `EntityForm`, `Sidebar`, `useMetadata`,
447
+ `useEntityList`, `MaestroClient`, …) para montar um layout próprio.
448
+
449
+ ---
450
+
451
+ ## 12. A API HTTP (para frontends próprios)
452
+
453
+ Se você quiser construir sua própria UI (ou integrar outro sistema), o servidor expõe:
454
+
455
+ ```
456
+ GET /health
457
+ GET /metadata # descreve todas as entidades (campos, tipos, capacidades)
458
+ GET /metadata/:entidade
459
+ GET /entities/:entidade # list — query: page, pageSize, search, searchFields, sort, filter
460
+ POST /entities/:entidade # criar
461
+ GET /entities/:entidade/:id # detalhe
462
+ PATCH /entities/:entidade/:id # editar
463
+ DELETE /entities/:entidade/:id # excluir (hard delete)
464
+ POST /entities/:entidade/:id/clone
465
+ POST /entities/:entidade/:id/soft-delete
466
+ POST /entities/:entidade/:id/restore
467
+ GET /entities/:entidade/export # ?format=csv|json
468
+ POST /operations/:operationId # { entityId, record, input }
469
+ ```
470
+
471
+ **Query string do list:**
472
+
473
+ | Param | Exemplo | Significado |
474
+ |---|---|---|
475
+ | `page`, `pageSize` | `?page=1&pageSize=20` | Paginação. |
476
+ | `search`, `searchFields` | `?search=ada&searchFields=name,email` | Busca textual. |
477
+ | `sort` | `?sort=name:asc` (repetível) | Ordenação. |
478
+ | `filter` | `?filter=status:equals:open` (repetível) | Filtro `campo:operador:valor`. |
479
+
480
+ Todo endpoint checa RBAC e emite auditoria. O `GET /metadata` é o contrato para gerar qualquer UI.
481
+
482
+ ---
483
+
484
+ ## 13. Referência rápida
485
+
486
+ **Operadores de filtro:** `equals`, `notEquals`, `contains`, `startsWith`, `endsWith`, `in`,
487
+ `notIn`, `gt`, `gte`, `lt`, `lte`, `between`, `isNull`, `isNotNull`, `isTrue`, `isFalse`.
488
+
489
+ **Capacidades de entidade:** `list`, `detail`, `create`, `update`, `clone`, `delete`, `softDelete`,
490
+ `export`, `bulkActions`. Padrão do core: `list`/`detail` ligadas, o resto desligado (por segurança).
491
+ No modo `createIntrospectedEngine({ access: 'full' })`, todas ligadas.
492
+
493
+ **Métodos da engine** (se você usar o core direto, sem o servidor): `list`, `findById`, `create`,
494
+ `update`, `clone`, `softDelete`, `restore`, `hardDelete`, `export`, `executeOperation`, `getMetadata`
495
+ — todos recebem o `actor` e checam RBAC + auditoria.
496
+
497
+ **Actor:** `{ id, type: 'user'|'system'|'job'|'integration'|'ai-agent', name?, email?, roles?, permissions?, metadata? }`.
498
+
499
+ ---
500
+
501
+ ## 14. Produção: checklist e ressalvas
502
+
503
+ - [ ] **Sempre** forneça um `actorResolver` real (JWT/cookie). Sem ele = sem auth.
504
+ - [ ] Defina papéis RBAC de verdade (não deixe todo mundo `admin`/`['*']`).
505
+ - [ ] Comece com `access: 'readonly'` para validar a leitura do banco de produção sem risco; suba
506
+ para `'full'` quando confiar.
507
+ - [ ] Implemente um `AuditRepository` que persista (não o InMemory).
508
+ - [ ] Configure CORS conforme seu frontend (`createMaestroServer({ cors: { origin, credentials } })`).
509
+ - [ ] Comece o admin pelas coleções **operacionais não cifradas** (usuários, configs, etc.). Campos
510
+ E2EE aparecem opacos.
511
+ - [ ] Rode o servidor atrás do seu gateway/HTTPS; o Maestro é só a camada de operação.
512
+
513
+ ---
514
+
515
+ ## 15. Solução de problemas
516
+
517
+ - **"Nome da coleção não bate" (MongoDB/Mongoose).** No modo introspecção, cada entidade é a coleção
518
+ **real** (ex.: `users`). No modo declarativo, o `entity` da declaração é o nome da coleção — o
519
+ Mongoose costuma pluralizar (`User` → `users`); declare o nome real, ou use o `EntitySchema` de
520
+ baixo nível (`source.table`) para mapear um id amigável a uma coleção diferente.
521
+ - **`_id` (MongoDB).** O provider trata `_id` como `ObjectId` nativo **ou** string de forma
522
+ transparente — funciona sobre coleções existentes sem migração.
523
+ - **Campos `currency`/`decimal` aparecem como texto?** Use a versão mais recente do `maestro-admin`.
524
+ - **Banco não coberto pelos 9 providers.** Implemente `DatasourceProvider` (6 métodos: `list`,
525
+ `findById`, `create`, `update`, `delete`, `count`) e passe em `datasources: { main: seuProvider }`.
526
+ - **Publicou no `@latest` por engano?** Auth e canais de release não fazem parte deste guia — o
527
+ admin em si só precisa dos pacotes instalados e do servidor no ar.
528
+
529
+ ---
530
+
531
+ ## 16. Pacotes e versões
532
+
533
+ Instale pela tag `latest` (estável):
534
+
535
+ ```bash
536
+ npm i @maykonpaulo/maestro-core \
537
+ @maykonpaulo/maestro-server \
538
+ @maykonpaulo/maestro-admin \
539
+ @maykonpaulo/maestro-provider-<seu-banco>
540
+ ```
541
+
542
+ | Pacote | O que é |
543
+ |---|---|
544
+ | `@maykonpaulo/maestro-core` | Engine, contratos, metadata, RBAC, auditoria, operações, export. |
545
+ | `@maykonpaulo/maestro-server` | Servidor HTTP turnkey (`createMaestroServer`, `createIntrospectedEngine`). |
546
+ | `@maykonpaulo/maestro-admin` | UI genérica metadata-driven (app + componentes React). |
547
+ | `@maykonpaulo/maestro-provider-*` | Provider do seu banco (9 opções). |
548
+ | `@maykonpaulo/maestro-cli` | CLI opcional (`introspect`/`generate`/`validate`/`diff`/`snapshot`). |
549
+
550
+ ---
551
+
552
+ ### Resumo em 6 linhas
553
+
554
+ ```ts
555
+ const provider = createMongoProvider({ uri, database }); // 1. conecte o banco
556
+ const engine = await createIntrospectedEngine({ provider, access: 'full', policies, audit }); // 2. engine
557
+ const server = createMaestroServer({ engine, actorResolver }); // 3. auth + servidor
558
+ await server.listen(3000); // 4. API no ar
559
+ // 5. rode @maykonpaulo/maestro-admin apontando VITE_MAESTRO_API_URL para :3000
560
+ // 6. pronto: admin de todo o sistema, com RBAC e auditoria
561
+ ```
562
+
563
+ ---
564
+
565
+ ## Referência do pacote `@maykonpaulo/maestro-server`
566
+
4
567
 
5
568
  The **turnkey HTTP server** for [`@maykonpaulo/maestro-core`](https://www.npmjs.com/package/@maykonpaulo/maestro-core), per [ADR 0008 — Camada Turnkey](../../docs/adr/0008-turnkey-server-and-admin-ui.md).
6
569
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maykonpaulo/maestro-server",
3
- "version": "0.1.1",
3
+ "version": "0.1.2-rc.0",
4
4
  "description": "Turnkey HTTP server for @maykonpaulo/maestro-core — mounts the framework-agnostic Maestro HTTP handlers on a real Express server and turns any live datasource provider into a full, governed admin over the whole database (ADR 0008). The core stays server-free; this sibling package is the batteries-included layer.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "access": "public"
21
21
  },
22
22
  "peerDependencies": {
23
- "@maykonpaulo/maestro-core": "0.7.1"
23
+ "@maykonpaulo/maestro-core": "0.7.2-rc.0"
24
24
  },
25
25
  "dependencies": {
26
26
  "express": "^4.19.2"
@@ -34,15 +34,10 @@
34
34
  "tsup": "^8.0.0",
35
35
  "typescript": "^5.6.0",
36
36
  "vitest": "^2.0.0",
37
- "@maykonpaulo/maestro-core": "0.7.1",
38
- "@maykonpaulo/maestro-provider-mongodb": "1.0.1"
37
+ "@maykonpaulo/maestro-core": "0.7.2-rc.0",
38
+ "@maykonpaulo/maestro-provider-mongodb": "1.0.2-rc.0"
39
39
  },
40
- "repository": {
41
- "type": "git",
42
- "url": "https://github.com/maykonpaulo/maestro.git",
43
- "directory": "packages/server"
44
- },
45
- "homepage": "https://github.com/maykonpaulo/maestro#readme",
40
+ "homepage": "https://www.npmjs.com/package/@maykonpaulo/maestro-server",
46
41
  "scripts": {
47
42
  "build": "tsup",
48
43
  "test": "vitest run",