98 lines
2.7 KiB
JavaScript
98 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const APP = path.join(ROOT, "app", "workspace");
|
|
const MODULE = path.join(ROOT, "modules", "workspace");
|
|
const MAX_LINES = 25;
|
|
const errors = [];
|
|
|
|
const ROUTES = [
|
|
"hub",
|
|
"hubs",
|
|
"hubs/[id]",
|
|
"projects",
|
|
"projects/[id]",
|
|
"tasks",
|
|
"teams",
|
|
"teams/[id]",
|
|
"content",
|
|
"content/[id]",
|
|
"content/calendar",
|
|
"content/board",
|
|
"approvals",
|
|
"assets",
|
|
"reports",
|
|
];
|
|
|
|
const FEATURE_FILES = [
|
|
"hub.tsx",
|
|
"hubs.tsx",
|
|
"hubDashboard.tsx",
|
|
"projects.tsx",
|
|
"projectDetail.tsx",
|
|
"tasks.tsx",
|
|
"teams.tsx",
|
|
"teamDetail.tsx",
|
|
"contentStudio.tsx",
|
|
"contentDetail.tsx",
|
|
"contentCalendar.tsx",
|
|
"contentBoard.tsx",
|
|
"approvals.tsx",
|
|
"assets.tsx",
|
|
"reports.tsx",
|
|
];
|
|
|
|
function walkPages(dir) {
|
|
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const p = path.join(dir, ent.name);
|
|
if (ent.isDirectory()) walkPages(p);
|
|
else if (ent.name === "page.tsx") checkPage(p);
|
|
}
|
|
}
|
|
|
|
function checkPage(file) {
|
|
const rel = path.relative(APP, file);
|
|
const content = fs.readFileSync(file, "utf8");
|
|
const lines = content.split("\n").length;
|
|
if (rel !== "page.tsx" && lines > MAX_LINES) errors.push(`${rel}: ${lines} lines (max ${MAX_LINES})`);
|
|
if (rel !== "page.tsx" && !content.includes("@/modules/workspace/")) {
|
|
errors.push(`${rel}: must import from @/modules/workspace/`);
|
|
}
|
|
}
|
|
|
|
for (const route of ROUTES) {
|
|
for (const file of ["page.tsx", "loading.tsx", "error.tsx"]) {
|
|
const p = path.join(APP, route, file);
|
|
if (!fs.existsSync(p)) errors.push(`missing app/workspace/${route}/${file}`);
|
|
}
|
|
}
|
|
|
|
for (const file of FEATURE_FILES) {
|
|
if (!fs.existsSync(path.join(MODULE, "features", file))) {
|
|
errors.push(`missing modules/workspace/features/${file}`);
|
|
}
|
|
}
|
|
|
|
for (const file of [
|
|
path.join(MODULE, "index.ts"),
|
|
path.join(MODULE, "services", "workspace-api.ts"),
|
|
path.join(MODULE, "labels.ts"),
|
|
path.join(ROOT, "app", "api", "workspace", "[...path]", "route.ts"),
|
|
path.join(APP, "layout.tsx"),
|
|
path.join(APP, "page.tsx"),
|
|
]) {
|
|
if (!fs.existsSync(file)) errors.push(`missing ${path.relative(ROOT, file)}`);
|
|
}
|
|
|
|
if (fs.existsSync(APP)) walkPages(APP);
|
|
else errors.push("app/workspace not found");
|
|
|
|
if (errors.length) {
|
|
console.error("Workspace route validation failed:\n" + errors.map((e) => " - " + e).join("\n"));
|
|
process.exit(1);
|
|
}
|
|
console.log(`Workspace routes OK (${ROUTES.length} routes, ${FEATURE_FILES.length} features)`);
|