@pukujan/create-modular-monolith 2.0.0 → 2.1.0

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.
Files changed (93) hide show
  1. package/README.md +91 -22
  2. package/index.js +47 -0
  3. package/package.json +16 -19
  4. package/template/.cursor/commands/planning-study-log.md +25 -0
  5. package/template/.cursor/commands/pre-push-dev-log.md +52 -0
  6. package/template/.cursor/rules/api-documentation.mdc +21 -0
  7. package/template/.cursor/rules/file-exchange-inbox.mdc +29 -0
  8. package/template/AGENTS.md +41 -0
  9. package/template/README.md +18 -57
  10. package/template/backend/.env.example +38 -0
  11. package/template/backend/package.json +14 -4
  12. package/template/backend/src/modules/model-condenser/README.md +7 -0
  13. package/template/backend/src/modules/model-condenser/config/index.js +20 -0
  14. package/template/backend/src/modules/model-condenser/events/index.js +1 -0
  15. package/template/backend/src/modules/model-condenser/index.js +12 -0
  16. package/template/backend/src/modules/model-condenser/routes/health.routes.js +10 -0
  17. package/template/backend/src/modules/model-condenser/routes/index.js +10 -0
  18. package/template/backend/src/modules/model-condenser/routes/modelCondenser.routes.js +44 -0
  19. package/template/backend/src/modules/model-condenser/services/health.service.js +8 -0
  20. package/template/backend/src/modules/model-condenser/services/modelCondenser.facade.js +58 -0
  21. package/template/backend/src/modules/model-condenser/services/modelCondenser.service.js +513 -0
  22. package/template/backend/src/modules/model-condenser/tests/integration/modelCondenser.routes.test.js +40 -0
  23. package/template/backend/src/modules/model-condenser/tests/unit/modelCondenser.service.test.js +31 -0
  24. package/template/backend/src/modules/model-condenser/utils/index.js +1 -0
  25. package/template/backend/src/shared/contracts/consolidatedExports.contract.js +19 -0
  26. package/template/backend/src/shared/contracts/prePushDevLog.contract.js +28 -0
  27. package/template/backend/src/shared/domain/case-filing/core-models.js +117 -0
  28. package/template/backend/src/shared/http/errors.js +8 -0
  29. package/template/backend/src/shared/utils/consolidatedExport.js +30 -0
  30. package/template/backend/src/shared/utils/formatExchangeTimestamp.js +47 -0
  31. package/template/backend/src/shared/utils/formatExchangeTimestamp.test.js +30 -0
  32. package/template/docs/API.md +42 -0
  33. package/template/docs/PUBLISHING.md +13 -1
  34. package/template/docs/README.md +4 -0
  35. package/template/docs/STARTER_PACK.md +4 -0
  36. package/template/docs/architecture/API_DOCUMENTATION_CONTRACT.md +112 -0
  37. package/template/docs/architecture/CONTRACTS_OVERVIEW.md +168 -0
  38. package/template/docs/architecture/MODULE_INTERNAL_CONTRACT.md +2 -0
  39. package/template/docs/architecture/PLATFORM_ARCHITECTURE.md +221 -0
  40. package/template/docs/architecture/REPO_ARTIFACT_LAYOUT.md +76 -0
  41. package/template/docs/architecture/contracts/apiDocumentationRegistry.contract.md +40 -0
  42. package/template/docs/architecture/contracts/changelog.jsonl +12 -0
  43. package/template/docs/architecture/contracts/consolidatedExports.contract.md +58 -0
  44. package/template/docs/architecture/contracts/fileExchange.contract.md +47 -0
  45. package/template/docs/architecture/contracts/manifest.json +56 -0
  46. package/template/docs/architecture/contracts/prePushDevLog.contract.md +69 -0
  47. package/template/docs/model-condenser/API.md +102 -0
  48. package/template/file-exchange/README.md +41 -0
  49. package/template/file-exchange/exports/.gitkeep +0 -0
  50. package/template/file-exchange/imports/.gitkeep +0 -0
  51. package/template/frontend/.env.example +2 -0
  52. package/template/frontend/package.json +1 -1
  53. package/template/frontend/src/index.css +311 -0
  54. package/template/frontend/src/modules/_reference/services/health-api.js +1 -1
  55. package/template/frontend/src/shared/api/client.js +67 -5
  56. package/template/models/.gitkeep +0 -0
  57. package/template/package.json +11 -4
  58. package/template/scripts/check-api-docs.mjs +183 -0
  59. package/template/scripts/condense-file-structure.mjs +44 -0
  60. package/template/scripts/condense-models.mjs +70 -0
  61. package/template/scripts/condense-prompts.mjs +161 -0
  62. package/template/scripts/consolidated-output.mjs +49 -0
  63. package/template/scripts/export-consolidated-models.mjs +11 -0
  64. package/template/scripts/git-hooks/pre-push.sample +15 -0
  65. package/template/scripts/import-to-file-exchange.mjs +43 -0
  66. package/template/scripts/lib/api-inventory.mjs +189 -0
  67. package/template/scripts/lib/dev-log-human-format.mjs +360 -0
  68. package/template/scripts/lib/git-snapshot.mjs +46 -0
  69. package/template/scripts/lib/module-scaffold.mjs +37 -1
  70. package/template/scripts/lib/repo-tree.mjs +127 -0
  71. package/template/scripts/lib/run-tests.mjs +60 -0
  72. package/template/scripts/lint-contracts.mjs +57 -0
  73. package/template/scripts/lint-repo-artifacts.mjs +37 -0
  74. package/template/scripts/new-module.mjs +7 -0
  75. package/template/scripts/resolve-import-stamp.mjs +50 -0
  76. package/template/scripts/verify-dev-log.mjs +50 -0
  77. package/template/scripts/write-pre-push-dev-log.mjs +220 -0
  78. package/template/work-log/INDEX.md +3 -0
  79. package/template/work-log/README.md +40 -0
  80. package/template/work-log/dev-logs/README.md +97 -0
  81. package/template/work-log/dev-logs/schemas/dev-log-agent.v1.schema.json +119 -0
  82. package/template/work-log/dev-logs/templates/dev-log-human.template.md +10 -0
  83. package/template/work-log/handoffs/README.md +36 -0
  84. package/template/work-log/study-docs/README.md +13 -0
  85. package/bin/create-modular-monolith.js +0 -132
  86. package/template/backend/package-lock.json +0 -882
  87. package/template/backend/src/modules/_reference/evals/README.md +0 -6
  88. package/template/backend/src/modules/_reference/evals/datasets/example.cases.json +0 -12
  89. package/template/backend/src/modules/_reference/evals/runners/example.eval.mjs +0 -25
  90. package/template/frontend/package-lock.json +0 -1724
  91. package/template/scripts/run-module-evals.mjs +0 -43
  92. package/template/scripts/sync-cli-template.mjs +0 -44
  93. /package/template/{frontend/src/modules → backend/db/migrations}/.gitkeep +0 -0
@@ -0,0 +1,119 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://legal-prmpt-eng.local/schemas/dev-log-agent.v1.json",
4
+ "title": "Agent audit dev log",
5
+ "description": "Machine-readable pre-push audit log for Cursor agents. Pair with human dev-log in work-log/dev-logs/human/.",
6
+ "type": "object",
7
+ "required": ["meta", "summary", "apis", "git", "tests", "repositoryTree", "changes", "decisions", "iterations", "tradeoffs", "improvements", "regressions", "risks", "followUps"],
8
+ "properties": {
9
+ "meta": {
10
+ "type": "object",
11
+ "required": ["schemaVersion", "entryId", "slug", "generatedAt", "humanLogPath", "audience"],
12
+ "properties": {
13
+ "schemaVersion": { "const": "1.0.0" },
14
+ "entryId": { "type": "string", "pattern": "^[0-9]{3}$" },
15
+ "slug": { "type": "string" },
16
+ "generatedAt": { "type": "string", "format": "date-time" },
17
+ "humanLogPath": { "type": "string" },
18
+ "audience": { "const": "agent" },
19
+ "filledBy": { "type": "string", "enum": ["script", "agent", "human"] },
20
+ "handoffRefs": { "type": "array", "items": { "type": "string" } }
21
+ }
22
+ },
23
+ "summary": { "type": "string" },
24
+ "apis": {
25
+ "type": "object",
26
+ "description": "HTTP routes, versioned contracts, deprecated surfaces",
27
+ "properties": {
28
+ "capturedAt": { "type": "string" },
29
+ "sourceDocs": { "type": "array", "items": { "type": "string" } },
30
+ "http": {
31
+ "type": "object",
32
+ "properties": {
33
+ "active": { "type": "array" },
34
+ "stub": { "type": "array" },
35
+ "deprecated": { "type": "array" }
36
+ }
37
+ },
38
+ "moduleStatus": { "type": "array" },
39
+ "versioned": { "type": "object" },
40
+ "deprecated": { "type": "object" },
41
+ "cli": { "type": "array" }
42
+ }
43
+ },
44
+ "git": {
45
+ "type": "object",
46
+ "properties": {
47
+ "branch": { "type": "string" },
48
+ "sha": { "type": "string" },
49
+ "shortSha": { "type": "string" },
50
+ "changedFiles": { "type": "array" },
51
+ "diffStatAgainstHead": { "type": "string" },
52
+ "recentCommits": { "type": "array", "items": { "type": "string" } }
53
+ }
54
+ },
55
+ "tests": {
56
+ "type": "object",
57
+ "properties": {
58
+ "ran": { "type": "boolean" },
59
+ "exitCode": { "type": ["integer", "null"] },
60
+ "summary": { "type": "string" },
61
+ "passed": { "type": "array", "items": { "type": "string" } },
62
+ "failed": { "type": "array", "items": { "type": "string" } },
63
+ "commands": { "type": "array", "items": { "type": "string" } }
64
+ }
65
+ },
66
+ "repositoryTree": {
67
+ "type": "object",
68
+ "properties": {
69
+ "capturedAt": { "type": "string" },
70
+ "excludeDirs": { "type": "array", "items": { "type": "string" } },
71
+ "treeIgnoreFlag": { "type": "string" },
72
+ "stats": { "type": "object" },
73
+ "treeText": { "type": "string" },
74
+ "flatPathCount": { "type": "integer" }
75
+ }
76
+ },
77
+ "changes": {
78
+ "type": "object",
79
+ "properties": {
80
+ "byArea": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } } },
81
+ "added": { "type": "array", "items": { "type": "string" } },
82
+ "modified": { "type": "array", "items": { "type": "string" } },
83
+ "deleted": { "type": "array", "items": { "type": "string" } },
84
+ "narrative": { "type": "array", "items": { "type": "string" } }
85
+ }
86
+ },
87
+ "decisions": {
88
+ "type": "array",
89
+ "items": {
90
+ "type": "object",
91
+ "required": ["id", "decision", "rationale"],
92
+ "properties": {
93
+ "id": { "type": "string" },
94
+ "decision": { "type": "string" },
95
+ "rationale": { "type": "string" },
96
+ "alternativesRejected": { "type": "array", "items": { "type": "string" } },
97
+ "tradeoff": { "type": "string" }
98
+ }
99
+ }
100
+ },
101
+ "iterations": {
102
+ "type": "array",
103
+ "items": {
104
+ "type": "object",
105
+ "properties": {
106
+ "attempt": { "type": "integer" },
107
+ "action": { "type": "string" },
108
+ "outcome": { "type": "string" },
109
+ "blockedBy": { "type": "string" }
110
+ }
111
+ }
112
+ },
113
+ "tradeoffs": { "type": "array", "items": { "type": "string" } },
114
+ "improvements": { "type": "array", "items": { "type": "string" } },
115
+ "regressions": { "type": "array", "items": { "type": "string" } },
116
+ "risks": { "type": "array", "items": { "type": "string" } },
117
+ "followUps": { "type": "array", "items": { "type": "string" } }
118
+ }
119
+ }
@@ -0,0 +1,10 @@
1
+ # Dev log (human) — two-part layout
2
+
3
+ Generated by `npm run dev-log:pre-push`. Do not edit this file directly.
4
+
5
+ The generator builds:
6
+
7
+ 1. **Part I — Summary** (top): TOC, mermaid diagrams, audit tables (API, versions/prompts, tests, git, condensed tree).
8
+ 2. **Part II — Detailed** (bottom): decisions, iterations, full API registry, full git snapshot, full tree.
9
+
10
+ See `scripts/lib/dev-log-human-format.mjs`.
@@ -0,0 +1,36 @@
1
+ # Handoffs
2
+
3
+ Implementation specs and starter packs. Parent folder: [work-log](../README.md).
4
+
5
+ Study logs and planning notes live in **[../study-docs/](../study-docs/)** — not here.
6
+
7
+ ## Layout
8
+
9
+ ```text
10
+ work-log/handoffs/
11
+ 001_*_starter_*/ ← starter pack (folder)
12
+ 002_*_handoff_*.md
13
+ 005_*_handoff_*.md ← original, v2, v3
14
+ ```
15
+
16
+ Full index: [../INDEX.md](../INDEX.md).
17
+
18
+ ## Filename convention
19
+
20
+ ```text
21
+ {NNN}_{YYYY-MM-DD}_{HH-MM}_{kind}_{short-slug}.md
22
+ ```
23
+
24
+ | Part | Example |
25
+ |------|---------|
26
+ | Date | `2026-05-23` |
27
+ | Time | `10-49` (24h, optional) |
28
+ | Kind | `handoff`, `handoff-v2`, `handoff-v3`, `handoff-original` |
29
+
30
+ Same pattern in [study-docs](../study-docs/README.md) (`study-log`) and [dev-logs](../dev-logs/README.md) (`dev-log`).
31
+
32
+ ## 005 execution order
33
+
34
+ 1. [Original](./005_2026-05-23_10-49_handoff-original_parsed-cache-rule-authority.md) — requirements
35
+ 2. [v3](./005_2026-05-23_11-20_handoff-v3_filing-structure-architecture.md) — architecture first
36
+ 3. [v2](./005_2026-05-23_11-14_handoff-v2_planned-review-in-cursor.md) — pipeline implementation
@@ -0,0 +1,13 @@
1
+ # Study docs
2
+
3
+ Design rationale, planning conversations, and portfolio study logs. Parent: [work-log](../README.md).
4
+
5
+ Implementation specs are in **[../handoffs/](../handoffs/)**.
6
+
7
+ ## Filename convention
8
+
9
+ Same as [handoffs](../handoffs/README.md) and [dev-logs](../dev-logs/README.md):
10
+
11
+ `{NNN}_{YYYY-MM-DD}_{HH-MM}_study-log_{slug}.md`
12
+
13
+ Full index: [../INDEX.md](../INDEX.md).
@@ -1,132 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- cpSync,
4
- existsSync,
5
- mkdirSync,
6
- readFileSync,
7
- readdirSync,
8
- writeFileSync
9
- } from "fs";
10
- import { join, resolve, basename } from "path";
11
- import { fileURLToPath } from "url";
12
- import { spawnSync } from "child_process";
13
-
14
- const __dirname = fileURLToPath(new URL(".", import.meta.url));
15
- const templateDir = join(__dirname, "..", "template");
16
-
17
- const args = process.argv.slice(2).filter((a) => a !== "--");
18
- const installDeps = args.includes("--install");
19
- const initGit = args.includes("--git");
20
- const positional = args.filter((a) => !a.startsWith("--"));
21
-
22
- const targetArg = positional[0];
23
- const cwd = process.cwd();
24
- const targetDir = targetArg ? resolve(cwd, targetArg) : resolve(cwd, "my-platform");
25
- const projectName = basename(targetDir);
26
-
27
- if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(projectName)) {
28
- console.error(
29
- "Project folder name must be kebab-case (example: my-platform).\n",
30
- "Usage: npm create @pukujan/modular-monolith@2 my-platform"
31
- );
32
- process.exit(1);
33
- }
34
-
35
- if (!existsSync(templateDir)) {
36
- console.error("Template missing. Reinstall @pukujan/create-modular-monolith.");
37
- process.exit(1);
38
- }
39
-
40
- if (existsSync(targetDir)) {
41
- try {
42
- const entries = readdirSync(targetDir);
43
- if (entries.length > 0) {
44
- console.error(`Target directory is not empty: ${targetDir}`);
45
- process.exit(1);
46
- }
47
- } catch {
48
- console.error(`Cannot use target: ${targetDir}`);
49
- process.exit(1);
50
- }
51
- }
52
-
53
- const displayName = toTitleCase(projectName);
54
-
55
- console.log(`\nCreating modular monolith starter: ${projectName}`);
56
- console.log(` → ${targetDir}\n`);
57
-
58
- mkdirSync(targetDir, { recursive: true });
59
- cpSync(templateDir, targetDir, { recursive: true });
60
-
61
- replaceInTree(targetDir, [
62
- ["modular-monolith-starter-backend", `${projectName}-backend`],
63
- ["modular-monolith-starter-frontend", `${projectName}-frontend`],
64
- ["modular-monolith-starter", projectName],
65
- ["Modular Monolith Platform Starter", displayName]
66
- ]);
67
-
68
- if (installDeps) {
69
- console.log("Installing dependencies…");
70
- run("npm", ["install"], join(targetDir, "backend"));
71
- run("npm", ["install"], join(targetDir, "frontend"));
72
- }
73
-
74
- if (initGit) {
75
- run("git", ["init"], targetDir);
76
- run("git", ["add", "."], targetDir);
77
- run("git", ["commit", "-m", "chore: scaffold modular monolith starter"], targetDir);
78
- }
79
-
80
- console.log("\nDone.\n");
81
- console.log("Next steps:");
82
- console.log(` cd ${targetArg || projectName}`);
83
- if (!installDeps) {
84
- console.log(" cd backend && npm install");
85
- console.log(" cd ../frontend && npm install");
86
- }
87
- console.log(" npm run dev:backend # terminal 1");
88
- console.log(" npm run dev:frontend # terminal 2");
89
- console.log(` npm run new:module -- my-feature --label "My Feature"`);
90
- console.log(" npm run lint:architecture && npm test\n");
91
-
92
- function replaceInTree(dir, pairs) {
93
- for (const file of walkFiles(dir)) {
94
- if (!/\.(json|md|js|jsx|mjs|html)$/.test(file)) continue;
95
- let content = readFileSync(file, "utf8");
96
- let changed = false;
97
- for (const [from, to] of pairs) {
98
- if (content.includes(from)) {
99
- content = content.split(from).join(to);
100
- changed = true;
101
- }
102
- }
103
- if (changed) writeFileSync(file, content, "utf8");
104
- }
105
- }
106
-
107
- function walkFiles(dir, acc = []) {
108
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
109
- const full = join(dir, entry.name);
110
- if (entry.isDirectory()) {
111
- if (entry.name === "node_modules") continue;
112
- walkFiles(full, acc);
113
- } else {
114
- acc.push(full);
115
- }
116
- }
117
- return acc;
118
- }
119
-
120
- function toTitleCase(value) {
121
- return value
122
- .split("-")
123
- .map((p) => p.charAt(0).toUpperCase() + p.slice(1))
124
- .join(" ");
125
- }
126
-
127
- function run(cmd, cmdArgs, dir) {
128
- const result = spawnSync(cmd, cmdArgs, { cwd: dir, stdio: "inherit" });
129
- if (result.status !== 0) {
130
- console.warn(`Warning: ${cmd} ${cmdArgs.join(" ")} exited with ${result.status}`);
131
- }
132
- }