Initial curated projectbrain source from 8a7b1e0651dbdab97d744cbd2e653ab3970ac6c5

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:43:26 +02:00
commit 5aa3e8d685
700 files changed
+132801

No files matched your search

+252
View File
@@ -0,0 +1,252 @@
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
const root = process.cwd();
const migrationsDir = path.join(root, "backend", "prisma", "migrations");
const schemaPath = path.join(root, "backend", "prisma", "schema.prisma");
const dockerComposePath = path.join(root, "docker-compose.yml");
const backendDockerfilePath = path.join(root, "backend", "Dockerfile");
const rootPackagePath = path.join(root, "package.json");
const workspacePath = path.join(root, "pnpm-workspace.yaml");
const backendEntrypointPath = path.join(root, "backend", "scripts", "docker-entrypoint.sh");
const systemReadinessRoutePath = path.join(root, "backend", "src", "routes", "systemReadiness.ts");
const appPath = path.join(root, "backend", "src", "app.ts");
const initiativeRoutesPath = path.join(root, "backend", "src", "routes", "initiatives.ts");
const initiativeRepoPath = path.join(root, "backend", "src", "repositories", "initiativesRepository.ts");
const initiativeSmokePath = path.join(root, "backend", "scripts", "smoke-initiatives.mjs");
const exists = (filePath) => fs.existsSync(filePath);
const read = (filePath) => fs.readFileSync(filePath, "utf8");
const fail = [];
const warn = [];
const requiredPnpmBuiltDeps = ["@prisma/client", "@prisma/engines", "@swc/core", "esbuild", "prisma"];
const parseWorkspaceAllowBuilds = (workspaceYaml) => {
const allowed = new Set();
const allowBuildsIndex = workspaceYaml.indexOf("allowBuilds:");
if (allowBuildsIndex === -1) return allowed;
const lines = workspaceYaml.slice(allowBuildsIndex).split("\n").slice(1);
for (const line of lines) {
if (/^[^\s#]/.test(line)) break;
const match = line.match(/^\s*[\'"]?([^\'":]+)[\'"]?\s*:\s*(true|false)\s*(?:#.*)?$/);
if (match && match[2] === "true") allowed.add(match[1].trim());
}
return allowed;
};
if (!exists(schemaPath)) fail.push("Missing backend/prisma/schema.prisma.");
if (!exists(migrationsDir)) fail.push("Missing backend/prisma/migrations directory.");
const migrationFolders = exists(migrationsDir)
? fs.readdirSync(migrationsDir).filter((entry) => fs.statSync(path.join(migrationsDir, entry)).isDirectory()).sort()
: [];
const migrationSql = migrationFolders.map((folder) => ({
folder,
path: path.join(migrationsDir, folder, "migration.sql"),
})).filter((item) => exists(item.path));
if (migrationSql.length === 0) {
fail.push("No Prisma migration.sql files were found.");
}
const legacyDuplicateInitMigration = "20260606200000_init_project_workspace";
if (migrationFolders.includes(legacyDuplicateInitMigration)) {
fail.push(`${legacyDuplicateInitMigration} must not exist. It is an obsolete duplicate init migration that recreates ProjectStatus and breaks fresh Docker database startup.`);
}
const initMigrations = migrationSql.filter((item) => item.folder.includes("init_project_workspace"));
if (initMigrations.length !== 1) {
fail.push(`Expected exactly one init_project_workspace migration, found ${initMigrations.length}: ${initMigrations.map((item) => item.folder).join(", ") || "none"}.`);
}
const initIndex = migrationSql.findIndex((item) => item.folder.includes("init_project_workspace"));
if (initIndex < 0) {
fail.push("No init_project_workspace migration found.");
} else if (initIndex !== 0) {
fail.push(`Init migration must be first, but it is at position ${initIndex + 1}: ${migrationSql[initIndex].folder}.`);
}
const projectTableIndex = migrationSql.findIndex((item) => read(item.path).includes('CREATE TABLE "Project"'));
const captureTableIndex = migrationSql.findIndex((item) => read(item.path).includes('CREATE TABLE "CaptureItem"'));
if (projectTableIndex < 0) fail.push('No migration creates "Project".');
if (captureTableIndex >= 0 && projectTableIndex >= 0 && projectTableIndex > captureTableIndex) {
fail.push('Migration order is invalid: "CaptureItem" appears before "Project".');
}
const schema = exists(schemaPath) ? read(schemaPath) : "";
const duplicateFields = [];
const modelBlocks = [...schema.matchAll(/model\s+(\w+)\s+\{([\s\S]*?)\n\}/g)];
for (const [, modelName, body] of modelBlocks) {
const seen = new Set();
for (const rawLine of body.split("\n")) {
const line = rawLine.trim();
if (!line || line.startsWith("@@") || line.startsWith("//")) continue;
const fieldName = line.split(/\s+/)[0];
if (!fieldName || fieldName.startsWith("@")) continue;
if (seen.has(fieldName)) duplicateFields.push(`${modelName}.${fieldName}`);
seen.add(fieldName);
}
}
if (duplicateFields.length > 0) fail.push(`Prisma schema contains duplicate field definitions: ${duplicateFields.join(", ")}.`);
if (!schema.includes("linux-musl-openssl-3.0.x")) fail.push("Prisma generator must include linux-musl-openssl-3.0.x binaryTarget for the Docker Alpine runtime.");
for (const model of ["Project", "CaptureItem", "AcceptedTruthItem", "CurrentStateReport", "DocumentationItem", "BlueprintGraph", "BlueprintNode", "BlueprintNodeRun", "BrainstormSession", "Initiative"]) {
if (!schema.includes(`model ${model} `)) fail.push(`Schema is missing model ${model}.`);
}
const migrationText = migrationSql.map((item) => read(item.path)).join("\n");
for (const table of ["Project", "CaptureItem", "AcceptedTruthItem", "CurrentStateReport", "DocumentationItem", "BlueprintGraph", "BlueprintNode", "BlueprintNodeRun", "BrainstormSession", "Initiative"]) {
if (!migrationText.includes(`"${table}"`)) fail.push(`Migrations do not reference table ${table}.`);
}
if (exists(rootPackagePath)) {
const rootPackage = JSON.parse(read(rootPackagePath));
if (rootPackage.packageManager !== "pnpm@11.5.2") {
fail.push("Root package.json must pin packageManager to pnpm@11.5.2 for reproducible Docker/Corepack builds.");
}
if (rootPackage.pnpm) {
fail.push("Root package.json must not contain a legacy pnpm field; pnpm 11 ignores it and emits Docker build warnings. Keep approvals in pnpm-workspace.yaml allowBuilds.");
}
} else {
fail.push("Missing root package.json.");
}
if (exists(workspacePath)) {
const workspaceAllowedBuilds = parseWorkspaceAllowBuilds(read(workspacePath));
for (const dependency of requiredPnpmBuiltDeps) {
if (!workspaceAllowedBuilds.has(dependency)) {
fail.push(`pnpm-workspace.yaml allowBuilds must set ${dependency}: true for Docker installs with pnpm 11.`);
}
}
} else {
fail.push("Missing pnpm-workspace.yaml.");
}
if (exists(dockerComposePath)) {
const compose = read(dockerComposePath);
if (!compose.includes("projectbrain-postgres")) fail.push("docker-compose.yml does not define projectbrain-postgres.");
if (!compose.includes("PROJECTBRAIN_DATA_SOURCE")) fail.push("docker-compose.yml does not configure PROJECTBRAIN_DATA_SOURCE.");
if (!compose.includes("VITE_PROJECTBRAIN_CLIENT_MODE")) warn.push("docker-compose.yml does not pass VITE_PROJECTBRAIN_CLIENT_MODE to frontend build args.");
if (!compose.includes("PROJECTBRAIN_SEED_ON_START")) warn.push("docker-compose.yml does not expose PROJECTBRAIN_SEED_ON_START.");
if (!compose.includes("/api/system/readiness")) fail.push("docker-compose.yml does not healthcheck /api/system/readiness.");
if (!compose.includes("condition: service_healthy")) fail.push("docker-compose.yml does not wait for healthy backend before frontend startup.");
} else {
fail.push("Missing docker-compose.yml.");
}
if (exists(backendDockerfilePath)) {
const dockerfile = read(backendDockerfilePath);
if (!dockerfile.includes("prisma:generate")) fail.push("Backend Dockerfile does not run prisma:generate during build.");
if (!dockerfile.includes("docker-entrypoint.sh")) fail.push("Backend Dockerfile does not use the database-aware docker entrypoint.");
if (!dockerfile.includes("/api/system/readiness")) fail.push("Backend Dockerfile does not expose a system readiness healthcheck.");
if (!dockerfile.includes("apk add --no-cache") || !dockerfile.includes("openssl")) fail.push("Backend Dockerfile does not install OpenSSL; Prisma migrations fail at runtime on Alpine without it.");
if (!dockerfile.includes("libc6-compat")) fail.push("Backend Dockerfile does not install libc6-compat for native engine compatibility on Alpine.");
} else {
fail.push("Missing backend/Dockerfile.");
}
if (exists(backendEntrypointPath)) {
const entrypoint = read(backendEntrypointPath);
if (!entrypoint.includes("prisma migrate deploy")) fail.push("Backend entrypoint does not run prisma migrate deploy.");
if (!entrypoint.includes("PROJECTBRAIN_SEED_ON_START")) fail.push("Backend entrypoint does not support PROJECTBRAIN_SEED_ON_START.");
if (!entrypoint.includes("20260606200000_init_project_workspace")) fail.push("Backend entrypoint must guard against the obsolete duplicate init migration when older overlay deployments left it on disk or in _prisma_migrations.");
if (!entrypoint.includes("prisma migrate resolve --rolled-back 20260606200000_init_project_workspace")) fail.push("Backend entrypoint must resolve failed obsolete duplicate init migration records as rolled back before migrate deploy.");
} else {
fail.push("Missing backend/scripts/docker-entrypoint.sh.");
}
if (!exists(systemReadinessRoutePath)) {
fail.push("Missing backend/src/routes/systemReadiness.ts live readiness route.");
} else {
const route = read(systemReadinessRoutePath);
if (!route.includes('/api/system/readiness')) fail.push("System readiness route does not expose /api/system/readiness.");
if (!route.includes('prisma.$queryRaw`SELECT 1`')) fail.push("System readiness route does not run a live Prisma SELECT 1 probe.");
}
if (exists(appPath)) {
const app = read(appPath);
if (!app.includes("registerSystemReadinessRoutes")) fail.push("Fastify app does not register system readiness routes.");
if (!app.includes("registerBrainstormRoutes")) fail.push("Fastify app does not register Brainstorm CPU routes.");
if (!app.includes("registerInitiativeRoutes")) fail.push("Fastify app does not register Initiative routes.");
} else {
fail.push("Missing backend/src/app.ts.");
}
if (!exists(initiativeRoutesPath)) {
fail.push("Missing backend/src/routes/initiatives.ts.");
} else {
const routes = read(initiativeRoutesPath);
for (const signal of [
"/api/projects/:projectId/initiatives",
"/api/projects/:projectId/initiatives/:initiativeId",
"/api/projects/:projectId/initiatives/:initiativeId/feature-candidates",
]) {
if (!routes.includes(signal)) fail.push(`Initiative routes are missing ${signal}.`);
}
}
if (!exists(initiativeRepoPath)) {
fail.push("Missing backend/src/repositories/initiativesRepository.ts.");
} else {
const repo = read(initiativeRepoPath);
for (const symbol of ["createInitiativeForProject", "updateInitiativeForProject", "getInitiativeForProject", "createFeatureCandidatesForInitiative", "syncInitiativeReviewAction"]) {
if (!repo.includes(symbol)) fail.push(`Initiative repository is missing ${symbol}.`);
}
}
if (!exists(initiativeSmokePath)) fail.push("Missing backend/scripts/smoke-initiatives.mjs.");
else {
const smoke = read(initiativeSmokePath);
if (!smoke.includes("/review-queue/${firstCandidate.reviewItemId}/accept")) fail.push("Initiative smoke does not validate review accept materialization.");
if (!smoke.includes("initiativeSync")) fail.push("Initiative smoke does not assert initiativeSync output.");
}
const result = {
status: fail.length === 0 ? "PASS" : "FAIL",
migrationRoots: [path.relative(root, migrationsDir).replaceAll("\\", "/")],
migrations: migrationSql.map((item) => item.folder),
initMigration: initIndex >= 0 ? migrationSql[initIndex]?.folder : null,
checks: {
projectTableBeforeCapture: projectTableIndex >= 0 && (captureTableIndex < 0 || projectTableIndex < captureTableIndex),
backendEntrypoint: exists(backendEntrypointPath),
dockerCompose: exists(dockerComposePath),
schema: exists(schemaPath),
systemReadinessRoute: exists(systemReadinessRoutePath),
legacyDuplicateInitMigrationAbsent: !migrationFolders.includes("20260606200000_init_project_workspace"),
exactlyOneInitMigration: initMigrations.length === 1,
initiativeRoutes: exists(initiativeRoutesPath),
initiativeSmoke: exists(initiativeSmokePath),
duplicateSchemaFields: duplicateFields.length === 0,
prismaAlpineBinaryTarget: schema.includes("linux-musl-openssl-3.0.x"),
backendDockerfileInstallsOpenSSL: exists(backendDockerfilePath) && read(backendDockerfilePath).includes("openssl"),
pnpmDockerBuildScriptsApproved: exists(workspacePath) && (() => {
const allowedBuilds = parseWorkspaceAllowBuilds(read(workspacePath));
return requiredPnpmBuiltDeps.every((dependency) => allowedBuilds.has(dependency));
})(),
},
warnings: warn,
failures: fail,
};
if (process.argv.includes("--json")) {
console.log(JSON.stringify(result, null, 2));
} else {
console.log(`ProjectBrain database readiness: ${result.status}`);
console.log(`Migration roots checked: ${result.migrationRoots.join(", ")}`);
console.log(`Migrations: ${migrationSql.length}`);
console.log(`Init migration: ${result.initMigration ?? "missing"}`);
if (warn.length > 0) {
console.log("Warnings:");
for (const item of warn) console.log(`- ${item}`);
}
if (fail.length > 0) {
console.log("Failures:");
for (const item of fail) console.log(`- ${item}`);
}
}
if (fail.length > 0) process.exit(1);