feat(FN-1803): add nodeId support to project registration and browse-directory

- Add nodeId parameter to registerProject in CentralCore for multi-project tracking
- Update POST /api/projects route to accept and persist nodeId
- Update browse-directory route to filter by nodeId
- Add nodeId field to frontend API wrappers for registerProject and browseDirectory
- Add comprehensive tests for nodeId in project registration and browse-directory routes
This commit is contained in:
Fusion
2026-04-16 04:34:49 -07:00
committed by gsxdsm
parent 020b27fc37
commit 1d706d7671
6 changed files with 486 additions and 6 deletions

View File

@@ -213,6 +213,39 @@ describe("CentralCore", () => {
expect(health?.totalTasksCompleted).toBe(0);
expect(health?.totalTasksFailed).toBe(0);
});
it("should persist nodeId when provided on registration", async () => {
const projectPath = join(tempDir, "node-project");
mkdirSync(projectPath);
projectPaths.push(projectPath);
const project = await central.registerProject({
name: "Node On Register",
path: projectPath,
nodeId: "node_abc123",
});
expect(project.nodeId).toBe("node_abc123");
const retrieved = await central.getProject(project.id);
expect(retrieved?.nodeId).toBe("node_abc123");
});
it("should have undefined nodeId when not provided on registration", async () => {
const projectPath = join(tempDir, "no-node-project");
mkdirSync(projectPath);
projectPaths.push(projectPath);
const project = await central.registerProject({
name: "No Node",
path: projectPath,
});
expect(project.nodeId).toBeUndefined();
const retrieved = await central.getProject(project.id);
expect(retrieved?.nodeId).toBeUndefined();
});
});
describe("project unregistration", () => {

View File

@@ -234,6 +234,7 @@ export class CentralCore extends EventEmitter<CentralCoreEvents> {
path: string;
isolationMode?: IsolationMode;
settings?: ProjectSettings;
nodeId?: string;
}): Promise<RegisteredProject> {
this.ensureInitialized();
@@ -261,6 +262,7 @@ export class CentralCore extends EventEmitter<CentralCoreEvents> {
path: input.path,
status: "initializing",
isolationMode: input.isolationMode ?? "in-process",
nodeId: input.nodeId,
createdAt: now,
updatedAt: now,
lastActivityAt: now,
@@ -270,8 +272,8 @@ export class CentralCore extends EventEmitter<CentralCoreEvents> {
this.db!.transaction(() => {
// Insert project
this.db!.prepare(
`INSERT INTO projects (id, name, path, status, isolationMode, createdAt, updatedAt, lastActivityAt, settings)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
`INSERT INTO projects (id, name, path, status, isolationMode, createdAt, updatedAt, lastActivityAt, nodeId, settings)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run(
project.id,
project.name,
@@ -281,6 +283,7 @@ export class CentralCore extends EventEmitter<CentralCoreEvents> {
project.createdAt,
project.updatedAt,
project.lastActivityAt ?? null,
project.nodeId ?? null,
toJsonNullable(project.settings)
);