@arela/uploader 0.2.13 β†’ 1.0.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 (43) hide show
  1. package/.env.template +66 -0
  2. package/README.md +263 -62
  3. package/docs/API_ENDPOINTS_FOR_DETECTION.md +647 -0
  4. package/docs/QUICK_REFERENCE_API_DETECTION.md +264 -0
  5. package/docs/REFACTORING_SUMMARY_DETECT_PEDIMENTOS.md +200 -0
  6. package/package.json +3 -2
  7. package/scripts/cleanup-ds-store.js +109 -0
  8. package/scripts/cleanup-system-files.js +69 -0
  9. package/scripts/tests/phase-7-features.test.js +415 -0
  10. package/scripts/tests/signal-handling.test.js +275 -0
  11. package/scripts/tests/smart-watch-integration.test.js +554 -0
  12. package/scripts/tests/watch-service-integration.test.js +584 -0
  13. package/src/commands/UploadCommand.js +31 -4
  14. package/src/commands/WatchCommand.js +1342 -0
  15. package/src/config/config.js +270 -2
  16. package/src/document-type-shared.js +2 -0
  17. package/src/document-types/support-document.js +200 -0
  18. package/src/file-detection.js +9 -1
  19. package/src/index.js +163 -4
  20. package/src/services/AdvancedFilterService.js +505 -0
  21. package/src/services/AutoProcessingService.js +749 -0
  22. package/src/services/BenchmarkingService.js +381 -0
  23. package/src/services/DatabaseService.js +1019 -539
  24. package/src/services/ErrorMonitor.js +275 -0
  25. package/src/services/LoggingService.js +419 -1
  26. package/src/services/MonitoringService.js +401 -0
  27. package/src/services/PerformanceOptimizer.js +511 -0
  28. package/src/services/ReportingService.js +511 -0
  29. package/src/services/SignalHandler.js +255 -0
  30. package/src/services/SmartWatchDatabaseService.js +527 -0
  31. package/src/services/WatchService.js +783 -0
  32. package/src/services/upload/ApiUploadService.js +447 -3
  33. package/src/services/upload/MultiApiUploadService.js +233 -0
  34. package/src/services/upload/SupabaseUploadService.js +12 -5
  35. package/src/services/upload/UploadServiceFactory.js +24 -0
  36. package/src/utils/CleanupManager.js +262 -0
  37. package/src/utils/FileOperations.js +44 -0
  38. package/src/utils/WatchEventHandler.js +522 -0
  39. package/supabase/migrations/001_create_initial_schema.sql +366 -0
  40. package/supabase/migrations/002_align_with_arela_api_schema.sql +145 -0
  41. package/.envbackup +0 -37
  42. package/SUPABASE_UPLOAD_FIX.md +0 -157
  43. package/commands.md +0 -14
package/src/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { Command } from 'commander';
3
3
 
4
4
  import UploadCommand from './commands/UploadCommand.js';
5
+ import watchCommand from './commands/WatchCommand.js';
5
6
  import appConfig from './config/config.js';
6
7
  import ErrorHandler from './errors/ErrorHandler.js';
7
8
  import logger from './services/LoggingService.js';
@@ -15,6 +16,7 @@ class ArelaUploaderCLI {
15
16
  this.program = new Command();
16
17
  this.errorHandler = new ErrorHandler(logger);
17
18
  this.uploadCommand = new UploadCommand();
19
+ this.watchCommand = watchCommand;
18
20
 
19
21
  this.#setupProgram();
20
22
  this.#setupCommands();
@@ -45,6 +47,19 @@ class ArelaUploaderCLI {
45
47
  this.program
46
48
  .command('upload')
47
49
  .description('Upload files to Arela with automatic processing')
50
+ .option(
51
+ '--api <target>',
52
+ 'API target: default|agencia|cliente',
53
+ 'default',
54
+ )
55
+ .option(
56
+ '--source-api <target>',
57
+ 'Source API for reading data (cross-tenant mode): agencia|cliente',
58
+ )
59
+ .option(
60
+ '--target-api <target>',
61
+ 'Target API for uploading files (cross-tenant mode): agencia|cliente',
62
+ )
48
63
  .option(
49
64
  '-b, --batch-size <size>',
50
65
  'Number of files to process in each batch',
@@ -75,6 +90,17 @@ class ArelaUploaderCLI {
75
90
  )
76
91
  .action(async (options) => {
77
92
  try {
93
+ // Handle cross-tenant mode (source and target APIs)
94
+ if (options.sourceApi && options.targetApi) {
95
+ appConfig.setCrossTenantTargets(
96
+ options.sourceApi,
97
+ options.targetApi,
98
+ );
99
+ } else if (options.api && options.api !== 'default') {
100
+ // Set single API target if specified
101
+ appConfig.setApiTarget(options.api);
102
+ }
103
+
78
104
  // Handle --upload-by-rfc as a specific operation
79
105
  if (options.uploadByRfc) {
80
106
  const databaseService = await import(
@@ -85,6 +111,9 @@ class ArelaUploaderCLI {
85
111
  batchSize: parseInt(options.batchSize) || 10,
86
112
  showProgress: true,
87
113
  folderStructure: options.folderStructure,
114
+ apiTarget: options.api,
115
+ sourceApi: options.sourceApi,
116
+ targetApi: options.targetApi,
88
117
  });
89
118
  console.log(
90
119
  `βœ… RFC upload completed: ${result.processedCount} processed, ${result.uploadedCount} uploaded, ${result.errorCount} errors`,
@@ -102,6 +131,11 @@ class ArelaUploaderCLI {
102
131
  this.program
103
132
  .command('stats')
104
133
  .description('Collect file statistics without uploading')
134
+ .option(
135
+ '--api <target>',
136
+ 'API target: agencia|cliente|default',
137
+ 'default',
138
+ )
105
139
  .option(
106
140
  '-b, --batch-size <size>',
107
141
  'Number of files to process in each batch',
@@ -119,6 +153,10 @@ class ArelaUploaderCLI {
119
153
  .option('--show-stats', 'Show performance statistics')
120
154
  .action(async (options) => {
121
155
  try {
156
+ // Set API target if specified
157
+ if (options.api && options.api !== 'default') {
158
+ appConfig.setApiTarget(options.api);
159
+ }
122
160
  const statsOptions = { ...options, statsOnly: true };
123
161
  await this.uploadCommand.execute(statsOptions);
124
162
  } catch (error) {
@@ -130,6 +168,11 @@ class ArelaUploaderCLI {
130
168
  this.program
131
169
  .command('detect')
132
170
  .description('Run document detection on existing file records')
171
+ .option(
172
+ '--api <target>',
173
+ 'API target: agencia|cliente|default',
174
+ 'default',
175
+ )
133
176
  .option(
134
177
  '-b, --batch-size <size>',
135
178
  'Number of files to process in each batch',
@@ -145,6 +188,11 @@ class ArelaUploaderCLI {
145
188
  )
146
189
  .action(async (options) => {
147
190
  try {
191
+ // Set API target if specified
192
+ if (options.api && options.api !== 'default') {
193
+ appConfig.setApiTarget(options.api);
194
+ }
195
+
148
196
  const databaseService = await import('./services/DatabaseService.js');
149
197
 
150
198
  // Handle --propagate-arela-path as a specific operation
@@ -229,6 +277,72 @@ class ArelaUploaderCLI {
229
277
  }
230
278
  });
231
279
 
280
+ // Watch command
281
+ this.program
282
+ .command('watch')
283
+ .description(
284
+ 'Monitor directories for file changes and upload automatically',
285
+ )
286
+ .option(
287
+ '--api <target>',
288
+ 'API target: default|agencia|cliente',
289
+ 'default',
290
+ )
291
+ .option(
292
+ '--source-api <target>',
293
+ 'Source API for reading data (cross-tenant mode): agencia|cliente',
294
+ )
295
+ .option(
296
+ '--target-api <target>',
297
+ 'Target API for uploading files (cross-tenant mode): agencia|cliente',
298
+ )
299
+ .option(
300
+ '-d, --directories <paths>',
301
+ 'Comma-separated directories to watch',
302
+ )
303
+ .option(
304
+ '-s, --strategy <strategy>',
305
+ 'Upload strategy: individual|batch|full-structure',
306
+ 'batch',
307
+ )
308
+ .option('--debounce <ms>', 'Debounce delay in milliseconds', '1000')
309
+ .option(
310
+ '-b, --batch-size <size>',
311
+ 'Number of files to process in each batch',
312
+ '10',
313
+ )
314
+ .option(
315
+ '--poll <ms>',
316
+ 'Use polling instead of native file system events (interval in ms)',
317
+ )
318
+ .option('--ignore <patterns>', 'Comma-separated patterns to ignore')
319
+ .option('--auto-detect', 'Enable automatic document type detection')
320
+ .option('--auto-organize', 'Enable automatic file organization')
321
+ .option(
322
+ '--auto-processing',
323
+ 'Enable automatic 4-step pipeline (stats, detect, propagate, upload)',
324
+ )
325
+ .option('--dry-run', 'Simulate changes without uploading')
326
+ .option('--verbose', 'Enable verbose logging')
327
+ .action(async (options) => {
328
+ try {
329
+ // Handle cross-tenant mode (source and target APIs)
330
+ if (options.sourceApi && options.targetApi) {
331
+ appConfig.setCrossTenantTargets(
332
+ options.sourceApi,
333
+ options.targetApi,
334
+ );
335
+ } else if (options.api && options.api !== 'default') {
336
+ // Set single API target if specified
337
+ appConfig.setApiTarget(options.api);
338
+ }
339
+
340
+ await this.watchCommand.execute(options);
341
+ } catch (error) {
342
+ this.errorHandler.handleFatalError(error, { command: 'watch' });
343
+ }
344
+ });
345
+
232
346
  // Version command (already handled by program.version())
233
347
 
234
348
  // Help command
@@ -286,9 +400,27 @@ class ArelaUploaderCLI {
286
400
  #showConfiguration() {
287
401
  console.log('πŸ”§ Current Configuration:');
288
402
  console.log(` Version: ${appConfig.packageVersion}`);
289
- console.log('\nπŸ“‘ API Configuration:');
290
- console.log(` Base URL: ${appConfig.api.baseUrl || 'Not configured'}`);
291
- console.log(` Token: ${appConfig.api.token ? 'βœ… Set' : '❌ Not set'}`);
403
+ console.log('\nπŸ“‘ API Configuration (Multi-Tenant):');
404
+ console.log(` Active Target: ${appConfig.api.activeTarget || 'default'}`);
405
+ console.log('\n 🌐 Default API:');
406
+ console.log(` URL: ${appConfig.api.baseUrl || 'Not configured'}`);
407
+ console.log(
408
+ ` Token: ${appConfig.api.token ? 'βœ… Set' : '❌ Not set'}`,
409
+ );
410
+ console.log('\n 🏒 Agencia API:');
411
+ console.log(
412
+ ` URL: ${appConfig.api.targets.agencia?.baseUrl || 'Not configured'}`,
413
+ );
414
+ console.log(
415
+ ` Token: ${appConfig.api.targets.agencia?.token ? 'βœ… Set' : '❌ Not set'}`,
416
+ );
417
+ console.log('\n πŸ‘€ Cliente API:');
418
+ console.log(
419
+ ` URL: ${appConfig.api.targets.cliente?.baseUrl || 'Not configured'}`,
420
+ );
421
+ console.log(
422
+ ` Token: ${appConfig.api.targets.cliente?.token ? 'βœ… Set' : '❌ Not set'}`,
423
+ );
292
424
  console.log('\nπŸ—„οΈ Supabase Configuration:');
293
425
  console.log(` URL: ${appConfig.supabase.url || 'Not configured'}`);
294
426
  console.log(` Key: ${appConfig.supabase.key ? 'βœ… Set' : '❌ Not set'}`);
@@ -316,11 +448,38 @@ class ArelaUploaderCLI {
316
448
  console.log(` Log File: ${appConfig.logging.logFilePath}`);
317
449
  console.log('\n🎯 Service Availability:');
318
450
  console.log(
319
- ` API Mode: ${appConfig.isApiModeAvailable() ? 'βœ… Available' : '❌ Not available'}`,
451
+ ` API Mode (default): ${appConfig.isApiModeAvailable() ? 'βœ… Available' : '❌ Not available'}`,
452
+ );
453
+ console.log(
454
+ ` API Mode (agencia): ${appConfig.isApiModeAvailable('agencia') ? 'βœ… Available' : '❌ Not available'}`,
455
+ );
456
+ console.log(
457
+ ` API Mode (cliente): ${appConfig.isApiModeAvailable('cliente') ? 'βœ… Available' : '❌ Not available'}`,
320
458
  );
321
459
  console.log(
322
460
  ` Supabase Mode: ${appConfig.isSupabaseModeAvailable() ? 'βœ… Available' : '❌ Not available'}`,
323
461
  );
462
+ console.log('\nπŸ“‹ Uso Multi-Tenant:');
463
+ console.log(
464
+ ' arela stats --api agencia # Registrar archivos en BD agencia',
465
+ );
466
+ console.log(
467
+ ' arela detect --api agencia # Detectar pedimentos en BD agencia',
468
+ );
469
+ console.log(
470
+ ' arela upload --api cliente # Subir archivos al cliente configurado',
471
+ );
472
+ console.log('\nπŸ‘οΈ Modo Watch Multi-Tenant:');
473
+ console.log(
474
+ ' arela watch --api cliente # Watch con API cliente',
475
+ );
476
+ console.log(
477
+ ' arela watch --source-api agencia --target-api cliente # Cross-tenant watch',
478
+ );
479
+ console.log(
480
+ '\nπŸ’‘ Tip: Configura ARELA_API_CLIENTE_URL y ARELA_API_CLIENTE_TOKEN',
481
+ );
482
+ console.log(' en .env para apuntar al cliente especΓ­fico que necesites.');
324
483
  }
325
484
 
326
485
  /**