Skip to content

Commit 466b81a

Browse files
committed
update
1 parent 167d049 commit 466b81a

18 files changed

+3603
-82
lines changed

src/routes/api.js

Lines changed: 0 additions & 82 deletions
This file was deleted.

src/routes/index.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// src/routes/index.js
2+
import { Router } from 'express';
3+
import v1Routes from './v1/index.js';
4+
import { requestLogger, errorLogger } from '../middleware/logging.js';
5+
import { securityMiddleware } from '../middleware/security.js';
6+
import { errorHandler, notFoundHandler } from '../middleware/errorHandler.js';
7+
import { db } from '../config/database.js';
8+
9+
const router = Router();
10+
11+
// Apply global middleware
12+
router.use(requestLogger);
13+
router.use(securityMiddleware);
14+
15+
// API health check that verifies database connectivity
16+
router.get('/health', async (req, res) => {
17+
try {
18+
// Check database connection
19+
await db.get('SELECT 1');
20+
21+
// Get application version
22+
const version = await db.get(
23+
"SELECT value FROM config WHERE key = 'app_version'"
24+
);
25+
26+
res.json({
27+
status: 'healthy',
28+
version: version?.value || 'unknown',
29+
timestamp: new Date().toISOString()
30+
});
31+
} catch (error) {
32+
res.status(503).json({
33+
status: 'unhealthy',
34+
error: 'Database connection failed',
35+
timestamp: new Date().toISOString()
36+
});
37+
}
38+
});
39+
40+
// Documentation endpoints
41+
router.get('/docs', (req, res) => {
42+
res.json({
43+
message: 'API documentation is available at /docs/swagger',
44+
version: 'v1',
45+
swagger_url: '/docs/swagger',
46+
postman_collection: '/docs/postman',
47+
openapi_spec: '/docs/openapi'
48+
});
49+
});
50+
51+
// Mount API version routes
52+
router.use('/api/v1', v1Routes);
53+
54+
// Catch-all route for undefined endpoints
55+
router.use('*', notFoundHandler);
56+
57+
// Error handling
58+
router.use(errorLogger);
59+
router.use(errorHandler);
60+
61+
export default router;

src/routes/v1/backup.js

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// src/routes/v1/backup.js
2+
import { Router } from 'express';
3+
import { backupController } from '../../controllers/backupController.js';
4+
import { authenticateApiKey, requireRole, requireScope } from '../../middleware/auth.js';
5+
import { validate } from '../../middleware/validation.js';
6+
import { backupValidation } from '../../middleware/validation.js';
7+
8+
const router = Router();
9+
10+
/**
11+
* Site Backup Routes
12+
* These routes handle individual site backups including files, databases,
13+
* and configuration settings. Each backup is stored in the site's backup
14+
* directory with proper timestamps and metadata.
15+
*/
16+
17+
router.post('/sites/:site_id',
18+
authenticateApiKey,
19+
requireRole('admin'),
20+
requireScope('backups:write'),
21+
validate(backupValidation.create),
22+
backupController.createSiteBackup
23+
);
24+
25+
router.post('/sites/:site_id/restore/:backup_timestamp',
26+
authenticateApiKey,
27+
requireRole('admin'),
28+
requireScope('backups:write'),
29+
validate(backupValidation.restore),
30+
backupController.restoreSiteBackup
31+
);
32+
33+
router.get('/sites/:site_id',
34+
authenticateApiKey,
35+
requireScope('backups:read'),
36+
validate([
37+
param('site_id').isInt().withMessage('Invalid site ID')
38+
]),
39+
backupController.listSiteBackups
40+
);
41+
42+
/**
43+
* Database Backup Routes
44+
* Handles database-specific backups with proper locking mechanisms
45+
* to ensure data consistency during backup operations.
46+
*/
47+
48+
router.post('/databases/:database_id',
49+
authenticateApiKey,
50+
requireRole('admin'),
51+
requireScope('backups:write'),
52+
validate([
53+
param('database_id').isInt().withMessage('Invalid database ID')
54+
]),
55+
backupController.createDatabaseBackup
56+
);
57+
58+
router.post('/databases/:database_id/restore',
59+
authenticateApiKey,
60+
requireRole('admin'),
61+
requireScope('backups:write'),
62+
validate([
63+
param('database_id').isInt().withMessage('Invalid database ID'),
64+
body('backup_file').notEmpty().withMessage('Backup file required')
65+
]),
66+
backupController.restoreDatabaseBackup
67+
);
68+
69+
/**
70+
* System Backup Routes
71+
* These routes handle system-wide backups including all sites,
72+
* configuration files, and system settings. Requires special
73+
* handling for maintaining consistency across all components.
74+
*/
75+
76+
router.post('/system',
77+
authenticateApiKey,
78+
requireRole('admin'),
79+
requireScope('backups:write'),
80+
validate([
81+
body('include_sites').optional().isBoolean(),
82+
body('include_databases').optional().isBoolean(),
83+
body('include_configs').optional().isBoolean()
84+
]),
85+
backupController.createSystemBackup
86+
);
87+
88+
router.post('/system/restore',
89+
authenticateApiKey,
90+
requireRole('admin'),
91+
requireScope('backups:write'),
92+
validate([
93+
body('backup_file').notEmpty().withMessage('Backup file required'),
94+
body('components').isArray().withMessage('Components selection required')
95+
]),
96+
backupController.restoreSystemBackup
97+
);
98+
99+
router.get('/system',
100+
authenticateApiKey,
101+
requireRole('admin'),
102+
requireScope('backups:read'),
103+
backupController.listSystemBackups
104+
);
105+
106+
/**
107+
* Backup Management Routes
108+
* Handles backup retention policies, cleanup, and verification
109+
*/
110+
111+
router.delete('/cleanup',
112+
authenticateApiKey,
113+
requireRole('admin'),
114+
requireScope('backups:write'),
115+
validate([
116+
body('older_than_days').isInt().withMessage('Days threshold required'),
117+
body('backup_type').isIn(['site', 'database', 'system']).withMessage('Invalid backup type')
118+
]),
119+
backupController.cleanupOldBackups
120+
);
121+
122+
router.post('/verify/:backup_id',
123+
authenticateApiKey,
124+
requireRole('admin'),
125+
requireScope('backups:write'),
126+
validate([
127+
param('backup_id').isString().withMessage('Invalid backup ID')
128+
]),
129+
backupController.verifyBackup
130+
);
131+
132+
router.get('/storage',
133+
authenticateApiKey,
134+
requireRole('admin'),
135+
requireScope('backups:read'),
136+
backupController.getBackupStorageStats
137+
);
138+
139+
/**
140+
* Scheduled Backup Routes
141+
* Manages automated backup schedules and configurations
142+
*/
143+
144+
router.post('/schedule',
145+
authenticateApiKey,
146+
requireRole('admin'),
147+
requireScope('backups:write'),
148+
validate([
149+
body('type').isIn(['site', 'database', 'system']).withMessage('Invalid backup type'),
150+
body('schedule').matches(/^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$/).withMessage('Invalid cron schedule format'),
151+
body('retention_days').isInt({ min: 1 }).withMessage('Invalid retention period')
152+
]),
153+
backupController.scheduleBackup
154+
);
155+
156+
router.get('/schedule',
157+
authenticateApiKey,
158+
requireRole('admin'),
159+
requireScope('backups:read'),
160+
backupController.listBackupSchedules
161+
);
162+
163+
router.delete('/schedule/:schedule_id',
164+
authenticateApiKey,
165+
requireRole('admin'),
166+
requireScope('backups:write'),
167+
validate([
168+
param('schedule_id').isInt().withMessage('Invalid schedule ID')
169+
]),
170+
backupController.deleteBackupSchedule
171+
);
172+
173+
export default router;

0 commit comments

Comments
 (0)