gufi-cli 0.1.50 → 0.1.52
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/dist/commands/docs.js +1 -5
- package/dist/index.js +1 -0
- package/dist/lib/docs-resolver.d.ts +8 -0
- package/dist/lib/docs-resolver.js +27 -0
- package/dist/mcp.d.ts +3 -1
- package/dist/mcp.js +232 -34
- package/docs/dev-guide/1-01-architecture.md +358 -0
- package/docs/dev-guide/1-02-multi-tenant.md +415 -0
- package/docs/dev-guide/1-03-column-types.md +594 -0
- package/docs/dev-guide/1-04-json-config.md +442 -0
- package/docs/dev-guide/1-05-authentication.md +427 -0
- package/docs/dev-guide/2-01-api-reference.md +564 -0
- package/docs/dev-guide/2-02-automations.md +508 -0
- package/docs/dev-guide/2-03-gufi-cli.md +568 -0
- package/docs/dev-guide/2-04-realtime.md +401 -0
- package/docs/dev-guide/2-05-permissions.md +497 -0
- package/docs/dev-guide/2-06-integrations-overview.md +104 -0
- package/docs/dev-guide/2-07-stripe.md +173 -0
- package/docs/dev-guide/2-08-nayax.md +297 -0
- package/docs/dev-guide/2-09-ourvend.md +226 -0
- package/docs/dev-guide/2-10-tns.md +177 -0
- package/docs/dev-guide/2-11-custom-http.md +268 -0
- package/docs/dev-guide/3-01-custom-views.md +555 -0
- package/docs/dev-guide/3-02-webhooks-api.md +446 -0
- package/docs/mcp/00-overview.md +329 -0
- package/docs/mcp/01-architecture.md +220 -0
- package/docs/mcp/02-modules.md +285 -0
- package/docs/mcp/03-fields.md +357 -0
- package/docs/mcp/04-views.md +613 -0
- package/docs/mcp/05-automations.md +461 -0
- package/docs/mcp/06-api.md +480 -0
- package/docs/mcp/07-packages.md +246 -0
- package/docs/mcp/08-common-errors.md +284 -0
- package/docs/mcp/09-examples.md +453 -0
- package/docs/mcp/README.md +71 -0
- package/docs/mcp/tool-descriptions.json +49 -0
- package/package.json +3 -2
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Gufi MCP - Overview
|
|
2
|
+
|
|
3
|
+
> **15 tools** para construir ERPs con Gufi. Simple, eficiente, directo.
|
|
4
|
+
|
|
5
|
+
## Que es Gufi
|
|
6
|
+
|
|
7
|
+
**Gufi** es una plataforma para crear ERPs personalizados sin codigo backend:
|
|
8
|
+
- Defines estructura de datos (modules) → Gufi crea tablas PostgreSQL
|
|
9
|
+
- Creas vistas React → Gufi las conecta con los datos
|
|
10
|
+
- Escribes automations JavaScript → Gufi las ejecuta en triggers/cron
|
|
11
|
+
|
|
12
|
+
**Filosofia**: "Simple · Professional · Elegance"
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Los 15 Tools MCP
|
|
17
|
+
|
|
18
|
+
### Contexto y Info (3)
|
|
19
|
+
|
|
20
|
+
| Tool | Uso |
|
|
21
|
+
|------|-----|
|
|
22
|
+
| `gufi_context` | **SIEMPRE PRIMERO** - Obtener schema completo |
|
|
23
|
+
| `gufi_whoami` | Ver usuario, entorno, empresas |
|
|
24
|
+
| `gufi_docs` | Leer documentacion (topics: fields, automations, errors...) |
|
|
25
|
+
|
|
26
|
+
### Schema (1)
|
|
27
|
+
|
|
28
|
+
| Tool | Uso |
|
|
29
|
+
|------|-----|
|
|
30
|
+
| `gufi_schema_modify` | Crear/editar entities y fields (operaciones atomicas) |
|
|
31
|
+
|
|
32
|
+
### Automations (5)
|
|
33
|
+
|
|
34
|
+
| Tool | Uso |
|
|
35
|
+
|------|-----|
|
|
36
|
+
| `gufi_automation_scripts` | Scripts: list, get, create, update, delete |
|
|
37
|
+
| `gufi_automation_script_test` | Testear script manualmente |
|
|
38
|
+
| `gufi_automation_meta` | Triggers: ver/configurar en entidades |
|
|
39
|
+
| `gufi_automation_integrations` | Ver integraciones built-in (Stripe, Nayax, etc.) |
|
|
40
|
+
| `gufi_automation_executions` | Debugging: historial de ejecuciones |
|
|
41
|
+
|
|
42
|
+
### Datos (1)
|
|
43
|
+
|
|
44
|
+
| Tool | Uso |
|
|
45
|
+
|------|-----|
|
|
46
|
+
| `gufi_data` | CRUD: list, get, create, update, delete, aggregate |
|
|
47
|
+
|
|
48
|
+
### Environment (1)
|
|
49
|
+
|
|
50
|
+
| Tool | Uso |
|
|
51
|
+
|------|-----|
|
|
52
|
+
| `gufi_env` | Variables: list, set, delete |
|
|
53
|
+
|
|
54
|
+
### Views (3)
|
|
55
|
+
|
|
56
|
+
| Tool | Uso |
|
|
57
|
+
|------|-----|
|
|
58
|
+
| `gufi_view_pull` | Descargar vista a local para editar |
|
|
59
|
+
| `gufi_view_push` | Subir cambios a draft |
|
|
60
|
+
| `gufi_view_test` | Test en headless browser (errores, screenshot) |
|
|
61
|
+
|
|
62
|
+
### Packages (1)
|
|
63
|
+
|
|
64
|
+
| Tool | Uso |
|
|
65
|
+
|------|-----|
|
|
66
|
+
| `gufi_package` | Gestion: list, get, create, delete, add_module, remove_module, publish |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Workflow Tipico
|
|
71
|
+
|
|
72
|
+
### 1. Obtener contexto (SIEMPRE PRIMERO)
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
gufi_context({ company_id: '146' })
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Devuelve schema completo: modulos, entidades, campos, relaciones, automations.
|
|
79
|
+
|
|
80
|
+
### 2. Modificar estructura (Schema)
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
// Crear entidad
|
|
84
|
+
gufi_schema_modify({
|
|
85
|
+
company_id: '146',
|
|
86
|
+
operations: [{
|
|
87
|
+
op: 'add_entity',
|
|
88
|
+
module: 'ventas',
|
|
89
|
+
entity: { name: 'facturas', label: 'Facturas', kind: 'table' }
|
|
90
|
+
}]
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Agregar campo
|
|
94
|
+
gufi_schema_modify({
|
|
95
|
+
company_id: '146',
|
|
96
|
+
operations: [{
|
|
97
|
+
op: 'add_field',
|
|
98
|
+
entity: 'ventas.facturas',
|
|
99
|
+
field: { name: 'total', type: 'currency', label: 'Total' }
|
|
100
|
+
}]
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// Preview (dry run)
|
|
104
|
+
gufi_schema_modify({
|
|
105
|
+
company_id: '146',
|
|
106
|
+
preview: true,
|
|
107
|
+
operations: [...]
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3. Operar datos (CRUD)
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// Listar
|
|
115
|
+
gufi_data({ action: 'list', table: 'ventas.facturas', company_id: '146' })
|
|
116
|
+
|
|
117
|
+
// Crear
|
|
118
|
+
gufi_data({
|
|
119
|
+
action: 'create',
|
|
120
|
+
table: 'ventas.facturas',
|
|
121
|
+
company_id: '146',
|
|
122
|
+
data: { numero: 'F-001', total: 150.50 }
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// Actualizar (IMPORTANTE: incluir __display para select/relation)
|
|
126
|
+
gufi_data({
|
|
127
|
+
action: 'update',
|
|
128
|
+
table: 'ventas.facturas',
|
|
129
|
+
company_id: '146',
|
|
130
|
+
id: 123,
|
|
131
|
+
data: {
|
|
132
|
+
estado: 'pagada',
|
|
133
|
+
estado__display: 'Pagada'
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
// Eliminar
|
|
138
|
+
gufi_data({ action: 'delete', table: 'ventas.facturas', company_id: '146', id: 123 })
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 4. Crear logica (Automations)
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
// Crear script
|
|
145
|
+
gufi_automation_scripts({
|
|
146
|
+
action: 'create',
|
|
147
|
+
company_id: '146',
|
|
148
|
+
name: 'enviar_factura',
|
|
149
|
+
code: `
|
|
150
|
+
async function enviar_factura(gufi) {
|
|
151
|
+
const { row, env } = gufi.context;
|
|
152
|
+
|
|
153
|
+
await gufi.integrations.notifications.email({
|
|
154
|
+
to: row.cliente_email,
|
|
155
|
+
subject: 'Nueva factura',
|
|
156
|
+
html: '<p>Adjuntamos su factura.</p>',
|
|
157
|
+
user: env.EMAIL_USER,
|
|
158
|
+
pass: env.EMAIL_PASS,
|
|
159
|
+
from: env.EMAIL_FROM,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
return { success: true };
|
|
163
|
+
}
|
|
164
|
+
`
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// Asignar trigger a entidad
|
|
168
|
+
gufi_automation_meta({
|
|
169
|
+
entity_id: '123',
|
|
170
|
+
company_id: '146',
|
|
171
|
+
automations: [
|
|
172
|
+
{ trigger: 'insert', function_name: 'enviar_factura' }
|
|
173
|
+
]
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// Debugging
|
|
177
|
+
gufi_automation_executions({ company_id: '146', script_name: 'enviar_factura' })
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 5. Editar vistas (Pull/Push/Test)
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
// 1. Descargar a ~/gufi-dev/view_13/
|
|
184
|
+
gufi_view_pull({ view_id: 13 })
|
|
185
|
+
|
|
186
|
+
// 2. Editar archivos localmente con Read/Edit tools
|
|
187
|
+
// ...
|
|
188
|
+
|
|
189
|
+
// 3. Subir cambios a draft
|
|
190
|
+
gufi_view_push({ view_id: 13, message: 'Fixed chart colors' })
|
|
191
|
+
|
|
192
|
+
// 4. Testear en headless browser (OBLIGATORIO antes de publicar)
|
|
193
|
+
gufi_view_test({ view_id: 13, company_id: '116' })
|
|
194
|
+
|
|
195
|
+
// 5. Si todo OK, publicar package
|
|
196
|
+
gufi_package({ action: 'publish', id: '19' })
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Entorno: Produccion vs Dev
|
|
202
|
+
|
|
203
|
+
### Cambiar entorno (forma principal)
|
|
204
|
+
|
|
205
|
+
El entorno se configura **globalmente** con el CLI:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Ver entorno actual
|
|
209
|
+
gufi whoami
|
|
210
|
+
|
|
211
|
+
# Cambiar a desarrollo (localhost:3000)
|
|
212
|
+
gufi config:local
|
|
213
|
+
gufi login
|
|
214
|
+
|
|
215
|
+
# Cambiar a produccion (gogufi.com)
|
|
216
|
+
gufi config:prod
|
|
217
|
+
gufi login
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Una vez configurado, **TODAS las herramientas MCP usan ese entorno automaticamente**.
|
|
221
|
+
|
|
222
|
+
### Override por llamada (requiere login previo)
|
|
223
|
+
|
|
224
|
+
Si ya tienes login en ambos entornos, puedes hacer override con `env`:
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
// Usa el entorno configurado (default)
|
|
228
|
+
gufi_context({ company_id: '146' })
|
|
229
|
+
|
|
230
|
+
// Override a dev (SOLO si ya hiciste gufi config:local && gufi login antes)
|
|
231
|
+
gufi_context({ company_id: '146', env: 'dev' })
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**IMPORTANTE**: El parametro `env: 'dev'` **fallará** si no tienes credenciales guardadas para ese entorno. Primero ejecuta:
|
|
235
|
+
```bash
|
|
236
|
+
gufi config:local && gufi login
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
| Entorno | URL | Base de datos | Cuando usar |
|
|
240
|
+
|---------|-----|---------------|-------------|
|
|
241
|
+
| `prod` (default) | gogufi.com | Cloud SQL Prod | Produccion, datos reales |
|
|
242
|
+
| `dev` / `local` | localhost:3000 | Cloud SQL Dev | Desarrollo, pruebas |
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Conceptos Clave
|
|
247
|
+
|
|
248
|
+
### Nombres de tabla: Logicos vs Fisicos
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
// CORRECTO - Nombre logico (dataProvider lo resuelve)
|
|
252
|
+
gufi_data({ table: 'ventas.facturas', ... })
|
|
253
|
+
|
|
254
|
+
// CORRECTO - ID fisico (cuando lo necesites)
|
|
255
|
+
gufi_data({ table: 'm360_t16192', ... })
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Campos __display
|
|
259
|
+
|
|
260
|
+
Para `select` y `relation`, actualizar AMBOS campos:
|
|
261
|
+
|
|
262
|
+
```javascript
|
|
263
|
+
gufi_data({
|
|
264
|
+
action: 'update',
|
|
265
|
+
data: {
|
|
266
|
+
estado: 'completado', // Valor
|
|
267
|
+
estado__display: 'Completado' // Label visible
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### gufi.query() en automations
|
|
273
|
+
|
|
274
|
+
**Devuelve rows directamente** (NO destructuring):
|
|
275
|
+
|
|
276
|
+
```javascript
|
|
277
|
+
// CORRECTO
|
|
278
|
+
const rows = await gufi.query('SELECT * FROM tabla WHERE id = $1', [5]);
|
|
279
|
+
|
|
280
|
+
// INCORRECTO
|
|
281
|
+
const { rows } = await gufi.query(...); // ERROR!
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Referencias Rapidas
|
|
287
|
+
|
|
288
|
+
### Topics de documentacion (gufi_docs)
|
|
289
|
+
|
|
290
|
+
| Topic | Contenido |
|
|
291
|
+
|-------|-----------|
|
|
292
|
+
| `overview` | Este archivo |
|
|
293
|
+
| `architecture` | Componentes del sistema |
|
|
294
|
+
| `modules` | Sistema de modulos |
|
|
295
|
+
| `fields` | Tipos de campos y CB builders |
|
|
296
|
+
| `views` | Custom Views |
|
|
297
|
+
| `automations` | Scripts y triggers |
|
|
298
|
+
| `api` | API REST |
|
|
299
|
+
| `packages` | Sistema de packages |
|
|
300
|
+
| `errors` | Errores comunes |
|
|
301
|
+
| `examples` | Ejemplos practicos |
|
|
302
|
+
|
|
303
|
+
### Operaciones de gufi_schema_modify
|
|
304
|
+
|
|
305
|
+
| Operacion | Descripcion |
|
|
306
|
+
|-----------|-------------|
|
|
307
|
+
| `add_entity` | Crear entidad |
|
|
308
|
+
| `update_entity` | Modificar entidad |
|
|
309
|
+
| `remove_entity` | Eliminar entidad |
|
|
310
|
+
| `add_field` | Agregar campo |
|
|
311
|
+
| `update_field` | Modificar campo |
|
|
312
|
+
| `remove_field` | Eliminar campo |
|
|
313
|
+
| `add_submodule` | Agregar seccion |
|
|
314
|
+
|
|
315
|
+
### Acciones de gufi_package
|
|
316
|
+
|
|
317
|
+
| Accion | Descripcion |
|
|
318
|
+
|--------|-------------|
|
|
319
|
+
| `list` | Listar mis packages |
|
|
320
|
+
| `get` | Ver detalles de package |
|
|
321
|
+
| `create` | Crear package |
|
|
322
|
+
| `delete` | Eliminar package |
|
|
323
|
+
| `add_module` | Agregar modulo |
|
|
324
|
+
| `remove_module` | Quitar modulo |
|
|
325
|
+
| `publish` | Publicar a produccion |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
**Ultima actualizacion**: 2025-02-04
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Arquitectura de Gufi
|
|
2
|
+
|
|
3
|
+
## Componentes principales
|
|
4
|
+
|
|
5
|
+
### Backend (Express.js) - Puerto 3000
|
|
6
|
+
|
|
7
|
+
Archivo principal: `backend/server.js`
|
|
8
|
+
|
|
9
|
+
**Features organizadas en:**
|
|
10
|
+
```
|
|
11
|
+
backend/src/features/
|
|
12
|
+
├── auth/ # Login, refresh, JWT
|
|
13
|
+
├── companies/ # CRUD companies, schema
|
|
14
|
+
├── modules/ # Estructura de datos (JSON -> DDL)
|
|
15
|
+
├── tables/ # CRUD generico de registros
|
|
16
|
+
├── automations/ # Scripts y triggers
|
|
17
|
+
├── views/ # Custom Views API
|
|
18
|
+
├── files/ # Upload/download GCS
|
|
19
|
+
├── imports/ # Import wizard (Excel)
|
|
20
|
+
├── exports/ # Export (Excel, PDF)
|
|
21
|
+
├── cli/ # Endpoints para CLI
|
|
22
|
+
├── push/ # Push notifications (FCM)
|
|
23
|
+
├── webhooks/ # Webhooks externos
|
|
24
|
+
└── ...
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Rutas importantes:**
|
|
28
|
+
- `/api/auth/*` - Autenticacion
|
|
29
|
+
- `/api/company/schema` - Schema completo
|
|
30
|
+
- `/api/company/modules` - CRUD modulos
|
|
31
|
+
- `/api/tables/:table/*` - CRUD registros
|
|
32
|
+
- `/api/automation-scripts/*` - Scripts
|
|
33
|
+
- `/api/cli/*` - CLI endpoints
|
|
34
|
+
|
|
35
|
+
### Frontend (React + Vite) - Puerto 5173
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
frontend/src/
|
|
39
|
+
├── sdk/ # SDK centralizado (@/sdk)
|
|
40
|
+
│ ├── hooks/ # useViewData, useFeatureData
|
|
41
|
+
│ ├── components/ # FeatureContainer, KPICard
|
|
42
|
+
│ ├── utils/ # formatNumber, groupBy
|
|
43
|
+
│ └── sdk/ # processSeedData, etc.
|
|
44
|
+
├── features/
|
|
45
|
+
│ ├── core_views/ # table, dashboard
|
|
46
|
+
│ ├── custom_views/ # Apps custom (delivery, machines)
|
|
47
|
+
│ ├── view_engine/ # ViewGateway, plugins
|
|
48
|
+
│ └── view_templates/ # Templates para crear vistas
|
|
49
|
+
├── pages/ # Paginas principales
|
|
50
|
+
├── shared/ # Componentes compartidos
|
|
51
|
+
└── stores/ # Zustand stores
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### WebSocket Server - Puerto 4000
|
|
55
|
+
|
|
56
|
+
Archivo: `websocket/server.js`
|
|
57
|
+
|
|
58
|
+
**Funcionalidades:**
|
|
59
|
+
- Realtime updates (PostgreSQL LISTEN/NOTIFY)
|
|
60
|
+
- Code refresh para desarrollo (CLI push)
|
|
61
|
+
- Developer logs (console.log de vistas)
|
|
62
|
+
- Subscriptions por tabla/company
|
|
63
|
+
|
|
64
|
+
**Formato mensaje:**
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"type": "subscribe",
|
|
68
|
+
"table": "m360_t16192",
|
|
69
|
+
"company_id": 116
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Worker (pg-boss)
|
|
74
|
+
|
|
75
|
+
Archivo: `backend/src/core/services/queue/pgBossWorkerV9.js`
|
|
76
|
+
|
|
77
|
+
**Colas:**
|
|
78
|
+
- `automation` - Ejecuta automations
|
|
79
|
+
- `duplicate-company` - Duplica companies
|
|
80
|
+
- `install-package` - Instala packages
|
|
81
|
+
- `geocode-batch` - Geocoding de imports
|
|
82
|
+
|
|
83
|
+
**Flujo automation:**
|
|
84
|
+
```
|
|
85
|
+
1. Trigger (insert/update/delete) en tabla
|
|
86
|
+
2. PostgreSQL NOTIFY → pg-boss job
|
|
87
|
+
3. Worker ejecuta runAutomation()
|
|
88
|
+
4. Resultado en automation_executions
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Views Server
|
|
92
|
+
|
|
93
|
+
Archivo: `views/src/views.controller.js`
|
|
94
|
+
|
|
95
|
+
**Funcionalidades:**
|
|
96
|
+
- Compilar vistas (esbuild)
|
|
97
|
+
- Validar featureConfig
|
|
98
|
+
- Gestionar versiones
|
|
99
|
+
- Hot reload para desarrollo
|
|
100
|
+
|
|
101
|
+
## Base de datos
|
|
102
|
+
|
|
103
|
+
### Schema `core` (compartido)
|
|
104
|
+
|
|
105
|
+
```sql
|
|
106
|
+
-- Usuarios y auth
|
|
107
|
+
core.users
|
|
108
|
+
core.user_companies
|
|
109
|
+
core.refresh_tokens
|
|
110
|
+
|
|
111
|
+
-- Estructura
|
|
112
|
+
core.modules
|
|
113
|
+
core.entities
|
|
114
|
+
|
|
115
|
+
-- Automations
|
|
116
|
+
core.automation_scripts
|
|
117
|
+
core.automation_meta
|
|
118
|
+
core.automation_executions
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
-- Config
|
|
122
|
+
core.company_env_variables
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Schema `company_{id}` (por empresa)
|
|
126
|
+
|
|
127
|
+
```sql
|
|
128
|
+
-- Tablas de datos (generadas de modules)
|
|
129
|
+
m{moduleId}_t{entityId}
|
|
130
|
+
|
|
131
|
+
-- Cada tabla tiene:
|
|
132
|
+
-- id SERIAL PRIMARY KEY
|
|
133
|
+
-- created_at TIMESTAMP
|
|
134
|
+
-- ... campos definidos en module JSON
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Schema `pgboss` (job queue)
|
|
138
|
+
|
|
139
|
+
```sql
|
|
140
|
+
pgboss.job -- Jobs pendientes
|
|
141
|
+
pgboss.archive -- Jobs completados
|
|
142
|
+
pgboss.schedule -- Scheduled jobs
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Multi-tenancy
|
|
146
|
+
|
|
147
|
+
### Aislamiento
|
|
148
|
+
|
|
149
|
+
1. JWT contiene `company_id`
|
|
150
|
+
2. Backend hace `SET search_path TO company_{id}, core, public`
|
|
151
|
+
3. Queries se ejecutan en schema correcto automaticamente
|
|
152
|
+
|
|
153
|
+
### Nombres de tabla
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
m{moduleId}_t{entityId}
|
|
157
|
+
|
|
158
|
+
Ejemplos:
|
|
159
|
+
- m360_t16192 (modulo 360, entidad 16192)
|
|
160
|
+
- m308_t4136 (modulo 308, entidad 4136)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Para saber que modulo/entidad:
|
|
164
|
+
```sql
|
|
165
|
+
SELECT m.id as module_id, e.id as entity_id, e.name
|
|
166
|
+
FROM core.modules m, jsonb_array_elements(m.json_definition->'submodules') sub,
|
|
167
|
+
jsonb_array_elements(sub->'entities') e
|
|
168
|
+
WHERE m.company_id = 116;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Autenticacion
|
|
172
|
+
|
|
173
|
+
### JWT Flow
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
1. POST /api/auth/login { email, password }
|
|
177
|
+
-> { accessToken, refreshToken }
|
|
178
|
+
|
|
179
|
+
2. Requests con: Authorization: Bearer {accessToken}
|
|
180
|
+
X-Company-ID: {companyId}
|
|
181
|
+
|
|
182
|
+
3. Token expira -> POST /api/auth/refresh
|
|
183
|
+
-> { accessToken, refreshToken }
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Permisos (RBAC)
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
// En entity.permissions:
|
|
190
|
+
{
|
|
191
|
+
"admin": "*", // Todo permitido
|
|
192
|
+
"manager": ["entity:view", "entity:create", "entity:update"],
|
|
193
|
+
"viewer": ["entity:view"]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Permisos posibles:
|
|
197
|
+
// entity:view, entity:create, entity:update, entity:delete
|
|
198
|
+
// entity:import, entity:export
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Comunicacion entre servicios
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
Frontend <--HTTP--> Backend <--SQL--> PostgreSQL
|
|
205
|
+
| | |
|
|
206
|
+
|<---WebSocket-----|<--NOTIFY---------|
|
|
207
|
+
| |
|
|
208
|
+
| Worker <--pg-boss queue
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Puertos por defecto
|
|
212
|
+
|
|
213
|
+
| Servicio | Puerto | Descripcion |
|
|
214
|
+
|----------|--------|-------------|
|
|
215
|
+
| Backend | 3000 | API principal |
|
|
216
|
+
| Frontend | 5173 | React dev server |
|
|
217
|
+
| WebSocket | 4000 | Realtime |
|
|
218
|
+
| PostgreSQL | 5432 | Base de datos |
|
|
219
|
+
| Redis | 6379 | Cache (opcional) |
|
|
220
|
+
| Views | 3001 | Compilacion vistas |
|