refactor(backend): extract container and port routers (phase 4c-4) (#742)

Move the six /api/containers/* and /api/ports/in-use endpoints out of
index.ts. Handlers moved verbatim. routes/containers.ts exports two
routers:
- containersRouter (mounted at /api/containers): list, stream logs,
  start, stop, restart.
- portsRouter (mounted at /api/ports): /in-use host port inventory.

Removes the now-unused requireAdmin import from index.ts. Middleware
chains, response shapes, and error messages are all preserved.

index.ts drops from 1437 to 1364 lines. Remaining inline groups:
stacks and nodes.
This commit is contained in:
Anso
2026-04-23 23:06:26 -04:00
committed by GitHub
parent 1a6ae8309d
commit d98b61cbca
2 changed files with 85 additions and 77 deletions
+81
View File
@@ -0,0 +1,81 @@
import { Router, type Request, type Response } from 'express';
import DockerController from '../services/DockerController';
import { FileSystemService } from '../services/FileSystemService';
import { requireAdmin } from '../middleware/tierGates';
import { invalidateNodeCaches } from '../helpers/cacheInvalidation';
export const containersRouter = Router();
containersRouter.get('/', async (req: Request, res: Response) => {
try {
const dockerController = DockerController.getInstance(req.nodeId);
const containers = await dockerController.getRunningContainers();
res.json(containers);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch containers' });
}
});
containersRouter.get('/:id/logs', async (req: Request, res: Response) => {
try {
const id = req.params.id as string;
const dockerController = DockerController.getInstance(req.nodeId);
await dockerController.streamContainerLogs(id, req, res);
} catch (error) {
res.status(500).json({ error: 'Failed to initialize log stream' });
}
});
containersRouter.post('/:id/start', async (req: Request, res: Response) => {
if (!requireAdmin(req, res)) return;
try {
const id = req.params.id as string;
const dockerController = DockerController.getInstance(req.nodeId);
await dockerController.startContainer(id);
invalidateNodeCaches(req.nodeId);
res.json({ message: 'Container started' });
} catch (error) {
res.status(500).json({ error: 'Failed to start container' });
}
});
containersRouter.post('/:id/stop', async (req: Request, res: Response) => {
if (!requireAdmin(req, res)) return;
try {
const id = req.params.id as string;
const dockerController = DockerController.getInstance(req.nodeId);
await dockerController.stopContainer(id);
invalidateNodeCaches(req.nodeId);
res.json({ message: 'Container stopped' });
} catch (error) {
res.status(500).json({ error: 'Failed to stop container' });
}
});
containersRouter.post('/:id/restart', async (req: Request, res: Response) => {
if (!requireAdmin(req, res)) return;
try {
const id = req.params.id as string;
const dockerController = DockerController.getInstance(req.nodeId);
await dockerController.restartContainer(id);
invalidateNodeCaches(req.nodeId);
res.json({ message: 'Container restarted' });
} catch (error) {
res.status(500).json({ error: 'Failed to restart container' });
}
});
export const portsRouter = Router();
portsRouter.get('/in-use', async (req: Request, res: Response) => {
try {
const fsService = FileSystemService.getInstance(req.nodeId);
const stacks = await fsService.getStacks();
const dockerController = DockerController.getInstance(req.nodeId);
const portsInUse = await dockerController.getPortsInUse(stacks);
res.json(portsInUse);
} catch (error) {
console.error('[Ports] Failed to fetch ports in use:', error);
res.status(500).json({ error: 'Failed to fetch ports in use' });
}
});