@pukujan/create-modular-monolith 2.2.1 → 2.2.3
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.
- package/package.json +1 -1
- package/template/.cursor/rules/file-exchange-inbox.mdc +1 -1
- package/template/ARCHITECTURE_EXPORT_README.md +30 -0
- package/template/EXPORT_MANIFEST.json +74 -0
- package/template/NOTICE +2 -3
- package/template/README.md +1 -61
- package/template/backend/package.json +1 -1
- package/template/backend/src/modules/model-condenser/services/modelCondenser.service.js +36 -465
- package/template/backend/src/modules/model-condenser/tests/unit/modelCondenser.service.test.js +2 -3
- package/template/backend/src/shared/utils/consolidatedExport.js +155 -11
- package/template/backend/src/shared/utils/consolidatedExport.test.js +50 -0
- package/template/docs/README.md +0 -1
- package/template/docs/architecture/EVAL_AND_CI.md +68 -41
- package/template/docs/architecture/REPO_ARTIFACT_LAYOUT.md +57 -14
- package/template/docs/architecture/contracts/consolidatedExports.contract.md +14 -10
- package/template/docs/architecture/contracts/manifest.json +17 -0
- package/template/file-exchange/README.md +20 -15
- package/template/frontend/package.json +1 -1
- package/template/package.json +3 -3
- package/template/scripts/condense-all.mjs +52 -0
- package/template/scripts/condense-file-structure.mjs +19 -10
- package/template/scripts/condense-models.mjs +5 -3
- package/template/scripts/condense-prompts.mjs +13 -51
- package/template/scripts/consolidated-output.mjs +22 -10
- package/template/scripts/export-architecture-starter.mjs +389 -0
- package/template/scripts/lib/api-inventory.mjs +16 -61
- package/template/scripts/lib/repo-tree.mjs +26 -4
- package/template/scripts/sync-cli-template.mjs +44 -0
- package/template/scripts/write-pre-push-dev-log.mjs +1 -0
- package/template/file-exchange/exports/consolidated-models.json +0 -625
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Run all consolidated exports into one dated audit folder:
|
|
4
|
+
* file-exchange/exports/{stamp}_consolidated/
|
|
5
|
+
*/
|
|
6
|
+
import { spawn } from "node:child_process";
|
|
7
|
+
import { join, dirname } from "path";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import { beginConsolidatedExportSession } from "../backend/src/shared/utils/consolidatedExport.js";
|
|
10
|
+
|
|
11
|
+
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
12
|
+
|
|
13
|
+
function runNpm(script) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const child = spawn("npm", ["run", script], {
|
|
16
|
+
cwd: repoRoot,
|
|
17
|
+
stdio: "inherit",
|
|
18
|
+
env: { ...process.env }
|
|
19
|
+
});
|
|
20
|
+
child.on("exit", (code) => {
|
|
21
|
+
if (code === 0) resolve();
|
|
22
|
+
else reject(new Error(`${script} exited with code ${code}`));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function main() {
|
|
28
|
+
const session = beginConsolidatedExportSession();
|
|
29
|
+
console.log(`Consolidated export session: ${session.exportDir}/`);
|
|
30
|
+
|
|
31
|
+
await runNpm("condense-prompts");
|
|
32
|
+
await runNpm("condense-file-structure");
|
|
33
|
+
|
|
34
|
+
await new Promise((resolve, reject) => {
|
|
35
|
+
const child = spawn("npm", ["run", "condense-models", "--", "--local"], {
|
|
36
|
+
cwd: join(repoRoot, "backend"),
|
|
37
|
+
stdio: "inherit",
|
|
38
|
+
env: { ...process.env }
|
|
39
|
+
});
|
|
40
|
+
child.on("exit", (code) => {
|
|
41
|
+
if (code === 0) resolve();
|
|
42
|
+
else reject(new Error(`condense-models exited with code ${code}`));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
console.log(`Done → ${session.exportDir}/ (latest copies also at file-exchange/exports/consolidated-*.json)`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
main().catch((err) => {
|
|
50
|
+
console.error(err.message || err);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
});
|
|
@@ -1,40 +1,49 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Write consolidated-file-structure.json — ASCII tree only (no nested JSON tree).
|
|
4
|
+
* Excludes node_modules, .git, dist, build, and runtime batch/export roots.
|
|
5
5
|
*
|
|
6
6
|
* Usage: node scripts/condense-file-structure.mjs
|
|
7
7
|
*/
|
|
8
8
|
import { join, dirname } from "path";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
import { writeConsolidatedArtifact } from "./consolidated-output.mjs";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
buildRepoTree,
|
|
13
|
+
TREE_IGNORE_DIRS,
|
|
14
|
+
TREE_IGNORE_FILES,
|
|
15
|
+
TREE_IGNORE_PREFIXES
|
|
16
|
+
} from "./lib/repo-tree.mjs";
|
|
12
17
|
|
|
13
18
|
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
14
19
|
|
|
15
20
|
async function main() {
|
|
16
|
-
const { rootName,
|
|
21
|
+
const { rootName, treeText, stats } = await buildRepoTree(repoRoot);
|
|
17
22
|
|
|
18
23
|
const doc = {
|
|
19
24
|
meta: {
|
|
20
25
|
generatedAt: new Date().toISOString(),
|
|
21
26
|
repositoryRoot: repoRoot,
|
|
27
|
+
rootName,
|
|
22
28
|
condensedBy: "condense-file-structure",
|
|
23
29
|
description:
|
|
24
|
-
"
|
|
30
|
+
"ASCII repository tree (tree(1)-style). Excludes node_modules, .git, dist, build, and runtime data/ (if present).",
|
|
25
31
|
excludeDirs: TREE_IGNORE_DIRS,
|
|
26
32
|
excludeFiles: TREE_IGNORE_FILES,
|
|
33
|
+
excludePrefixes: TREE_IGNORE_PREFIXES,
|
|
27
34
|
treeIgnoreFlag: 'tree -I "node_modules|.git|dist|build"'
|
|
28
35
|
},
|
|
29
36
|
stats,
|
|
30
|
-
|
|
31
|
-
treeText,
|
|
32
|
-
flatPaths
|
|
37
|
+
treeText
|
|
33
38
|
};
|
|
34
39
|
|
|
35
|
-
const { exportPath, modelsPath } = await writeConsolidatedArtifact(
|
|
40
|
+
const { exportPath, datedExportDir, modelsPath } = await writeConsolidatedArtifact(
|
|
41
|
+
"fileStructure",
|
|
42
|
+
doc
|
|
43
|
+
);
|
|
44
|
+
const lineCount = treeText.split("\n").length;
|
|
36
45
|
console.log(
|
|
37
|
-
`Consolidated ${
|
|
46
|
+
`Consolidated tree (${lineCount} lines, ${stats.fileCount} files) → ${exportPath} (${datedExportDir}/, mirror ${modelsPath})`
|
|
38
47
|
);
|
|
39
48
|
}
|
|
40
49
|
|
|
@@ -53,11 +53,13 @@ try {
|
|
|
53
53
|
await import("../backend/src/shared/utils/consolidatedExport.js");
|
|
54
54
|
const modelsPath = join(repoRoot, "models", CONSOLIDATED_FILENAMES.models);
|
|
55
55
|
const json = await readFile(modelsPath, "utf8");
|
|
56
|
-
await writeConsolidatedExport(repoRoot, CONSOLIDATED_FILENAMES.models, json
|
|
57
|
-
|
|
56
|
+
const written = await writeConsolidatedExport(repoRoot, CONSOLIDATED_FILENAMES.models, json, {
|
|
57
|
+
condensedBy: "model-condenser"
|
|
58
|
+
});
|
|
58
59
|
|
|
59
60
|
console.log(`Model condenser: ${result.modelCount} models`);
|
|
60
|
-
console.log(` → ${
|
|
61
|
+
console.log(` → ${written.exportPath} (audit)`);
|
|
62
|
+
console.log(` → ${CONSOLIDATED_EXPORT_DIR}/${CONSOLIDATED_FILENAMES.models} (latest)`);
|
|
61
63
|
console.log(` → models/${CONSOLIDATED_FILENAMES.models} (API mirror)`);
|
|
62
64
|
console.log(`Generated at: ${result.generatedAt}`);
|
|
63
65
|
} catch (error) {
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Collect
|
|
4
|
-
* Usage: node scripts/condense-prompts.mjs
|
|
3
|
+
* Collect prompt templates from backend modules into consolidated-prompts.json.
|
|
5
4
|
*/
|
|
6
|
-
import { readFile, readdir, stat
|
|
7
|
-
import { existsSync } from "fs";
|
|
5
|
+
import { readFile, readdir, stat } from "fs/promises";
|
|
8
6
|
import { join, relative, dirname } from "path";
|
|
9
7
|
import { fileURLToPath } from "url";
|
|
10
8
|
import { writeConsolidatedArtifact } from "./consolidated-output.mjs";
|
|
11
9
|
|
|
12
10
|
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
13
|
-
|
|
14
11
|
const SCAN_ROOTS = ["backend/src/modules"];
|
|
15
|
-
|
|
16
12
|
const PROMPT_EXTENSIONS = [".prompt.md", ".prompt.js"];
|
|
17
13
|
|
|
18
14
|
function extractVariables(text) {
|
|
19
15
|
const vars = new Set();
|
|
20
16
|
const re = /\{\{(\w+)\}\}/g;
|
|
21
17
|
let m;
|
|
22
|
-
while ((m = re.exec(text)) !== null)
|
|
23
|
-
vars.add(m[1]);
|
|
24
|
-
}
|
|
18
|
+
while ((m = re.exec(text)) !== null) vars.add(m[1]);
|
|
25
19
|
return [...vars].sort();
|
|
26
20
|
}
|
|
27
21
|
|
|
@@ -72,36 +66,12 @@ async function findManifests() {
|
|
|
72
66
|
return manifests;
|
|
73
67
|
}
|
|
74
68
|
|
|
75
|
-
async function loadDomainPromptVersions() {
|
|
76
|
-
const path = join(
|
|
77
|
-
repoRoot,
|
|
78
|
-
"backend/src/modules/case-filing-ai/prompts/promptVersions.js"
|
|
79
|
-
);
|
|
80
|
-
if (!existsSync(path)) {
|
|
81
|
-
return { sourcePath: null, versions: {} };
|
|
82
|
-
}
|
|
83
|
-
const raw = await readFile(path, "utf8");
|
|
84
|
-
const versions = {};
|
|
85
|
-
const blockRe = /(\w+):\s*\{[^}]*id:\s*"([^"]+)"[^}]*masterCaseFiling:\s*"([^"]+)"[^}]*description:\s*"([^"]+)"/gs;
|
|
86
|
-
let m;
|
|
87
|
-
while ((m = blockRe.exec(raw)) !== null) {
|
|
88
|
-
versions[m[2]] = {
|
|
89
|
-
key: m[1],
|
|
90
|
-
id: m[2],
|
|
91
|
-
masterCaseFiling: m[3],
|
|
92
|
-
description: m[4]
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
return { sourcePath: relative(repoRoot, path), versions };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
69
|
async function main() {
|
|
99
70
|
const promptFiles = [];
|
|
100
71
|
for (const root of SCAN_ROOTS) {
|
|
101
72
|
const found = await walk(join(repoRoot, root));
|
|
102
|
-
promptFiles.push(...found
|
|
73
|
+
promptFiles.push(...found);
|
|
103
74
|
}
|
|
104
|
-
|
|
105
75
|
promptFiles.sort();
|
|
106
76
|
|
|
107
77
|
const inventory = [];
|
|
@@ -112,11 +82,8 @@ async function main() {
|
|
|
112
82
|
const content = await readFile(abs, "utf8");
|
|
113
83
|
const st = await stat(abs);
|
|
114
84
|
const moduleMatch = rel.match(/^backend\/src\/modules\/([^/]+)/);
|
|
115
|
-
const module = moduleMatch ? moduleMatch[1] : "
|
|
116
|
-
const id = rel
|
|
117
|
-
.replace(/^backend\/src\/modules\/[^/]+\/prompts\//, "")
|
|
118
|
-
.replace(/^work-log\/handoffs\/[^/]+\/prompts\//, "starter/")
|
|
119
|
-
.replace(/[/.]/g, "_");
|
|
85
|
+
const module = moduleMatch ? moduleMatch[1] : "unknown";
|
|
86
|
+
const id = rel.replace(/^backend\/src\/modules\/[^/]+\/prompts\//, "").replace(/[/.]/g, "_");
|
|
120
87
|
|
|
121
88
|
const entry = {
|
|
122
89
|
id,
|
|
@@ -128,31 +95,26 @@ async function main() {
|
|
|
128
95
|
modifiedAt: st.mtime.toISOString()
|
|
129
96
|
};
|
|
130
97
|
inventory.push(entry);
|
|
131
|
-
prompts[rel] = {
|
|
132
|
-
...entry,
|
|
133
|
-
content
|
|
134
|
-
};
|
|
98
|
+
prompts[rel] = { ...entry, content };
|
|
135
99
|
}
|
|
136
100
|
|
|
137
|
-
const domainPromptVersions = await loadDomainPromptVersions();
|
|
138
|
-
const moduleManifests = await findManifests();
|
|
139
|
-
|
|
140
101
|
const doc = {
|
|
141
102
|
meta: {
|
|
142
103
|
generatedAt: new Date().toISOString(),
|
|
143
104
|
repositoryRoot: repoRoot,
|
|
144
105
|
condensedBy: "condense-prompts",
|
|
145
|
-
description: "Consolidated prompt templates
|
|
106
|
+
description: "Consolidated prompt templates from backend modules.",
|
|
146
107
|
promptCount: inventory.length
|
|
147
108
|
},
|
|
148
|
-
|
|
149
|
-
moduleManifests,
|
|
109
|
+
moduleManifests: await findManifests(),
|
|
150
110
|
inventory,
|
|
151
111
|
prompts
|
|
152
112
|
};
|
|
153
113
|
|
|
154
|
-
const { exportPath, modelsPath } = await writeConsolidatedArtifact("prompts", doc);
|
|
155
|
-
console.log(
|
|
114
|
+
const { exportPath, datedExportDir, modelsPath } = await writeConsolidatedArtifact("prompts", doc);
|
|
115
|
+
console.log(
|
|
116
|
+
`Consolidated ${inventory.length} prompts → ${exportPath} (${datedExportDir}/, mirror ${modelsPath})`
|
|
117
|
+
);
|
|
156
118
|
}
|
|
157
119
|
|
|
158
120
|
main().catch((err) => {
|
|
@@ -4,46 +4,58 @@ import { fileURLToPath } from "url";
|
|
|
4
4
|
import {
|
|
5
5
|
CONSOLIDATED_EXPORT_DIR,
|
|
6
6
|
CONSOLIDATED_FILENAMES,
|
|
7
|
-
writeConsolidatedExport
|
|
7
|
+
writeConsolidatedExport,
|
|
8
|
+
getConsolidatedExportStamp
|
|
8
9
|
} from "../backend/src/shared/utils/consolidatedExport.js";
|
|
9
10
|
|
|
10
11
|
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
12
|
|
|
12
|
-
export {
|
|
13
|
+
export {
|
|
14
|
+
CONSOLIDATED_EXPORT_DIR,
|
|
15
|
+
CONSOLIDATED_FILENAMES,
|
|
16
|
+
getConsolidatedExportStamp,
|
|
17
|
+
beginConsolidatedExportSession
|
|
18
|
+
} from "../backend/src/shared/utils/consolidatedExport.js";
|
|
13
19
|
|
|
14
|
-
/** Repo-relative paths: exports/ is primary; models/
|
|
20
|
+
/** Repo-relative paths: dated exports/ folder is primary audit trail; models/ is latest mirror. */
|
|
15
21
|
export const CONSOLIDATED_ARTIFACTS = {
|
|
16
22
|
models: {
|
|
17
23
|
filename: CONSOLIDATED_FILENAMES.models,
|
|
18
|
-
exportPath: `${CONSOLIDATED_EXPORT_DIR}/${CONSOLIDATED_FILENAMES.models}`,
|
|
19
24
|
modelsPath: `models/${CONSOLIDATED_FILENAMES.models}`
|
|
20
25
|
},
|
|
21
26
|
prompts: {
|
|
22
27
|
filename: CONSOLIDATED_FILENAMES.prompts,
|
|
23
|
-
exportPath: `${CONSOLIDATED_EXPORT_DIR}/${CONSOLIDATED_FILENAMES.prompts}`,
|
|
24
28
|
modelsPath: `models/${CONSOLIDATED_FILENAMES.prompts}`
|
|
25
29
|
},
|
|
26
30
|
fileStructure: {
|
|
27
31
|
filename: CONSOLIDATED_FILENAMES.fileStructure,
|
|
28
|
-
exportPath: `${CONSOLIDATED_EXPORT_DIR}/${CONSOLIDATED_FILENAMES.fileStructure}`,
|
|
29
32
|
modelsPath: `models/${CONSOLIDATED_FILENAMES.fileStructure}`
|
|
30
33
|
}
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
/**
|
|
34
|
-
* Write JSON to file-exchange/exports/
|
|
37
|
+
* Write JSON to dated file-exchange/exports/{stamp}_consolidated/ and models/ mirror.
|
|
35
38
|
* @param {"models"|"prompts"|"fileStructure"} kind
|
|
36
39
|
* @param {object} doc
|
|
37
40
|
*/
|
|
38
41
|
export async function writeConsolidatedArtifact(kind, doc) {
|
|
39
42
|
const spec = CONSOLIDATED_ARTIFACTS[kind];
|
|
40
43
|
const json = JSON.stringify(doc, null, 2);
|
|
41
|
-
|
|
44
|
+
const condensedBy = doc?.meta?.condensedBy ?? null;
|
|
45
|
+
const written = await writeConsolidatedExport(repoRoot, spec.filename, json, {
|
|
46
|
+
condensedBy
|
|
47
|
+
});
|
|
48
|
+
|
|
42
49
|
const modelsAbs = join(repoRoot, spec.modelsPath);
|
|
43
50
|
await mkdir(dirname(modelsAbs), { recursive: true });
|
|
44
51
|
await writeFile(modelsAbs, json);
|
|
52
|
+
|
|
45
53
|
return {
|
|
46
|
-
exportPath:
|
|
47
|
-
|
|
54
|
+
exportPath: written.exportPath,
|
|
55
|
+
datedExportDir: written.datedExportDir,
|
|
56
|
+
stamp: written.stamp,
|
|
57
|
+
folderName: written.folderName,
|
|
58
|
+
modelsPath: spec.modelsPath,
|
|
59
|
+
latestExportPath: `${CONSOLIDATED_EXPORT_DIR}/${spec.filename}`
|
|
48
60
|
};
|
|
49
61
|
}
|