@dforge-core/dforge-mcp 0.2.4 → 0.2.14

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/CHANGELOG.md CHANGED
@@ -4,6 +4,189 @@ All notable changes to `@dforge-core/dforge-mcp`. This project uses semver-ish
4
4
  `0.1.0-rc.N` pre-release tags; the published version is set at publish time via
5
5
  the release workflow, so committed `package.json` versions are placeholders.
6
6
 
7
+ ## 0.2.6
8
+
9
+ Record reports — a report attached to an entity so it opens **from a record**, with the
10
+ record's values feeding its parameters — plus a report-level home for report parameters,
11
+ and the removal of two parameter spellings the installer never read.
12
+
13
+ Requires `@dforge-core/metadata` ≥ 0.0.15 (bumped): the vendored
14
+ `resources/schemas/reports.schema.json` served as `dforge://schema/reports` comes from
15
+ there.
16
+
17
+ ### Added — record-report attachments
18
+
19
+ A report in `ui/reports.json` gains an `entities` array. Each entry attaches the report to
20
+ one entity, mapping report parameters to source columns on it:
21
+
22
+ ```jsonc
23
+ "credit_check": {
24
+ "entities": [
25
+ { "entityCd": "parties.party", "params": { "customer_id": "party_id" }, "orderNum": 45 },
26
+ { "entityCd": "crm.quote", "params": { "customer_id": "customer_id" }, "orderNum": 45 }
27
+ ]
28
+ }
29
+ ```
30
+
31
+ The report then appears on that record's toolbar and opens on a record-scoped route with
32
+ the mapped params resolved server-side and hidden. `dforge_report_add` accepts and
33
+ documents the block; `references/reports.md` gains a **Record reports** section with the
34
+ rules (source-column allowlist, type compatibility, one attachment per (entity, report)
35
+ pair, the `"metadata": ">=1.5.0"` gate, and the cross-module dependency bound).
36
+
37
+ Note the two different `params` keys, which the tool description now calls out: on an
38
+ attachment it is the *mapping* (param code → column); on the report or a dataset it is the
39
+ *declaration*.
40
+
41
+ ### Added — `dforge_module_validate` checks reports
42
+
43
+ Mirrors the server's new pack-time `ReportAttachmentValidator`, so these fail offline
44
+ instead of at install against a live tenant:
45
+
46
+ - a mapped param code neither the report-level `parameters` block nor any dataset declares;
47
+ - a source column the entity doesn't have, or one that's a set / formula / free-text column;
48
+ - two attachments to the same entity in one report (the second overwrites the first);
49
+ - an attachment to a cross-module entity whose module isn't a declared dependency;
50
+ - `isRequired`, a top-level `link`, or `fieldTypeCd` + `domain` together on a param;
51
+ - a warning when a module ships attachments with no `metadata` dependency.
52
+
53
+ ### Added — report-level `parameters`
54
+
55
+ Report parameters are **report-scoped**: the declaration is stored once per report
56
+ (`report.param_set_id` → `param_set`), the authoring API is `report.params.save`, and
57
+ `report.get` flattens per-dataset defaults report-wide before use. The installer had only
58
+ ever read the per-dataset shorthand, so a report-level block was silently dropped and the
59
+ report installed with no parameters at all — which is what made
60
+ `crm-fin.customer_statement` and `wms-fin.vendor_statement` ship parameterless.
61
+
62
+ Both declaration sites are now legal and mean the same thing; the installer merges them,
63
+ **report level winning** on a code collision:
64
+
65
+ ```jsonc
66
+ "customer_statement": {
67
+ "parameters": {
68
+ "customer_id": { "label": "Customer", "fieldTypeCd": "lookup",
69
+ "params": { "link": { "entity": "parties.party" } }, "required": true }
70
+ },
71
+ "datasets": { "statement_invoices": { }, "statement_payments": { } }
72
+ }
73
+ ```
74
+
75
+ Declare at report level when several datasets use the parameter — `customer_statement` is
76
+ exactly that case, and there is no meaningful dataset to attribute it to.
77
+ `datasets.<cd>.params` stays the right shorthand for a single-dataset parameter, and every
78
+ module written before this keeps working.
79
+
80
+ `dforge_module_validate` merges both sites when resolving a record-report mapping, so a
81
+ mapping onto a report-level parameter resolves exactly as install will resolve it.
82
+
83
+ ### Fixed — two report-param spellings that are silently ignored
84
+
85
+ Unlike `parameters`, these are simply misspellings of keys that already exist, so they are
86
+ gone from the schema rather than implemented — and the validator flags them at either
87
+ declaration site:
88
+
89
+ - **`isRequired`** — the key is `required`; the parameter installed as optional.
90
+ - **top-level `link`** on a lookup parameter — it belongs under `params`; the parameter
91
+ installed with no autocomplete.
92
+
93
+ `references/reports.md` also corrects the rights-key example from `report.<code>` to the
94
+ colon form `report:<code>`, and the lookup parameter config from `params.entityCd` to
95
+ `params.link.entity`.
96
+
97
+ ### Changed — steer calculation toward reports, not the DSL
98
+
99
+ `action-dsl.md`'s *When an action is the wrong tool* now names the record report as the
100
+ direct replacement for a `check_…` action — same toolbar entry point, but the user sees
101
+ the open invoices and the ageing rather than just "FAILED" — and adds the general rule:
102
+ **do not compute in the DSL what a report dataset already aggregates.** Sums, ratios,
103
+ ageing buckets and exposure get formatting, drill-through, row caps and live re-reads for
104
+ free from a report; DSL arithmetic over `select()` reproduces that badly, once, somewhere
105
+ nothing else can reuse. Write DSL when the number must be *written down* or must *stop*
106
+ something. The same steer is in `dsl-reference.md`, Phase 2a and Phase 3c of the
107
+ `dforge-module-build` skill, and the validation checklist.
108
+
109
+ ## 0.2.5
110
+
111
+ Catches up with the platform's parameter-options work (dForge-core 1.20.0). A dropdown
112
+ parameter can now carry real labels, and — better — borrow the shared list its target
113
+ column already uses. Both were undocumented here, and one reference actively said the
114
+ first was impossible.
115
+
116
+ ### Changed — `translations.md` said param option labels didn't exist
117
+
118
+ The section table listed `actions` / `reports` params as translating `{ label }` and
119
+ nothing else, which was accurate when written: parameters had no schema location for a
120
+ per-choice label at all. An author who followed it concluded — correctly, at the time —
121
+ that a dropdown param showing `bank_transfer` instead of "Bank transfer" was unfixable.
122
+ The platform added the slot, so the table now shows
123
+ `params: { param_cd: { label, options: { value: … } } }` for both sections, and a new
124
+ **"Action / report PARAM option labels ARE translatable"** section documents the
125
+ value-keyed, partial-override shape (identical to field options) plus the two things that
126
+ trip authors up: base labels must exist in the DSL first, and a domain-backed param
127
+ shouldn't be translated here at all.
128
+
129
+ ### Added — `domain <domainCd>` param form
130
+
131
+ `action-dsl.md` and `dsl-reference.md` gain the parameter form that borrows a column
132
+ domain:
133
+
134
+ ```
135
+ params:
136
+ payment_method: domain payment_method required "Payment method for this batch"
137
+ status: domain fin.doc_status optional "Status"
138
+ ```
139
+
140
+ Both now lead with it and frame inline `options=` as the narrow case. The reason is
141
+ duplication, not typing: a param whose value gets written to a domain-backed column used
142
+ to restate that column's enum, so the same list was authored twice, translated twice, and
143
+ free to drift — and a param option whose code isn't on the column is a value the grid
144
+ can't label. `column-domains.md` gains a matching **"Using a domain in an action / report
145
+ param"** section, and `reports.md` documents the JSON equivalent
146
+ (`{"domain": "fin.doc_status"}`, mutually exclusive with `fieldTypeCd`).
147
+
148
+ Also documented: the param keeps its **own** caption (only the choices come from the
149
+ domain), install materializes just the domain's `fieldTypeCd` (a parameter has no
150
+ storage, so datatype and sizing don't apply), and nothing may follow the description —
151
+ `options=`, `min=` and friends are a compile error there, the same authority rule columns
152
+ already had.
153
+
154
+ ### Changed — labeled `options=` in the DSL references
155
+
156
+ The dropdown row in `dsl-reference.md` showed only `options=low,medium,high`, which is
157
+ exactly the shape that renders raw codes in every locale. It now shows the labeled forms
158
+ (`options=[low:Low, medium:Medium, high:High]`, and the JSON object form for icon/colour),
159
+ with the wrapping rule spelled out: the trailing `key=value` scan is whitespace-delimited,
160
+ so a label containing a space needs `[ ]` or quotes around the list.
161
+
162
+ `resources/docs/conventions.md` (vendored from dForge-core) gains the same guidance
163
+ inline. It was **not** re-synced wholesale: the vendored copy has diverged *forward* from
164
+ core in ~15 places — seed-data `cuid`-is-int8 warnings, mandatory-flag `M` semantics,
165
+ rights characters — so a straight `cp` (what `VENDOR_REFS=1` does) would silently drop
166
+ them. That drift is worth reconciling deliberately, in its own pass.
167
+
168
+ ### Fixed — `dforge_module_validate` rejected a domain-backed report param
169
+
170
+ `resources/schemas/reports.schema.json` required `fieldTypeCd` and had no `domain` key, so
171
+ the very form the docs above now recommend failed validation. `@dforge-core/metadata` is
172
+ bumped to `^0.0.14` and the 16 vendored schemas re-synced, which lands the new `paramDef`:
173
+ `domain` is accepted (`domain_cd` or `module_cd.domain_cd`), `fieldTypeCd` is no longer
174
+ required — a param declaring neither installs as `text` — and the one rejected combination
175
+ is declaring both. Action params were never affected (the DSL has no JSON schema).
176
+
177
+ ### Changed — dependency bumps
178
+
179
+ `@dforge-core/dforge-cli` `^0.2.12` → `^0.2.13`, `@dforge-core/metadata` `^0.0.13` →
180
+ `^0.0.14`, and the dev toolchain moves to `vitest` 4 and `@types/node` 26. A
181
+ `pnpm-workspace.yaml` pins the pnpm build allowlist and exempts the freshly-published
182
+ dForge packages from `minimumReleaseAge`, which otherwise blocks installing them the day
183
+ they ship.
184
+
185
+ ### Known gap
186
+
187
+ `dforge_translation_sync` doesn't seed `options` maps for fields, domains or params —
188
+ authors write those keys by hand.
189
+
7
190
  ## 0.2.3
8
191
 
9
192
  Catches up with the platform's current-user work: `currentUserId()` exists now,