@arela/uploader 1.0.23 → 1.1.0

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 (85) 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/scripts/scoring-compare.js +243 -0
  29. package/scripts/scoring-phase4-check.js +96 -0
  30. package/src/commands/IdentifyCommand.js +36 -0
  31. package/src/config/config.js +2 -2
  32. package/src/file-detection.js +71 -4
  33. package/src/scoring/db-matcher-adapter.js +98 -0
  34. package/src/scoring/matchers-seed.js +386 -0
  35. package/src/scoring/scoring-engine.js +246 -0
  36. package/src/services/ScanApiService.js +14 -0
  37. package/tests/unit/scoring-engine.test.js +221 -0
  38. package/.vscode/settings.json +0 -1
  39. package/coverage/IdentifyCommand.js.html +0 -1462
  40. package/coverage/PropagateCommand.js.html +0 -1507
  41. package/coverage/PushCommand.js.html +0 -1504
  42. package/coverage/ScanCommand.js.html +0 -1654
  43. package/coverage/UploadCommand.js.html +0 -1846
  44. package/coverage/WatchCommand.js.html +0 -4111
  45. package/coverage/base.css +0 -224
  46. package/coverage/block-navigation.js +0 -87
  47. package/coverage/favicon.png +0 -0
  48. package/coverage/index.html +0 -191
  49. package/coverage/lcov-report/IdentifyCommand.js.html +0 -1462
  50. package/coverage/lcov-report/PropagateCommand.js.html +0 -1507
  51. package/coverage/lcov-report/PushCommand.js.html +0 -1504
  52. package/coverage/lcov-report/ScanCommand.js.html +0 -1654
  53. package/coverage/lcov-report/UploadCommand.js.html +0 -1846
  54. package/coverage/lcov-report/WatchCommand.js.html +0 -4111
  55. package/coverage/lcov-report/base.css +0 -224
  56. package/coverage/lcov-report/block-navigation.js +0 -87
  57. package/coverage/lcov-report/favicon.png +0 -0
  58. package/coverage/lcov-report/index.html +0 -191
  59. package/coverage/lcov-report/prettify.css +0 -1
  60. package/coverage/lcov-report/prettify.js +0 -2
  61. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  62. package/coverage/lcov-report/sorter.js +0 -210
  63. package/coverage/lcov.info +0 -1937
  64. package/coverage/prettify.css +0 -1
  65. package/coverage/prettify.js +0 -2
  66. package/coverage/sort-arrow-sprite.png +0 -0
  67. package/coverage/sorter.js +0 -210
  68. package/docs/API_ENDPOINTS_FOR_DETECTION.md +0 -647
  69. package/docs/API_RETRY_MECHANISM.md +0 -338
  70. package/docs/ARELA_IDENTIFY_IMPLEMENTATION.md +0 -489
  71. package/docs/ARELA_IDENTIFY_QUICKREF.md +0 -186
  72. package/docs/ARELA_PROPAGATE_IMPLEMENTATION.md +0 -581
  73. package/docs/ARELA_PROPAGATE_QUICKREF.md +0 -272
  74. package/docs/ARELA_PUSH_IMPLEMENTATION.md +0 -577
  75. package/docs/ARELA_PUSH_QUICKREF.md +0 -322
  76. package/docs/ARELA_SCAN_IMPLEMENTATION.md +0 -373
  77. package/docs/ARELA_SCAN_QUICKREF.md +0 -139
  78. package/docs/CROSS_PLATFORM_PATH_HANDLING.md +0 -597
  79. package/docs/DETECTION_ATTEMPT_TRACKING.md +0 -414
  80. package/docs/MIGRATION_UPLOADER_TO_FILE_STATS.md +0 -1020
  81. package/docs/MULTI_LEVEL_DIRECTORY_SCANNING.md +0 -494
  82. package/docs/QUICK_REFERENCE_API_DETECTION.md +0 -264
  83. package/docs/REFACTORING_SUMMARY_DETECT_PEDIMENTOS.md +0 -200
  84. package/docs/STATS_COMMAND_SEQUENCE_DIAGRAM.md +0 -287
  85. package/docs/STATS_COMMAND_SIMPLE.md +0 -93
@@ -0,0 +1,395 @@
1
+ # Arquitectura de Watch Mode con Auto-Processing Pipeline
2
+
3
+ ## 🏗️ Diagrama de Componentes
4
+
5
+ ```
6
+ ┌─────────────────────────────────────────────────────────────────────────┐
7
+ │ arela watch │
8
+ │ (index.js - CLI) │
9
+ └──────────────────────────┬──────────────────────────────────────────────┘
10
+
11
+
12
+ ┌─────────────────────────────────────────────────────────────────────────┐
13
+ │ WatchCommand.js │
14
+ │ • Parsea directorios con JSON (WATCH_DIRECTORY_CONFIGS) │
15
+ │ • Crea configuraciones de directorio con folderStructure │
16
+ │ • Inicializa WatchService con directoryConfigs │
17
+ │ • Habilita auto-processing │
18
+ └──────────────────────────┬──────────────────────────────────────────────┘
19
+
20
+
21
+ ┌─────────────────────────────────────────────────────────────────────────┐
22
+ │ WatchService.js │
23
+ │ ┌──────────────────────────────────────────────────────────┐ │
24
+ │ │ Watchers (chokidar) │ │
25
+ │ │ • Monitorea cambios en filesystem │ │
26
+ │ │ • Emite eventos: add, change, unlink │ │
27
+ │ └──────────────────────────────────────────────────────────┘ │
28
+ │ │ │
29
+ │ ┌──────────────────────┐▼──────────────────────┐ │
30
+ │ │ #handleFileAdded() │ (evento: add) │ │
31
+ │ └──────────────────────┬──────────────────────┘ │
32
+ │ │ │
33
+ │ ┌──────────────────────┐▼──────────────────────┐ │
34
+ │ │ #triggerAutoPipeline()│ (if autoProcessing) │ │
35
+ │ └──────────────────────┬──────────────────────┘ │
36
+ │ │ │
37
+ │ ┌──────────────────────┐▼──────────────────────┐ │
38
+ │ │ directoryConfigs Map │ findWatchDirectory() │ │
39
+ │ │ • watchDir -> config │ folderStructure │ │
40
+ │ └──────────────────────┬──────────────────────┘ │
41
+ └──────────────────────────┼──────────────────────────────────────────────┘
42
+
43
+
44
+ ┌─────────────────────────────────────────────────────────────────────────┐
45
+ │ AutoProcessingService.js │
46
+ │ (4-Step Pipeline) │
47
+ │ │
48
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
49
+ │ │ STEP 1 │ │ STEP 2 │ │ STEP 3 │ │ STEP 4 │ │
50
+ │ │ Stats │→ │ Detect │→ │ Propagate │→ │ Upload │ │
51
+ │ │ Only │ │ PDFs │ │ Arela Path │ │ by RFC │ │
52
+ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
53
+ │ │ │ │ │ │
54
+ │ ▼ ▼ ▼ ▼ │
55
+ │ UploadCommand DatabaseService DatabaseService UploadCommand │
56
+ │ │
57
+ └─────────────────────────────────────────────────────────────────────────┘
58
+ ```
59
+
60
+ ## 📊 Flujo de Datos
61
+
62
+ ### Secuencia de Eventos
63
+
64
+ ```
65
+ 1. Usuario coloca archivo en directorio monitoreado
66
+
67
+ 2. Chokidar detecta evento 'add'
68
+
69
+ 3. WatchService.#handleFileAdded() es invocado
70
+
71
+ 4. Si autoProcessingEnabled:
72
+ - WatchService.#triggerAutoPipeline(filePath) es llamado
73
+
74
+ 5. Se identifica el watchDir correspondiente
75
+ - Se obtiene folderStructure de directoryConfigs
76
+
77
+ 6. AutoProcessingService.executeProcessingPipeline() inicia
78
+
79
+ 7. Secuencia de 4 pasos:
80
+ - Step 1: stats --stats-only
81
+ - Step 2: detect --detect-pdfs
82
+ - Step 3: detect --propagate-arela-path
83
+ - Step 4: upload --upload-by-rfc --folder-structure
84
+
85
+ 8. Resultado es loguead y resumido
86
+ ```
87
+
88
+ ## 🔌 Integración de Componentes
89
+
90
+ ### config.js
91
+ ```javascript
92
+ // Parsea WATCH_DIRECTORY_CONFIGS desde .env
93
+ watch.directoryConfigs = JSON.parse(process.env.WATCH_DIRECTORY_CONFIGS)
94
+ // Resultado:
95
+ // {
96
+ // "../../Documents/2022": "estructura-2022",
97
+ // "../../Documents/2023": "estructura-2023"
98
+ // }
99
+ ```
100
+
101
+ ### WatchCommand.js
102
+ ```javascript
103
+ // Convierte configuración a array de objetos
104
+ const directories = [
105
+ { path: "../../Documents/2022", folderStructure: "estructura-2022" },
106
+ { path: "../../Documents/2023", folderStructure: "estructura-2023" }
107
+ ]
108
+
109
+ // Pasa directoryConfigs a WatchService
110
+ for (const dirConfig of directories) {
111
+ await watchService.addWatcher(dirPath, options, dirConfig)
112
+ }
113
+
114
+ // Habilita auto-processing
115
+ watchService.enableAutoProcessing({ batchSize: 10 })
116
+ ```
117
+
118
+ ### WatchService.js
119
+ ```javascript
120
+ // Almacena configuración de directorios
121
+ directoryConfigs = new Map([
122
+ ["path/to/Documents/2022", { path: "...", folderStructure: "estructura-2022" }],
123
+ ["path/to/Documents/2023", { path: "...", folderStructure: "estructura-2023" }]
124
+ ])
125
+
126
+ // Cuando detecta archivo nuevo
127
+ #handleFileAdded(filePath) {
128
+ if (this.autoProcessingEnabled) {
129
+ this.#triggerAutoPipeline(filePath)
130
+ }
131
+ }
132
+
133
+ // Encuentra configuración del directorio
134
+ #triggerAutoPipeline(filePath) {
135
+ const watchDir = this.#findWatchDirectory(filePath)
136
+ const dirConfig = this.directoryConfigs.get(watchDir)
137
+ const folderStructure = dirConfig.folderStructure
138
+
139
+ // Ejecuta pipeline con folderStructure
140
+ autoProcessingService.executeProcessingPipeline({
141
+ filePath,
142
+ watchDir,
143
+ folderStructure,
144
+ batchSize: 10
145
+ })
146
+ }
147
+ ```
148
+
149
+ ### AutoProcessingService.js
150
+ ```javascript
151
+ // Ejecuta 4 pasos secuencialmente
152
+ async executeProcessingPipeline(options) {
153
+ // Step 1: stats
154
+ await this.#executeStatsOnly(options)
155
+
156
+ // Step 2: detect
157
+ await this.#executeDetectPdfs(options)
158
+
159
+ // Step 3: propagate
160
+ await this.#executePropagateArelaPath()
161
+
162
+ // Step 4: upload with folderStructure
163
+ await this.#executeUploadByRfc({
164
+ ...options,
165
+ folderStructure: options.folderStructure // ← Se usa aquí
166
+ })
167
+ }
168
+ ```
169
+
170
+ ## 📁 Estructura de Archivos Modificados
171
+
172
+ ```
173
+ src/
174
+ ├── index.js (Sin cambios mayores)
175
+ ├── config/
176
+ │ └── config.js (✅ Actualizado: #loadWatchConfig)
177
+ ├── commands/
178
+ │ ├── WatchCommand.js (✅ Actualizado: #parseDirectories, auto-processing)
179
+ │ └── UploadCommand.js (Sin cambios)
180
+ ├── services/
181
+ │ ├── WatchService.js (✅ Actualizado: directoryConfigs, auto-pipeline)
182
+ │ ├── AutoProcessingService.js (🆕 Creado: 4-step pipeline)
183
+ │ ├── DatabaseService.js (Sin cambios)
184
+ │ └── LoggingService.js (Sin cambios)
185
+ └── utils/
186
+ └── WatchEventHandler.js (✅ Actualizado: processNewFilesWithPipeline)
187
+
188
+ .env (✅ Actualizado: WATCH_DIRECTORY_CONFIGS)
189
+ .env.template (✅ Actualizado: nueva configuración)
190
+ docs/
191
+ └── WATCH_AUTO_PIPELINE.md (🆕 Creado: esta documentación)
192
+ ```
193
+
194
+ ## 🔄 Estados y Transiciones
195
+
196
+ ### WatchService Estados
197
+
198
+ ```
199
+ ┌──────────┐
200
+ │ IDLE │
201
+ │(created) │
202
+ └────┬─────┘
203
+ │ addWatcher()
204
+
205
+ ┌──────────────┐
206
+ │ WATCHING │ ← directoryConfigs se cargan aquí
207
+ │ │
208
+ └────┬─────────┘
209
+ │ autoProcessing = true
210
+
211
+ ┌──────────────────────┐
212
+ │ AUTO-PROCESSING │
213
+ │ ENABLED │
214
+ └────┬─────────────────┘
215
+ │ detecta archivo new
216
+
217
+ ┌──────────────────────┐
218
+ │ EXECUTING PIPELINE │
219
+ │ (AutoProcessing │
220
+ │ Service) │
221
+ └────┬─────────────────┘
222
+ │ pipeline completa
223
+
224
+ ┌──────────────┐
225
+ │ WATCHING │ ← Vuelve a estado de espera
226
+ └──────────────┘
227
+ ```
228
+
229
+ ### Pipeline Estados
230
+
231
+ ```
232
+ ┌──────────┐
233
+ │ PENDING │
234
+ └────┬─────┘
235
+ │ executeProcessingPipeline()
236
+
237
+ ┌──────────────┐
238
+ │ STEP 1 │
239
+ │ STATS ONLY │
240
+ └────┬─────────┘
241
+ │ success
242
+
243
+ ┌──────────────┐
244
+ │ STEP 2 │
245
+ │ DETECT PDFS │
246
+ └────┬─────────┘
247
+ │ success
248
+
249
+ ┌──────────────┐
250
+ │ STEP 3 │
251
+ │ PROPAGATE │
252
+ └────┬─────────┘
253
+ │ success/warning
254
+
255
+ ┌──────────────┐
256
+ │ STEP 4 │
257
+ │ UPLOAD RFC │
258
+ └────┬─────────┘
259
+ │ success/fail
260
+
261
+ ┌──────────────┐
262
+ │ COMPLETED │
263
+ └──────────────┘
264
+ ```
265
+
266
+ ## 🎯 Caso de Uso Detallado
267
+
268
+ ### Escenario: Nuevo archivo en Documents/2022
269
+
270
+ #### Configuración
271
+ ```env
272
+ WATCH_DIRECTORY_CONFIGS={"../../Documents/2022":"estructura-2022"}
273
+ WATCH_ENABLED=true
274
+ ```
275
+
276
+ #### Ejecución
277
+
278
+ 1. **Evento del Filesystem**
279
+ - Usuario: `cp documento.pdf ../../Documents/2022/`
280
+ - Chokidar: Detecta evento 'add' para el archivo
281
+
282
+ 2. **WatchService**
283
+ ```
284
+ #handleFileAdded(filePath) →
285
+ #triggerAutoPipeline(filePath) →
286
+ #findWatchDirectory() → "../../Documents/2022" →
287
+ directoryConfigs.get() → { folderStructure: "estructura-2022" } →
288
+ autoProcessingService.executeProcessingPipeline()
289
+ ```
290
+
291
+ 3. **AutoProcessingService - Step 1**
292
+ ```
293
+ #executeStatsOnly() →
294
+ UploadCommand.execute({ statsOnly: true }) →
295
+ Database: INSERT INTO uploads VALUES (...)
296
+ ```
297
+
298
+ 4. **AutoProcessingService - Step 2**
299
+ ```
300
+ #executeDetectPdfs() →
301
+ DatabaseService.detectPedimentosInDatabase() →
302
+ Database: UPDATE uploads SET document_type = 'pedimento-simplificado' WHERE ...
303
+ ```
304
+
305
+ 5. **AutoProcessingService - Step 3**
306
+ ```
307
+ #executePropagateArelaPath() →
308
+ DatabaseService.propagateArelaPath() →
309
+ Database: UPDATE uploads SET arela_path = ... WHERE original_path = ...
310
+ ```
311
+
312
+ 6. **AutoProcessingService - Step 4**
313
+ ```
314
+ #executeUploadByRfc() →
315
+ DatabaseService.uploadFilesByRfc({ folderStructure: "estructura-2022" }) →
316
+ UploadService: POST /api/upload/file (with folderStructure header/param) →
317
+ Result: File uploaded to Arela with path bucket/estructura-2022/...
318
+ ```
319
+
320
+ 7. **Resultado Final**
321
+ ```
322
+ ✅ Pipeline execution complete
323
+ - Stats collected
324
+ - PDFs detected
325
+ - Arela paths propagated
326
+ - Files uploaded with structure
327
+ - All 4 steps successful
328
+ ```
329
+
330
+ ## 🧪 Testing
331
+
332
+ ### Unit Tests Recomendados
333
+
334
+ ```javascript
335
+ // Test: directoryConfigs se cargan correctamente
336
+ describe('WatchService', () => {
337
+ it('should load directory configs from addWatcher', () => {
338
+ const dirConfig = { path: 'test', folderStructure: 'test-struct' }
339
+ watchService.addWatcher('test', {}, dirConfig)
340
+ expect(watchService.directoryConfigs.get(path.resolve('test'))).toEqual(...)
341
+ })
342
+ })
343
+
344
+ // Test: auto-processing se habilita
345
+ it('should enable auto-processing', () => {
346
+ watchService.enableAutoProcessing({ batchSize: 10 })
347
+ expect(watchService.isAutoProcessingEnabled()).toBe(true)
348
+ })
349
+
350
+ // Test: pipeline se ejecuta en archivo nuevo
351
+ it('should trigger pipeline on file added', async () => {
352
+ // Mock AutoProcessingService
353
+ // Simulate #handleFileAdded
354
+ // Verify pipeline was called
355
+ })
356
+ ```
357
+
358
+ ## 📈 Métricas y Monitoreo
359
+
360
+ ### Stats Disponibles
361
+
362
+ ```javascript
363
+ // WatchService stats
364
+ {
365
+ filesAdded: 42,
366
+ filesModified: 15,
367
+ filesRemoved: 3,
368
+ uploadsTriggered: 10,
369
+ pipelinesTriggered: 8, // ← Novo
370
+ errorsEncountered: 0,
371
+ watchedDirectories: 2,
372
+ activeWatchers: 2,
373
+ isRunning: true,
374
+ autoProcessingEnabled: true // ← Novo
375
+ }
376
+ ```
377
+
378
+ ## 🔐 Consideraciones de Seguridad
379
+
380
+ 1. **Validación de Ruta**
381
+ - Se valida que el archivo está en directorio vigilado
382
+ - Se previene procesamiento de archivos fuera del scope
383
+
384
+ 2. **Prevención de Concurrencia**
385
+ - Solo un pipeline por vez (`this.isProcessing`)
386
+ - Se colan nuevas solicitudes mientras uno está en ejecución
387
+
388
+ 3. **Manejo de Errores**
389
+ - Errores en pasos iniciales detienen el pipeline
390
+ - Errores posteriores se loguean pero continúan
391
+ - No se pierden datos incluso con fallos
392
+
393
+ ---
394
+
395
+ Para implementación y uso, ver [WATCH_AUTO_PIPELINE.md](WATCH_AUTO_PIPELINE.md)