55 lines
2.1 KiB
TypeScript
55 lines
2.1 KiB
TypeScript
/**
|
|
* Next.js instrumentation hook — runs once when the server boots.
|
|
*
|
|
* Scope is intentionally narrow: warn early about ZITADEL misconfigurations
|
|
* that would otherwise cause silent feature failures (Bugs 20, 21, 23, 24
|
|
* from the test triage). The check is fire-and-forget — it must NEVER
|
|
* crash the server, even if ZITADEL is briefly unreachable at boot.
|
|
*
|
|
* Add new self-checks here only if they meet the same bar: cheap, side-effect
|
|
* free, and useful at the precise moment a misconfiguration would otherwise
|
|
* go unnoticed.
|
|
*
|
|
* Docs: https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation
|
|
*/
|
|
|
|
const REQUIRED_ROLE_KEYS = [
|
|
"owner",
|
|
"user",
|
|
"platform_admin",
|
|
"platform_operator",
|
|
] as const;
|
|
|
|
export async function register() {
|
|
if (process.env.NEXT_RUNTIME !== "nodejs") return;
|
|
// Skip during `next build` — there's no need to talk to ZITADEL just to
|
|
// produce a static build, and we don't want CI builds to depend on it.
|
|
if (process.env.NEXT_PHASE === "phase-production-build") return;
|
|
|
|
// Lazy import: the instrumentation file runs in a constrained context
|
|
// before app code; importing at top-level would pull NextAuth/etc.
|
|
const { listProjectRoles } = await import("@/lib/zitadel");
|
|
|
|
try {
|
|
const present = new Set(await listProjectRoles());
|
|
const missing = REQUIRED_ROLE_KEYS.filter((k) => !present.has(k));
|
|
|
|
if (missing.length === 0) {
|
|
console.log(
|
|
`[startup] ZITADEL project roles OK (${REQUIRED_ROLE_KEYS.length} canonical keys present).`
|
|
);
|
|
return;
|
|
}
|
|
|
|
console.warn(
|
|
`[startup] ZITADEL project ${process.env.ZITADEL_PROJECT_ID} is missing canonical role key(s): ${missing.join(", ")}. ` +
|
|
`Customer invites and team-page badges will not work. ` +
|
|
`Run \`node --env-file=.env scripts/zitadel-roles.mjs apply\` to repair.`
|
|
);
|
|
} catch (err) {
|
|
// Never block startup. The portal can still serve unauthenticated
|
|
// pages and the operator can investigate at leisure.
|
|
console.warn("[startup] ZITADEL self-check failed (continuing):", err);
|
|
}
|
|
}
|