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,284 @@
|
|
|
1
|
+
# Errores Comunes y Soluciones
|
|
2
|
+
|
|
3
|
+
## Datos y tipos
|
|
4
|
+
|
|
5
|
+
### Currency como objeto (INCORRECTO)
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
// ERROR: Formato legacy
|
|
9
|
+
precio: { currency: 'EUR', amount: 150 }
|
|
10
|
+
|
|
11
|
+
// CORRECTO: Solo el numero
|
|
12
|
+
precio: gufi.CB.currency(150)
|
|
13
|
+
// o directamente:
|
|
14
|
+
precio: 150
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Currency ahora es NUMERIC. El codigo de moneda va en el schema del campo.
|
|
18
|
+
|
|
19
|
+
### Phone con formato incorrecto
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
// ERROR: Formato legacy
|
|
23
|
+
telefono: { country: 'ES', number: '612345678' }
|
|
24
|
+
|
|
25
|
+
// CORRECTO: Usar CB.phone
|
|
26
|
+
telefono: gufi.CB.phone('612345678')
|
|
27
|
+
// Resultado: { prefix: '+34', number: '612345678' }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Olvidar __display en updates
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
// ERROR: UI no muestra el cambio
|
|
34
|
+
await dataProvider.update({
|
|
35
|
+
resource: table,
|
|
36
|
+
id: 5,
|
|
37
|
+
variables: { estado: 'completado' }
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// CORRECTO: Actualizar ambos
|
|
41
|
+
await dataProvider.update({
|
|
42
|
+
resource: table,
|
|
43
|
+
id: 5,
|
|
44
|
+
variables: {
|
|
45
|
+
estado: 'completado',
|
|
46
|
+
estado__display: 'Completado'
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Aplica a: `select`, `relation`, `currency` (si tenia formato viejo)
|
|
52
|
+
|
|
53
|
+
### Base64 en campos file
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// ERROR: Base64 directo
|
|
57
|
+
foto: 'data:image/png;base64,iVBOR...'
|
|
58
|
+
|
|
59
|
+
// CORRECTO: Subir primero, luego guardar URL
|
|
60
|
+
const { url, name } = await uploadFile(file);
|
|
61
|
+
foto: gufi.CB.file(url, name)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Solo `signature` acepta base64 directo.
|
|
65
|
+
|
|
66
|
+
## Vistas
|
|
67
|
+
|
|
68
|
+
### Hardcodear IDs físicos de tabla
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// ERROR: IDs físicos difíciles de leer y no portables
|
|
72
|
+
const data = await dataProvider.getList({ resource: 'm360_t16192' });
|
|
73
|
+
|
|
74
|
+
// CORRECTO: Usar nombres lógicos (dataProvider los resuelve automáticamente)
|
|
75
|
+
const pedidosTable = 'ventas.pedidos';
|
|
76
|
+
const data = await dataProvider.getList({ resource: pedidosTable });
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Importar stores directamente
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// ERROR: Rompe aislamiento
|
|
83
|
+
import { useAuthStore } from '@/stores/useAuthStore';
|
|
84
|
+
|
|
85
|
+
// CORRECTO: Usar gufi.context
|
|
86
|
+
const user = gufi.context?.user;
|
|
87
|
+
const company = gufi.context?.activeCompany;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Toast de shadcn
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// ERROR: No es el toast de Gufi
|
|
94
|
+
import { toast } from '@/components/ui/toast';
|
|
95
|
+
|
|
96
|
+
// CORRECTO: Toast del SDK
|
|
97
|
+
import { toastSuccess, toastError } from '@/sdk';
|
|
98
|
+
toastSuccess('Guardado');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Olvidar exportar featureConfig
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// ERROR: Vista no tiene dataSources
|
|
105
|
+
export default function MiVista() { ... }
|
|
106
|
+
|
|
107
|
+
// CORRECTO: Exportar featureConfig
|
|
108
|
+
export { featureConfig } from './core/dataProvider';
|
|
109
|
+
export default function MiVista() { ... }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Automations
|
|
113
|
+
|
|
114
|
+
### Destructuring en api.query
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
// ERROR: api.query devuelve rows directamente
|
|
118
|
+
const { rows } = await gufi.query("SELECT * FROM table");
|
|
119
|
+
|
|
120
|
+
// CORRECTO:
|
|
121
|
+
const rows = await gufi.query("SELECT * FROM table");
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### SQL injection
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// ERROR: Interpolacion directa
|
|
128
|
+
const rows = await gufi.query(`SELECT * FROM users WHERE id = ${id}`);
|
|
129
|
+
|
|
130
|
+
// CORRECTO: Parametros
|
|
131
|
+
const rows = await gufi.query("SELECT * FROM users WHERE id = $1", [id]);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Return sin success
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
// ERROR: Worker no sabe si funciono
|
|
138
|
+
async function mi_automation(ctx, api, logger) {
|
|
139
|
+
// ... hacer cosas
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// CORRECTO: Retornar estado
|
|
143
|
+
async function mi_automation(ctx, api, logger) {
|
|
144
|
+
// ... hacer cosas
|
|
145
|
+
return { success: true, message: 'OK' };
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## API y autenticacion
|
|
150
|
+
|
|
151
|
+
### Falta X-Company-ID
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
// ERROR: 400 Bad Request
|
|
155
|
+
GET /api/company/schema
|
|
156
|
+
Authorization: Bearer xxx
|
|
157
|
+
|
|
158
|
+
// CORRECTO:
|
|
159
|
+
GET /api/company/schema
|
|
160
|
+
Authorization: Bearer xxx
|
|
161
|
+
X-Company-ID: 116
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Token expirado
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
// Response: 401 Unauthorized
|
|
168
|
+
// Solucion: Refresh token
|
|
169
|
+
|
|
170
|
+
POST /api/auth/refresh
|
|
171
|
+
X-Refresh-Token: {refreshToken}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Sin permisos
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
// Response: 403 Forbidden
|
|
178
|
+
// Causa: Usuario no tiene permiso para esa accion
|
|
179
|
+
|
|
180
|
+
// Verificar permisos de la entidad:
|
|
181
|
+
gufi_context({ company_id: "116" })
|
|
182
|
+
// Ver permissions de cada entity
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Modulos
|
|
186
|
+
|
|
187
|
+
### Field type incorrecto
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
// ERROR: Tipo no existe
|
|
191
|
+
{ "name": "fecha", "type": "timestamp" }
|
|
192
|
+
|
|
193
|
+
// CORRECTO: Usar date (con includeTime si necesitas hora)
|
|
194
|
+
{ "name": "fecha", "type": "date" }
|
|
195
|
+
{ "name": "fecha_hora", "type": "date", "includeTime": true }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Tipos validos: `text`, `email`, `url`, `barcode`, `number`, `number_int`, `number_float`, `percentage`, `date`, `time`, `select`, `multiselect`, `boolean`, `relation`, `users`, `currency`, `phone`, `location`, `file`, `signature`, `json`, `formula`, `mirror`
|
|
199
|
+
|
|
200
|
+
### Relacion sin displayField
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
// WARNING: Muestra ID en lugar de nombre
|
|
204
|
+
{
|
|
205
|
+
"name": "cliente",
|
|
206
|
+
"type": "relation",
|
|
207
|
+
"relation": { "module": "crm", "entity": "clientes" }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// MEJOR: Especificar displayField
|
|
211
|
+
{
|
|
212
|
+
"name": "cliente",
|
|
213
|
+
"type": "relation",
|
|
214
|
+
"relation": {
|
|
215
|
+
"module": "crm",
|
|
216
|
+
"entity": "clientes",
|
|
217
|
+
"displayField": "nombre"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Select sin options
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
// ERROR: No hay opciones que seleccionar
|
|
226
|
+
{ "name": "estado", "type": "select" }
|
|
227
|
+
|
|
228
|
+
// CORRECTO:
|
|
229
|
+
{
|
|
230
|
+
"name": "estado",
|
|
231
|
+
"type": "select",
|
|
232
|
+
"options": [
|
|
233
|
+
{ "value": "activo", "label": "Activo", "color": "green" },
|
|
234
|
+
{ "value": "inactivo", "label": "Inactivo", "color": "gray" }
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Packages
|
|
240
|
+
|
|
241
|
+
### Publicar sin cambios guardados
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
// ERROR: Cambios no se reflejan
|
|
245
|
+
|
|
246
|
+
// CORRECTO: Verificar con get antes de publicar
|
|
247
|
+
gufi_package({ action: "get", id: "14" })
|
|
248
|
+
// Ver has_unpublished_changes
|
|
249
|
+
|
|
250
|
+
// Publicar
|
|
251
|
+
gufi_package({ action: "publish", id: "14" })
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Debug tips
|
|
255
|
+
|
|
256
|
+
### Ver logs de automation
|
|
257
|
+
|
|
258
|
+
```javascript
|
|
259
|
+
gufi_automation_executions({
|
|
260
|
+
company_id: "116",
|
|
261
|
+
script_name: "mi_automation",
|
|
262
|
+
limit: 5
|
|
263
|
+
})
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Ver schema completo
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
gufi_context({ company_id: "116" })
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Verificar configuracion
|
|
273
|
+
|
|
274
|
+
```javascript
|
|
275
|
+
gufi_whoami()
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Probar API directamente
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
curl -X GET "https://api.gogufi.com/api/company/schema" \
|
|
282
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
283
|
+
-H "X-Company-ID: 116"
|
|
284
|
+
```
|