@arela/uploader 1.0.24 → 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 (79) 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 +8 -0
  29. package/src/config/config.js +2 -2
  30. package/src/file-detection.js +42 -1
  31. package/src/scoring/scoring-engine.js +35 -7
  32. package/.vscode/settings.json +0 -1
  33. package/coverage/IdentifyCommand.js.html +0 -1462
  34. package/coverage/PropagateCommand.js.html +0 -1507
  35. package/coverage/PushCommand.js.html +0 -1504
  36. package/coverage/ScanCommand.js.html +0 -1654
  37. package/coverage/UploadCommand.js.html +0 -1846
  38. package/coverage/WatchCommand.js.html +0 -4111
  39. package/coverage/base.css +0 -224
  40. package/coverage/block-navigation.js +0 -87
  41. package/coverage/favicon.png +0 -0
  42. package/coverage/index.html +0 -191
  43. package/coverage/lcov-report/IdentifyCommand.js.html +0 -1462
  44. package/coverage/lcov-report/PropagateCommand.js.html +0 -1507
  45. package/coverage/lcov-report/PushCommand.js.html +0 -1504
  46. package/coverage/lcov-report/ScanCommand.js.html +0 -1654
  47. package/coverage/lcov-report/UploadCommand.js.html +0 -1846
  48. package/coverage/lcov-report/WatchCommand.js.html +0 -4111
  49. package/coverage/lcov-report/base.css +0 -224
  50. package/coverage/lcov-report/block-navigation.js +0 -87
  51. package/coverage/lcov-report/favicon.png +0 -0
  52. package/coverage/lcov-report/index.html +0 -191
  53. package/coverage/lcov-report/prettify.css +0 -1
  54. package/coverage/lcov-report/prettify.js +0 -2
  55. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  56. package/coverage/lcov-report/sorter.js +0 -210
  57. package/coverage/lcov.info +0 -1937
  58. package/coverage/prettify.css +0 -1
  59. package/coverage/prettify.js +0 -2
  60. package/coverage/sort-arrow-sprite.png +0 -0
  61. package/coverage/sorter.js +0 -210
  62. package/docs/API_ENDPOINTS_FOR_DETECTION.md +0 -647
  63. package/docs/API_RETRY_MECHANISM.md +0 -338
  64. package/docs/ARELA_IDENTIFY_IMPLEMENTATION.md +0 -489
  65. package/docs/ARELA_IDENTIFY_QUICKREF.md +0 -186
  66. package/docs/ARELA_PROPAGATE_IMPLEMENTATION.md +0 -581
  67. package/docs/ARELA_PROPAGATE_QUICKREF.md +0 -272
  68. package/docs/ARELA_PUSH_IMPLEMENTATION.md +0 -577
  69. package/docs/ARELA_PUSH_QUICKREF.md +0 -322
  70. package/docs/ARELA_SCAN_IMPLEMENTATION.md +0 -373
  71. package/docs/ARELA_SCAN_QUICKREF.md +0 -139
  72. package/docs/CROSS_PLATFORM_PATH_HANDLING.md +0 -597
  73. package/docs/DETECTION_ATTEMPT_TRACKING.md +0 -414
  74. package/docs/MIGRATION_UPLOADER_TO_FILE_STATS.md +0 -1020
  75. package/docs/MULTI_LEVEL_DIRECTORY_SCANNING.md +0 -494
  76. package/docs/QUICK_REFERENCE_API_DETECTION.md +0 -264
  77. package/docs/REFACTORING_SUMMARY_DETECT_PEDIMENTOS.md +0 -200
  78. package/docs/STATS_COMMAND_SEQUENCE_DIAGRAM.md +0 -287
  79. package/docs/STATS_COMMAND_SIMPLE.md +0 -93
@@ -0,0 +1,614 @@
1
+ # 🚀 Guía Paso a Paso: Integrar Watcher con arela-api
2
+
3
+ ## 📌 Objetivo Final
4
+ Permitir que el frontend monitoree el estado del watcher en tiempo real a través de endpoints REST en la arela-api.
5
+
6
+ ---
7
+
8
+ ## ✅ Pasos de Implementación
9
+
10
+ ### **Paso 1: Preparar arela-uploader para exportar WatchService**
11
+
12
+ #### 1.1 Crear archivo de exportaciones
13
+
14
+ Crear: `src/services/index.js`
15
+
16
+ ```javascript
17
+ // Exportar todos los servicios disponibles públicamente
18
+ export { default as watchService } from './WatchService.js';
19
+ export { default as databaseService } from './DatabaseService.js';
20
+ export { default as autoProcessingService } from './AutoProcessingService.js';
21
+ export { default as logger } from './LoggingService.js';
22
+ ```
23
+
24
+ #### 1.2 Actualizar package.json de arela-uploader
25
+
26
+ Agregar campo `exports`:
27
+
28
+ ```json
29
+ {
30
+ "name": "arela-uploader",
31
+ "version": "1.0.0",
32
+ "type": "module",
33
+ "exports": {
34
+ ".": "./src/index.js",
35
+ "./services": "./src/services/index.js",
36
+ "./commands": "./src/commands/index.js"
37
+ },
38
+ "main": "./src/index.js"
39
+ }
40
+ ```
41
+
42
+ ✅ **Resultado:** Otros módulos pueden hacer:
43
+ ```javascript
44
+ import { watchService } from 'arela-uploader/services';
45
+ ```
46
+
47
+ ---
48
+
49
+ ### **Paso 2: Preparar arela-api para usar WatchService**
50
+
51
+ #### 2.1 Instalar dependencia de arela-uploader
52
+
53
+ En el directorio `arela-api`:
54
+
55
+ ```bash
56
+ # Opción A: Instalar desde ruta local
57
+ npm install ../arela-uploader
58
+
59
+ # Opción B: Si está publicado en npm
60
+ npm install arela-uploader
61
+ ```
62
+
63
+ #### 2.2 Crear carpeta de rutas si no existe
64
+
65
+ ```bash
66
+ mkdir -p src/routes
67
+ ```
68
+
69
+ #### 2.3 Crear archivo de rutas del watcher
70
+
71
+ Crear: `arela-api/src/routes/watcher.routes.js`
72
+
73
+ **Copiar contenido completo del archivo en `WATCHER_API_IMPLEMENTATION.md`**
74
+
75
+ ```javascript
76
+ import express from 'express';
77
+ import logger from '../services/LoggingService.js';
78
+
79
+ const router = express.Router();
80
+
81
+ export function initWatcherRoutes(app, watchService) {
82
+ // ... copiar todos los endpoints de WATCHER_API_IMPLEMENTATION.md ...
83
+ }
84
+
85
+ export default router;
86
+ ```
87
+
88
+ #### 2.4 Integrar rutas en app.js
89
+
90
+ En `arela-api/src/app.js`:
91
+
92
+ ```javascript
93
+ import express from 'express';
94
+ import { initWatcherRoutes } from './routes/watcher.routes.js';
95
+ import { watchService } from 'arela-uploader/services'; // ✨ Nuevo
96
+
97
+ const app = express();
98
+
99
+ // Middleware
100
+ app.use(express.json());
101
+ app.use(express.urlencoded({ extended: true }));
102
+
103
+ // ... otras rutas ...
104
+
105
+ // ✨ Inicializar rutas del watcher
106
+ initWatcherRoutes(app, watchService);
107
+
108
+ // Error handling
109
+ app.use((err, req, res, next) => {
110
+ console.error(err);
111
+ res.status(500).json({
112
+ error: 'Internal server error',
113
+ message: err.message,
114
+ });
115
+ });
116
+
117
+ export default app;
118
+ ```
119
+
120
+ ---
121
+
122
+ ### **Paso 3: Agregar Autenticación (Opcional pero Recomendado)**
123
+
124
+ #### 3.1 Crear middleware de autenticación
125
+
126
+ Crear: `arela-api/src/middleware/auth.js`
127
+
128
+ ```javascript
129
+ import jwt from 'jsonwebtoken';
130
+
131
+ export const verifyAuth = (req, res, next) => {
132
+ try {
133
+ const token = req.headers.authorization?.split(' ')[1];
134
+
135
+ if (!token) {
136
+ return res.status(401).json({ error: 'No token provided' });
137
+ }
138
+
139
+ const decoded = jwt.verify(token, process.env.JWT_SECRET);
140
+ req.user = decoded;
141
+ next();
142
+ } catch (error) {
143
+ res.status(401).json({ error: 'Invalid token' });
144
+ }
145
+ };
146
+
147
+ export const requireRole = (role) => (req, res, next) => {
148
+ if (req.user?.role !== role && req.user?.role !== 'admin') {
149
+ return res.status(403).json({ error: 'Insufficient permissions' });
150
+ }
151
+ next();
152
+ };
153
+ ```
154
+
155
+ #### 3.2 Actualizar rutas para protegerlas
156
+
157
+ En `watcher.routes.js`, agregar autenticación:
158
+
159
+ ```javascript
160
+ import { verifyAuth, requireRole } from '../middleware/auth.js';
161
+
162
+ export function initWatcherRoutes(app, watchService) {
163
+ // Endpoints de lectura (cualquier usuario autenticado)
164
+ router.get('/status', verifyAuth, (req, res) => {
165
+ // ... implementación ...
166
+ });
167
+
168
+ router.get('/queue-stats', verifyAuth, async (req, res) => {
169
+ // ... implementación ...
170
+ });
171
+
172
+ router.get('/directories', verifyAuth, (req, res) => {
173
+ // ... implementación ...
174
+ });
175
+
176
+ // Endpoints de control (solo admin)
177
+ router.post('/start', verifyAuth, requireRole('admin'), async (req, res) => {
178
+ // ... implementación ...
179
+ });
180
+
181
+ router.post('/stop', verifyAuth, requireRole('admin'), async (req, res) => {
182
+ // ... implementación ...
183
+ });
184
+
185
+ // ... resto de rutas ...
186
+ }
187
+ ```
188
+
189
+ ---
190
+
191
+ ### **Paso 4: Actualizar Frontend para Consumir Endpoints**
192
+
193
+ #### 4.1 Crear hook de React para monitorear watcher
194
+
195
+ Crear: `frontend/src/hooks/useWatcherMonitor.js`
196
+
197
+ ```javascript
198
+ import { useState, useEffect, useCallback } from 'react';
199
+
200
+ export const useWatcherMonitor = (pollInterval = 5000) => {
201
+ const [status, setStatus] = useState(null);
202
+ const [queue, setQueue] = useState(null);
203
+ const [directories, setDirectories] = useState([]);
204
+ const [loading, setLoading] = useState(false);
205
+ const [error, setError] = useState(null);
206
+
207
+ // Refrescar datos
208
+ const refresh = useCallback(async () => {
209
+ try {
210
+ setLoading(true);
211
+ setError(null);
212
+
213
+ const token = localStorage.getItem('token'); // O de donde lo tengas
214
+ const headers = {
215
+ 'Content-Type': 'application/json',
216
+ 'Authorization': `Bearer ${token}`,
217
+ };
218
+
219
+ const [statusRes, queueRes, dirRes] = await Promise.all([
220
+ fetch('/api/watcher/status', { headers }),
221
+ fetch('/api/watcher/queue-stats', { headers }),
222
+ fetch('/api/watcher/directories', { headers }),
223
+ ]);
224
+
225
+ if (!statusRes.ok || !queueRes.ok || !dirRes.ok) {
226
+ throw new Error('Failed to fetch watcher data');
227
+ }
228
+
229
+ setStatus(await statusRes.json());
230
+ setQueue(await queueRes.json());
231
+ setDirectories(await dirRes.json());
232
+ } catch (err) {
233
+ setError(err.message);
234
+ console.error('Error fetching watcher data:', err);
235
+ } finally {
236
+ setLoading(false);
237
+ }
238
+ }, []);
239
+
240
+ // Poll automático
241
+ useEffect(() => {
242
+ refresh(); // Fetch inicial
243
+ const interval = setInterval(refresh, pollInterval);
244
+ return () => clearInterval(interval);
245
+ }, [pollInterval, refresh]);
246
+
247
+ // Acciones
248
+ const startWatcher = useCallback(
249
+ async (directories) => {
250
+ const token = localStorage.getItem('token');
251
+ const res = await fetch('/api/watcher/start', {
252
+ method: 'POST',
253
+ headers: {
254
+ 'Content-Type': 'application/json',
255
+ 'Authorization': `Bearer ${token}`,
256
+ },
257
+ body: JSON.stringify({ directories, autoProcessing: true }),
258
+ });
259
+ if (!res.ok) throw new Error('Failed to start watcher');
260
+ await refresh();
261
+ return res.json();
262
+ },
263
+ [refresh]
264
+ );
265
+
266
+ const stopWatcher = useCallback(async () => {
267
+ const token = localStorage.getItem('token');
268
+ const res = await fetch('/api/watcher/stop', {
269
+ method: 'POST',
270
+ headers: { 'Authorization': `Bearer ${token}` },
271
+ });
272
+ if (!res.ok) throw new Error('Failed to stop watcher');
273
+ await refresh();
274
+ return res.json();
275
+ }, [refresh]);
276
+
277
+ return {
278
+ status,
279
+ queue,
280
+ directories,
281
+ loading,
282
+ error,
283
+ refresh,
284
+ startWatcher,
285
+ stopWatcher,
286
+ };
287
+ };
288
+ ```
289
+
290
+ #### 4.2 Usar el hook en un componente
291
+
292
+ ```javascript
293
+ // WatcherDashboard.jsx
294
+ import React from 'react';
295
+ import { useWatcherMonitor } from './hooks/useWatcherMonitor';
296
+
297
+ export const WatcherDashboard = () => {
298
+ const { status, queue, directories, loading, error, startWatcher, stopWatcher } =
299
+ useWatcherMonitor(5000); // Refrescar cada 5 segundos
300
+
301
+ if (loading && !status) return <div>Loading...</div>;
302
+ if (error) return <div className="error">Error: {error}</div>;
303
+
304
+ return (
305
+ <div className="watcher-dashboard">
306
+ <h1>🔍 File Watcher Monitor</h1>
307
+
308
+ {/* Status Section */}
309
+ <section className="status-card">
310
+ <h2>Estado</h2>
311
+ <div className="status-grid">
312
+ <div>
313
+ <span>Estado:</span>
314
+ <strong>{status?.isRunning ? '✅ Activo' : '❌ Detenido'}</strong>
315
+ </div>
316
+ <div>
317
+ <span>Directorios monitoreados:</span>
318
+ <strong>{status?.watchedDirectories}</strong>
319
+ </div>
320
+ <div>
321
+ <span>Auto-procesamiento:</span>
322
+ <strong>
323
+ {status?.autoProcessingEnabled ? '✅ Activo' : '❌ Inactivo'}
324
+ </strong>
325
+ </div>
326
+ </div>
327
+ </section>
328
+
329
+ {/* Queue Statistics Section */}
330
+ <section className="queue-stats-card">
331
+ <h2>Cola de Procesamiento</h2>
332
+ <div className="progress-bar">
333
+ <div
334
+ className="progress-fill"
335
+ style={{
336
+ width: `${queue?.progress?.percentComplete || 0}%`,
337
+ }}
338
+ />
339
+ </div>
340
+ <p>{queue?.progress?.percentComplete?.toFixed(1)}% completado</p>
341
+
342
+ <div className="queue-grid">
343
+ <div className="queue-item">
344
+ <span>Pendientes</span>
345
+ <strong>{queue?.queue?.pending || 0}</strong>
346
+ </div>
347
+ <div className="queue-item">
348
+ <span>Listos</span>
349
+ <strong>{queue?.queue?.readyToUpload || 0}</strong>
350
+ </div>
351
+ <div className="queue-item">
352
+ <span>Procesando</span>
353
+ <strong>{queue?.queue?.processing || 0}</strong>
354
+ </div>
355
+ <div className="queue-item">
356
+ <span>Subidos</span>
357
+ <strong>{queue?.queue?.uploaded || 0}</strong>
358
+ </div>
359
+ </div>
360
+ </section>
361
+
362
+ {/* Directories Section */}
363
+ <section className="directories-card">
364
+ <h2>Directorios Monitoreados</h2>
365
+ <ul>
366
+ {directories?.directories?.map((dir) => (
367
+ <li key={dir.path}>
368
+ <span>{dir.isReady ? '✅' : '⏳'}</span>
369
+ <span>{dir.path}</span>
370
+ <small>{dir.folderStructure}</small>
371
+ </li>
372
+ ))}
373
+ </ul>
374
+ </section>
375
+
376
+ {/* Control Buttons */}
377
+ <section className="controls">
378
+ <button
379
+ onClick={() => startWatcher(['/path/to/watch'])}
380
+ disabled={status?.isRunning}
381
+ >
382
+ Iniciar Watcher
383
+ </button>
384
+ <button onClick={stopWatcher} disabled={!status?.isRunning}>
385
+ Detener Watcher
386
+ </button>
387
+ </section>
388
+ </div>
389
+ );
390
+ };
391
+ ```
392
+
393
+ ---
394
+
395
+ ### **Paso 5: Documentar API con Swagger (Opcional)**
396
+
397
+ #### 5.1 Instalar dependencias
398
+
399
+ ```bash
400
+ cd arela-api
401
+ npm install swagger-ui-express swagger-jsdoc
402
+ ```
403
+
404
+ #### 5.2 Crear especificación de Swagger
405
+
406
+ Crear: `arela-api/src/swagger/watcher.swagger.js`
407
+
408
+ ```javascript
409
+ export const watcherSwaggerDef = {
410
+ paths: {
411
+ '/api/watcher/status': {
412
+ get: {
413
+ summary: 'Get watcher status',
414
+ tags: ['Watcher'],
415
+ responses: {
416
+ 200: {
417
+ description: 'Current watcher status',
418
+ schema: {
419
+ type: 'object',
420
+ properties: {
421
+ isRunning: { type: 'boolean' },
422
+ autoProcessingEnabled: { type: 'boolean' },
423
+ watchedDirectories: { type: 'number' },
424
+ stats: { type: 'object' },
425
+ },
426
+ },
427
+ },
428
+ 500: {
429
+ description: 'Error getting status',
430
+ },
431
+ },
432
+ },
433
+ },
434
+ '/api/watcher/start': {
435
+ post: {
436
+ summary: 'Start the watcher',
437
+ tags: ['Watcher'],
438
+ requestBody: {
439
+ required: true,
440
+ content: {
441
+ 'application/json': {
442
+ schema: {
443
+ type: 'object',
444
+ properties: {
445
+ directories: {
446
+ type: 'array',
447
+ items: { type: 'string' },
448
+ },
449
+ autoProcessing: { type: 'boolean' },
450
+ folderStructure: { type: 'string' },
451
+ },
452
+ required: ['directories'],
453
+ },
454
+ },
455
+ },
456
+ },
457
+ responses: {
458
+ 200: { description: 'Watcher started successfully' },
459
+ 400: { description: 'Invalid request' },
460
+ 500: { description: 'Error starting watcher' },
461
+ },
462
+ },
463
+ },
464
+ // ... agregar más endpoints ...
465
+ },
466
+ };
467
+ ```
468
+
469
+ #### 5.3 Integrar en app.js
470
+
471
+ ```javascript
472
+ import swaggerUi from 'swagger-ui-express';
473
+ import swaggerJsdoc from 'swagger-jsdoc';
474
+ import { watcherSwaggerDef } from './swagger/watcher.swagger.js';
475
+
476
+ const swaggerSpec = swaggerJsdoc({
477
+ definition: {
478
+ openapi: '3.0.0',
479
+ info: {
480
+ title: 'Arela API',
481
+ version: '1.0.0',
482
+ },
483
+ servers: [
484
+ { url: 'http://localhost:3000', description: 'Development' },
485
+ ],
486
+ ...watcherSwaggerDef,
487
+ },
488
+ apis: [],
489
+ });
490
+
491
+ app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
492
+ ```
493
+
494
+ **Acceder en:** `http://localhost:3000/api-docs`
495
+
496
+ ---
497
+
498
+ ### **Paso 6: Testing**
499
+
500
+ #### 6.1 Crear tests de integración
501
+
502
+ Crear: `arela-api/test/watcher.test.js`
503
+
504
+ ```javascript
505
+ import request from 'supertest';
506
+ import app from '../src/app.js';
507
+
508
+ describe('Watcher API Routes', () => {
509
+ it('GET /api/watcher/status should return watcher status', async () => {
510
+ const response = await request(app)
511
+ .get('/api/watcher/status')
512
+ .set('Authorization', `Bearer ${validToken}`);
513
+
514
+ expect(response.status).toBe(200);
515
+ expect(response.body).toHaveProperty('isRunning');
516
+ expect(response.body).toHaveProperty('stats');
517
+ });
518
+
519
+ it('GET /api/watcher/queue-stats should return queue statistics', async () => {
520
+ const response = await request(app)
521
+ .get('/api/watcher/queue-stats')
522
+ .set('Authorization', `Bearer ${validToken}`);
523
+
524
+ expect(response.status).toBe(200);
525
+ expect(response.body).toHaveProperty('queue');
526
+ expect(response.body).toHaveProperty('progress');
527
+ });
528
+
529
+ it('POST /api/watcher/start should start watcher with directories', async () => {
530
+ const response = await request(app)
531
+ .post('/api/watcher/start')
532
+ .set('Authorization', `Bearer ${validToken}`)
533
+ .send({
534
+ directories: ['/test/dir'],
535
+ autoProcessing: true,
536
+ });
537
+
538
+ expect(response.status).toBe(200);
539
+ expect(response.body.success).toBe(true);
540
+ });
541
+ });
542
+ ```
543
+
544
+ #### 6.2 Ejecutar tests
545
+
546
+ ```bash
547
+ npm test -- test/watcher.test.js
548
+ ```
549
+
550
+ ---
551
+
552
+ ## 📋 Checklist Final
553
+
554
+ - [ ] Crear `src/services/index.js` en arela-uploader
555
+ - [ ] Actualizar `package.json` de arela-uploader con `exports`
556
+ - [ ] Instalar arela-uploader en arela-api
557
+ - [ ] Crear `src/routes/watcher.routes.js` en arela-api
558
+ - [ ] Integrar rutas en `app.js`
559
+ - [ ] Crear middleware de autenticación (opcional)
560
+ - [ ] Proteger rutas con autenticación
561
+ - [ ] Crear hook `useWatcherMonitor` en frontend
562
+ - [ ] Crear componente `WatcherDashboard` en frontend
563
+ - [ ] Agregar Swagger (opcional)
564
+ - [ ] Crear tests de integración
565
+ - [ ] Documentar endpoints
566
+ - [ ] Validar que funciona end-to-end
567
+
568
+ ---
569
+
570
+ ## 🧪 Testing End-to-End
571
+
572
+ ### 1. Iniciar arela-api
573
+ ```bash
574
+ cd arela-api
575
+ npm start
576
+ ```
577
+
578
+ ### 2. Probar endpoints con curl
579
+
580
+ ```bash
581
+ # Get status
582
+ curl http://localhost:3000/api/watcher/status \
583
+ -H "Authorization: Bearer YOUR_TOKEN"
584
+
585
+ # Get queue stats
586
+ curl http://localhost:3000/api/watcher/queue-stats \
587
+ -H "Authorization: Bearer YOUR_TOKEN"
588
+
589
+ # Start watcher
590
+ curl -X POST http://localhost:3000/api/watcher/start \
591
+ -H "Content-Type: application/json" \
592
+ -H "Authorization: Bearer YOUR_TOKEN" \
593
+ -d '{
594
+ "directories": ["/path/to/watch"],
595
+ "autoProcessing": true
596
+ }'
597
+
598
+ # Stop watcher
599
+ curl -X POST http://localhost:3000/api/watcher/stop \
600
+ -H "Authorization: Bearer YOUR_TOKEN"
601
+ ```
602
+
603
+ ### 3. Verificar en frontend
604
+ - Abrir DevTools (F12)
605
+ - Ir a Network tab
606
+ - Verificar que se hacen llamadas a `/api/watcher/*`
607
+ - Ver respuestas JSON en Preview
608
+
609
+ ---
610
+
611
+ ## 🎉 ¡Listo!
612
+
613
+ El frontend ahora puede monitorear el watcher en tiempo real a través de la API REST.
614
+