fix(FN-758): fix project-scoped real-time dashboard updates
- Add project-store-resolver to correctly scope SSE and WebSocket connections to the active project's TaskStore - Fix shared resolver so multi-project setups deliver task events only to the right dashboard clients - Add regression tests for project store resolver (routing, missing project, SSE integration) - Remove unused import and clean up stale changeset - Add changeset for published package patch bump
This commit is contained in:
@@ -8,6 +8,7 @@ import type { AuthStorageLike, ModelRegistryLike } from "./routes.js";
|
||||
import { createApiRoutes } from "./routes.js";
|
||||
import { createSSE } from "./sse.js";
|
||||
import { rateLimit, RATE_LIMITS } from "./rate-limit.js";
|
||||
import { getOrCreateProjectStore, evictAllProjectStores } from "./project-store-resolver.js";
|
||||
import { getTerminalService, type TerminalSession } from "./terminal-service.js";
|
||||
import { WebSocketServer, type WebSocket } from "ws";
|
||||
import { terminalSessionManager } from "./terminal.js";
|
||||
@@ -117,8 +118,9 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
|
||||
}
|
||||
|
||||
try {
|
||||
const { TaskStore: TaskStoreClass } = await import("@fusion/core");
|
||||
const scopedStore = await TaskStoreClass.getOrCreateForProject(projectId);
|
||||
// Use the shared project-store resolver so SSE listeners attach to
|
||||
// the same EventEmitter used by project-scoped task API routes.
|
||||
const scopedStore = await getOrCreateProjectStore(projectId);
|
||||
createSSE(scopedStore, scopedStore.getMissionStore())(req, res);
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: err.message ?? "Failed to open project event stream" });
|
||||
@@ -143,8 +145,7 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
|
||||
|
||||
void (async () => {
|
||||
if (projectId) {
|
||||
const { TaskStore: TaskStoreClass } = await import("@fusion/core");
|
||||
activeStore = await TaskStoreClass.getOrCreateForProject(projectId);
|
||||
activeStore = await getOrCreateProjectStore(projectId);
|
||||
}
|
||||
|
||||
const onAgentLog = (entry: { taskId: string; text: string; type: string; timestamp: string }) => {
|
||||
@@ -631,6 +632,8 @@ export function setupBadgeWebSocket(
|
||||
wsManager.dispose();
|
||||
void badgePubSub.dispose();
|
||||
wss.close();
|
||||
// Clean up cached project-scoped stores (stop watchers, close DB connections)
|
||||
evictAllProjectStores();
|
||||
dashboardApp.terminalWsServer = null;
|
||||
dashboardApp.badgeWsServer = null;
|
||||
dashboardApp.badgeWsManager = null;
|
||||
|
||||
Reference in New Issue
Block a user