@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.
- package/LICENSE +50 -0
- package/README.md +146 -61
- package/package.json +3 -2
- package/template/.github/workflows/ci.yml +44 -0
- package/template/LICENSE +11 -0
- package/template/NOTICE +13 -0
- package/template/README.md +98 -18
- package/template/backend/package-lock.json +1976 -0
- package/template/backend/scripts/check-module-boundaries.mjs +3 -0
- package/template/backend/src/modules/model-condenser/tests/unit/modelCondenser.service.test.js +2 -2
- package/template/backend/src/shared/utils/traceId.js +19 -0
- package/template/docs/README.md +3 -1
- package/template/docs/architecture/CONTRACTS_OVERVIEW.md +12 -0
- package/template/docs/architecture/EVAL_AND_CI.md +79 -0
- package/template/docs/architecture/REPO_ARTIFACT_LAYOUT.md +12 -55
- package/template/docs/architecture/contracts/manifest.json +0 -17
- package/template/file-exchange/README.md +1 -1
- package/template/file-exchange/exports/consolidated-models.json +625 -0
- package/template/frontend/package-lock.json +1727 -0
- package/template/package.json +2 -0
- package/template/scripts/condense-prompts.mjs +10 -10
- package/template/scripts/lib/api-inventory.mjs +14 -21
- package/template/scripts/run-module-evals.mjs +43 -0
|
@@ -22,6 +22,9 @@ for (const app of apps) {
|
|
|
22
22
|
.map((d) => d.name);
|
|
23
23
|
|
|
24
24
|
for (const moduleName of moduleNames) {
|
|
25
|
+
// model-condenser embeds repo path strings in schema inventory metadata only (no imports).
|
|
26
|
+
if (moduleName === "model-condenser") continue;
|
|
27
|
+
|
|
25
28
|
const moduleRoot = join(modulesDir, moduleName);
|
|
26
29
|
const files = walk(moduleRoot).filter((f) =>
|
|
27
30
|
[".js", ".mjs", ".jsx"].some((ext) => f.endsWith(ext))
|
package/template/backend/src/modules/model-condenser/tests/unit/modelCondenser.service.test.js
CHANGED
|
@@ -18,8 +18,8 @@ test("condenseModels writes consolidated-models.json", async () => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
assert.equal(result.status, "condensed");
|
|
21
|
-
assert.ok(result.modelCount >=
|
|
22
|
-
assert.ok(result.exampleInstanceCount >=
|
|
21
|
+
assert.ok(result.modelCount >= 8);
|
|
22
|
+
assert.ok(result.exampleInstanceCount >= 2);
|
|
23
23
|
|
|
24
24
|
const raw = await readFile(join(modelsDir, "consolidated-models.json"), "utf8");
|
|
25
25
|
const parsed = JSON.parse(raw);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} [prefix]
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
export function createTraceId(prefix = "trace") {
|
|
8
|
+
const short = randomUUID().replace(/-/g, "").slice(0, 12);
|
|
9
|
+
return `${prefix}_${short}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} batchTraceId
|
|
14
|
+
* @param {number} docIndex
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
export function docTraceId(batchTraceId, docIndex) {
|
|
18
|
+
return `${batchTraceId}_doc${String(docIndex).padStart(3, "0")}`;
|
|
19
|
+
}
|
package/template/docs/README.md
CHANGED
|
@@ -11,7 +11,9 @@ This folder describes the **modular monolith platform starter** and how **archit
|
|
|
11
11
|
| [Starter pack](./STARTER_PACK.md) | What ships in the repo, how to run it, and how to add modules |
|
|
12
12
|
| [Architecture guardrails](./architecture/ARCHITECTURE_GUARDRAILS.md) | Module contracts, boundaries, naming, and how enforcement works |
|
|
13
13
|
| [Module internal contract](./architecture/MODULE_INTERNAL_CONTRACT.md) | MVC layers, prompts, evals, tests inside each feature module |
|
|
14
|
+
| [Evals, regression, and CI gates](./architecture/EVAL_AND_CI.md) | `test:ci`, GitHub Actions, optional per-case golden |
|
|
15
|
+
| [Evals, regression, and CI gates](./architecture/EVAL_AND_CI.md) | Golden evals, `test:evals`, GitHub Actions gates |
|
|
14
16
|
| [Publishing the CLI](./PUBLISHING.md) | Release `@pukujan/create-modular-monolith` to npm |
|
|
15
17
|
| [Case Filing AI starter](./case-filing-ai/README.md) | Domain blueprint, module split, pipeline, guardrails, and DB schema |
|
|
16
18
|
|
|
17
|
-
Canonical repository: [https://github.com/Pukujan/litigation-
|
|
19
|
+
Canonical repository: [https://github.com/Pukujan/litigation-prompt-engineering](https://github.com/Pukujan/litigation-prompt-engineering)
|
|
@@ -158,6 +158,18 @@ HTTP entrypoint: `POST /api/case-filing-ai/process-batch` ([API.md](../API.md)).
|
|
|
158
158
|
|
|
159
159
|
---
|
|
160
160
|
|
|
161
|
+
## Exporting architecture to the npm starter
|
|
162
|
+
|
|
163
|
+
To refresh the **boilerplate CLI template** without domain modules:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npm run export:architecture-starter -- --to packages/create-modular-monolith/template
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Output defaults to `export/architecture-starter/`. See `EXPORT_MANIFEST.json` and [PUBLISHING.md](../PUBLISHING.md).
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
161
173
|
## Adding a new contract
|
|
162
174
|
|
|
163
175
|
1. Add `docs/architecture/contracts/<name>.contract.md`
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Evals, regression, and CI gates
|
|
2
|
+
|
|
3
|
+
Plain-language guide for **domain-agnostic** projects scaffolded from this template.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What is a “gate”?
|
|
8
|
+
|
|
9
|
+
A **gate** is an automatic check that must pass before code is merged.
|
|
10
|
+
|
|
11
|
+
| Gate | What it blocks |
|
|
12
|
+
|------|----------------|
|
|
13
|
+
| `npm run lint:contracts` | Broken contract paths in `manifest.json` |
|
|
14
|
+
| `npm run lint:repo-artifacts` | Missing platform folders (file-exchange, dev-logs, …) |
|
|
15
|
+
| `npm run lint:architecture` | Module boundary / layer / API doc violations |
|
|
16
|
+
| `npm test` | Unit/integration failures |
|
|
17
|
+
| `npm run test:evals` | Module `evals/runners/*.eval.mjs` failures |
|
|
18
|
+
|
|
19
|
+
GitHub Actions runs these on push/PR (see `.github/workflows/ci.yml`). Locally: **`npm run test:ci`**.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What is “eval / regression”?
|
|
24
|
+
|
|
25
|
+
**Eval** = automated check that output meets expectations.
|
|
26
|
+
|
|
27
|
+
**Regression** = re-run evals after a change to catch quality going **down**.
|
|
28
|
+
|
|
29
|
+
### Golden data is per domain case — not universal
|
|
30
|
+
|
|
31
|
+
Every product case is different (different users, documents, rules). You **do not** ship one golden dataset for all future cases.
|
|
32
|
+
|
|
33
|
+
| Pattern | When to use |
|
|
34
|
+
|---------|-------------|
|
|
35
|
+
| **Module example evals** | Shipped in `_reference` — smoke tests, no API keys |
|
|
36
|
+
| **Optional `evals/golden/{caseId}/`** | When **you** curate expected JSON for one fixed regression case |
|
|
37
|
+
| **Live runs only** | New cases with no golden yet — process, review, optionally add golden later |
|
|
38
|
+
|
|
39
|
+
Golden answers the question: *“On **this** known fixture, did we get worse than last time?”*
|
|
40
|
+
Not: *“We already know the truth for every new case.”*
|
|
41
|
+
|
|
42
|
+
When you add a domain module (`npm run new:module`), add `evals/runners/` and optional `evals/golden/` for cases you control.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Trace IDs (observability)
|
|
47
|
+
|
|
48
|
+
Use `backend/src/shared/utils/traceId.js` in long-running workflows:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import { createTraceId, docTraceId } from "../shared/utils/traceId.js";
|
|
52
|
+
|
|
53
|
+
const batchTraceId = createTraceId("batch_my-job");
|
|
54
|
+
const traceId = docTraceId(batchTraceId, 1);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Log both IDs in JSONL or structured logs so agents and humans can correlate steps. Plug the same IDs into Langfuse/OpenTelemetry later if needed.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## CI workflow
|
|
62
|
+
|
|
63
|
+
`.github/workflows/ci.yml`:
|
|
64
|
+
|
|
65
|
+
1. Install backend + frontend
|
|
66
|
+
2. `lint:contracts` · `lint:repo-artifacts` · `lint:architecture`
|
|
67
|
+
3. `npm test` · `npm run test:evals`
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Adding domain evals
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm run new:module -- billing --label "Billing"
|
|
75
|
+
# Add backend/src/modules/billing/evals/runners/my-check.eval.mjs
|
|
76
|
+
npm run test:evals -- billing
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
See [MODULE_INTERNAL_CONTRACT.md](./MODULE_INTERNAL_CONTRACT.md) for colocated `prompts/` and `evals/`.
|
|
@@ -1,40 +1,17 @@
|
|
|
1
1
|
# Repository artifact layout
|
|
2
2
|
|
|
3
|
-
Canonical paths for
|
|
3
|
+
Canonical paths for platform artifacts and human↔agent exchange.
|
|
4
4
|
|
|
5
5
|
## Roots
|
|
6
6
|
|
|
7
|
-
| Root |
|
|
8
|
-
|
|
9
|
-
| `
|
|
10
|
-
| `
|
|
11
|
-
| `
|
|
12
|
-
| `
|
|
13
|
-
| `
|
|
14
|
-
| `
|
|
15
|
-
| `work-log/dev-logs/human\|agent/` | — | Yes (pre-push audit) |
|
|
16
|
-
| `models/consolidated-*.json` | — | Yes (condenser mirror) |
|
|
17
|
-
| `work-log/` | — | Yes (docs only) |
|
|
18
|
-
|
|
19
|
-
## Batch folder (`batches/batch-NNN/`)
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
uploads/
|
|
23
|
-
parsed-documents/doc-NNN/ # v2+ parsed cache
|
|
24
|
-
outputs/doc-NNN.json
|
|
25
|
-
evals/doc_NNN.eval-report.json
|
|
26
|
-
rule/
|
|
27
|
-
case-snapshot.json
|
|
28
|
-
processing-log.jsonl
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Golden (`evals/golden/case_001/`)
|
|
32
|
-
|
|
33
|
-
```text
|
|
34
|
-
case_001.golden-dataset.json
|
|
35
|
-
doc_NNN.expected.json
|
|
36
|
-
parsed/doc-NNN/ # optional parse golden (v2)
|
|
37
|
-
```
|
|
7
|
+
| Root | Writable at runtime | Purpose |
|
|
8
|
+
|------|---------------------|---------|
|
|
9
|
+
| `file-exchange/imports\|exports/` | Yes | Dated human↔agent handoff |
|
|
10
|
+
| `work-log/dev-logs/human\|agent/` | Yes | Pre-push audit pairs |
|
|
11
|
+
| `models/consolidated-*.json` | Yes | Mirror of `file-exchange/exports/consolidated-*.json` |
|
|
12
|
+
| `work-log/handoffs/` | Yes | Session handoffs (markdown) |
|
|
13
|
+
| `data/` | Yes | **Your** domain runtime data (gitignore by default) |
|
|
14
|
+
| `evals/golden/{caseId}/` | Optional | Per-case regression fixtures when you add them |
|
|
38
15
|
|
|
39
16
|
## File exchange
|
|
40
17
|
|
|
@@ -42,7 +19,7 @@ Imports: `file-exchange/imports/{2026-05-23_15-59-43Z}/`
|
|
|
42
19
|
Session exports: `file-exchange/exports/{stamp}/`
|
|
43
20
|
Consolidated snapshots: `file-exchange/exports/consolidated-*.json`
|
|
44
21
|
|
|
45
|
-
See [file-exchange/README.md](../../file-exchange/README.md)
|
|
22
|
+
See [file-exchange/README.md](../../file-exchange/README.md).
|
|
46
23
|
|
|
47
24
|
## Pre-push dev logs
|
|
48
25
|
|
|
@@ -51,26 +28,6 @@ work-log/dev-logs/human/{NNN}_{date}_{time}_dev-log_{slug}.md
|
|
|
51
28
|
work-log/dev-logs/agent/{NNN}_{date}_{time}_dev-log-agent_{slug}.json
|
|
52
29
|
```
|
|
53
30
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
## Consolidated exports
|
|
57
|
-
|
|
58
|
-
`npm run condense:all` → [contracts/consolidatedExports.contract.md](./contracts/consolidatedExports.contract.md).
|
|
59
|
-
|
|
60
|
-
## Contracts
|
|
61
|
-
|
|
62
|
-
**Overview (start here):** [CONTRACTS_OVERVIEW.md](./CONTRACTS_OVERVIEW.md)
|
|
63
|
-
Manifest: [contracts/manifest.json](./contracts/manifest.json) · Changelog: [contracts/changelog.jsonl](./contracts/changelog.jsonl)
|
|
64
|
-
|
|
65
|
-
| Contract | Doc |
|
|
66
|
-
|----------|-----|
|
|
67
|
-
| File exchange | [fileExchange.contract.md](./contracts/fileExchange.contract.md) |
|
|
68
|
-
| Consolidated exports | [consolidatedExports.contract.md](./contracts/consolidatedExports.contract.md) |
|
|
69
|
-
| Pre-push dev log | [prePushDevLog.contract.md](./contracts/prePushDevLog.contract.md) |
|
|
70
|
-
| API registry | [apiDocumentationRegistry.contract.md](./contracts/apiDocumentationRegistry.contract.md) |
|
|
71
|
-
| Case filing storage | `backend/src/modules/case-filing-ai/contracts/storageLayout.contract.js` |
|
|
72
|
-
| Parsed artifacts | `parsedDocumentArtifacts.contract.js` |
|
|
73
|
-
| Pipeline versions | `pipelineVersions.js` |
|
|
74
|
-
| Rule authority | `court-rules/contracts/ruleAuthority.contract.js` |
|
|
31
|
+
## Domain modules
|
|
75
32
|
|
|
76
|
-
|
|
33
|
+
When you add features with `npm run new:module`, colocate runtime data under `data/<module>/` and optional `evals/golden/` per [EVAL_AND_CI.md](./EVAL_AND_CI.md).
|
|
@@ -35,22 +35,5 @@
|
|
|
35
35
|
"registry": "docs/API.md",
|
|
36
36
|
"lintScript": "scripts/check-api-docs.mjs",
|
|
37
37
|
"architectureDoc": "docs/architecture/API_DOCUMENTATION_CONTRACT.md"
|
|
38
|
-
},
|
|
39
|
-
"caseFilingStorageLayout": {
|
|
40
|
-
"version": "v001",
|
|
41
|
-
"file": "backend/src/modules/case-filing-ai/contracts/storageLayout.contract.js"
|
|
42
|
-
},
|
|
43
|
-
"parsedDocumentArtifacts": {
|
|
44
|
-
"version": "v001",
|
|
45
|
-
"file": "backend/src/modules/case-filing-ai/contracts/parsedDocumentArtifacts.contract.js"
|
|
46
|
-
},
|
|
47
|
-
"pipelineVersions": {
|
|
48
|
-
"version": "v001",
|
|
49
|
-
"file": "backend/src/modules/case-filing-ai/contracts/pipelineVersions.js",
|
|
50
|
-
"promptVersions": "backend/src/modules/case-filing-ai/prompts/promptVersions.js"
|
|
51
|
-
},
|
|
52
|
-
"ruleAuthority": {
|
|
53
|
-
"version": "v001",
|
|
54
|
-
"file": "backend/src/modules/court-rules/contracts/ruleAuthority.contract.js"
|
|
55
38
|
}
|
|
56
39
|
}
|
|
@@ -32,7 +32,7 @@ npm run condense:all
|
|
|
32
32
|
## Workflow
|
|
33
33
|
|
|
34
34
|
1. Triage loose files into `imports/{stamp}/` (`npm run import:file-exchange -- <path>`).
|
|
35
|
-
2. Process via
|
|
35
|
+
2. Process via your domain module APIs using files **under that stamp** only.
|
|
36
36
|
3. Copy batch bundles / reports to `exports/{stamp}/` when done.
|
|
37
37
|
4. Refresh consolidated snapshots: `npm run condense:all`.
|
|
38
38
|
|