feat(FN-3637): establish canonical roadmap plugin ID and compatibility rout

Merged commits stabilize the Fusion roadmap plugin's identity and routing surface, establishing a canonical plugin ID and compatibility routes so the roadmap plugin integrates cleanly with the dashboard's plugin system. Added new roadmap-routes and roadmap-suggestions modules in the dashboard packag

Fusion-Task-Id: FN-3637
This commit is contained in:
Fusion
2026-05-11 06:04:17 -07:00
committed by gsxdsm
parent d152261240
commit 3a67c1b065
33 changed files with 219 additions and 81 deletions

View File

@@ -44,11 +44,11 @@ describe("roadmap dashboard api client", () => {
await updateRoadmap("RM-1", { title: "B" }, "proj-1");
await deleteRoadmap("RM-1", "proj-1");
expect(fetchMock.mock.calls[0][0]).toBe("/api/plugins/roadmap-planner/roadmaps?projectId=proj-1");
expect(fetchMock.mock.calls[1][0]).toBe("/api/plugins/roadmap-planner/roadmaps/RM-1?projectId=proj-1");
expect(fetchMock.mock.calls[2][0]).toBe("/api/plugins/roadmap-planner/roadmaps?projectId=proj-1");
expect(fetchMock.mock.calls[3][0]).toBe("/api/plugins/roadmap-planner/roadmaps/RM-1?projectId=proj-1");
expect(fetchMock.mock.calls[4][0]).toBe("/api/plugins/roadmap-planner/roadmaps/RM-1?projectId=proj-1");
expect(fetchMock.mock.calls[0][0]).toBe("/api/plugins/fusion-plugin-roadmap/roadmaps?projectId=proj-1");
expect(fetchMock.mock.calls[1][0]).toBe("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1?projectId=proj-1");
expect(fetchMock.mock.calls[2][0]).toBe("/api/plugins/fusion-plugin-roadmap/roadmaps?projectId=proj-1");
expect(fetchMock.mock.calls[3][0]).toBe("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1?projectId=proj-1");
expect(fetchMock.mock.calls[4][0]).toBe("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1?projectId=proj-1");
});
it("uses plugin namespace for milestone and feature reorder/move + suggestions + handoff", async () => {
@@ -68,14 +68,14 @@ describe("roadmap dashboard api client", () => {
await fetchRoadmapHandoff("RM-1", "proj-1");
const calledUrls = fetchMock.mock.calls.map((call) => String(call[0]));
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/RM-1/milestones?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/milestones/RMS-1?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/RM-1/milestones/reorder?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/milestones/RMS-1/features/reorder?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/features/RF-1/move?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/RM-1/suggestions/milestones?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/milestones/RMS-1/suggestions/features?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/roadmap-planner/roadmaps/RM-1/handoff?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1/milestones?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/milestones/RMS-1?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1/milestones/reorder?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/milestones/RMS-1/features/reorder?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/features/RF-1/move?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1/suggestions/milestones?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/milestones/RMS-1/suggestions/features?projectId=proj-1");
expect(calledUrls).toContain("/api/plugins/fusion-plugin-roadmap/roadmaps/RM-1/handoff?projectId=proj-1");
});
it("surfaces server error body when available", async () => {

View File

@@ -17,7 +17,7 @@ import plugin, {
normalizeRoadmapMilestoneOrder,
} from "../index.js";
describe("roadmap-planner package surface", () => {
describe("fusion-plugin-roadmap package surface", () => {
const tmpDirs: string[] = [];
afterEach(async () => {
@@ -48,7 +48,7 @@ describe("roadmap-planner package surface", () => {
});
it("exports plugin manifest with roadmap id", () => {
expect(plugin.manifest.id).toBe("roadmap-planner");
expect(plugin.manifest.id).toBe("fusion-plugin-roadmap");
});
it("registers onSchemaInit hook that creates roadmap tables and indexes", () => {

View File

@@ -3,7 +3,7 @@ import { createRoadmapPluginRoutes } from "../roadmap-routes.js";
function createCtx() {
return {
pluginId: "roadmap-planner",
pluginId: "fusion-plugin-roadmap",
taskStore: {
getDatabase: () => ({}),
getRootDir: () => "/tmp/project",

View File

@@ -13,7 +13,7 @@ import type {
RoadmapFeatureTaskPlanningHandoff,
} from "../roadmap-types.js";
const BASE = "/api/plugins/roadmap-planner";
const BASE = "/api/plugins/fusion-plugin-roadmap";
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const response = await fetch(`${BASE}${path}`, {

View File

@@ -4,7 +4,7 @@ import { ensureRoadmapSchema } from "./roadmap-schema.js";
const plugin = definePlugin({
manifest: {
id: "roadmap-planner",
id: "fusion-plugin-roadmap",
name: "Roadmaps",
version: "0.1.0",
description: "Standalone roadmap planning plugin",
@@ -57,17 +57,17 @@ export {
normalizeRoadmapFeatureOrder,
applyRoadmapFeatureReorder,
moveRoadmapFeature,
} from "./store/roadmap-ordering.js";
} from "./roadmap-ordering.js";
export {
mapFeatureToTaskHandoff,
mapRoadmapToMissionHandoff,
mapRoadmapWithHierarchyToMissionHandoff,
mapAllFeaturesToTaskHandoffs,
} from "./store/roadmap-handoff.js";
} from "./roadmap-handoff.js";
export { RoadmapStore } from "./store/roadmap-store.js";
export type { RoadmapStoreEvents } from "./store/roadmap-store.js";
export { RoadmapStore } from "./roadmap-store.js";
export type { RoadmapStoreEvents } from "./roadmap-store.js";
export { ensureRoadmapSchema } from "./roadmap-schema.js";
export { RoadmapDashboardView } from "./dashboard-view.js";

View File

@@ -0,0 +1,6 @@
export {
mapFeatureToTaskHandoff,
mapRoadmapToMissionHandoff,
mapRoadmapWithHierarchyToMissionHandoff,
mapAllFeaturesToTaskHandoffs,
} from "./store/roadmap-handoff.js";

View File

@@ -0,0 +1,7 @@
export {
normalizeRoadmapMilestoneOrder,
applyRoadmapMilestoneReorder,
normalizeRoadmapFeatureOrder,
applyRoadmapFeatureReorder,
moveRoadmapFeature,
} from "./store/roadmap-ordering.js";

View File

@@ -0,0 +1,2 @@
export { RoadmapStore } from "./store/roadmap-store.js";
export type { RoadmapStoreEvents } from "./store/roadmap-store.js";