// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // A business module is its service: every procedure is a call to it, so the module runs only on the profiles // its business requirement names, and its manifest says so in `profiles`, which is what the Convex generator // and the profile tests read (template lesson core-17). Without it, CRM was projected into the Convex backend // once an app selected it. A native requirement (OCR, AI) is different: the module degrades without it, and // `documents` deploys to Convex on purpose. import { existsSync, readdirSync } from "node:fs" import { join } from "node:path" import type { ModuleManifest } from "@conusai-kit/core" import { expect, it } from "vitest" const modulesDir = join(import.meta.dirname, "..", "modules") const moduleIds = readdirSync(modulesDir).filter((name) => existsSync(join(modulesDir, name, "index.ts"))) const isManifest = (value: unknown): value is ModuleManifest => typeof value === "object" && value !== null && "id" in value && "procedures" in value it("a business module claims no profile its service does not run on", async () => { const problems: string[] = [] for (const id of moduleIds) { const exports = (await import(join(modulesDir, id, "index.ts"))) as Record for (const manifest of Object.values(exports).filter(isManifest)) { for (const requirement of manifest.serviceRequirements ?? []) { if (requirement.transport !== "business" || requirement.profiles === undefined) continue const supported = new Set(requirement.profiles) const claimed = manifest.profiles ?? ["every profile"] const extra = claimed.filter((profile) => !supported.has(profile)) if (extra.length > 0) { problems.push( `${manifest.id}: claims ${extra.join(", ")}; ${requirement.service} runs on ${requirement.profiles.join(", ")}`, ) } } } } expect(problems).toEqual([]) }, 120_000)