fix(api): check scanned project folders before creating their projects

The onboarding scan resolved each repository with realpath and left the
remaining checks to wireProjectWorkspace, which ran them only after the
project had been created. wireProjectWorkspace now stores the folder it
is given, so the scan resolves and checks the folder with
resolveProjectWorkspaceDirectory first, like spaces.create, and skips a
repository whose folder cannot be linked before creating its project.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HG4pFTUBDpuCS2Y44TV8x
This commit is contained in:
Claude 2026-10-03 16:51:28 +00:00
parent a8169da11c
commit 0047671458
No known key found for this signature in database

View File

@ -1,13 +1,14 @@
// Onboarding scan — real filesystem scan, Git analysis, and profile compilation. // Onboarding scan — real filesystem scan, Git analysis, and profile compilation.
// Runs synchronously on the host machine (no sandbox needed). // Runs synchronously on the host machine (no sandbox needed).
import { spawn } from "node:child_process"; import { spawn } from "node:child_process";
import { access, readdir, realpath, stat } from "node:fs/promises"; import { access, readdir, stat } from "node:fs/promises";
import { basename, dirname, join } from "node:path"; import { basename, dirname, join } from "node:path";
import type { Actor } from "@rakazo/contracts"; import type { Actor } from "@rakazo/contracts";
import type { PrismaClient } from "@rakazo/db"; import type { PrismaClient } from "@rakazo/db";
import { import {
createSpaceForMember, createSpaceForMember,
InvalidSpaceNameError, InvalidSpaceNameError,
resolveProjectWorkspaceDirectory,
SpaceLimitError, SpaceLimitError,
wireProjectWorkspace, wireProjectWorkspace,
} from "@rakazo/db"; } from "@rakazo/db";
@ -656,7 +657,8 @@ async function createProjects(
for (const repo of repos) { for (const repo of repos) {
// Compare and link the real folder, so the next scan recognizes the projects of this one. // Compare and link the real folder, so the next scan recognizes the projects of this one.
const folder = await realpath(repo.path).catch(() => null); // Checking it before the project exists means a folder that cannot be linked leaves none.
const folder = await resolveProjectWorkspaceDirectory(repo.path).catch(() => null);
if (!folder || linkedFolders.has(folder)) continue; if (!folder || linkedFolders.has(folder)) continue;
let space: { id: string; name: string }; let space: { id: string; name: string };
try { try {