Initial commit
Dieser Commit ist enthalten in:
123
backend/src/routes/sync.ts
Normale Datei
123
backend/src/routes/sync.ts
Normale Datei
@ -0,0 +1,123 @@
|
||||
import { Router } from 'express'
|
||||
import { authenticate, authorize } from '../middleware/auth'
|
||||
import { syncService } from '../services/syncService'
|
||||
import { logger } from '../utils/logger'
|
||||
import type { AuthRequest } from '../middleware/auth'
|
||||
|
||||
const router = Router()
|
||||
|
||||
// Receive sync data from another node
|
||||
router.post('/receive', authenticate, async (req: AuthRequest, res, next) => {
|
||||
try {
|
||||
const nodeId = req.headers['x-node-id'] as string
|
||||
if (!nodeId) {
|
||||
return res.status(400).json({
|
||||
error: { message: 'Missing node ID in headers' }
|
||||
})
|
||||
}
|
||||
|
||||
const result = await syncService.receiveSync(req.body)
|
||||
|
||||
res.json(result)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
// Get sync status
|
||||
router.get('/status', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
|
||||
try {
|
||||
const status = syncService.getSyncStatus()
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: status
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
// Trigger manual sync
|
||||
router.post('/trigger', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
|
||||
try {
|
||||
// Run sync in background
|
||||
syncService.triggerSync().catch(error => {
|
||||
logger.error('Background sync failed:', error)
|
||||
})
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Sync triggered successfully'
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
// Sync with specific node
|
||||
router.post('/sync/:nodeId', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
|
||||
try {
|
||||
const { nodeId } = req.params
|
||||
const result = await syncService.syncWithNode(nodeId)
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
// Get sync conflicts
|
||||
router.get('/conflicts', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
|
||||
try {
|
||||
const { db } = await import('../config/database')
|
||||
|
||||
const conflicts = db.prepare(`
|
||||
SELECT * FROM sync_conflicts
|
||||
WHERE resolution_status = 'pending'
|
||||
ORDER BY created_at DESC
|
||||
`).all()
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: conflicts
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
// Resolve sync conflict
|
||||
router.post('/conflicts/:conflictId/resolve', authenticate, authorize('admin'), async (req: AuthRequest, res, next) => {
|
||||
try {
|
||||
const { conflictId } = req.params
|
||||
const { resolution, data } = req.body
|
||||
const { db } = await import('../config/database')
|
||||
|
||||
// Update conflict status
|
||||
db.prepare(`
|
||||
UPDATE sync_conflicts
|
||||
SET resolution_status = 'resolved',
|
||||
resolved_by = ?,
|
||||
resolved_at = ?
|
||||
WHERE id = ?
|
||||
`).run(req.user!.id, new Date().toISOString(), conflictId)
|
||||
|
||||
// Apply resolution if needed
|
||||
if (resolution === 'apply' && data) {
|
||||
await syncService.receiveSync(data)
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Conflict resolved successfully'
|
||||
})
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren