Initial commit: DashCaddy v1.0

Full codebase including API server (32 modules + routes), dashboard frontend,
DashCA certificate distribution, installer script, and deployment skills.
This commit is contained in:
2026-03-05 02:26:12 -08:00
commit f61e85d9a7
337 changed files with 75282 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
const express = require('express');
const { paginate, parsePaginationParams } = require('../pagination');
module.exports = function(ctx) {
const router = express.Router();
// ===== UPDATE MANAGEMENT ENDPOINTS =====
// Check for updates
router.post('/updates/check', ctx.asyncHandler(async (req, res) => {
await ctx.updateManager.checkForUpdates();
const updates = ctx.updateManager.getAvailableUpdates();
res.json({ success: true, updates, count: updates.length });
}, 'updates-check'));
// Get available updates
router.get('/updates/available', ctx.asyncHandler(async (req, res) => {
const updates = ctx.updateManager.getAvailableUpdates();
const paginationParams = parsePaginationParams(req.query);
const result = paginate(updates, paginationParams);
res.json({ success: true, updates: result.data, count: updates.length, ...(result.pagination && { pagination: result.pagination }) });
}, 'updates-available'));
// Update a container
router.post('/updates/update/:containerId', ctx.asyncHandler(async (req, res) => {
const result = await ctx.updateManager.updateContainer(req.params.containerId, req.body);
res.json({ success: true, result });
}, 'updates-update'));
// Rollback update
router.post('/updates/rollback/:containerId', ctx.asyncHandler(async (req, res) => {
await ctx.updateManager.rollbackUpdate(req.params.containerId);
res.json({ success: true, message: 'Rollback completed' });
}, 'updates-rollback'));
// Get update history
router.get('/updates/history', ctx.asyncHandler(async (req, res) => {
const paginationParams = parsePaginationParams(req.query);
// When paginating, fetch all history so pagination can slice correctly
const fetchLimit = paginationParams ? Number.MAX_SAFE_INTEGER : (parseInt(req.query.limit) || 50);
const history = ctx.updateManager.getHistory(fetchLimit);
const result = paginate(history, paginationParams);
res.json({ success: true, history: result.data, ...(result.pagination && { pagination: result.pagination }) });
}, 'updates-history'));
// Configure auto-update
router.post('/updates/auto-update/:containerId', ctx.asyncHandler(async (req, res) => {
ctx.updateManager.configureAutoUpdate(req.params.containerId, req.body);
res.json({ success: true, message: 'Auto-update configured' });
}, 'updates-auto-update'));
// Schedule update
router.post('/updates/schedule/:containerId', ctx.asyncHandler(async (req, res) => {
const { scheduledTime } = req.body;
if (!scheduledTime) {
return ctx.errorResponse(res, 400, 'scheduledTime is required');
}
ctx.updateManager.scheduleUpdate(req.params.containerId, scheduledTime);
res.json({ success: true, message: 'Update scheduled', scheduledTime });
}, 'updates-schedule'));
return router;
};