feat(FN-1228): complete Step 1 — Backend API Routes modifications

- Modified POST /api/nodes to make type optional (defaults to 'remote')
- Changed DELETE /api/nodes/:id to return 204 No Content
- Updated GET /api/nodes/:id/metrics to return SystemMetrics from node.systemMetrics
- Added GET /api/mesh/state route for full mesh topology state
This commit is contained in:
gsxdsm
2026-04-09 11:51:03 -07:00
parent 26ff7eb900
commit ea8d32d4bf
13 changed files with 497 additions and 8 deletions

View File

@@ -869,4 +869,80 @@ export class Scheduler {
return null;
}
}
/**
* Reconcile feature status for all active missions on startup.
*
* This ensures that feature statuses are in sync with their linked task
* columns for all missions, not just autopilot-enabled ones. The
* reconciliation logic mirrors MissionAutopilot.reconcileMissionConsistency()
* but runs unconditionally on startup.
*
* @returns The total number of fixes applied across all missions
*/
async reconcileAllMissionFeatures(): Promise<number> {
if (!this.options.missionStore) {
return 0;
}
const missionStore = this.options.missionStore;
let totalFixed = 0;
try {
const missions = missionStore.listMissions();
const activeMissions = missions.filter((m) => m.status === "active");
for (const mission of activeMissions) {
const hierarchy = missionStore.getMissionWithHierarchy(mission.id);
if (!hierarchy) continue;
const activeSlices = hierarchy.milestones
.flatMap((milestone) => milestone.slices)
.filter((slice) => slice.status === "active");
for (const slice of activeSlices) {
for (const feature of slice.features) {
if (!feature.taskId) continue;
const task = await this.store.getTask(feature.taskId);
if (!task) continue;
// Task done but feature not done -> update feature to done
if (task.column === "done" && feature.status !== "done") {
missionStore.updateFeatureStatus(feature.id, "done");
totalFixed++;
continue;
}
// Task in-progress and feature triaged/defined -> update to in-progress
if (
task.column === "in-progress"
&& (feature.status === "triaged" || feature.status === "defined")
) {
missionStore.updateFeatureStatus(feature.id, "in-progress");
totalFixed++;
continue;
}
// Task in triage/todo and feature in-progress -> update to triaged
if (
(task.column === "triage" || task.column === "todo")
&& feature.status === "in-progress"
) {
missionStore.updateFeatureStatus(feature.id, "triaged");
totalFixed++;
}
}
}
}
if (totalFixed > 0) {
schedulerLog.log(`Mission feature reconciliation: fixed ${totalFixed} inconsistencies`);
}
} catch (err) {
schedulerLog.error("Error during mission feature reconciliation:", err);
}
return totalFixed;
}
}