@dforge-core/metadata 0.0.9 → 0.0.11

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
@@ -5,6 +5,23 @@ 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.10] — 2026-07-24
9
+
10
+ ### Added
11
+
12
+ - **Column domains** — a reusable, named semantic type (base datatype + control +
13
+ sizing + shared option list) that a column references via `FieldDef.domain`
14
+ (`"module_cd.domain_cd"`) instead of restating the definition. The domain supplies
15
+ `baseDatatypeCd`, `dbDatatype`, `fieldTypeCd`, `maxLen`, `precision` and `params`;
16
+ declaring any of those alongside `domain` is rejected at install.
17
+ - `schemas/domains.schema.json` — the `domains.json` authoring schema (re-vendored
18
+ from `docs/schemas`). Each domain requires `baseDatatypeCd`; `params.options`
19
+ carries the shared dropdown/radio/flags option list.
20
+ - `schemas/entity.schema.json` — new "Domain-backed column" branch: `required: ["domain"]`,
21
+ forbidding restatement of the domain-owned fields.
22
+ - `DomainsFile` / `DomainDef` types (`src/domains.ts`) — typed authoring surface for
23
+ `domains.json`; `FieldDef` gains `domain?: string`.
24
+
8
25
  ## [0.0.9] — 2026-07-22
9
26
 
10
27
  ### Added
@@ -0,0 +1,32 @@
1
+ import type { BaseDatatypeCd, FieldTypeCd, FieldOption } from "./types";
2
+ /** A single reusable column domain. */
3
+ export interface DomainDef {
4
+ /** Human-readable label. Localizable via `translations/<locale>.json` → `domains.<code>.label`. */
5
+ description?: string;
6
+ /**
7
+ * Base datatype the domain stands for. Required — it is what a consuming column's
8
+ * DDL is generated from.
9
+ */
10
+ baseDatatypeCd: BaseDatatypeCd;
11
+ /** Physical Postgres type for consuming columns; omit to infer from `fieldTypeCd`. */
12
+ dbDatatype?: string;
13
+ /** Control used to render/edit consuming columns (e.g. `dropdown`, `text`, `number`). */
14
+ fieldTypeCd?: FieldTypeCd;
15
+ /** Max length for string-backed domains. */
16
+ maxLen?: number;
17
+ /** Decimal precision for numeric domains. */
18
+ precision?: number;
19
+ /**
20
+ * Field-type config shared by every consuming column — most importantly the option
21
+ * list for `dropdown`/`radio`/`flags`. Never copied onto columns: it resolves from
22
+ * the domain at load time, which is what lets its labels be translated once for all
23
+ * consumers. Per-locale label/icon/color overrides live in `translations/<locale>.json`
24
+ * under `domains.<code>.options.<value>`.
25
+ */
26
+ params?: {
27
+ options?: (string | FieldOption)[];
28
+ } & Record<string, unknown>;
29
+ }
30
+ /** A `domains.json` file: reusable column domains keyed by domain code. */
31
+ export type DomainsFile = Record<string, DomainDef>;
32
+ //# sourceMappingURL=domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../src/domains.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAExE,uCAAuC;AACvC,MAAM,WAAW,SAAS;IACzB,mGAAmG;IACnG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1E;AAED,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ // Column domains — authoring shape of `domains.json`. Mirror of domains.schema.json.
2
+ //
3
+ // A domain is a reusable, named semantic type: a base datatype, a control, sizing and
4
+ // a shared option list under one code (e.g. `doc_status`). A column references it via
5
+ // `FieldDef.domain` ("module_cd.domain_cd") instead of restating the definition. The
6
+ // structural fields are materialized onto each column at install; `params` (the option
7
+ // list) stays on the domain and resolves at load time, so a shared list is authored and
8
+ // translated exactly once. See docs/modules/MODULE_CONVENTIONS.md.
9
+ export {};
10
+ //# sourceMappingURL=domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.js","sourceRoot":"","sources":["../src/domains.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,sFAAsF;AACtF,sFAAsF;AACtF,qFAAqF;AACrF,uFAAuF;AACvF,wFAAwF;AACxF,mEAAmE"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export { vizTypes, chartTypes, type ReportsFile, type ReportDef, type ReportLayo
13
13
  export type { ManifestDef, ManifestAuthor, ModuleDependency } from "./manifest";
14
14
  export type { DepsFile, DepEntity, DepColumn, DepColumnType, DepColumnMode, DepProvenance, DepProvenanceKind } from "./deps";
15
15
  export { DEP_COLUMN_TYPES } from "./deps";
16
+ export type { DomainsFile, DomainDef } from "./domains";
16
17
  export type { MenusFile, MenuDef, MenuItemDef, MenuItemType } from "./menus";
17
18
  export type { FoldersFile, FolderDef, FolderEntityBinding } from "./folders";
18
19
  export type { RolesFile, RoleDef } from "./roles";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,8BAA8B;AAC9B,gFAAgF;AAChF,gFAAgF;AAChF,yCAAyC;AACzC,0EAA0E;AAC1E,iFAAiF;AACjF,+EAA+E;AAC/E,iDAAiD;AACjD,EAAE;AACF,8EAA8E;AAC9E,4CAA4C;AAkB5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,aAAa,GAEb,MAAM,UAAU,CAAC;AAiBlB,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,EACN,aAAa,GAYb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACN,QAAQ,EACR,UAAU,GAUV,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAY1C,mEAAmE;AACnE,sDAAsD;AACtD,MAAM,CAAC,MAAM,QAAQ,GAAqE;IACzF,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IAChC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IACjC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IACjC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAClC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;CACtB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,8BAA8B;AAC9B,gFAAgF;AAChF,gFAAgF;AAChF,yCAAyC;AACzC,0EAA0E;AAC1E,iFAAiF;AACjF,+EAA+E;AAC/E,iDAAiD;AACjD,EAAE;AACF,8EAA8E;AAC9E,4CAA4C;AAkB5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,aAAa,GAEb,MAAM,UAAU,CAAC;AAiBlB,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,EACN,aAAa,GAYb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACN,QAAQ,EACR,UAAU,GAUV,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAa1C,mEAAmE;AACnE,sDAAsD;AACtD,MAAM,CAAC,MAAM,QAAQ,GAAqE;IACzF,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE;IAChC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IACjC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE;IACjC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE;IAClC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;CACtB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -91,6 +91,13 @@ export interface FieldDef {
91
91
  * Absent ⇒ treated as an acyclic hierarchy guarded at the DB level.
92
92
  */
93
93
  cyclic?: boolean;
94
+ /**
95
+ * Reference to a reusable column domain, qualified as `module_cd.domain_cd`
96
+ * (unqualified resolves within the current module first, then tenant-created
97
+ * domains). Supplies `baseDatatypeCd`, `dbDatatype`, `fieldTypeCd`, `maxLen`,
98
+ * `precision` and `params`; declaring any of those alongside `domain` fails install.
99
+ */
100
+ domain?: string;
94
101
  /** Filter criteria for reference lookups. */
95
102
  refFilter?: unknown;
96
103
  /** Field-type-specific configuration (dropdown options, register config, …). */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,60 +1,60 @@
1
1
  {
2
- "name": "@dforge-core/metadata",
3
- "version": "0.0.9",
4
- "description": "Canonical dForge authoring registries — field types, base datatypes, column types, traits, data-view kinds and chart types — with derivation helpers. Runtime-dependency-free; the single source of truth shared by editors, the web app and the CLI.",
5
- "license": "MIT",
6
- "author": "dForge",
7
- "homepage": "https://github.com/iash44/dForge-core/tree/main/clients/packages/metadata#readme",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/iash44/dForge-core.git",
11
- "directory": "clients/packages/metadata"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/iash44/dForge-core/issues"
15
- },
16
- "keywords": [
17
- "dforge",
18
- "metadata",
19
- "field-type",
20
- "trait",
21
- "registry",
22
- "low-code"
23
- ],
24
- "publishConfig": {
25
- "access": "public"
26
- },
27
- "type": "module",
28
- "main": "./dist/index.js",
29
- "module": "./dist/index.js",
30
- "types": "./dist/index.d.ts",
31
- "exports": {
32
- ".": {
33
- "source": "./src/index.ts",
34
- "types": "./dist/index.d.ts",
35
- "default": "./dist/index.js"
36
- },
37
- "./schemas/*": "./schemas/*",
38
- "./package.json": "./package.json"
39
- },
40
- "files": [
41
- "dist",
42
- "src",
43
- "schemas",
44
- "CHANGELOG.md"
45
- ],
46
- "scripts": {
47
- "sync-schemas": "node scripts/sync-schemas.mjs",
48
- "build": "tsc -p tsconfig.build.json",
49
- "dev": "tsc -p tsconfig.build.json --watch",
50
- "test": "vitest run",
51
- "prepack": "pnpm sync-schemas && pnpm build",
52
- "package": "pnpm pack"
53
- },
54
- "devDependencies": {
55
- "@types/node": "^25.9.4",
56
- "ajv": "^8.20.0",
57
- "typescript": "^6.0.3",
58
- "vitest": "^4.1.9"
59
- }
2
+ "name": "@dforge-core/metadata",
3
+ "version": "0.0.11",
4
+ "description": "Canonical dForge authoring registries \u2014 field types, base datatypes, column types, traits, data-view kinds and chart types \u2014 with derivation helpers. Runtime-dependency-free; the single source of truth shared by editors, the web app and the CLI.",
5
+ "license": "MIT",
6
+ "author": "dForge",
7
+ "homepage": "https://github.com/iash44/dForge-core/tree/main/clients/packages/metadata#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/iash44/dForge-core.git",
11
+ "directory": "clients/packages/metadata"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/iash44/dForge-core/issues"
15
+ },
16
+ "keywords": [
17
+ "dforge",
18
+ "metadata",
19
+ "field-type",
20
+ "trait",
21
+ "registry",
22
+ "low-code"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "type": "module",
28
+ "main": "./dist/index.js",
29
+ "module": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "source": "./src/index.ts",
34
+ "types": "./dist/index.d.ts",
35
+ "default": "./dist/index.js"
36
+ },
37
+ "./schemas/*": "./schemas/*",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "src",
43
+ "schemas",
44
+ "CHANGELOG.md"
45
+ ],
46
+ "scripts": {
47
+ "sync-schemas": "node scripts/sync-schemas.mjs",
48
+ "build": "tsc -p tsconfig.build.json",
49
+ "dev": "tsc -p tsconfig.build.json --watch",
50
+ "test": "vitest run",
51
+ "prepack": "pnpm sync-schemas && pnpm build",
52
+ "package": "pnpm pack"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^25.9.4",
56
+ "ajv": "^8.20.0",
57
+ "typescript": "^6.0.3",
58
+ "vitest": "^4.1.9"
59
+ }
60
60
  }
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/domains.schema.json",
4
+ "title": "dForge Column Domains",
5
+ "description": "domains.json — reusable, named semantic types. A domain bundles a base datatype, a control, sizing and a shared option list under one code; columns reference it via \"domain\": \"module_cd.domain_cd\" instead of restating the definition. Structural fields are materialized onto each column at install; options stay on the domain and resolve at metadata-load time, so a shared list is authored and translated exactly once.",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "$ref": "#/$defs/domain"
9
+ },
10
+ "propertyNames": {
11
+ "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
12
+ "description": "Domain code. Must not contain '.', which is reserved for the qualified 'module_cd.domain_cd' form."
13
+ },
14
+ "$defs": {
15
+ "domain": {
16
+ "type": "object",
17
+ "required": ["baseDatatypeCd"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "description": {
21
+ "type": "string",
22
+ "description": "Human-readable label. Localizable via translations/<locale>.json under domains.<domain_cd>.label."
23
+ },
24
+ "baseDatatypeCd": {
25
+ "type": "string",
26
+ "description": "Base datatype the domain stands for (e.g. string, number, date, datetime, boolean). Required — it is what consuming columns' DDL is generated from."
27
+ },
28
+ "dbDatatype": {
29
+ "type": "string",
30
+ "description": "Physical Postgres type for consuming columns (e.g. varchar, int4, numeric). Omit to let it be inferred from fieldTypeCd."
31
+ },
32
+ "fieldTypeCd": {
33
+ "type": "string",
34
+ "description": "Control used to render/edit consuming columns (e.g. dropdown, radio, flags, text, number)."
35
+ },
36
+ "maxLen": {
37
+ "type": "integer",
38
+ "minimum": 1,
39
+ "description": "Max length for string-backed domains."
40
+ },
41
+ "precision": {
42
+ "type": "integer",
43
+ "minimum": 0,
44
+ "description": "Decimal precision for numeric domains."
45
+ },
46
+ "params": {
47
+ "type": "object",
48
+ "description": "Field-type config shared by every consuming column — most importantly the 'options' list for dropdown/radio/flags. Never copied onto columns: it resolves from the domain at load time, which is what lets its labels be translated once for all consumers.",
49
+ "properties": {
50
+ "options": {
51
+ "type": "array",
52
+ "description": "Option list. Each entry is either a bare string (value doubles as label) or an object. Per-locale label/icon/color overrides live in translations/<locale>.json under domains.<domain_cd>.options.<value>.",
53
+ "items": {
54
+ "oneOf": [
55
+ { "type": "string" },
56
+ {
57
+ "type": "object",
58
+ "required": ["value"],
59
+ "additionalProperties": false,
60
+ "properties": {
61
+ "value": {
62
+ "type": "string",
63
+ "description": "The stored code. Never translatable — translations match on it."
64
+ },
65
+ "label": { "type": "string" },
66
+ "icon": { "type": "string" },
67
+ "color": { "type": "string" }
68
+ }
69
+ }
70
+ ]
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
@@ -209,11 +209,29 @@
209
209
  "type": "boolean",
210
210
  "description": "On a self-referencing reference column (R column whose link.entity is the owning entity), set true to ALLOW parent/child cycles. When absent the self-reference is treated as an acyclic hierarchy and DB-level guards reject loops. Ignored on non-self-referencing columns."
211
211
  },
212
+ "domain": {
213
+ "type": "string",
214
+ "description": "Reference to a reusable column domain, qualified as 'module_cd.domain_cd' (unqualified resolves within this module, then tenant-created domains). The domain supplies dbDatatype, baseDatatypeCd, fieldTypeCd, maxLen, precision and params; declaring any of those alongside 'domain' is rejected at install. The column keeps its own description, flags, orderNum, isNullable and isPk."
215
+ },
212
216
  "refFilter": {
213
217
  "description": "Filter criteria for reference lookups. Condition values support @[field] placeholders resolved against the current record at lookup time (e.g. {\"c\":\"channel\",\"o\":\"eq\",\"v\":\"@[channel]\"} narrows options to rows matching the record's own channel); a condition whose placeholder is unset is dropped rather than matching nothing."
214
218
  }
215
219
  },
216
220
  "oneOf": [
221
+ {
222
+ "title": "Domain-backed column",
223
+ "description": "Physical column whose datatype, control, sizing and options all come from a reusable column domain. Requires 'domain' and must NOT restate what the domain owns.",
224
+ "required": ["domain"],
225
+ "properties": {
226
+ "link": false,
227
+ "dbDatatype": false,
228
+ "baseDatatypeCd": false,
229
+ "fieldTypeCd": false,
230
+ "maxLen": false,
231
+ "precision": false,
232
+ "params": false
233
+ }
234
+ },
217
235
  {
218
236
  "title": "Data column",
219
237
  "description": "Physical DB column (columnType 'D' or unspecified). Requires 'dbDatatype'. Must NOT have 'link'.",
@@ -37,20 +37,20 @@
37
37
  },
38
38
  "condition": {
39
39
  "type": "string",
40
- "description": "Optional formula expression — same shape as canExecute in action DSL. Uses `[field]` syntax to reference the affected record. Single-line, evaluates to boolean. If omitted, trigger fires for every matching event."
40
+ "description": "Optional formula expression — same shape as canExecute in action DSL. Uses `[field]` syntax to reference the affected record. Single-line, evaluates to boolean. If omitted, trigger fires for every matching event. Reference navigation (`[ref].[target]`) is REJECTED here: the event-time evaluator only reads columns of the changed row, so a nav path would resolve to null and the trigger would misfire. Navigate inside the action instead, or denormalise the value onto the watched entity."
41
41
  },
42
42
  "action": {
43
43
  "type": "string",
44
- "description": "Action code to invoke. The action must NOT use record-context (`[field]`) syntax in a way that requires the original triggering record — the trigger passes the record id via params. Cross-module form 'module.action' is supported."
44
+ "description": "Action code to invoke. The trigger binds the affected record to the action as RECORD CONTEXT, so the action reads its columns with `[field]` (and its PK with `[pk_column]`) exactly like a UI-invoked action — no lookup needed. The action's `entityCode` MUST equal this trigger's `entity`, and its `executionMode` must not be `batch`; both are enforced at pack time. Cross-module references use the qualified form 'module.action'."
45
45
  },
46
46
  "params": {
47
47
  "type": "object",
48
- "description": "Optional static parameters passed to the action at invocation time. Merged with the runtime-injected `record_id` / `record_old` (if event uses old-record diff)."
48
+ "description": "Optional STATIC parameters passed to the action at invocation time — the literal values written here, nothing else. Nothing is injected at runtime: there is no `record_id` param. The affected record arrives as record context (`[field]`), and its pre-change values as `old[field]` on update/delete/status_change events."
49
49
  },
50
50
  "async": {
51
51
  "type": "boolean",
52
- "default": false,
53
- "description": "When true, the action runs in the background — the triggering transaction commits before the action starts. Recommended for slow actions (emails, external API calls); background failures are logged, not surfaced to the caller. When false, the action runs synchronously inside the same transaction as the triggering insert/update/delete: if the action fails (e.g. calls error()), the whole mutation rolls back and the error is returned to the caller. Keep async:false actions fast — they run on the request's transaction."
52
+ "default": true,
53
+ "description": "When true (the default), the action runs in the background — the triggering transaction commits before the action starts. Recommended for slow actions (emails, external API calls); background failures are logged, not surfaced to the caller. When false, the action runs synchronously inside the same transaction as the triggering insert/update/delete: if the action fails (e.g. calls error()), the whole mutation rolls back and the error is returned to the caller — so an async:false trigger can undo the user's write. Keep async:false actions fast; they run on the request's transaction."
54
54
  }
55
55
  },
56
56
  "additionalProperties": false
package/src/domains.ts ADDED
@@ -0,0 +1,40 @@
1
+ // Column domains — authoring shape of `domains.json`. Mirror of domains.schema.json.
2
+ //
3
+ // A domain is a reusable, named semantic type: a base datatype, a control, sizing and
4
+ // a shared option list under one code (e.g. `doc_status`). A column references it via
5
+ // `FieldDef.domain` ("module_cd.domain_cd") instead of restating the definition. The
6
+ // structural fields are materialized onto each column at install; `params` (the option
7
+ // list) stays on the domain and resolves at load time, so a shared list is authored and
8
+ // translated exactly once. See docs/modules/MODULE_CONVENTIONS.md.
9
+
10
+ import type { BaseDatatypeCd, FieldTypeCd, FieldOption } from "./types";
11
+
12
+ /** A single reusable column domain. */
13
+ export interface DomainDef {
14
+ /** Human-readable label. Localizable via `translations/<locale>.json` → `domains.<code>.label`. */
15
+ description?: string;
16
+ /**
17
+ * Base datatype the domain stands for. Required — it is what a consuming column's
18
+ * DDL is generated from.
19
+ */
20
+ baseDatatypeCd: BaseDatatypeCd;
21
+ /** Physical Postgres type for consuming columns; omit to infer from `fieldTypeCd`. */
22
+ dbDatatype?: string;
23
+ /** Control used to render/edit consuming columns (e.g. `dropdown`, `text`, `number`). */
24
+ fieldTypeCd?: FieldTypeCd;
25
+ /** Max length for string-backed domains. */
26
+ maxLen?: number;
27
+ /** Decimal precision for numeric domains. */
28
+ precision?: number;
29
+ /**
30
+ * Field-type config shared by every consuming column — most importantly the option
31
+ * list for `dropdown`/`radio`/`flags`. Never copied onto columns: it resolves from
32
+ * the domain at load time, which is what lets its labels be translated once for all
33
+ * consumers. Per-locale label/icon/color overrides live in `translations/<locale>.json`
34
+ * under `domains.<code>.options.<value>`.
35
+ */
36
+ params?: { options?: (string | FieldOption)[] } & Record<string, unknown>;
37
+ }
38
+
39
+ /** A `domains.json` file: reusable column domains keyed by domain code. */
40
+ export type DomainsFile = Record<string, DomainDef>;
package/src/index.ts CHANGED
@@ -92,6 +92,7 @@ export {
92
92
  export type { ManifestDef, ManifestAuthor, ModuleDependency } from "./manifest";
93
93
  export type { DepsFile, DepEntity, DepColumn, DepColumnType, DepColumnMode, DepProvenance, DepProvenanceKind } from "./deps";
94
94
  export { DEP_COLUMN_TYPES } from "./deps";
95
+ export type { DomainsFile, DomainDef } from "./domains";
95
96
  export type { MenusFile, MenuDef, MenuItemDef, MenuItemType } from "./menus";
96
97
  export type { FoldersFile, FolderDef, FolderEntityBinding } from "./folders";
97
98
  export type { RolesFile, RoleDef } from "./roles";
package/src/types.ts CHANGED
@@ -151,6 +151,13 @@ export interface FieldDef {
151
151
  * Absent ⇒ treated as an acyclic hierarchy guarded at the DB level.
152
152
  */
153
153
  cyclic?: boolean;
154
+ /**
155
+ * Reference to a reusable column domain, qualified as `module_cd.domain_cd`
156
+ * (unqualified resolves within the current module first, then tenant-created
157
+ * domains). Supplies `baseDatatypeCd`, `dbDatatype`, `fieldTypeCd`, `maxLen`,
158
+ * `precision` and `params`; declaring any of those alongside `domain` fails install.
159
+ */
160
+ domain?: string;
154
161
  /** Filter criteria for reference lookups. */
155
162
  refFilter?: unknown;
156
163
  /** Field-type-specific configuration (dropdown options, register config, …). */