@arela/uploader 1.0.24 → 1.1.1
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/docs/AUTO_PROCESSING_PIPELINE.md +258 -0
- package/docs/COMPLETE_USAGE_GUIDE.md +1363 -0
- package/docs/DATABASESERVICE_IMPROVEMENTS.md +546 -0
- package/docs/PASO_2_TEST_RESULTS.md +298 -0
- package/docs/PASO_3_PLAN.md +385 -0
- package/docs/PHASE_1_FILE_DETECTION.md +366 -0
- package/docs/PHASE_2_API_INTEGRATION.md +426 -0
- package/docs/PHASE_3_DATABASE_MANAGEMENT.md +480 -0
- package/docs/PHASE_4_FILE_OPERATIONS.md +448 -0
- package/docs/PHASE_5_WATCH_MODE.md +450 -0
- package/docs/PHASE_6_SIGNAL_HANDLING.md +472 -0
- package/docs/PHASE_7_ADVANCED_FEATURES.md +560 -0
- package/docs/PLAN_WATCH_FEATURE.md +417 -0
- package/docs/README.md +480 -0
- package/docs/SCHEMA_ALIGNMENT_SUMMARY.md +301 -0
- package/docs/SMARTWATCH_DATABASE_REFACTORING.md +181 -0
- package/docs/SMART_WATCH_DATABASE_CHANGES.md +502 -0
- package/docs/TESTING_WATCH_MODE.md +212 -0
- package/docs/WATCHER_API_IMPLEMENTATION.md +520 -0
- package/docs/WATCHER_API_INTEGRATION.md +562 -0
- package/docs/WATCHER_SETUP_GUIDE.md +614 -0
- package/docs/WATCH_ARCHITECTURE.md +395 -0
- package/docs/WATCH_AUTO_PIPELINE.md +334 -0
- package/docs/WATCH_CONFIGURATION.md +267 -0
- package/docs/WATCH_USAGE_GUIDE.md +567 -0
- package/docs/commands.md +14 -0
- package/package.json +1 -1
- package/src/commands/IdentifyCommand.js +11 -0
- package/src/config/config.js +2 -2
- package/src/file-detection.js +42 -1
- package/src/scoring/scoring-engine.js +40 -7
- package/src/services/LoggingService.js +5 -3
- package/.vscode/settings.json +0 -1
- package/coverage/IdentifyCommand.js.html +0 -1462
- package/coverage/PropagateCommand.js.html +0 -1507
- package/coverage/PushCommand.js.html +0 -1504
- package/coverage/ScanCommand.js.html +0 -1654
- package/coverage/UploadCommand.js.html +0 -1846
- package/coverage/WatchCommand.js.html +0 -4111
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -191
- package/coverage/lcov-report/IdentifyCommand.js.html +0 -1462
- package/coverage/lcov-report/PropagateCommand.js.html +0 -1507
- package/coverage/lcov-report/PushCommand.js.html +0 -1504
- package/coverage/lcov-report/ScanCommand.js.html +0 -1654
- package/coverage/lcov-report/UploadCommand.js.html +0 -1846
- package/coverage/lcov-report/WatchCommand.js.html +0 -4111
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -191
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov.info +0 -1937
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/docs/API_ENDPOINTS_FOR_DETECTION.md +0 -647
- package/docs/API_RETRY_MECHANISM.md +0 -338
- package/docs/ARELA_IDENTIFY_IMPLEMENTATION.md +0 -489
- package/docs/ARELA_IDENTIFY_QUICKREF.md +0 -186
- package/docs/ARELA_PROPAGATE_IMPLEMENTATION.md +0 -581
- package/docs/ARELA_PROPAGATE_QUICKREF.md +0 -272
- package/docs/ARELA_PUSH_IMPLEMENTATION.md +0 -577
- package/docs/ARELA_PUSH_QUICKREF.md +0 -322
- package/docs/ARELA_SCAN_IMPLEMENTATION.md +0 -373
- package/docs/ARELA_SCAN_QUICKREF.md +0 -139
- package/docs/CROSS_PLATFORM_PATH_HANDLING.md +0 -597
- package/docs/DETECTION_ATTEMPT_TRACKING.md +0 -414
- package/docs/MIGRATION_UPLOADER_TO_FILE_STATS.md +0 -1020
- package/docs/MULTI_LEVEL_DIRECTORY_SCANNING.md +0 -494
- package/docs/QUICK_REFERENCE_API_DETECTION.md +0 -264
- package/docs/REFACTORING_SUMMARY_DETECT_PEDIMENTOS.md +0 -200
- package/docs/STATS_COMMAND_SEQUENCE_DIAGRAM.md +0 -287
- package/docs/STATS_COMMAND_SIMPLE.md +0 -93
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
# Watch Mode - Guía Práctica de Uso
|
|
2
|
+
|
|
3
|
+
## 🚀 Inicio Rápido
|
|
4
|
+
|
|
5
|
+
### 1. Configuración Básica
|
|
6
|
+
|
|
7
|
+
**Editar `.env`:**
|
|
8
|
+
|
|
9
|
+
```env
|
|
10
|
+
WATCH_ENABLED=true
|
|
11
|
+
WATCH_DIRECTORY_CONFIGS={"../../Documents/2022":"estructura-2022"}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 2. Iniciar Watch Mode
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Básico
|
|
18
|
+
node src/index.js watch
|
|
19
|
+
|
|
20
|
+
# Con verbose logging
|
|
21
|
+
node src/index.js watch -v
|
|
22
|
+
|
|
23
|
+
# Sin auto-processing
|
|
24
|
+
node src/index.js watch --no-auto-processing
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 3. Colocar Archivo y Observar
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Terminal 1: Iniciar watch
|
|
31
|
+
$ node src/index.js watch -v
|
|
32
|
+
|
|
33
|
+
# Terminal 2: Copiar archivo
|
|
34
|
+
$ cp /path/to/documento.pdf ../../Documents/2022/
|
|
35
|
+
|
|
36
|
+
# Terminal 1: Ver pipeline ejecutándose
|
|
37
|
+
🔄 Starting processing pipeline pipeline-1731557400000-xyz123...
|
|
38
|
+
📊 [Step 1/4] Running stats collection...
|
|
39
|
+
✅ Stats collection completed in 1250ms
|
|
40
|
+
...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 📋 Ejemplos de Configuración
|
|
46
|
+
|
|
47
|
+
### Ejemplo 1: Un Directorio Simple
|
|
48
|
+
|
|
49
|
+
```env
|
|
50
|
+
# .env
|
|
51
|
+
WATCH_DIRECTORY_CONFIGS={"../../Documents":"estructura-principal"}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
node src/index.js watch
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Comportamiento:**
|
|
59
|
+
- Monitorea `../../Documents`
|
|
60
|
+
- Todos los archivos se suben con `estructura-principal`
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### Ejemplo 2: Múltiples Directorios con Estructuras Diferentes
|
|
65
|
+
|
|
66
|
+
```env
|
|
67
|
+
# .env
|
|
68
|
+
WATCH_DIRECTORY_CONFIGS={"../../Documents/2022":"estructura-2022","../../Documents/2023":"estructura-2023","../../Invoices":"estructura-facturas"}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
node src/index.js watch -v
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Comportamiento:**
|
|
76
|
+
```
|
|
77
|
+
Archivo en Documents/2022/documento.pdf
|
|
78
|
+
→ estructura-2022
|
|
79
|
+
|
|
80
|
+
Archivo en Documents/2023/contrato.pdf
|
|
81
|
+
→ estructura-2023
|
|
82
|
+
|
|
83
|
+
Archivo en Invoices/factura.pdf
|
|
84
|
+
→ estructura-facturas
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Ejemplo 3: Configuración Avanzada con Opciones
|
|
90
|
+
|
|
91
|
+
```env
|
|
92
|
+
# .env
|
|
93
|
+
WATCH_DIRECTORY_CONFIGS={"../../Documents":"estructura-docs"}
|
|
94
|
+
WATCH_STRATEGY=batch
|
|
95
|
+
WATCH_BATCH_SIZE=20
|
|
96
|
+
WATCH_DEBOUNCE_MS=2000
|
|
97
|
+
WATCH_STABILITY_THRESHOLD=500
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# CLI
|
|
102
|
+
node src/index.js watch -b 25 --debounce 2500
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Parámetros:**
|
|
106
|
+
- `WATCH_STRATEGY=batch` - Procesa en lotes
|
|
107
|
+
- `WATCH_BATCH_SIZE=20` - 20 archivos por lote
|
|
108
|
+
- `WATCH_DEBOUNCE_MS=2000` - Espera 2s entre eventos
|
|
109
|
+
- `WATCH_STABILITY_THRESHOLD=500` - Archivo debe estar estable 500ms
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### Ejemplo 4: Ignorar Archivos Temporales
|
|
114
|
+
|
|
115
|
+
```env
|
|
116
|
+
# .env
|
|
117
|
+
WATCH_IGNORE_PATTERNS=*.tmp,*.bak,*.swp,._*,.DS_Store
|
|
118
|
+
WATCH_DIRECTORY_CONFIGS={"../../Documents":"estructura-principal"}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
node src/index.js watch -v
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Archivos ignorados:**
|
|
126
|
+
- `documento.tmp` ✗
|
|
127
|
+
- `documento.bak` ✗
|
|
128
|
+
- `.documento.swp` ✗
|
|
129
|
+
- `._documento` ✗
|
|
130
|
+
- `.DS_Store` ✗
|
|
131
|
+
- `documento.pdf` ✓
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 🔄 Casos de Uso Completos
|
|
136
|
+
|
|
137
|
+
### Caso 1: Empresa de Logística - Documentos por Año
|
|
138
|
+
|
|
139
|
+
**Estructura del Negocio:**
|
|
140
|
+
- Archivos de 2022 → Estructura "logistica-2022"
|
|
141
|
+
- Archivos de 2023 → Estructura "logistica-2023"
|
|
142
|
+
- Archivos de 2024 → Estructura "logistica-2024"
|
|
143
|
+
|
|
144
|
+
**Configuración:**
|
|
145
|
+
|
|
146
|
+
```env
|
|
147
|
+
# .env
|
|
148
|
+
WATCH_ENABLED=true
|
|
149
|
+
WATCH_DIRECTORY_CONFIGS={
|
|
150
|
+
"/var/data/shipments/2022":"logistica-2022",
|
|
151
|
+
"/var/data/shipments/2023":"logistica-2023",
|
|
152
|
+
"/var/data/shipments/2024":"logistica-2024"
|
|
153
|
+
}
|
|
154
|
+
WATCH_STRATEGY=batch
|
|
155
|
+
WATCH_BATCH_SIZE=50
|
|
156
|
+
WATCH_AUTO_DETECT=true
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Pipeline por archivo:**
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
Nuevo archivo: shipment-2024-001.pdf
|
|
163
|
+
|
|
164
|
+
1️⃣ Stats: Se registra en base de datos
|
|
165
|
+
2️⃣ Detect: Se identifica tipo de documento
|
|
166
|
+
3️⃣ Propagate: Se vinculan documentos relacionados
|
|
167
|
+
4️⃣ Upload: Se sube a bucket con estructura "logistica-2024"
|
|
168
|
+
|
|
169
|
+
Resultado: bucket/logistica-2024/shipment-2024-001.pdf
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### Caso 2: Despacho de Aduanas - Pedimentos y Anexos
|
|
175
|
+
|
|
176
|
+
**Estructura del Negocio:**
|
|
177
|
+
- Pedimentos simplificados (detecta automáticamente)
|
|
178
|
+
- Documentos anexos (solo se suben si hay pedimento)
|
|
179
|
+
|
|
180
|
+
**Configuración:**
|
|
181
|
+
|
|
182
|
+
```env
|
|
183
|
+
# .env
|
|
184
|
+
WATCH_ENABLED=true
|
|
185
|
+
WATCH_DIRECTORY_CONFIGS={"../../Pedimentos":"estructura-aduanas"}
|
|
186
|
+
WATCH_AUTO_DETECT=true
|
|
187
|
+
WATCH_STABILITY_THRESHOLD=1000
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Flujo de Trabajo:**
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
Usuario coloca 3 archivos en Pedimentos/:
|
|
194
|
+
1. pedimento-simplificado.pdf (pedimento)
|
|
195
|
+
2. factura.pdf (anexo)
|
|
196
|
+
3. packing-list.pdf (anexo)
|
|
197
|
+
|
|
198
|
+
Step 1 (Stats):
|
|
199
|
+
✅ Registra los 3 archivos en uploads
|
|
200
|
+
|
|
201
|
+
Step 2 (Detect):
|
|
202
|
+
✅ Identifica pedimento-simplificado.pdf como "pedimento-simplificado"
|
|
203
|
+
|
|
204
|
+
Step 3 (Propagate):
|
|
205
|
+
✅ Vincula factura.pdf a pedimento
|
|
206
|
+
✅ Vincula packing-list.pdf a pedimento
|
|
207
|
+
|
|
208
|
+
Step 4 (Upload):
|
|
209
|
+
✅ Sube los 3 con estructura "estructura-aduanas"
|
|
210
|
+
|
|
211
|
+
Resultado en Arela:
|
|
212
|
+
bucket/estructura-aduanas/pedimento-simplificado.pdf
|
|
213
|
+
bucket/estructura-aduanas/factura.pdf
|
|
214
|
+
bucket/estructura-aduanas/packing-list.pdf
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
### Caso 3: Agencia de Viajes - Documentos por Cliente
|
|
220
|
+
|
|
221
|
+
**Estructura del Negocio:**
|
|
222
|
+
- Cada cliente tiene carpeta: `/clients/{cliente-code}/`
|
|
223
|
+
- Documentos varían según tipo
|
|
224
|
+
|
|
225
|
+
**Configuración:**
|
|
226
|
+
|
|
227
|
+
```env
|
|
228
|
+
# .env
|
|
229
|
+
WATCH_ENABLED=true
|
|
230
|
+
WATCH_DIRECTORY_CONFIGS={
|
|
231
|
+
"/data/clients/CLIENT001":"cliente-001",
|
|
232
|
+
"/data/clients/CLIENT002":"cliente-002",
|
|
233
|
+
"/data/clients/CLIENT003":"cliente-003"
|
|
234
|
+
}
|
|
235
|
+
WATCH_IGNORE_PATTERNS=~*,*.tmp
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Mantenimiento:**
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Agregar nuevo cliente dinámicamente
|
|
242
|
+
# (Requiere reiniciar watch, pero mantiene otros activos)
|
|
243
|
+
|
|
244
|
+
# Editar .env
|
|
245
|
+
WATCH_DIRECTORY_CONFIGS={
|
|
246
|
+
"/data/clients/CLIENT001":"cliente-001",
|
|
247
|
+
"/data/clients/CLIENT002":"cliente-002",
|
|
248
|
+
"/data/clients/CLIENT003":"cliente-003",
|
|
249
|
+
"/data/clients/CLIENT004":"cliente-004"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# Reiniciar
|
|
253
|
+
Ctrl+C
|
|
254
|
+
node src/index.js watch -v
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 🛑 Detener y Reiniciar
|
|
260
|
+
|
|
261
|
+
### Parada Graceful
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Presionar Ctrl+C
|
|
265
|
+
^C
|
|
266
|
+
👋 Received SIGINT. Gracefully shutting down...
|
|
267
|
+
|
|
268
|
+
# Output:
|
|
269
|
+
✅ WatchService stopped successfully
|
|
270
|
+
|
|
271
|
+
Final Stats:
|
|
272
|
+
├─ Files Added: 45
|
|
273
|
+
├─ Files Modified: 12
|
|
274
|
+
├─ Files Removed: 3
|
|
275
|
+
├─ Uploads Triggered: 10
|
|
276
|
+
├─ Pipelines Triggered: 8
|
|
277
|
+
└─ Errors Encountered: 0
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Reiniciar Rápidamente
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
# Usar -v para verbose y --clear-log para log limpio
|
|
284
|
+
node src/index.js watch -v --clear-log
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## 📊 Monitoreo Mientras Funciona
|
|
290
|
+
|
|
291
|
+
### Abrir Nueva Terminal
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Terminal 1: Watch está corriendo
|
|
295
|
+
$ node src/index.js watch -v
|
|
296
|
+
|
|
297
|
+
# Terminal 2: Ver configuración
|
|
298
|
+
$ node src/index.js config
|
|
299
|
+
|
|
300
|
+
# Terminal 3: Verificar archivos listos
|
|
301
|
+
$ node src/index.js query --ready-files
|
|
302
|
+
|
|
303
|
+
# Terminal 4: Procesar manualmente si necesitas
|
|
304
|
+
$ node src/index.js stats --stats-only
|
|
305
|
+
$ node src/index.js detect --detect-pdfs
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 🐛 Troubleshooting
|
|
311
|
+
|
|
312
|
+
### Problema: Pipeline no se ejecuta
|
|
313
|
+
|
|
314
|
+
**Síntoma:**
|
|
315
|
+
```
|
|
316
|
+
📄 File added: documento.pdf
|
|
317
|
+
⚡ Processing event: add - documento.pdf
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Falta el `[AutoPipeline]` log.
|
|
321
|
+
|
|
322
|
+
**Causa**: Auto-processing deshabilitado
|
|
323
|
+
|
|
324
|
+
**Solución:**
|
|
325
|
+
```bash
|
|
326
|
+
# Verificar que está habilitado (default)
|
|
327
|
+
node src/index.js watch
|
|
328
|
+
|
|
329
|
+
# O remover flag --no-auto-processing si está presente
|
|
330
|
+
node src/index.js watch --no-auto-processing # ❌ Deshabilita
|
|
331
|
+
node src/index.js watch # ✅ Habilita (default)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### Problema: Errores en Step 2 (Detect PDFs)
|
|
337
|
+
|
|
338
|
+
**Síntoma:**
|
|
339
|
+
```
|
|
340
|
+
[AutoPipeline] ❌ Pipeline failed:
|
|
341
|
+
Cannot read property 'detectPedimentosInDatabase' of undefined
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Causa**: DatabaseService no está disponible
|
|
345
|
+
|
|
346
|
+
**Solución:**
|
|
347
|
+
```env
|
|
348
|
+
# Verificar configuración Supabase en .env
|
|
349
|
+
SUPABASE_URL=http://127.0.0.1:54321
|
|
350
|
+
SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
351
|
+
SUPABASE_BUCKET=arela
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
# Reiniciar
|
|
356
|
+
node src/index.js watch -v --clear-log
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
### Problema: Archivos no se suben (Step 4)
|
|
362
|
+
|
|
363
|
+
**Síntoma:**
|
|
364
|
+
```
|
|
365
|
+
[Step 4/4] Running RFC-based upload...
|
|
366
|
+
✅ RFC upload completed in 1500ms
|
|
367
|
+
📊 Results: 0 processed, 0 uploaded
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Causa**: No hay RFCs válidos configurados o archivos no cumplían requisitos
|
|
371
|
+
|
|
372
|
+
**Solución:**
|
|
373
|
+
```bash
|
|
374
|
+
# Ver configuración
|
|
375
|
+
node src/index.js config
|
|
376
|
+
|
|
377
|
+
# Verificar RFCs configurados
|
|
378
|
+
# Expected output:
|
|
379
|
+
# 🎯 Service Availability:
|
|
380
|
+
# RFCs: AKS151005E46|IMS030409FZ0|RDG1107154L7|...
|
|
381
|
+
|
|
382
|
+
# Si está vacío, agregar en .env
|
|
383
|
+
UPLOAD_RFCS=AKS151005E46|IMS030409FZ0|RDG1107154L7
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
### Problema: Archivos duplicados en upload
|
|
389
|
+
|
|
390
|
+
**Síntoma:**
|
|
391
|
+
```
|
|
392
|
+
🔄 Triggering 4-step processing pipeline...
|
|
393
|
+
(Se ejecuta 2-3 veces para el mismo archivo)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Causa**: Debounce muy bajo, múltiples eventos del mismo archivo
|
|
397
|
+
|
|
398
|
+
**Solución:**
|
|
399
|
+
```env
|
|
400
|
+
# Aumentar debounce
|
|
401
|
+
WATCH_DEBOUNCE_MS=3000 # 3 segundos
|
|
402
|
+
WATCH_STABILITY_THRESHOLD=1000 # 1 segundo
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
### Problema: Consumo alto de CPU
|
|
408
|
+
|
|
409
|
+
**Síntoma:**
|
|
410
|
+
```
|
|
411
|
+
watch: cpu > 50%
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Causa**: Demasiados watchers o archivo inestable (escritura continua)
|
|
415
|
+
|
|
416
|
+
**Solución:**
|
|
417
|
+
```env
|
|
418
|
+
# Aumentar estabilidad y debounce
|
|
419
|
+
WATCH_STABILITY_THRESHOLD=2000
|
|
420
|
+
WATCH_DEBOUNCE_MS=5000
|
|
421
|
+
|
|
422
|
+
# Ignorar más patrones
|
|
423
|
+
WATCH_IGNORE_PATTERNS=*.tmp,*.bak,*.lock,*.swp,._*
|
|
424
|
+
|
|
425
|
+
# O reducir directorios a monitorear
|
|
426
|
+
# Solo monitorear directorios específicos
|
|
427
|
+
WATCH_DIRECTORY_CONFIGS={"../../Critical/2024":"critico-2024"}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 📚 Comandos Relacionados
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
# Ver todos los comandos
|
|
436
|
+
node src/index.js --help
|
|
437
|
+
|
|
438
|
+
# Ver configuración actual
|
|
439
|
+
node src/index.js config
|
|
440
|
+
|
|
441
|
+
# Ver estadísticas sin upload
|
|
442
|
+
node src/index.js stats --stats-only
|
|
443
|
+
|
|
444
|
+
# Detectar PDFs manualmente
|
|
445
|
+
node src/index.js detect --detect-pdfs
|
|
446
|
+
|
|
447
|
+
# Propagar arela_path manualmente
|
|
448
|
+
node src/index.js detect --propagate-arela-path
|
|
449
|
+
|
|
450
|
+
# Upload manual por RFC
|
|
451
|
+
node src/index.js upload --upload-by-rfc
|
|
452
|
+
|
|
453
|
+
# Query de archivos listos
|
|
454
|
+
node src/index.js query --ready-files
|
|
455
|
+
|
|
456
|
+
# Verbose mode
|
|
457
|
+
node src/index.js watch -v
|
|
458
|
+
|
|
459
|
+
# Limpiar log
|
|
460
|
+
node src/index.js watch --clear-log
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
## 💡 Tips y Mejores Prácticas
|
|
466
|
+
|
|
467
|
+
### 1. Iniciar Sesiones Nombradas (tmux/screen)
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
# Con tmux
|
|
471
|
+
tmux new-session -d -s arela-watch "node src/index.js watch -v"
|
|
472
|
+
|
|
473
|
+
# Ver logs
|
|
474
|
+
tmux attach -t arela-watch
|
|
475
|
+
|
|
476
|
+
# Detener
|
|
477
|
+
tmux kill-session -t arela-watch
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### 2. Usar Systemd para Arranque Automático
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
# /etc/systemd/system/arela-watch.service
|
|
484
|
+
[Unit]
|
|
485
|
+
Description=Arela Uploader Watch Mode
|
|
486
|
+
After=network.target
|
|
487
|
+
|
|
488
|
+
[Service]
|
|
489
|
+
Type=simple
|
|
490
|
+
User=arela
|
|
491
|
+
WorkingDirectory=/opt/arela-uploader
|
|
492
|
+
ExecStart=/usr/bin/node src/index.js watch -v
|
|
493
|
+
Restart=on-failure
|
|
494
|
+
RestartSec=10
|
|
495
|
+
|
|
496
|
+
[Install]
|
|
497
|
+
WantedBy=multi-user.target
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
sudo systemctl enable arela-watch
|
|
502
|
+
sudo systemctl start arela-watch
|
|
503
|
+
sudo systemctl logs -u arela-watch -f
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### 3. Monitoreo con Logs Centralizados
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
# Redirigir logs
|
|
510
|
+
node src/index.js watch -v >> /var/log/arela-watch.log 2>&1 &
|
|
511
|
+
|
|
512
|
+
# Seguir logs
|
|
513
|
+
tail -f /var/log/arela-watch.log
|
|
514
|
+
|
|
515
|
+
# Con rotación
|
|
516
|
+
/var/log/arela-watch.log {
|
|
517
|
+
daily
|
|
518
|
+
rotate 7
|
|
519
|
+
compress
|
|
520
|
+
missingok
|
|
521
|
+
notifempty
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### 4. Variables de Entorno para Producción
|
|
526
|
+
|
|
527
|
+
```env
|
|
528
|
+
# .env.production
|
|
529
|
+
NODE_ENV=production
|
|
530
|
+
VERBOSE_LOGGING=false
|
|
531
|
+
WATCH_DEBOUNCE_MS=3000
|
|
532
|
+
WATCH_BATCH_SIZE=100
|
|
533
|
+
BATCH_DELAY=500
|
|
534
|
+
MAX_API_CONNECTIONS=20
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
NODE_ENV=production node src/index.js watch
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
## ✅ Checklist de Configuración
|
|
544
|
+
|
|
545
|
+
- [ ] `.env` configurado con `WATCH_DIRECTORY_CONFIGS`
|
|
546
|
+
- [ ] Directorios a monitorear existen y son accesibles
|
|
547
|
+
- [ ] Credenciales Supabase configuradas
|
|
548
|
+
- [ ] RFCs configurados en `UPLOAD_RFCS`
|
|
549
|
+
- [ ] Base de datos está disponible
|
|
550
|
+
- [ ] API endpoint configurado (si usas API mode)
|
|
551
|
+
- [ ] Patterns de ignore configurados (si necesitas)
|
|
552
|
+
- [ ] Verbose logging habilitado para troubleshooting
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## 📞 Soporte
|
|
557
|
+
|
|
558
|
+
Si encuentras problemas:
|
|
559
|
+
|
|
560
|
+
1. Habilita verbose logging: `node src/index.js watch -v`
|
|
561
|
+
2. Revisa el archivo log: `cat arela-upload.log`
|
|
562
|
+
3. Consulta [WATCH_ARCHITECTURE.md](WATCH_ARCHITECTURE.md)
|
|
563
|
+
4. Consulta [WATCH_AUTO_PIPELINE.md](WATCH_AUTO_PIPELINE.md)
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
Última actualización: 2025-11-14
|
package/docs/commands.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
node src/index.js --stats-only
|
|
2
|
+
node src/index.js --detect-pdfs
|
|
3
|
+
node src/index.js --propagate-arela-path
|
|
4
|
+
node src/index.js --upload-by-rfc --folder-structure palco
|
|
5
|
+
|
|
6
|
+
UPLOAD_RFCS="RFC1|RFC2" node src/index.js --upload-by-rfc --folder-structure target-folder
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
node src/index.js stats --stats-only
|
|
12
|
+
node src/index.js detect --detect-pdfs
|
|
13
|
+
node src/index.js detect --propagate-arela-path
|
|
14
|
+
node src/index.js upload --upload-by-rfc --folder-structure palco
|
package/package.json
CHANGED
|
@@ -248,6 +248,14 @@ export class IdentifyCommand {
|
|
|
248
248
|
logger.info(` Duration: ${duration}s`);
|
|
249
249
|
logger.info(` Speed: ${avgSpeed} files/sec`);
|
|
250
250
|
|
|
251
|
+
// Classification distribution for the run (observability: detect shifts /
|
|
252
|
+
// rising unmatched rate, and which detection mode was used).
|
|
253
|
+
if (
|
|
254
|
+
typeof this.detectionService.logClassificationSummary === 'function'
|
|
255
|
+
) {
|
|
256
|
+
this.detectionService.logClassificationSummary(logger);
|
|
257
|
+
}
|
|
258
|
+
|
|
251
259
|
if (options.showStats) {
|
|
252
260
|
this.#showDetailedStats(
|
|
253
261
|
startTime,
|
|
@@ -303,6 +311,9 @@ export class IdentifyCommand {
|
|
|
303
311
|
return {
|
|
304
312
|
processed: 0,
|
|
305
313
|
detected: 0,
|
|
314
|
+
// Must include every field totalStats accumulates — omitting proformas
|
|
315
|
+
// made `totalStats.proformas += undefined` = NaN in the final summary.
|
|
316
|
+
proformas: 0,
|
|
306
317
|
errors: 0,
|
|
307
318
|
};
|
|
308
319
|
}
|
package/src/config/config.js
CHANGED
|
@@ -37,10 +37,10 @@ class Config {
|
|
|
37
37
|
const __dirname = path.dirname(__filename);
|
|
38
38
|
const packageJsonPath = path.resolve(__dirname, '../../package.json');
|
|
39
39
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
40
|
-
return packageJson.version || '1.0
|
|
40
|
+
return packageJson.version || '1.1.0';
|
|
41
41
|
} catch (error) {
|
|
42
42
|
console.warn('⚠️ Could not read package.json version, using fallback');
|
|
43
|
-
return '1.0
|
|
43
|
+
return '1.1.0';
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
package/src/file-detection.js
CHANGED
|
@@ -89,6 +89,13 @@ export class FileDetectionService {
|
|
|
89
89
|
// Best-match matchers (adapted from the API). When set, classification uses
|
|
90
90
|
// the scoring engine; otherwise it falls back to legacy first-match-wins.
|
|
91
91
|
this.matchers = null;
|
|
92
|
+
// Per-run classification tally for observability (distribution + unmatched).
|
|
93
|
+
this.classificationStats = {
|
|
94
|
+
total: 0,
|
|
95
|
+
matched: 0,
|
|
96
|
+
unmatched: 0,
|
|
97
|
+
byType: {},
|
|
98
|
+
};
|
|
92
99
|
}
|
|
93
100
|
|
|
94
101
|
/** Provide the resolved+adapted matcher set for scoring-based classification. */
|
|
@@ -96,12 +103,46 @@ export class FileDetectionService {
|
|
|
96
103
|
this.matchers = matchers && matchers.length ? matchers : null;
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Detect document type, tallying the outcome for a per-run summary. Wraps the
|
|
108
|
+
* implementation so every return path is counted from one place.
|
|
109
|
+
*/
|
|
110
|
+
async detectFile(filePath) {
|
|
111
|
+
const result = await this.#detectFileImpl(filePath);
|
|
112
|
+
const type = result?.detectedType ?? null;
|
|
113
|
+
this.classificationStats.total += 1;
|
|
114
|
+
if (type) {
|
|
115
|
+
this.classificationStats.matched += 1;
|
|
116
|
+
this.classificationStats.byType[type] =
|
|
117
|
+
(this.classificationStats.byType[type] ?? 0) + 1;
|
|
118
|
+
} else {
|
|
119
|
+
this.classificationStats.unmatched += 1;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Log the classification distribution for the run (call after processing). */
|
|
125
|
+
logClassificationSummary(logger) {
|
|
126
|
+
const s = this.classificationStats;
|
|
127
|
+
if (!s.total) return;
|
|
128
|
+
const mode = this.matchers ? 'scoring' : 'legacy';
|
|
129
|
+
const dist = Object.entries(s.byType)
|
|
130
|
+
.sort((a, b) => b[1] - a[1])
|
|
131
|
+
.map(([t, n]) => `${t}=${n}`)
|
|
132
|
+
.join(', ');
|
|
133
|
+
const log = logger?.info ? logger : console;
|
|
134
|
+
log.info(
|
|
135
|
+
`🧩 Classification summary (${mode}): ${s.total} docs, ${s.matched} matched, ` +
|
|
136
|
+
`${s.unmatched} unmatched${dist ? ` — ${dist}` : ''}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
99
140
|
/**
|
|
100
141
|
* Detect document type from a file
|
|
101
142
|
* @param {string} filePath - Path to the file to analyze
|
|
102
143
|
* @returns {Promise<{detectedType: string|null, fields: Array, detectedPedimento: string|null, detectedPedimentoYear: number|null, text: string}>}
|
|
103
144
|
*/
|
|
104
|
-
async
|
|
145
|
+
async #detectFileImpl(filePath) {
|
|
105
146
|
try {
|
|
106
147
|
const fileExtension = path
|
|
107
148
|
.extname(filePath)
|