@dforge-core/metadata 0.0.14 → 0.0.16
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 +157 -0
- package/dist/index.d.ts +187 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schemas/data_views.schema.json +40 -0
- package/schemas/entity.schema.json +77 -0
- package/schemas/folders.schema.json +1 -1
- package/schemas/manifest.schema.json +6 -0
- package/schemas/reports.schema.json +41 -17
- package/src/actions.ts +31 -3
- package/src/entity.ts +53 -0
- package/src/folders.ts +10 -1
- package/src/index.ts +4 -1
- package/src/manifest.ts +21 -0
- package/src/reports.ts +75 -9
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,163 @@ All notable changes to `@dforge-core/metadata` are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.16] — 2026-08-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`EntityDef.views`** — entity views, the platform's column-level security, typed as
|
|
13
|
+
the new exported `EntityViewDef` / `EntityViewColumnDef`. A view is a named subset of
|
|
14
|
+
an entity's columns; a folder binds one per entity through `ui/folders.json`
|
|
15
|
+
(`entities.<code>.viewName`, already typed on `FolderEntityDef`), and users working in
|
|
16
|
+
that folder see ONLY the columns the view lists. The JSON schema gained the property
|
|
17
|
+
first — this closes the gap where the authoring types could not express a `views`
|
|
18
|
+
block at all.
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
"views": {
|
|
22
|
+
"accountant": {
|
|
23
|
+
"columns": {
|
|
24
|
+
"product_id": {},
|
|
25
|
+
"name": { "flags": "VOG" },
|
|
26
|
+
"price": { "flags": "EVO" }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
A column ABSENT from `columns` is hidden — that is the mechanism, not an oversight —
|
|
33
|
+
and the view must list the primary key, since records are addressed by it.
|
|
34
|
+
|
|
35
|
+
- **`EntityViewColumnDef.formula`** — per-view formula override, in the same DSL as a
|
|
36
|
+
field's `formula`. Allowed only on a column the entity declares as `columnType: "F"`;
|
|
37
|
+
on any other column that field holds the SQL default, so an override there would be
|
|
38
|
+
inert, and the installer rejects it.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- **`schemas/entity.schema.json`** re-synced from `docs/schemas/` — it had drifted since
|
|
43
|
+
`views` was added there, so the shipped copy rejected a block the platform accepts
|
|
44
|
+
(the schema is `additionalProperties: false`, so editors flagged `views` as an error).
|
|
45
|
+
- **`FolderEntityBinding.viewName` was documented as a data view code** — it is not. It
|
|
46
|
+
names a key under the entity definition's `views`, and `ui/data_views.json` codes are
|
|
47
|
+
referenced by menus' `dataViewCode` instead. Corrected here and in
|
|
48
|
+
`schemas/folders.schema.json`. The word "view" names three different things in this
|
|
49
|
+
platform (entity views, data views, and `isView`/`viewSql` SQL-backed entities), so
|
|
50
|
+
both declaration sites now say which one they mean.
|
|
51
|
+
|
|
52
|
+
### Note for authors
|
|
53
|
+
|
|
54
|
+
An EMPTY override is not the same as an omitted one. The runtime merges view over entity
|
|
55
|
+
with `COALESCE`, which skips NULL only — so `"flags": ""` means "no flags in this view" (a
|
|
56
|
+
column neither visible nor editable) and `"params": {}` suppresses the entity-level params
|
|
57
|
+
rather than inheriting them. Omit the key entirely to inherit.
|
|
58
|
+
|
|
59
|
+
## [0.0.15] — 2026-08-17
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- **`ManifestDef.features`** — opt-in platform behaviours a package was authored for,
|
|
64
|
+
typed as the new exported `ModuleFeature` union. Absent or empty means the
|
|
65
|
+
pre-feature behaviour for all of them, so a module written before a feature existed
|
|
66
|
+
keeps working until its author declares it and republishes.
|
|
67
|
+
|
|
68
|
+
```jsonc
|
|
69
|
+
"features": ["report-security"]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`"report-security"` makes this module's reports require the `E` right on their
|
|
73
|
+
security object; declare the matching `"report:<code>": "E"` grants in
|
|
74
|
+
`security/roles.json` first, or the reports go dark for every role. Unknown names
|
|
75
|
+
are rejected at package load rather than ignored — a misspelled feature would
|
|
76
|
+
otherwise leave the old behaviour in place while the manifest claims otherwise.
|
|
77
|
+
`schemas/manifest.schema.json` carries the matching `enum`, and the three lists
|
|
78
|
+
(schema enum, this union, and the server's `ModuleFeatures`) are edited together.
|
|
79
|
+
|
|
80
|
+
- **`ParamDef.columnType`** — `"R"` declares a REFERENCE parameter, whose submitted
|
|
81
|
+
value is the whole picked record rather than its bare key. The JSON counterpart of
|
|
82
|
+
the action DSL's `paramCd: ref <entityCd>`, stored in the same `param.column_type`.
|
|
83
|
+
The schema already accepted it; the type did not.
|
|
84
|
+
|
|
85
|
+
The choice is not cosmetic: omitting it (a plain `lookup`) submits the key, which is
|
|
86
|
+
what a filter comparing against a reference column needs, since the server
|
|
87
|
+
destructures a key object across every key column and ignores non-key fields.
|
|
88
|
+
Declare `"R"` when the report wants the record itself. Either way the picker is
|
|
89
|
+
configured by `params.link` (`{ entity, otherKey? }`), and `otherKey` is filled from
|
|
90
|
+
the target's primary key when omitted — comma-joined and paired POSITIONALLY with
|
|
91
|
+
the key columns.
|
|
92
|
+
|
|
93
|
+
- **`matrixViewConfig.calculatedMembers`** (schema) — synthetic read-only rows or
|
|
94
|
+
columns of a pivot-like view, derived by formula over OTHER members' values at each
|
|
95
|
+
cross-axis position (a Gross Margin % line, a Q1 total column). The feature shipped
|
|
96
|
+
some time ago and `gl`'s P&L matrix uses it, but `matrixViewConfig` is
|
|
97
|
+
`additionalProperties: false`, so declaring it was a validation error — editors
|
|
98
|
+
flagged a config the platform renders correctly.
|
|
99
|
+
|
|
100
|
+
The new `calculatedMember` `$def` mirrors `CalculatedMember` in `@dforge/data`:
|
|
101
|
+
`key`, `axis` (`row` default / `column`), `label`, `field`, `refs` (bracket-alias →
|
|
102
|
+
member identity), `formula`, `position`, `depth` and `format`. Platform-generic —
|
|
103
|
+
any pivot-like surface consumes the same shape, so adding an indicator is config
|
|
104
|
+
only, evaluated client-side by the stock formula engine.
|
|
105
|
+
|
|
106
|
+
- **Record-report attachments.** `ReportDef` gains `entities` — an array of
|
|
107
|
+
`ReportEntityAttachment` (also exported) declaring which entities a report can be
|
|
108
|
+
opened *from*, with the mapping from report parameter to source column on each. Each
|
|
109
|
+
entry becomes one `dForge.entity_report` row, and the report opens on a record-scoped
|
|
110
|
+
route with the record's values feeding its params server-side.
|
|
111
|
+
|
|
112
|
+
```jsonc
|
|
113
|
+
"credit_check": {
|
|
114
|
+
"entities": [
|
|
115
|
+
{ "entityCd": "parties.party", "params": { "customer_id": "party_id" }, "orderNum": 45 }
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The binding lives on the attachment, not the report: the same report attaches to
|
|
121
|
+
several entities with different mappings, and reports stay entity-agnostic. A qualified
|
|
122
|
+
`entityCd` must name a declared dependency; source columns are limited to the PK, a
|
|
123
|
+
reference (`R`) column, or a bounded scalar, and must be type-compatible with the target
|
|
124
|
+
param. `schemas/reports.schema.json` carries the matching `entityAttachment` `$def`.
|
|
125
|
+
|
|
126
|
+
- **`ReportDef.reloadInterval`** — the report's auto-refresh interval in seconds. It has
|
|
127
|
+
worked since long before this release but was absent from the schema, and since the
|
|
128
|
+
report object is `additionalProperties: false`, setting it was a validation error.
|
|
129
|
+
|
|
130
|
+
### Changed — report parameters have a report-level home again
|
|
131
|
+
|
|
132
|
+
`ReportDef.parameters` is **kept and now implemented**. Parameters are report-scoped
|
|
133
|
+
throughout the platform — the declaration is stored once per report
|
|
134
|
+
(`report.param_set_id` → `param_set`), the authoring API is `report.params.save`, and
|
|
135
|
+
`report.get` flattens per-dataset defaults report-wide before use — but the installer had
|
|
136
|
+
only ever read the per-dataset shorthand, so a report-level block was silently dropped and
|
|
137
|
+
the report installed with no parameters at all.
|
|
138
|
+
|
|
139
|
+
Both sites are now legal and mean the same thing. The installer merges them into the
|
|
140
|
+
report's single parameter set, **report level winning** on a code collision:
|
|
141
|
+
|
|
142
|
+
```jsonc
|
|
143
|
+
"customer_statement": {
|
|
144
|
+
"parameters": {
|
|
145
|
+
"customer_id": { "label": "Customer", "fieldTypeCd": "lookup",
|
|
146
|
+
"params": { "link": { "entity": "parties.party" } }, "required": true }
|
|
147
|
+
},
|
|
148
|
+
"datasets": { "statement_invoices": { }, "statement_payments": { } }
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Declare a parameter at report level when more than one dataset uses it — there is no
|
|
153
|
+
meaningful dataset to attribute it to, which is why the exporter previously had to dump the
|
|
154
|
+
whole set onto "the first dataset that had params". `datasets.<cd>.params` stays fully
|
|
155
|
+
supported and is the right shorthand when exactly one dataset uses the parameter.
|
|
156
|
+
|
|
157
|
+
### Removed
|
|
158
|
+
|
|
159
|
+
- **`paramDef.isRequired` and `paramDef.link`.** Neither is read by the installer: the key
|
|
160
|
+
is `required` (so `isRequired` installed the parameter as optional), and a lookup's
|
|
161
|
+
binding nests under `params` as `params.link` (so a top-level `link` installed the
|
|
162
|
+
parameter with no autocomplete). Unlike `parameters` these are simply misspellings, with
|
|
163
|
+
a correct spelling already in the schema — so they are gone rather than implemented.
|
|
164
|
+
|
|
8
165
|
## [0.0.14] — 2026-08-10
|
|
9
166
|
|
|
10
167
|
### Added
|
package/dist/index.d.ts
CHANGED
|
@@ -525,6 +525,46 @@ interface EntityReference {
|
|
|
525
525
|
/** ON UPDATE rule; a no-op for immutable `cuid` PKs. */
|
|
526
526
|
onUpdate?: ReferentialAction;
|
|
527
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* Per-view overrides for one column (`views.<name>.columns.<column_cd>`). Every
|
|
530
|
+
* property is optional; an omitted one falls back to the entity-level value.
|
|
531
|
+
*
|
|
532
|
+
* An EMPTY value is not the same as an omitted one — the runtime merges view over
|
|
533
|
+
* entity with COALESCE, so `flags: ""` means "no flags in this view" (a column
|
|
534
|
+
* neither visible nor editable) and `params: {}` suppresses the entity-level
|
|
535
|
+
* params rather than inheriting them.
|
|
536
|
+
*/
|
|
537
|
+
interface EntityViewColumnDef {
|
|
538
|
+
/** Flag letters for this column in this view, e.g. "VO" to expose it read-only. */
|
|
539
|
+
flags?: string;
|
|
540
|
+
orderNum?: number;
|
|
541
|
+
isNullable?: boolean;
|
|
542
|
+
editMask?: string;
|
|
543
|
+
displayFmt?: string;
|
|
544
|
+
/**
|
|
545
|
+
* Formula override for this column in this view, same DSL as a field's
|
|
546
|
+
* `formula`. Only on a column the entity declares as `columnType: "F"` — on any
|
|
547
|
+
* other column that field is the SQL default, so an override would be inert.
|
|
548
|
+
*/
|
|
549
|
+
formula?: string;
|
|
550
|
+
/** Lookup filter override for a reference column in this view. */
|
|
551
|
+
refFilter?: unknown;
|
|
552
|
+
/** Control-specific configuration override for this view. */
|
|
553
|
+
params?: Record<string, unknown>;
|
|
554
|
+
}
|
|
555
|
+
/** One entity view: the columns it exposes, plus optional per-view overrides. */
|
|
556
|
+
interface EntityViewDef {
|
|
557
|
+
/**
|
|
558
|
+
* Column code → per-view overrides. Columns ABSENT from this map are hidden in
|
|
559
|
+
* a folder bound to the view — that is the mechanism, not an oversight. `{}`
|
|
560
|
+
* (or null) exposes a column with no overrides. Must include the entity's
|
|
561
|
+
* primary key: records are addressed by it (hide it by omitting `V` from its
|
|
562
|
+
* flags instead).
|
|
563
|
+
*/
|
|
564
|
+
columns: Record<string, EntityViewColumnDef | null>;
|
|
565
|
+
/** Free-form view configuration, stored on entity_view.params. */
|
|
566
|
+
params?: Record<string, unknown>;
|
|
567
|
+
}
|
|
528
568
|
/** Automatic document numbering config (entity `numberSequence`). */
|
|
529
569
|
interface NumberSequenceDef {
|
|
530
570
|
/** Column code that receives the auto-generated number. */
|
|
@@ -620,6 +660,17 @@ interface EntityDef {
|
|
|
620
660
|
params?: {
|
|
621
661
|
restricted?: boolean;
|
|
622
662
|
} & Record<string, unknown>;
|
|
663
|
+
/**
|
|
664
|
+
* Entity views keyed by view name — the platform's column-level security.
|
|
665
|
+
* Unrelated to `isView`/`viewSql` above (a SQL-view-backed entity) and to
|
|
666
|
+
* `ui/data_views.json` (grids, kanban, calendars), both of which the word
|
|
667
|
+
* "view" also names in this platform. A
|
|
668
|
+
* folder binds one view per entity through `ui/folders.json`
|
|
669
|
+
* (`entities.<code>.viewName`); users working in that folder see ONLY the
|
|
670
|
+
* columns the view lists. An entity without views (or a folder naming the
|
|
671
|
+
* conventional `"default"`, which declares nothing) shows the full column set.
|
|
672
|
+
*/
|
|
673
|
+
views?: Record<string, EntityViewDef>;
|
|
623
674
|
}
|
|
624
675
|
|
|
625
676
|
/** `{ field, target }` for each Reference (R) column that declares a link. */
|
|
@@ -742,27 +793,45 @@ interface ParamDefBase {
|
|
|
742
793
|
label?: string;
|
|
743
794
|
/** Display order in the parameter form (falls back to declaration order). */
|
|
744
795
|
orderNum?: number;
|
|
745
|
-
/**
|
|
796
|
+
/**
|
|
797
|
+
* Whether the user must provide a value. Stored inverted as `param.is_nullable`.
|
|
798
|
+
* There is no `isRequired` spelling — the installer reads this key only.
|
|
799
|
+
*/
|
|
746
800
|
required?: boolean;
|
|
747
|
-
/** Alternate spelling of `required` used by some modules. Prefer `required`. */
|
|
748
|
-
isRequired?: boolean;
|
|
749
801
|
/** Default value applied when the user doesn't provide one. */
|
|
750
802
|
default?: unknown;
|
|
751
|
-
/** Entity link for lookup-type params. */
|
|
752
|
-
link?: {
|
|
753
|
-
entity: string;
|
|
754
|
-
otherKey?: string;
|
|
755
|
-
};
|
|
756
803
|
/**
|
|
757
|
-
* Field-type-specific params
|
|
804
|
+
* Field-type-specific params, nested under this key — there is no top-level
|
|
805
|
+
* `link`. A lookup param needs `{ link: { entity, otherKey? } }`.
|
|
806
|
+
* Most importantly `options` for a dropdown.
|
|
758
807
|
* Options accept the same rich `{value,label,icon,color}` form entity columns
|
|
759
808
|
* use; a bare string list renders the raw codes in every locale, so label them.
|
|
760
809
|
* Omitted on a domain-backed param: the domain owns the list.
|
|
761
810
|
*/
|
|
762
811
|
params?: Record<string, unknown>;
|
|
812
|
+
/**
|
|
813
|
+
* Declares a REFERENCE parameter: the submitted value is the whole picked
|
|
814
|
+
* record rather than its bare key. The JSON counterpart of the action DSL's
|
|
815
|
+
* `paramCd: ref <entityCd>`, stored in the same `param.column_type`.
|
|
816
|
+
*
|
|
817
|
+
* Optional, and the choice is not cosmetic. Omitting it (a plain `lookup`)
|
|
818
|
+
* submits the key, which is what a filter comparing against a reference
|
|
819
|
+
* column needs — the server destructures a key object across every key
|
|
820
|
+
* column and ignores non-key fields. Declare `"R"` when the report wants the
|
|
821
|
+
* record itself, not just its identity.
|
|
822
|
+
*
|
|
823
|
+
* Either way the picker is configured by `params.link` (`{ entity, otherKey? }`);
|
|
824
|
+
* `otherKey` is filled from the target's primary key when omitted, comma-joined
|
|
825
|
+
* and paired POSITIONALLY with the key columns.
|
|
826
|
+
*/
|
|
827
|
+
columnType?: "R";
|
|
763
828
|
}
|
|
764
829
|
/**
|
|
765
|
-
* A report parameter definition
|
|
830
|
+
* A report parameter definition. Declared in the report-level `parameters` block,
|
|
831
|
+
* or as shorthand under the `params` of the dataset that consumes it — the
|
|
832
|
+
* installer merges both into the report's single param set, so either way the
|
|
833
|
+
* parameter serves the whole report. Report level wins on a code collision, and
|
|
834
|
+
* is the only sensible home for a parameter several datasets use.
|
|
766
835
|
*
|
|
767
836
|
* A parameter takes its control from an explicit `fieldTypeCd` **or** from a
|
|
768
837
|
* column `domain` — never both. Declaring both is the one rejected combination
|
|
@@ -815,9 +884,40 @@ interface Dataset {
|
|
|
815
884
|
procedureName?: string;
|
|
816
885
|
/** Optional column metadata overrides: field code → override. */
|
|
817
886
|
columnsDef?: Record<string, ColumnDef>;
|
|
818
|
-
/**
|
|
887
|
+
/**
|
|
888
|
+
* Parameters declared on this dataset — shorthand for the report-level
|
|
889
|
+
* `parameters` block, convenient when exactly one dataset uses the parameter.
|
|
890
|
+
* The installer merges both into the report's one param set either way.
|
|
891
|
+
*/
|
|
819
892
|
params?: Record<string, ParamDef>;
|
|
820
893
|
}
|
|
894
|
+
/**
|
|
895
|
+
* One (entity, report) **record-report attachment**: the report becomes openable
|
|
896
|
+
* from that entity's record, with the record's values feeding its parameters.
|
|
897
|
+
* Each entry becomes one `dForge.entity_report` row.
|
|
898
|
+
*
|
|
899
|
+
* The binding is per-attachment, not per-report — the same report can attach to
|
|
900
|
+
* several entities with different parameter mappings, which is why the mapping
|
|
901
|
+
* lives here rather than on the report.
|
|
902
|
+
*/
|
|
903
|
+
interface ReportEntityAttachment {
|
|
904
|
+
/**
|
|
905
|
+
* Entity the report attaches to, qualified `module.entity` for anything
|
|
906
|
+
* outside the declaring module. That module must be a declared dependency.
|
|
907
|
+
*/
|
|
908
|
+
entityCd: string;
|
|
909
|
+
/**
|
|
910
|
+
* Parameter mapping: report param code → **source column on the entity**.
|
|
911
|
+
* (Not a param declaration — those live in the report's `parameters` block or a
|
|
912
|
+
* dataset's `params`.) Resolved server-side
|
|
913
|
+
* from the record's PK. Source columns are limited to the PK, reference (`R`)
|
|
914
|
+
* columns, and bounded scalars; source and target must be type-compatible.
|
|
915
|
+
* Params left unmapped keep their normal behaviour (default, or prompt).
|
|
916
|
+
*/
|
|
917
|
+
params?: Record<string, string>;
|
|
918
|
+
/** Sort position in the record's combined action + report menu. */
|
|
919
|
+
orderNum?: number;
|
|
920
|
+
}
|
|
821
921
|
/** A single visualization panel within the report layout. */
|
|
822
922
|
interface ReportPanel {
|
|
823
923
|
vizType: VizType;
|
|
@@ -837,8 +937,21 @@ interface ReportDef {
|
|
|
837
937
|
layout: ReportLayout;
|
|
838
938
|
/** Dataset code → dataset definition. */
|
|
839
939
|
datasets: Record<string, Dataset>;
|
|
840
|
-
/**
|
|
940
|
+
/** Auto-refresh interval in seconds. Omit (or 0) for no auto-refresh. */
|
|
941
|
+
reloadInterval?: number;
|
|
942
|
+
/**
|
|
943
|
+
* Report-level parameter declarations — the canonical home for a parameter, and
|
|
944
|
+
* the only one that fits a parameter several datasets use. Merged with each
|
|
945
|
+
* dataset's `params` into the report's single param set; this block wins on a
|
|
946
|
+
* code collision.
|
|
947
|
+
*/
|
|
841
948
|
parameters?: Record<string, ParamDef>;
|
|
949
|
+
/**
|
|
950
|
+
* Record-report attachments: entities this report can be opened from, with the
|
|
951
|
+
* mapping from report parameter to source column on each. Omit for a report
|
|
952
|
+
* that is only reached from a menu.
|
|
953
|
+
*/
|
|
954
|
+
entities?: ReportEntityAttachment[];
|
|
842
955
|
}
|
|
843
956
|
/** A `ui/reports.json` file: report code → definition. */
|
|
844
957
|
type ReportsFile = Record<string, ReportDef>;
|
|
@@ -853,6 +966,12 @@ type ModuleDependency = string | {
|
|
|
853
966
|
version: string;
|
|
854
967
|
entities?: string[];
|
|
855
968
|
};
|
|
969
|
+
/**
|
|
970
|
+
* A platform behaviour a package can opt into via `manifest.features`.
|
|
971
|
+
* Mirrors `dForge.Core.ModuleFeatures` and the `features` enum in
|
|
972
|
+
* manifest.schema.json — all three are edited together.
|
|
973
|
+
*/
|
|
974
|
+
type ModuleFeature = "report-security";
|
|
856
975
|
/** A module package manifest (`manifest.json`). */
|
|
857
976
|
interface ManifestDef {
|
|
858
977
|
/** Package format version (currently 1). */
|
|
@@ -890,6 +1009,20 @@ interface ManifestDef {
|
|
|
890
1009
|
icon?: string;
|
|
891
1010
|
/** Non-English locales the package promises to translate. */
|
|
892
1011
|
supportedLocales?: string[];
|
|
1012
|
+
/**
|
|
1013
|
+
* Opt-in platform behaviours this package was authored for. Absent or empty
|
|
1014
|
+
* = the pre-feature behaviour for all of them, so a module written before a
|
|
1015
|
+
* feature existed keeps working until its author declares it and republishes.
|
|
1016
|
+
*
|
|
1017
|
+
* Unknown names are rejected at package load, never ignored — a misspelled
|
|
1018
|
+
* feature would silently leave the old behaviour in place while the manifest
|
|
1019
|
+
* claims otherwise.
|
|
1020
|
+
*
|
|
1021
|
+
* - `report-security` — this module's reports require 'E' on their
|
|
1022
|
+
* `sec_object`. Declare the matching `"report:<code>": "E"` grants in
|
|
1023
|
+
* `security/roles.json` first, or the reports go dark for every role.
|
|
1024
|
+
*/
|
|
1025
|
+
features?: ModuleFeature[];
|
|
893
1026
|
/** Initial creation date (YYYY-MM-DD). Informational. */
|
|
894
1027
|
created?: string;
|
|
895
1028
|
/** Last manifest edit date (YYYY-MM-DD). Informational. */
|
|
@@ -1016,7 +1149,16 @@ type MenusFile = Record<string, MenuDef>;
|
|
|
1016
1149
|
|
|
1017
1150
|
/** Per-entity binding within a folder. */
|
|
1018
1151
|
interface FolderEntityBinding {
|
|
1019
|
-
/**
|
|
1152
|
+
/**
|
|
1153
|
+
* Entity view to bind for this entity in this folder — a key under the entity
|
|
1154
|
+
* definition's `views` (see `EntityViewDef`), NOT a data view code from
|
|
1155
|
+
* `ui/data_views.json`. Users in this folder then see only the columns that
|
|
1156
|
+
* view lists.
|
|
1157
|
+
*
|
|
1158
|
+
* The conventional `"default"` declares nothing and means "no view" (the full
|
|
1159
|
+
* column set); any other name the entity does not declare fails the install,
|
|
1160
|
+
* since falling back would grant more access than naming a view asks for.
|
|
1161
|
+
*/
|
|
1020
1162
|
viewName?: string;
|
|
1021
1163
|
/** Enable the quick-add (+) button for this entity here. */
|
|
1022
1164
|
quickAdd?: boolean;
|
|
@@ -1234,13 +1376,41 @@ interface ActionDef {
|
|
|
1234
1376
|
executionMode: ActionExecutionMode;
|
|
1235
1377
|
/** DSL script name (file under `logic/actions/<script>.dsl`). */
|
|
1236
1378
|
script: string;
|
|
1237
|
-
/**
|
|
1379
|
+
/**
|
|
1380
|
+
* Run the whole selection in one transaction, so a failure on any record
|
|
1381
|
+
* rolls back the records already processed. **Defaults to `true`** when
|
|
1382
|
+
* omitted (`ActionDef.IsTransacted` in the installer is a non-nullable
|
|
1383
|
+
* `bool` initialised to `true`), so omit it only when you want atomicity.
|
|
1384
|
+
*
|
|
1385
|
+
* `false` opens no transaction, and what follows a failure depends on
|
|
1386
|
+
* {@link ActionDef.executionMode}: `single` / `each` report it and continue
|
|
1387
|
+
* with the next record, so use that for independent per-record work that
|
|
1388
|
+
* should process as many records as pass; `batch` is a single script
|
|
1389
|
+
* invocation with no loop to continue, so the run simply ends with its
|
|
1390
|
+
* earlier writes committed.
|
|
1391
|
+
*
|
|
1392
|
+
* On a run queued to the background the **rollback** guarantee is lost
|
|
1393
|
+
* outright — the worker opens no transaction, so nothing is ever undone. What
|
|
1394
|
+
* remains of the flag there depends on the mode: the worker's `single`/`each`
|
|
1395
|
+
* loop still reads it for control flow (stop after the first failed record vs.
|
|
1396
|
+
* continue), while its `batch` path never reads it at all — one invocation,
|
|
1397
|
+
* which ends on failure under either value.
|
|
1398
|
+
*/
|
|
1238
1399
|
isTransacted?: boolean;
|
|
1239
1400
|
/** Display order. */
|
|
1240
1401
|
orderNum?: number;
|
|
1241
|
-
/**
|
|
1402
|
+
/**
|
|
1403
|
+
* @deprecated Not read by the installer — use {@link ActionDef.isAsync}.
|
|
1404
|
+
* The module manifest model binds `isAsync` only, so this key is silently
|
|
1405
|
+
* ignored and the action installs as synchronous.
|
|
1406
|
+
*/
|
|
1242
1407
|
async?: boolean;
|
|
1243
|
-
/**
|
|
1408
|
+
/**
|
|
1409
|
+
* Permit background execution. It does not force it: `action.execute`
|
|
1410
|
+
* carries its own `async` argument and the server branches on that, so an
|
|
1411
|
+
* action with parameters is offered to the user as both "Run" (inline) and
|
|
1412
|
+
* "Run in Background". A parameterless `isAsync` action is queued directly.
|
|
1413
|
+
*/
|
|
1244
1414
|
isAsync?: boolean;
|
|
1245
1415
|
}
|
|
1246
1416
|
/** A `ui/actions.json` file: action code → definition. */
|
|
@@ -1251,4 +1421,4 @@ declare const flagDefs: readonly {
|
|
|
1251
1421
|
label: string;
|
|
1252
1422
|
}[];
|
|
1253
1423
|
|
|
1254
|
-
export { AGG_TYPE_LIST, type AccumulationConfig, type ActionDef, type ActionExecutionMode, type ActionsFile, AggType, type AlignType, type BaseDatatypeCd, type CalendarViewConfig, type ColumnDef, type ColumnTypeCd, type ColumnTypeDef, DEP_COLUMN_TYPES, type DataSource, type DataViewDef, type DataViewsFile, type Dataset, type DepColumn, type DepColumnMode, type DepColumnType, type DepEntity, type DepProvenance, type DepProvenanceKind, type DepsFile, type DeriveOptions, type DiagramViewConfig, type DomainDef, type DomainsFile, type EntityDef, type EntityEvent, type EntityReference, FILTER_GROUP_OPERATORS, FILTER_OPERATORS, type FieldDef, type FieldLink, type FieldOption, type FieldTypeCd, type FieldTypeDef, type Filter, type FilterCondition, type FilterGroup, type FilterGroupOperator, type FilterOperator, type FlagCd, type FolderDef, type FolderEntityBinding, type FoldersFile, type JobDef, type JobsFile, type KanbanViewConfig, type LedgerRegistryEntry, type ListLevelConfig, type ListViewConfig, type ManifestAuthor, type ManifestDef, type MenuDef, type MenuItemDef, type MenuItemType, type MenusFile, type ModuleDependency, NUMERIC_TOTAL, type NamedKind, type NumberSequenceDef, type ParamDef, type ParamDefBase, type PeriodConfig, type PrintMargins, type PrintPageSettings, type PrintTemplateDef, type PrintTemplatesFile, type ReportDef, type ReportLayout, type ReportPanel, type ReportQuery, type ReportsFile, type RoleDef, type RolesFile, type SeedDataFile, type SettingBaseDatatype, type SettingDef, type SettingsFile, type SignConfig, type SortClause, type TraitCd, type TraitDef, type TreeGridViewConfig, type TriggerDef, type TriggersFile, type ViewColumn, type ViewType, type VizType, type WebhookPayload, type WebhookSubscription, type WebhooksFile, baseDatatypes, baseToDbDatatype, chartTypes, columnTypes, dataViewKinds, defaultParams, deriveBaseDatatype, deriveDbDatatype, expandTrait, expandTraits, fieldTypeCds, fieldTypes, fieldTypesByColumnType, flagDefs, getColumnType, getFieldType, getIdentityKeys, getLinks, getPrimaryKeys, getTrait, isFieldTypeCd, traits, vizTypes };
|
|
1424
|
+
export { AGG_TYPE_LIST, type AccumulationConfig, type ActionDef, type ActionExecutionMode, type ActionsFile, AggType, type AlignType, type BaseDatatypeCd, type CalendarViewConfig, type ColumnDef, type ColumnTypeCd, type ColumnTypeDef, DEP_COLUMN_TYPES, type DataSource, type DataViewDef, type DataViewsFile, type Dataset, type DepColumn, type DepColumnMode, type DepColumnType, type DepEntity, type DepProvenance, type DepProvenanceKind, type DepsFile, type DeriveOptions, type DiagramViewConfig, type DomainDef, type DomainsFile, type EntityDef, type EntityEvent, type EntityReference, type EntityViewColumnDef, type EntityViewDef, FILTER_GROUP_OPERATORS, FILTER_OPERATORS, type FieldDef, type FieldLink, type FieldOption, type FieldTypeCd, type FieldTypeDef, type Filter, type FilterCondition, type FilterGroup, type FilterGroupOperator, type FilterOperator, type FlagCd, type FolderDef, type FolderEntityBinding, type FoldersFile, type JobDef, type JobsFile, type KanbanViewConfig, type LedgerRegistryEntry, type ListLevelConfig, type ListViewConfig, type ManifestAuthor, type ManifestDef, type MenuDef, type MenuItemDef, type MenuItemType, type MenusFile, type ModuleDependency, type ModuleFeature, NUMERIC_TOTAL, type NamedKind, type NumberSequenceDef, type ParamDef, type ParamDefBase, type PeriodConfig, type PrintMargins, type PrintPageSettings, type PrintTemplateDef, type PrintTemplatesFile, type ReportDef, type ReportEntityAttachment, type ReportLayout, type ReportPanel, type ReportQuery, type ReportsFile, type RoleDef, type RolesFile, type SeedDataFile, type SettingBaseDatatype, type SettingDef, type SettingsFile, type SignConfig, type SortClause, type TraitCd, type TraitDef, type TreeGridViewConfig, type TriggerDef, type TriggersFile, type ViewColumn, type ViewType, type VizType, type WebhookPayload, type WebhookSubscription, type WebhooksFile, baseDatatypes, baseToDbDatatype, chartTypes, columnTypes, dataViewKinds, defaultParams, deriveBaseDatatype, deriveDbDatatype, expandTrait, expandTraits, fieldTypeCds, fieldTypes, fieldTypesByColumnType, flagDefs, getColumnType, getFieldType, getIdentityKeys, getLinks, getPrimaryKeys, getTrait, isFieldTypeCd, traits, vizTypes };
|