gufi-cli 0.1.11 → 0.1.16

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/CLAUDE.md CHANGED
@@ -21,9 +21,10 @@ Gufi es un **ERP multi-tenant** donde cada empresa (company) tiene su propia bas
21
21
  │ │
22
22
  ├─────────────────────────────────────────────────────────────────┤
23
23
  │ core.modules → Definiciones JSON de módulos │
24
- │ core.entities → Metadatos de cada tabla
24
+ │ core.entities → Metadatos (permissions, automations)
25
+ │ core.entities.automations → FUENTE DE VERDAD de automations │
25
26
  │ core.automation_scripts → Código JavaScript de automations │
26
- │ core.automation_meta → Vincula scripts a triggers
27
+ │ core.automation_meta → Índice para worker (sync auto)
27
28
  ├─────────────────────────────────────────────────────────────────┤
28
29
  │ marketplace.packages → Paquetes publicados │
29
30
  │ marketplace.views → Vistas React/TypeScript │
@@ -44,6 +45,105 @@ Ejemplo:
44
45
 
45
46
  ---
46
47
 
48
+ ## 💜 Core Database - Relaciones Importantes
49
+
50
+ ### Diagrama de Relaciones
51
+
52
+ ```
53
+ ┌─────────────────────────────────────────────────────────────────────────────┐
54
+ │ SCHEMA: core │
55
+ ├─────────────────────────────────────────────────────────────────────────────┤
56
+ │ │
57
+ │ companies (1) │
58
+ │ ├── id: 116 │
59
+ │ ├── name: "Fitvending" │
60
+ │ └── schema: "company_116" │
61
+ │ │ │
62
+ │ │ 1:N │
63
+ │ ▼ │
64
+ │ modules (N) users (N) │
65
+ │ ├── id: 308 ├── id: 16 │
66
+ │ ├── company_id: 116 ◄────────── ├── email: "juan@gufi.es" │
67
+ │ ├── name: "nayax" └── platform_role: "admin" │
68
+ │ └── json_definition: {...} │ │
69
+ │ │ │ N:M │
70
+ │ │ 1:N ▼ │
71
+ │ ▼ company_users │
72
+ │ entities (N) ├── user_id: 16 │
73
+ │ ├── id: 4136 ├── company_id: 116 │
74
+ │ ├── module_id: 308 ◄─────────── └── roles: ["Admin"] │
75
+ │ ├── company_id: 116 │
76
+ │ ├── name: "machines" │
77
+ │ ├── permissions: {"Admin": "*"} ◄── Permisos por rol │
78
+ │ └── automations: [{...}] ◄── JSONB array de triggers │
79
+ │ │ │
80
+ │ │ N:1 (via script_id en automations) │
81
+ │ ▼ │
82
+ │ automation_scripts (N) │
83
+ │ ├── id: 15 │
84
+ │ ├── company_id: 116 │
85
+ │ ├── name: "sync_machines" │
86
+ │ └── code: "async function..." ◄── El JavaScript │
87
+ │ │ │
88
+ │ │ (sync automático) │
89
+ │ ▼ │
90
+ │ automation_meta (índice para worker) │
91
+ │ automation_executions (historial) │
92
+ │ │
93
+ └─────────────────────────────────────────────────────────────────────────────┘
94
+
95
+ ┌─────────────────────────────────────────────────────────────────────────────┐
96
+ │ SCHEMA: company_116 │
97
+ ├─────────────────────────────────────────────────────────────────────────────┤
98
+ │ │
99
+ │ m308_t4136 (machines) m308_t4137 (products) m308_t4140 (sales) │
100
+ │ ├── id ├── id ├── id │
101
+ │ ├── name ├── name ├── machine_id (FK) │
102
+ │ └── ... └── ... └── ... │
103
+ │ │
104
+ │ __audit_log__ (historial de cambios) │
105
+ │ │
106
+ └─────────────────────────────────────────────────────────────────────────────┘
107
+ ```
108
+
109
+ ### Tablas Core Principales
110
+
111
+ | Tabla | Descripción | Relaciones |
112
+ |-------|-------------|------------|
113
+ | `companies` | Empresas/tenants | 1 company → N modules, N users |
114
+ | `users` | Usuarios globales | N:M con companies via company_users |
115
+ | `company_users` | Membresía usuario-empresa | Contiene roles[] del usuario en esa company |
116
+ | `modules` | Definición JSON de módulos | 1 module → N entities |
117
+ | `entities` | Metadatos de tablas | Contiene permissions, automations, config |
118
+ | `automation_scripts` | Código JavaScript | 1 script → N entities pueden usarlo |
119
+ | `automation_meta` | Índice para worker | Generado auto desde entities.automations |
120
+
121
+ ### Flujo de Datos
122
+
123
+ ```
124
+ Usuario hace login
125
+
126
+
127
+ JWT contiene: { user_id, company_id, roles[], platform_role }
128
+
129
+
130
+ Backend: SET search_path TO company_116, core;
131
+
132
+
133
+ Queries van automáticamente al schema correcto
134
+ ```
135
+
136
+ ### IDs Importantes para CLI
137
+
138
+ | Quiero trabajar con... | Necesito el ID de... | Cómo obtenerlo |
139
+ |------------------------|---------------------|----------------|
140
+ | Datos de una tabla | entity (tabla física: m308_t4136) | `gufi schema -c 116` |
141
+ | Estructura de módulo | module_id | `gufi modules 116` |
142
+ | Código de automation | script_id | `gufi automations -c 116` |
143
+ | Triggers de una entity | entity_id | `gufi schema -c 116` |
144
+
145
+ ---
146
+
47
147
  ## Estructura de un Módulo (JSON)
48
148
 
49
149
  Un módulo es un JSON que define **toda la estructura de datos** de una funcionalidad. Gufi lee este JSON y automáticamente:
@@ -122,11 +222,6 @@ Un módulo es un JSON que define **toda la estructura de datos** de una funciona
122
222
  "label": "Comercial Asignado"
123
223
  }
124
224
  ],
125
- "permissions": {
126
- "Admin": "*",
127
- "Comercial": "crud",
128
- "User": "read"
129
- },
130
225
  "ui": {
131
226
  "defaultSort": { "field": "nombre", "order": "ASC" },
132
227
  "searchFields": ["nombre", "email"],
@@ -180,11 +275,7 @@ Un módulo es un JSON que define **toda la estructura de datos** de una funciona
180
275
  "type": "image",
181
276
  "label": "Imagen"
182
277
  }
183
- ],
184
- "permissions": {
185
- "Admin": "*",
186
- "User": "read"
187
- }
278
+ ]
188
279
  }
189
280
  ]
190
281
  },
@@ -251,18 +342,13 @@ Un módulo es un JSON que define **toda la estructura de datos** de una funciona
251
342
  "label": "Observaciones"
252
343
  }
253
344
  ],
254
- "permissions": {
255
- "Admin": "*",
256
- "Comercial": "crud",
257
- "User": "read"
258
- },
259
345
  "automations": [
260
346
  {
261
- "trigger": "on_insert",
347
+ "trigger": "insert",
262
348
  "function_name": "notificar_nuevo_pedido"
263
349
  },
264
350
  {
265
- "trigger": "on_update",
351
+ "trigger": "update",
266
352
  "condition": "estado = 'confirmado'",
267
353
  "function_name": "procesar_pedido"
268
354
  },
@@ -318,10 +404,6 @@ Un módulo es un JSON que define **toda la estructura de datos** de una funciona
318
404
  "computed": "cantidad * precio_unitario"
319
405
  }
320
406
  ],
321
- "permissions": {
322
- "Admin": "*",
323
- "Comercial": "crud"
324
- },
325
407
  "ui": {
326
408
  "inline": true,
327
409
  "parentField": "pedido_id"
@@ -383,29 +465,59 @@ Un módulo es un JSON que define **toda la estructura de datos** de una funciona
383
465
 
384
466
  ### Permisos por Rol
385
467
 
386
- ```json
387
- "permissions": {
388
- "Admin": "*", // Todos los permisos
389
- "Manager": "crud", // Create, Read, Update, Delete
390
- "User": "cru", // Create, Read, Update (no delete)
391
- "Viewer": "read", // Solo lectura
392
- "Guest": "" // Sin acceso
393
- }
468
+ > **⚠️ IMPORTANTE**: Los permisos ya NO se definen en el JSON del módulo.
469
+ > Se gestionan exclusivamente via la columna `permissions` de `core.entities`.
470
+
471
+ Al crear una entidad nueva, el Admin obtiene `"*"` (full access) automáticamente.
472
+ Los permisos se gestionan desde la UI de permisos o directamente en la base de datos:
473
+
474
+ ```sql
475
+ -- Ejemplo: Configurar permisos de una entidad
476
+ UPDATE core.entities
477
+ SET permissions = '{"Admin": "*", "Manager": "crud", "User": "read"}'::jsonb
478
+ WHERE id = 6420;
394
479
  ```
395
480
 
481
+ | Valor | Significado |
482
+ |-------|-------------|
483
+ | `"*"` | Full access |
484
+ | `"crud"` | Create, Read, Update, Delete |
485
+ | `"read"` | Solo lectura |
486
+ | `""` | Sin acceso |
487
+
396
488
  ---
397
489
 
398
490
  ## Automations (Código JavaScript)
399
491
 
400
492
  Las automations son **funciones JavaScript** almacenadas en la base de datos que se ejecutan en respuesta a eventos.
401
493
 
402
- ### Dónde se almacenan
494
+ ### 💜 Nueva Arquitectura (2025)
495
+
496
+ Las automations se almacenan en **tres lugares que trabajan juntos**:
497
+
498
+ ```
499
+ core.entities.automations (JSONB) ← FUENTE DE VERDAD
500
+ │ (configuración de triggers)
501
+
502
+ ▼ (sync automático)
503
+ core.automation_meta ← ÍNDICE PARA WORKER
504
+ │ (sincronizado automáticamente)
505
+
506
+ ▼ (referencias)
507
+ core.automation_scripts ← CÓDIGO JAVASCRIPT
508
+ (la función que se ejecuta)
509
+ ```
510
+
511
+ ### Dónde se almacena cada cosa
403
512
 
404
513
  ```sql
405
- -- El código está en:
514
+ -- CONFIGURACIÓN: Qué automations tiene cada entity (triggers, enabled, etc.)
515
+ SELECT id, name, automations FROM core.entities WHERE id = 4589;
516
+
517
+ -- CÓDIGO: El JavaScript de cada automation
406
518
  SELECT function_name, js_code FROM core.automation_scripts WHERE company_id = 116;
407
519
 
408
- -- Los triggers están en:
520
+ -- ÍNDICE: Lo que consulta el worker (sincronizado automáticamente)
409
521
  SELECT * FROM core.automation_meta WHERE company_id = 116;
410
522
  ```
411
523
 
@@ -413,18 +525,37 @@ SELECT * FROM core.automation_meta WHERE company_id = 116;
413
525
 
414
526
  | Trigger | Cuándo se ejecuta |
415
527
  |---------|-------------------|
416
- | `on_insert` | Al crear un registro |
417
- | `on_update` | Al modificar un registro |
418
- | `on_delete` | Al eliminar un registro |
419
- | `click` | Botón manual en la UI |
528
+ | `insert` | Al crear un registro |
529
+ | `update` | Al modificar un registro |
530
+ | `delete` | Al eliminar un registro |
531
+ | `click` / `click` | Botón manual en la UI |
420
532
  | `scheduled` | Cron job (ej: "0 9 * * *") |
421
533
 
534
+ ### Formato de entities.automations
535
+
536
+ ```json
537
+ [
538
+ {
539
+ "trigger": "insert",
540
+ "function_name": "procesar_pedido",
541
+ "script_id": 42,
542
+ "enabled": true
543
+ },
544
+ {
545
+ "trigger": "click",
546
+ "function_name": "generar_factura",
547
+ "label": "Generar Factura",
548
+ "enabled": true
549
+ }
550
+ ]
551
+ ```
552
+
422
553
  ### Estructura de una Automation
423
554
 
424
555
  ```javascript
425
556
  /**
426
557
  * Función: procesar_pedido
427
- * Trigger: on_update cuando estado = 'confirmado'
558
+ * Trigger: update cuando estado = 'confirmado'
428
559
  *
429
560
  * @param {Object} context - Contexto de ejecución
430
561
  * @param {Object} api - API para interactuar con el sistema
@@ -440,7 +571,7 @@ async function procesar_pedido(context, api, logger) {
440
571
  entity_id, // ID de la entidad/tabla (ej: 4136)
441
572
  table, // Nombre físico de tabla (ej: "m308_t4136")
442
573
  row, // Registro actual (después del cambio)
443
- old_row, // Registro anterior (solo en on_update)
574
+ old_row, // Registro anterior (solo en update)
444
575
  input, // Input del usuario (solo en click)
445
576
  env, // Variables de entorno de la company
446
577
  user // Usuario que disparó el evento
@@ -635,7 +766,13 @@ Cuando descargas una view con `gufi view:pull <id>`, obtienes:
635
766
 
636
767
  ### 💜 dataSources - Declarar qué Tablas Necesita la Vista
637
768
 
638
- El archivo `core/dataProvider.ts` define qué tablas necesita la vista. El Developer Center lee esto y muestra UI para que el usuario asigne sus tablas.
769
+ El archivo `core/dataProvider.ts` define qué tablas necesita la vista.
770
+
771
+ **Arquitectura:**
772
+ 1. Se declaran en código (`core/dataProvider.ts`)
773
+ 2. Se editan con CLI: `gufi pull` → editar → `gufi push`
774
+ 3. Developer Center los muestra como **solo lectura**
775
+ 4. Al instalar la vista, el sistema mapea nombres lógicos automáticamente
639
776
 
640
777
  ```typescript
641
778
  // core/dataProvider.ts
@@ -702,9 +839,9 @@ export default function MiVista({ gufi }) { ... }
702
839
  export default function MiVista({ gufi }) {
703
840
  const viewSpec = gufi?.context?.viewSpec || {};
704
841
 
705
- // Keys de dataSources → nombres de tabla físicos
706
- const tareasTable = viewSpec.tareasTable; // "m360_t16194"
707
- const proyectosTable = viewSpec.proyectosTable; // "m360_t16200" o undefined
842
+ // Keys de dataSources → NOMBRES LÓGICOS (nunca IDs físicos)
843
+ const tareasTable = viewSpec.tareasTable; // "tareas.asignaciones"
844
+ const proyectosTable = viewSpec.proyectosTable; // "tareas.proyectos" o undefined
708
845
 
709
846
  // Usar para queries
710
847
  const res = await gufi.dataProvider.getList({
@@ -1085,7 +1222,7 @@ Las vistas pueden incluir automations que se ejecutan al hacer click.
1085
1222
  // automations/send_notification.js
1086
1223
  /**
1087
1224
  * 💜 Automation: send_notification
1088
- * Trigger: ON_CLICK (desde la vista)
1225
+ * Trigger: CLICK (desde la vista)
1089
1226
  */
1090
1227
  async function send_notification(context, api, logger) {
1091
1228
  const { input, env } = context;
@@ -1562,6 +1699,31 @@ SELECT * FROM marketplace.package_modules WHERE package_id = 14;
1562
1699
 
1563
1700
  ## Comandos del CLI
1564
1701
 
1702
+ ### 💜 Resumen Rápido para Claude
1703
+
1704
+ **El CLI gestiona companies, módulos, automations y datos. Todo es dinámico - detecta la company automáticamente.**
1705
+
1706
+ | Quiero... | Comando |
1707
+ |-----------|---------|
1708
+ | Ver companies | `gufi companies` |
1709
+ | Ver módulos de company | `gufi modules 146` |
1710
+ | Ver/editar módulo | `gufi module 360` |
1711
+ | Ver registros | `gufi rows m308_t4136` |
1712
+ | Listar scripts | `gufi automations` |
1713
+ | Ver/editar script | `gufi automation 15` |
1714
+ | **Ver índice del worker** | `gufi automations:meta` |
1715
+ | **Ver ejecuciones** | `gufi automations:executions` |
1716
+ | **Ver/editar triggers** | `gufi entity:automations 4136` |
1717
+ | **Ver mis packages** | `gufi packages` |
1718
+ | **Ver package** | `gufi package 14` |
1719
+ | **Crear package** | `gufi package:create "Nombre"` |
1720
+ | **Desarrollar view** | `gufi pull 13` → `gufi watch` → `gufi logs` |
1721
+
1722
+ **3 cosas que saber:**
1723
+ 1. **Auto-login**: `gufi login` guarda credenciales → funciona para siempre (logout NO las borra)
1724
+ 2. **Auto-detección**: `module`, `automation`, `rows` detectan la company automáticamente
1725
+ 3. **Sin prefijos**: `gufi pull/push/watch/logs` (no `view:pull`, etc.)
1726
+
1565
1727
  ### Instalación
1566
1728
 
1567
1729
  ```bash
@@ -1601,14 +1763,14 @@ gufi companies
1601
1763
  # Ver módulos de una company
1602
1764
  gufi modules 146
1603
1765
 
1604
- # Ver JSON de un módulo
1605
- gufi module 360 -c 146
1766
+ # Ver JSON de un módulo (auto-detecta company)
1767
+ gufi module 360
1606
1768
 
1607
1769
  # Editar módulo con tu editor
1608
- gufi module 360 -c 146 --edit
1770
+ gufi module 360 --edit
1609
1771
 
1610
1772
  # Guardar JSON a archivo
1611
- gufi module 360 -c 146 --file modulo.json
1773
+ gufi module 360 --file modulo.json
1612
1774
 
1613
1775
  # Actualizar módulo desde archivo
1614
1776
  gufi module:update 360 modulo.json -c 146
@@ -1620,7 +1782,7 @@ gufi module:update 360 modulo.json -c 146 --dry-run
1620
1782
  gufi company:create "Mi Empresa"
1621
1783
  ```
1622
1784
 
1623
- ### Automations
1785
+ ### Automations (Scripts Globales)
1624
1786
 
1625
1787
  ```bash
1626
1788
  # Listar automation scripts
@@ -1634,8 +1796,69 @@ gufi automation calcular_stock -c 116 --edit
1634
1796
 
1635
1797
  # Guardar a archivo
1636
1798
  gufi automation calcular_stock -c 116 --file script.js
1799
+
1800
+ # Crear/actualizar automation desde archivo JS
1801
+ gufi automation:create calcular_stock script.js -c 116
1802
+
1803
+ # 💜 Debugging - Ver índice del worker (auto-synced desde entities.automations)
1804
+ gufi automations:meta -c 116
1805
+
1806
+ # 💜 Ver historial de ejecuciones
1807
+ gufi automations:executions -c 116
1808
+ gufi automations:executions -c 116 --limit 50
1809
+ gufi automations:executions -c 116 --script sync_nayax
1637
1810
  ```
1638
1811
 
1812
+ ### Entity Automations (Automations por Entidad)
1813
+
1814
+ Las automations de entidad están vinculadas a una entidad específica (tabla) y se almacenan en `core.entities.automations`.
1815
+
1816
+ ```bash
1817
+ # Ver automations de una entidad (auto-detecta company)
1818
+ gufi entity:automations 4589
1819
+
1820
+ # Editar automations con tu editor ($EDITOR)
1821
+ gufi entity:automations 4589 --edit
1822
+
1823
+ # Guardar automations a archivo JSON
1824
+ gufi entity:automations 4589 --file automations.json
1825
+
1826
+ # Actualizar automations desde archivo JSON
1827
+ gufi entity:automations:update 4589 automations.json
1828
+ ```
1829
+
1830
+ **Formato del JSON de automations:**
1831
+ ```json
1832
+ [
1833
+ {
1834
+ "trigger": "insert",
1835
+ "function_name": "notificar_nuevo",
1836
+ "enabled": true
1837
+ },
1838
+ {
1839
+ "trigger": "click",
1840
+ "function_name": "generar_factura",
1841
+ "label": "Generar Factura",
1842
+ "enabled": true
1843
+ },
1844
+ {
1845
+ "trigger": "scheduled",
1846
+ "function_name": "sync_diario",
1847
+ "interval_ms": 86400000,
1848
+ "enabled": true
1849
+ }
1850
+ ]
1851
+ ```
1852
+
1853
+ **Triggers disponibles:**
1854
+ | Trigger | Descripción |
1855
+ |---------|-------------|
1856
+ | `insert` | Al crear registro |
1857
+ | `update` | Al modificar registro |
1858
+ | `delete` | Al eliminar registro |
1859
+ | `click` | Botón manual en UI |
1860
+ | `scheduled` | Intervalo programado |
1861
+
1639
1862
  ### Environment Variables
1640
1863
 
1641
1864
  ```bash
@@ -1661,8 +1884,12 @@ gufi schema -m 360
1661
1884
 
1662
1885
  ### Row CRUD (Datos de Tablas)
1663
1886
 
1887
+ > 💜 **Auto-detección de Company**: El CLI detecta automáticamente a qué company pertenece una tabla
1888
+ > analizando el nombre (ej: `m308_t4136` → módulo 308 → busca en qué company está).
1889
+ > Ya no necesitas usar `-c` en la mayoría de casos.
1890
+
1664
1891
  ```bash
1665
- # Listar registros de una tabla
1892
+ # Listar registros de una tabla (auto-detecta company)
1666
1893
  gufi rows m360_t16192 # Últimos 20 registros
1667
1894
  gufi rows m360_t16192 -l 50 # Últimos 50 registros
1668
1895
  gufi rows m360_t16192 -f estado=activo # Filtrar por campo
@@ -1687,6 +1914,9 @@ gufi row:duplicate m360_t16192 123
1687
1914
  # Crear múltiples registros desde archivo JSON
1688
1915
  gufi rows:create m360_t16192 --file datos.json
1689
1916
  # datos.json debe ser un array: [{"nombre":"A"},{"nombre":"B"}]
1917
+
1918
+ # Si necesitas forzar una company específica, usa -c
1919
+ gufi rows m360_t16192 -c 146
1690
1920
  ```
1691
1921
 
1692
1922
  ### Desarrollo de Views
@@ -1713,48 +1943,162 @@ gufi view:push
1713
1943
  gufi view:status
1714
1944
  ```
1715
1945
 
1946
+ ### Packages del Marketplace
1947
+
1948
+ ```bash
1949
+ # Ver mis packages
1950
+ gufi packages
1951
+
1952
+ # Ver detalles de un package (módulos, views, estado)
1953
+ gufi package 14
1954
+
1955
+ # Crear nuevo package
1956
+ gufi package:create "Mi Package" --description "Descripción opcional"
1957
+
1958
+ # Añadir módulo de una company al package
1959
+ gufi package:add-module 14 --company 146 --module 360
1960
+ # O interactivo (muestra companies disponibles)
1961
+ gufi package:add-module 14
1962
+
1963
+ # Ver cambios pendientes en módulos
1964
+ gufi package:check 14
1965
+
1966
+ # Sincronizar versión (actualiza snapshots de módulos)
1967
+ gufi package:sync 14
1968
+
1969
+ # Publicar package al Marketplace
1970
+ gufi package:publish 14
1971
+
1972
+ # Despublicar
1973
+ gufi package:unpublish 14
1974
+
1975
+ # Gestionar views del package
1976
+ gufi package:views 14
1977
+ gufi package:add-view 14 <viewId>
1978
+ gufi package:remove-view 14 <packageViewId>
1979
+
1980
+ # Eliminar módulo o package
1981
+ gufi package:remove-module 14 <moduleId>
1982
+ gufi package:delete 14
1983
+ ```
1984
+
1716
1985
  ### Opciones Globales
1717
1986
 
1718
1987
  | Opción | Descripción |
1719
1988
  |--------|-------------|
1720
- | `-c, --company <id>` | ID de company |
1989
+ | `-c, --company <id>` | ID de company (solo para `modules`, `automations`, `*:create`) |
1721
1990
  | `-e, --edit` | Abrir en editor ($EDITOR) |
1722
1991
  | `-f, --file <path>` | Guardar a archivo |
1723
1992
  | `--dry-run` | Validar sin aplicar |
1724
1993
  | `-h, --help` | Ayuda del comando |
1725
1994
 
1995
+ **Auto-detección:** `module`, `module:update`, `automation`, `entity:automations`, `rows` detectan company automáticamente del ID.
1996
+
1726
1997
  ---
1727
1998
 
1728
1999
  ## Tips para Claude
1729
2000
 
2001
+ ### 💜 Flujo de Trabajo Recomendado
2002
+
2003
+ ```bash
2004
+ # 1. Primero, oriéntate
2005
+ gufi companies # Ver companies disponibles
2006
+ gufi modules 146 # Ver módulos de una company
2007
+
2008
+ # 2. Para ver/modificar datos (auto-detecta company)
2009
+ gufi rows m308_t4136 # Auto-detecta company del módulo 308
2010
+ gufi row m308_t4136 123 # Ver registro específico
2011
+ gufi row:update m308_t4136 123 --data '{"status":"done"}'
2012
+
2013
+ # 3. Para editar estructura (módulos - auto-detecta company)
2014
+ gufi module 360 --edit # Abre JSON en tu $EDITOR
2015
+
2016
+ # 4. Para editar lógica (automations - auto-detecta company)
2017
+ gufi automation 15 # Busca por script_id
2018
+ gufi automation 15 --edit # Editar código JS
2019
+ ```
2020
+
1730
2021
  ### Cuándo usar cada comando
1731
2022
 
1732
2023
  | El usuario quiere... | Comando |
1733
2024
  |---------------------|---------|
1734
- | Ver qué companies tiene | `gufi companies` |
1735
- | Ver estructura de una company | `gufi modules <company_id>` |
1736
- | Ver/editar JSON de módulo | `gufi module <id> -c <company>` |
1737
- | Ver/editar código de automation | `gufi automation <nombre> -c <company>` |
1738
- | Desarrollar una vista | `gufi view:pull <id>`, `gufi view:watch`, `gufi view:logs` |
2025
+ | Ver companies | `gufi companies` |
2026
+ | Ver módulos de company | `gufi modules 146` |
2027
+ | Ver/editar módulo | `gufi module 360` |
2028
+ | Ver/editar automation | `gufi automation 15` |
2029
+ | Ver/editar datos | `gufi rows m308_t4136` |
2030
+ | Desarrollar vista | `gufi pull "Mi Vista"` → `gufi watch` → `gufi logs` |
2031
+
2032
+ ### Auto-detección
2033
+
2034
+ Todo automático:
2035
+ - `gufi module 360` → detecta company del módulo
2036
+ - `gufi automation 15` → detecta company del script
2037
+ - `gufi rows m308_t4136` → detecta company de la tabla
2038
+
2039
+ ### Automations: 4 tablas que trabajan juntas
2040
+
2041
+ ```
2042
+ automation_scripts (id=15) ← CÓDIGO JavaScript
2043
+
2044
+ └── entities.automations ← CONFIGURACIÓN (qué trigger, cuándo ejecutar)
2045
+
2046
+ ▼ (sync automático)
2047
+ automation_meta ← ÍNDICE para worker
2048
+
2049
+
2050
+ automation_executions ← HISTORIAL de ejecuciones
2051
+ ```
2052
+
2053
+ | Tabla | Qué guarda | CLI |
2054
+ |-------|------------|-----|
2055
+ | `automation_scripts` | Código JS | `gufi automation 15` |
2056
+ | `entities.automations` | Triggers (on_insert, on_click...) | `gufi entity:automations 4136` |
2057
+ | `automation_meta` | Índice para worker (auto-sync) | `gufi automations:meta` |
2058
+ | `automation_executions` | Historial de ejecuciones | `gufi automations:executions` |
2059
+
2060
+ **Ejemplo:** Un script puede usarse en varias entities:
2061
+ ```
2062
+ script 15 "sync_nayax" → machines (on_click), products (scheduled), sales (on_insert)
2063
+ ```
2064
+
2065
+ **Flujo típico:**
2066
+ ```bash
2067
+ gufi automations # Ver scripts
2068
+ gufi automation 15 --edit # Editar código
2069
+ gufi entity:automations 4136 # Ver/editar triggers
2070
+ gufi automations:meta # Ver qué tiene el worker indexado (debugging)
2071
+ gufi automations:executions # Ver historial de ejecuciones
2072
+ ```
1739
2073
 
1740
2074
  ### Errores comunes
1741
2075
 
1742
2076
  | Error | Solución |
1743
2077
  |-------|----------|
1744
2078
  | "No estás logueado" | `gufi login` (guarda credenciales para auto-login) |
1745
- | "Módulo no encontrado" | Verificar `-c <company_id>` |
2079
+ | "Módulo no encontrado" | Verificar que el ID existe con `gufi modules <company>` |
1746
2080
  | "Token expirado" | Automático: refresh o auto-login con credenciales guardadas |
1747
2081
  | "JSON inválido" | Validar estructura del JSON |
2082
+ | "API Error 404" | Verificar nombre de tabla (formato: `m{moduleId}_t{entityId}`) |
1748
2083
 
1749
2084
  ### Conceptos clave
1750
2085
 
1751
2086
  - **Multi-tenant**: Cada company = schema aislado en PostgreSQL
1752
- - **Tablas físicas**: `m{moduleId}_t{entityId}`
2087
+ - **Tablas físicas**: `m{moduleId}_t{entityId}` (ej: `m308_t4136`)
1753
2088
  - **Módulos**: JSON que define estructura → Gufi crea tablas/UI
1754
2089
  - **Automations**: JS en DB, ejecutado por worker (pg-boss)
1755
2090
  - **Views**: React/TS en DB, ejecutado en frontend dinámicamente
1756
2091
  - **Marketplace**: Sistema de distribución de packages
1757
2092
 
2093
+ ### Companies Importantes
2094
+
2095
+ | ID | Nombre | Uso |
2096
+ |----|--------|-----|
2097
+ | 101 | Demo | Pruebas generales |
2098
+ | 116 | Fitvending | Producción - cliente real |
2099
+ | 146 | Gufi | Desarrollo interno |
2100
+ | 147 | Apuestas Pro | Cliente real |
2101
+
1758
2102
  ---
1759
2103
 
1760
2104
  ## Links