@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.
Files changed (80) hide show
  1. package/docs/AUTO_PROCESSING_PIPELINE.md +258 -0
  2. package/docs/COMPLETE_USAGE_GUIDE.md +1363 -0
  3. package/docs/DATABASESERVICE_IMPROVEMENTS.md +546 -0
  4. package/docs/PASO_2_TEST_RESULTS.md +298 -0
  5. package/docs/PASO_3_PLAN.md +385 -0
  6. package/docs/PHASE_1_FILE_DETECTION.md +366 -0
  7. package/docs/PHASE_2_API_INTEGRATION.md +426 -0
  8. package/docs/PHASE_3_DATABASE_MANAGEMENT.md +480 -0
  9. package/docs/PHASE_4_FILE_OPERATIONS.md +448 -0
  10. package/docs/PHASE_5_WATCH_MODE.md +450 -0
  11. package/docs/PHASE_6_SIGNAL_HANDLING.md +472 -0
  12. package/docs/PHASE_7_ADVANCED_FEATURES.md +560 -0
  13. package/docs/PLAN_WATCH_FEATURE.md +417 -0
  14. package/docs/README.md +480 -0
  15. package/docs/SCHEMA_ALIGNMENT_SUMMARY.md +301 -0
  16. package/docs/SMARTWATCH_DATABASE_REFACTORING.md +181 -0
  17. package/docs/SMART_WATCH_DATABASE_CHANGES.md +502 -0
  18. package/docs/TESTING_WATCH_MODE.md +212 -0
  19. package/docs/WATCHER_API_IMPLEMENTATION.md +520 -0
  20. package/docs/WATCHER_API_INTEGRATION.md +562 -0
  21. package/docs/WATCHER_SETUP_GUIDE.md +614 -0
  22. package/docs/WATCH_ARCHITECTURE.md +395 -0
  23. package/docs/WATCH_AUTO_PIPELINE.md +334 -0
  24. package/docs/WATCH_CONFIGURATION.md +267 -0
  25. package/docs/WATCH_USAGE_GUIDE.md +567 -0
  26. package/docs/commands.md +14 -0
  27. package/package.json +1 -1
  28. package/src/commands/IdentifyCommand.js +11 -0
  29. package/src/config/config.js +2 -2
  30. package/src/file-detection.js +42 -1
  31. package/src/scoring/scoring-engine.js +40 -7
  32. package/src/services/LoggingService.js +5 -3
  33. package/.vscode/settings.json +0 -1
  34. package/coverage/IdentifyCommand.js.html +0 -1462
  35. package/coverage/PropagateCommand.js.html +0 -1507
  36. package/coverage/PushCommand.js.html +0 -1504
  37. package/coverage/ScanCommand.js.html +0 -1654
  38. package/coverage/UploadCommand.js.html +0 -1846
  39. package/coverage/WatchCommand.js.html +0 -4111
  40. package/coverage/base.css +0 -224
  41. package/coverage/block-navigation.js +0 -87
  42. package/coverage/favicon.png +0 -0
  43. package/coverage/index.html +0 -191
  44. package/coverage/lcov-report/IdentifyCommand.js.html +0 -1462
  45. package/coverage/lcov-report/PropagateCommand.js.html +0 -1507
  46. package/coverage/lcov-report/PushCommand.js.html +0 -1504
  47. package/coverage/lcov-report/ScanCommand.js.html +0 -1654
  48. package/coverage/lcov-report/UploadCommand.js.html +0 -1846
  49. package/coverage/lcov-report/WatchCommand.js.html +0 -4111
  50. package/coverage/lcov-report/base.css +0 -224
  51. package/coverage/lcov-report/block-navigation.js +0 -87
  52. package/coverage/lcov-report/favicon.png +0 -0
  53. package/coverage/lcov-report/index.html +0 -191
  54. package/coverage/lcov-report/prettify.css +0 -1
  55. package/coverage/lcov-report/prettify.js +0 -2
  56. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  57. package/coverage/lcov-report/sorter.js +0 -210
  58. package/coverage/lcov.info +0 -1937
  59. package/coverage/prettify.css +0 -1
  60. package/coverage/prettify.js +0 -2
  61. package/coverage/sort-arrow-sprite.png +0 -0
  62. package/coverage/sorter.js +0 -210
  63. package/docs/API_ENDPOINTS_FOR_DETECTION.md +0 -647
  64. package/docs/API_RETRY_MECHANISM.md +0 -338
  65. package/docs/ARELA_IDENTIFY_IMPLEMENTATION.md +0 -489
  66. package/docs/ARELA_IDENTIFY_QUICKREF.md +0 -186
  67. package/docs/ARELA_PROPAGATE_IMPLEMENTATION.md +0 -581
  68. package/docs/ARELA_PROPAGATE_QUICKREF.md +0 -272
  69. package/docs/ARELA_PUSH_IMPLEMENTATION.md +0 -577
  70. package/docs/ARELA_PUSH_QUICKREF.md +0 -322
  71. package/docs/ARELA_SCAN_IMPLEMENTATION.md +0 -373
  72. package/docs/ARELA_SCAN_QUICKREF.md +0 -139
  73. package/docs/CROSS_PLATFORM_PATH_HANDLING.md +0 -597
  74. package/docs/DETECTION_ATTEMPT_TRACKING.md +0 -414
  75. package/docs/MIGRATION_UPLOADER_TO_FILE_STATS.md +0 -1020
  76. package/docs/MULTI_LEVEL_DIRECTORY_SCANNING.md +0 -494
  77. package/docs/QUICK_REFERENCE_API_DETECTION.md +0 -264
  78. package/docs/REFACTORING_SUMMARY_DETECT_PEDIMENTOS.md +0 -200
  79. package/docs/STATS_COMMAND_SEQUENCE_DIAGRAM.md +0 -287
  80. 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
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arela/uploader",
3
- "version": "1.0.24",
3
+ "version": "1.1.1",
4
4
  "description": "CLI to upload files/directories to Arela",
5
5
  "bin": {
6
6
  "arela": "./src/index.js"
@@ -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
  }
@@ -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.24';
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.24';
43
+ return '1.1.0';
44
44
  }
45
45
  }
46
46
 
@@ -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 detectFile(filePath) {
145
+ async #detectFileImpl(filePath) {
105
146
  try {
106
147
  const fileExtension = path
107
148
  .extname(filePath)