4 * @description Manual synchronization endpoints for MeshCentral device and group sync operations.
5 * Provides on-demand sync triggers and status monitoring for background sync workers.
7 * @requires middleware/auth
8 * @requires workers/meshcentral-device-sync
9 * @author RMM-PSA Development Team
10 * @copyright 2026 RMM-PSA Platform
11 * @license Proprietary
15 * @apiDefine Sync Synchronization
16 * Manual sync operations for external integrations
19const express = require('express');
20const router = express.Router();
21const authenticateToken = require('../middleware/auth');
24 * @api {post} /api/sync/meshcentral Manual MeshCentral sync
25 * @apiName ManualMeshCentralSync
27 * @apiDescription Trigger manual synchronization of MeshCentral devices and mesh groups.
28 * Calls sync worker to import devices and groups from MeshCentral into RMM database.
29 * Returns sync statistics and timestamps. Requires authentication.
30 * @apiSuccess {boolean} success=true Sync completed successfully
31 * @apiSuccess {string} message="MeshCentral sync completed"
32 * @apiSuccess {object} stats Sync statistics
33 * @apiSuccess {number} stats.devicesUpdated Number of devices synced
34 * @apiSuccess {number} stats.groupsUpdated Number of mesh groups synced
35 * @apiSuccess {DateTime} lastSync Last device sync timestamp
36 * @apiSuccess {DateTime} lastGroupSync Last group sync timestamp
37 * @apiError {boolean} success=false Sync failed
38 * @apiError {string} message="Sync failed"
39 * @apiError {string} error Error message details
40 * @apiExample {curl} Example:
41 * curl -X POST http://localhost:3000/api/sync/meshcentral \\
42 * -H "Authorization: Bearer YOUR_TOKEN"
43 * @apiSuccessExample {json} Success-Response:
47 * "message": "MeshCentral sync completed",
49 * "devicesUpdated": 145,
52 * "lastSync": "2026-03-12T10:30:00.000Z",
53 * "lastGroupSync": "2026-03-12T10:30:15.000Z"
56router.post('/meshcentral', authenticateToken, async (req, res) => {
58 console.log('[API] Manual MeshCentral sync triggered by user:', req.user.email);
60 // Get the sync worker
61 const syncWorker = require('../workers/meshcentral-device-sync');
63 // Trigger manual sync
64 await syncWorker.sync();
65 await syncWorker.syncMeshGroups();
67 const status = syncWorker.getStatus();
71 message: 'MeshCentral sync completed',
73 lastSync: status.lastDeviceSync,
74 lastGroupSync: status.lastGroupSync
77 console.error('[API] Manual sync error:', error);
78 res.status(500).json({
80 message: 'Sync failed',
87 * @api {get} /api/sync/meshcentral/status Get sync status
88 * @apiName GetMeshCentralSyncStatus
90 * @apiDescription Get current status of MeshCentral sync worker including statistics,
91 * last sync timestamps, and sync interval configuration. Does not trigger sync.
92 * @apiSuccess {boolean} success=true Status retrieved successfully
93 * @apiSuccess {object} status Sync worker status
94 * @apiSuccess {object} status.stats Sync statistics
95 * @apiSuccess {number} status.stats.devicesUpdated Devices synced in last run
96 * @apiSuccess {number} status.stats.groupsUpdated Groups synced in last run
97 * @apiSuccess {DateTime} status.lastDeviceSync Last device sync timestamp
98 * @apiSuccess {DateTime} status.lastGroupSync Last group sync timestamp
99 * @apiSuccess {number} status.syncInterval Sync interval in milliseconds
100 * @apiError {boolean} success=false Status check failed
101 * @apiError {string} error Error message details
102 * @apiExample {curl} Example:
103 * curl -X GET http://localhost:3000/api/sync/meshcentral/status \\
104 * -H "Authorization: Bearer YOUR_TOKEN"
105 * @apiSuccessExample {json} Success-Response:
111 * "devicesUpdated": 145,
114 * "lastDeviceSync": "2026-03-12T10:30:00.000Z",
115 * "lastGroupSync": "2026-03-12T10:30:15.000Z",
116 * "syncInterval": 300000
120router.get('/meshcentral/status', authenticateToken, async (req, res) => {
122 const syncWorker = require('../workers/meshcentral-device-sync');
123 const status = syncWorker.getStatus();
130 console.error('[API] Status check error:', error);
131 res.status(500).json({
138module.exports = router;