Files
fusion/packages/core
Semih 2d43ac7bd2 dashboard: mount plugin-defined routes with project-scoped TaskStore
Phase-1 telemetry-watcher's grafana-webhook handler 401'd because the
dashboard never mounted plugin-supplied routes — getPluginRoutes()
exists on PluginLoader but no caller consumed it. The smoke test was
working around this by injecting incident tasks directly through
/api/tasks; we want the real path to work end-to-end.

Two changes:

1. PluginLoader gains createContextFor(pluginId, { taskStore? }).
   Lifecycle hooks still see the loader's bound store (the cwd
   project), but REST handlers receive a project-scoped store derived
   from the request's projectId so a Grafana webhook addressed to
   sase opens tasks in sase even though fusion's loader is bound
   to its own cwd. Settings still come from the loader's store at
   load time, which is the right thing — settings don't follow the
   request.

2. routes.ts iterates pluginLoader.getPluginRoutes() once at server
   startup and binds /api/plugins/:pluginId/:routePath to a handler
   that resolves project context per request, builds the context via
   createContextFor, and forwards to the plugin's route. ApiError +
   rethrowAsApiError preserve the dashboard's standard error envelope.

Plugins added after server start still need a restart for routes to
bind; reloadPlugin doesn't currently re-mount Express handlers. That
limitation matches the existing constraint and is out of scope here.
2026-05-10 08:56:48 +00:00
..
2026-04-26 12:24:08 -07:00
2026-04-26 12:24:08 -07:00