mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-09 02:12:59 +00:00
af4083175c
* feat(fleet): add read-only dependency map tab Add a fleet-wide Dependencies tab to Fleet view that maps how stacks, services, networks, volumes, and ports relate, with flags for missing dependencies, port conflicts, orphaned resources, and cross-stack shared resources. Read-only; filterable by stack, node, and flag; collapsed by default with a list-view fallback at scale. The graph is derived at request time from Docker and compose metadata, so no new table or persisted state is introduced. A per-node graph endpoint feeds a hub aggregation endpoint that fans out across the fleet and degrades gracefully, surfacing unreachable or unparseable nodes inline while the rest of the map still renders. * fix(fleet): harden dependency map flag detection and remote merge Address review findings on the dependency map: - Port-conflict detection now does pairwise host-scope overlap, so an unrelated bind on the same port and protocol but a different specific host IP is no longer flagged, and the flag lands on the exact scoped port node. - A running service's depends_on target is only considered satisfied when it is actually running, so a crashed (exited) dependency is surfaced while a deliberately stopped stack stays quiet. - Declared external networks and volumes are reported missing when they do not exist on the host instead of being assumed present. - The hub deep-validates each remote node-graph payload before merging, so a reachable-but-malformed remote degrades to a single node error rather than failing the whole fleet map, and the validation failure is logged. - Searching or filtering on a network, volume, or port now also reveals the services that claim it and their stacks.
24 lines
1.0 KiB
TypeScript
24 lines
1.0 KiB
TypeScript
import { Router, type Request, type Response } from 'express';
|
|
import { authMiddleware } from '../middleware/auth';
|
|
import { DatabaseService } from '../services/DatabaseService';
|
|
import { buildLocalGraph } from '../services/DependencyGraphService';
|
|
|
|
export const dependencyMapRouter = Router();
|
|
|
|
/**
|
|
* Per-node dependency graph. Auth-only (never tier-gated) so the hub's
|
|
* fleet-wide fan-out can reach this route on every node, including Community
|
|
* remotes. Served against the local Docker of whichever node handles it.
|
|
*/
|
|
dependencyMapRouter.get('/node-graph', authMiddleware, async (req: Request, res: Response): Promise<void> => {
|
|
try {
|
|
const nodeId = req.nodeId;
|
|
const name = DatabaseService.getInstance().getNodes().find((n) => n.id === nodeId)?.name ?? 'This node';
|
|
const graph = await buildLocalGraph(nodeId, name);
|
|
res.json(graph);
|
|
} catch (error) {
|
|
console.error('[DependencyMap] node-graph error:', error);
|
|
res.status(500).json({ error: 'Failed to build dependency graph' });
|
|
}
|
|
});
|