@pukujan/create-modular-monolith 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,8 @@
12
12
  "lint:repo-artifacts": "node scripts/lint-repo-artifacts.mjs",
13
13
  "lint:architecture": "npm --prefix backend run lint:architecture",
14
14
  "test": "npm --prefix backend test && npm --prefix frontend test",
15
+ "test:evals": "npm --prefix backend run test:evals",
16
+ "test:ci": "npm run lint:contracts && npm run lint:repo-artifacts && npm run lint:architecture && npm test && npm run test:evals",
15
17
  "new:module": "node scripts/new-module.mjs",
16
18
  "condense-prompts": "node scripts/condense-prompts.mjs",
17
19
  "condense-file-structure": "node scripts/condense-file-structure.mjs",
@@ -3,17 +3,15 @@
3
3
  * Collect all versioned prompt templates into models/consolidated-prompts.json
4
4
  * Usage: node scripts/condense-prompts.mjs
5
5
  */
6
- import { readFile, readdir, stat } from "fs/promises";
6
+ import { readFile, readdir, stat, access } from "fs/promises";
7
+ import { existsSync } from "fs";
7
8
  import { join, relative, dirname } from "path";
8
9
  import { fileURLToPath } from "url";
9
10
  import { writeConsolidatedArtifact } from "./consolidated-output.mjs";
10
11
 
11
12
  const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
12
13
 
13
- const SCAN_ROOTS = [
14
- "backend/src/modules",
15
- "work-log/handoffs/001_2026-05-23_starter_case-filing-ai-updated/prompts"
16
- ];
14
+ const SCAN_ROOTS = ["backend/src/modules"];
17
15
 
18
16
  const PROMPT_EXTENSIONS = [".prompt.md", ".prompt.js"];
19
17
 
@@ -74,11 +72,14 @@ async function findManifests() {
74
72
  return manifests;
75
73
  }
76
74
 
77
- async function loadCaseFilingVersions() {
75
+ async function loadDomainPromptVersions() {
78
76
  const path = join(
79
77
  repoRoot,
80
78
  "backend/src/modules/case-filing-ai/prompts/promptVersions.js"
81
79
  );
80
+ if (!existsSync(path)) {
81
+ return { sourcePath: null, versions: {} };
82
+ }
82
83
  const raw = await readFile(path, "utf8");
83
84
  const versions = {};
84
85
  const blockRe = /(\w+):\s*\{[^}]*id:\s*"([^"]+)"[^}]*masterCaseFiling:\s*"([^"]+)"[^}]*description:\s*"([^"]+)"/gs;
@@ -133,7 +134,7 @@ async function main() {
133
134
  };
134
135
  }
135
136
 
136
- const caseFilingVersions = await loadCaseFilingVersions();
137
+ const domainPromptVersions = await loadDomainPromptVersions();
137
138
  const moduleManifests = await findManifests();
138
139
 
139
140
  const doc = {
@@ -141,11 +142,10 @@ async function main() {
141
142
  generatedAt: new Date().toISOString(),
142
143
  repositoryRoot: repoRoot,
143
144
  condensedBy: "condense-prompts",
144
- description:
145
- "Consolidated prompt templates for legal-prmpt-eng (active + starter reference).",
145
+ description: "Consolidated prompt templates across backend modules.",
146
146
  promptCount: inventory.length
147
147
  },
148
- caseFilingPromptVersions: caseFilingVersions,
148
+ domainPromptVersions,
149
149
  moduleManifests,
150
150
  inventory,
151
151
  prompts
@@ -1,10 +1,6 @@
1
- import { readFileSync, readdirSync, statSync, existsSync } from "fs";
1
+ import { readFileSync, existsSync } from "fs";
2
2
  import { join } from "path";
3
3
 
4
- const SKIP_MODULES = new Set(["_reference"]);
5
- const ROUTE_RE = /router\.(get|post|put|patch|delete)\(\s*["'`]([^"'`]+)["'`]/gi;
6
- const BASE_PATH_RE = /app\.use\(\s*["'`](\/api\/[^"'`]+)["'`]/;
7
-
8
4
  function readText(path) {
9
5
  return readFileSync(path, "utf8");
10
6
  }
@@ -80,8 +76,7 @@ export async function collectApiInventory(repoRoot) {
80
76
 
81
77
  const http = { active: [], stub: [], deprecated: [] };
82
78
  for (const row of registry) {
83
- const bucket = classifyRoute(row);
84
- http[bucket].push({
79
+ http[classifyRoute(row)].push({
85
80
  method: row.method,
86
81
  path: row.path,
87
82
  module: row.module,
@@ -89,23 +84,20 @@ export async function collectApiInventory(repoRoot) {
89
84
  });
90
85
  }
91
86
 
92
- const promptVersions = {
93
- defaultEnv: "n/a",
94
- envVar: "MASTER_PROMPT_VERSION",
95
- allowed: [],
96
- specs: {},
97
- notes: ["Add promptVersions.js in your domain module when you introduce LLM workflows"]
98
- };
99
-
100
87
  const pkg = JSON.parse(readText(join(repoRoot, "package.json")));
101
- const pipelineVersions = {
102
- app: pkg.version ?? "2.0.0",
103
- note: "Add pipelineVersions.contract.js in domain modules for batch/runtime versioning"
104
- };
105
88
 
106
89
  const versioned = {
107
- pipeline: pipelineVersions,
108
- prompts: promptVersions,
90
+ pipeline: {
91
+ app: pkg.version ?? "2.0.0",
92
+ note: "Add pipelineVersions.contract.js in domain modules when you introduce batch workflows"
93
+ },
94
+ prompts: {
95
+ defaultEnv: "n/a",
96
+ envVar: "MASTER_PROMPT_VERSION",
97
+ allowed: [],
98
+ specs: {},
99
+ notes: ["Add promptVersions.js in your domain module when you introduce LLM workflows"]
100
+ },
109
101
  storage: {},
110
102
  app: { packageJson: pkg.version }
111
103
  };
@@ -123,6 +115,7 @@ export async function collectApiInventory(repoRoot) {
123
115
  }
124
116
 
125
117
  const cli = [
118
+ { command: "npm run test:ci", purpose: "All CI gates (lint + test + evals)" },
126
119
  { command: "npm run dev-log:pre-push", purpose: "Paired human + agent dev logs" },
127
120
  { command: "npm run condense:all", purpose: "Snapshots → file-exchange/exports/" },
128
121
  { command: "npm run import:file-exchange", purpose: "Inbound → file-exchange/imports/{stamp}/" },
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { readdirSync, existsSync } from "fs";
3
+ import { join } from "path";
4
+ import { spawnSync } from "child_process";
5
+
6
+ const moduleName = process.argv[2];
7
+ const root = new URL("../", import.meta.url).pathname;
8
+ const modulesDir = join(root, "backend/src/modules");
9
+
10
+ if (!existsSync(modulesDir)) {
11
+ console.error("No modules directory.");
12
+ process.exit(1);
13
+ }
14
+
15
+ const targets = moduleName
16
+ ? [moduleName]
17
+ : readdirSync(modulesDir, { withFileTypes: true })
18
+ .filter((d) => d.isDirectory() && !d.name.startsWith("_"))
19
+ .map((d) => d.name);
20
+
21
+ let failed = false;
22
+
23
+ for (const name of targets) {
24
+ const runnersDir = join(modulesDir, name, "evals", "runners");
25
+ if (!existsSync(runnersDir)) continue;
26
+
27
+ const runners = readdirSync(runnersDir).filter(
28
+ (f) => f.endsWith(".eval.mjs") || f.endsWith(".eval.js")
29
+ );
30
+
31
+ for (const runner of runners) {
32
+ const file = join(runnersDir, runner);
33
+ console.log(`\n▶ eval ${name}/${runner}`);
34
+ const result = spawnSync(process.execPath, ["--test", file], {
35
+ stdio: "inherit",
36
+ cwd: join(root, "backend")
37
+ });
38
+ if (result.status !== 0) failed = true;
39
+ }
40
+ }
41
+
42
+ if (failed) process.exit(1);
43
+ console.log("\nEvals complete.");