@cxtms/cx-schema 1.8.1 → 1.8.2

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 (64) hide show
  1. package/.claude/skills/cx-core/ref-cli-auth.md +120 -0
  2. package/.claude/skills/cx-core/ref-entity-accounting.md +7 -0
  3. package/.claude/skills/cx-core/ref-entity-commodity.md +12 -0
  4. package/.claude/skills/cx-core/ref-entity-contact.md +10 -0
  5. package/.claude/skills/cx-core/ref-entity-geography.md +34 -1
  6. package/.claude/skills/cx-core/ref-entity-order-sub.md +13 -0
  7. package/.claude/skills/cx-core/ref-entity-order.md +14 -0
  8. package/.claude/skills/cx-core/ref-entity-rate.md +8 -0
  9. package/.claude/skills/cx-core/ref-entity-shared.md +9 -0
  10. package/.claude/skills/cx-core/ref-entity-warehouse.md +5 -0
  11. package/.claude/skills/cx-core/ref-graphql-query.md +320 -0
  12. package/.claude/skills/cx-module/SKILL.md +103 -28
  13. package/.claude/skills/cx-module/ref-components-data.md +7 -0
  14. package/.claude/skills/cx-module/ref-components-display.md +17 -0
  15. package/.claude/skills/cx-module/ref-components-forms.md +7 -1
  16. package/.claude/skills/cx-module/ref-components-interactive.md +11 -0
  17. package/.claude/skills/cx-module/ref-components-layout.md +11 -0
  18. package/.claude/skills/cx-module/ref-components-specialized.md +50 -0
  19. package/.claude/skills/cx-workflow/SKILL.md +127 -18
  20. package/.claude/skills/cx-workflow/ref-communication.md +8 -0
  21. package/.claude/skills/cx-workflow/ref-entity.md +43 -0
  22. package/.claude/skills/cx-workflow/ref-expressions-ncalc.md +128 -0
  23. package/.claude/skills/cx-workflow/ref-expressions-template.md +159 -0
  24. package/.claude/skills/cx-workflow/ref-flow.md +8 -1
  25. package/.claude/skills/cx-workflow/ref-other.md +9 -0
  26. package/README.md +34 -34
  27. package/dist/cli.js +2395 -167
  28. package/dist/cli.js.map +1 -1
  29. package/dist/types.d.ts +2 -0
  30. package/dist/types.d.ts.map +1 -1
  31. package/dist/validator.d.ts +8 -0
  32. package/dist/validator.d.ts.map +1 -1
  33. package/dist/validator.js +54 -2
  34. package/dist/validator.js.map +1 -1
  35. package/dist/workflowValidator.d.ts +4 -0
  36. package/dist/workflowValidator.d.ts.map +1 -1
  37. package/dist/workflowValidator.js +28 -2
  38. package/dist/workflowValidator.js.map +1 -1
  39. package/package.json +1 -1
  40. package/schemas/components/appComponent.json +8 -0
  41. package/schemas/components/module.json +31 -2
  42. package/schemas/components/timelineGrid.json +4 -0
  43. package/schemas/schemas.json +12 -0
  44. package/schemas/workflows/tasks/authentication.json +26 -12
  45. package/schemas/workflows/workflow.json +0 -4
  46. package/scripts/postinstall.js +1 -1
  47. package/templates/module-configuration.yaml +23 -89
  48. package/templates/module-form.yaml +3 -3
  49. package/templates/module-grid.yaml +3 -3
  50. package/templates/module-select.yaml +3 -3
  51. package/templates/module.yaml +3 -2
  52. package/templates/workflow-api-tracking.yaml +1 -1
  53. package/templates/workflow-basic.yaml +1 -1
  54. package/templates/workflow-document.yaml +1 -1
  55. package/templates/workflow-entity-trigger.yaml +1 -1
  56. package/templates/workflow-ftp-edi.yaml +1 -1
  57. package/templates/workflow-ftp-tracking.yaml +1 -1
  58. package/templates/workflow-mcp-tool.yaml +1 -1
  59. package/templates/workflow-public-api.yaml +1 -1
  60. package/templates/workflow-scheduled.yaml +1 -1
  61. package/templates/workflow-utility.yaml +1 -1
  62. package/templates/workflow-webhook.yaml +1 -1
  63. package/templates/workflow.yaml +1 -1
  64. package/.claude/skills/cx-workflow/ref-expressions.md +0 -272
@@ -0,0 +1,120 @@
1
+ # CX Server Authentication & Management
2
+
3
+ ## Contents
4
+ - Authentication (OAuth2 login/logout)
5
+ - PAT Tokens (CI/CD alternative to OAuth)
6
+ - Organization Management
7
+ - Session Resolution
8
+ - Publish (push modules and workflows to server)
9
+
10
+ ## Authentication
11
+
12
+ ```bash
13
+ # Login to a CX environment (OAuth2 + PKCE — opens browser)
14
+ npx cxtms login https://tms-v3-dev.usatrt.com
15
+
16
+ # Logout from current session
17
+ npx cxtms logout
18
+ ```
19
+
20
+ The session is stored at `~/.cxtms/<project-dir>/.session.json`, scoped by project directory name. Each project gets its own server session. The CLI auto-refreshes expired tokens.
21
+
22
+ ## PAT Tokens (alternative to OAuth)
23
+
24
+ For CI/CD or headless environments, use Personal Access Tokens instead of interactive OAuth:
25
+
26
+ ```bash
27
+ # Check PAT status and setup instructions
28
+ npx cxtms pat setup
29
+
30
+ # Create a new PAT token (requires OAuth login first)
31
+ npx cxtms pat create "my-ci-token"
32
+
33
+ # List active PAT tokens
34
+ npx cxtms pat list
35
+
36
+ # Revoke a PAT token
37
+ npx cxtms pat revoke <tokenId>
38
+ ```
39
+
40
+ After creating a PAT, add to `.env` in your project root:
41
+ ```
42
+ CXTMS_AUTH=pat_xxxxx...
43
+ CXTMS_SERVER=https://tms-v3-dev.usatrt.com
44
+ ```
45
+
46
+ When `CXTMS_AUTH` is set, the CLI skips OAuth and uses the PAT token directly. `CXTMS_SERVER` provides the server URL (or set `server` in `app.yaml`).
47
+
48
+ ## Organization Management
49
+
50
+ ```bash
51
+ # List organizations on the server
52
+ npx cxtms orgs list
53
+
54
+ # Select an organization interactively
55
+ npx cxtms orgs select
56
+
57
+ # Set active organization by ID
58
+ npx cxtms orgs use <orgId>
59
+
60
+ # Show current context (server, org, app)
61
+ npx cxtms orgs use
62
+ ```
63
+
64
+ The active org is cached in the session file and used by all server commands. **Always pass `--org <id>` on deploy/undeploy/release/execute/logs commands** to avoid the interactive org picker blocking automation.
65
+
66
+ ## Session Resolution
67
+
68
+ Server commands resolve the target session in this order:
69
+ 1. `CXTMS_AUTH` env var → PAT token auth (with `CXTMS_SERVER` or `app.yaml` server field)
70
+ 2. `~/.cxtms/<project-dir>/.session.json` → project-scoped OAuth session
71
+ 3. Not logged in → error
72
+
73
+ ## Publish
74
+
75
+ ```bash
76
+ # Publish all modules and workflows from current project
77
+ npx cxtms publish
78
+
79
+ # Publish only a specific feature directory
80
+ npx cxtms publish --feature billing
81
+ npx cxtms publish billing
82
+
83
+ # Publish with explicit org ID
84
+ npx cxtms publish --org 42
85
+ ```
86
+
87
+ Validates all YAML files first, then pushes modules and workflows to the server. Skips files with validation errors and reports results.
88
+
89
+ ## App Manifest Management
90
+
91
+ Server-side app manifest operations — install from git, release changes to git, and list installed apps.
92
+
93
+ ```bash
94
+ # Install/refresh app from its git repository into the CX server
95
+ npx cxtms app install
96
+
97
+ # Force reinstall even if same version is already installed
98
+ npx cxtms app install --force
99
+
100
+ # Install from a specific branch
101
+ npx cxtms app install --branch develop
102
+
103
+ # Install but skip modules that have unpublished local changes
104
+ npx cxtms app install --skip-changed
105
+
106
+ # Release server changes to git (creates a PR) — message is required
107
+ npx cxtms app release -m "Add new shipping module"
108
+
109
+ # Force release all modules and workflows (not just changed ones)
110
+ npx cxtms app release -m "Full republish" --force
111
+
112
+ # List installed app manifests on the server
113
+ npx cxtms app list
114
+ ```
115
+
116
+ **`app install`** reads `repository` and `branch` from `app.yaml`, downloads the repo on the server side, and installs/updates all modules and workflows. Use `--force` to reinstall even if the version hasn't changed. Use `--skip-changed` to preserve modules with unpublished changes.
117
+
118
+ **`app release`** takes the current server state and releases it to git by creating a PR. Requires a `-m` message describing the changes (like a git commit message). The server increments the version, creates a release branch, commits all module/workflow YAML files, and opens a pull request to the target branch.
119
+
120
+ **`app list`** shows all installed app manifests with their version, status flags (disabled, unpublished changes, update available), and repository info.
@@ -1,5 +1,12 @@
1
1
  # Accounting Transaction Entity Field Reference
2
2
 
3
+ ## Contents
4
+ - AccountingTransaction Fields
5
+ - Charge Entity
6
+ - Payment Entity
7
+ - Accounting Enums
8
+ - Accounting CustomValues
9
+
3
10
  Field names as used in workflow expressions: `{{ entity.transactionNumber }}`, `{{ entity.customValues.myField }}`.
4
11
 
5
12
  ## AccountingTransaction Fields
@@ -1,5 +1,17 @@
1
1
  # Commodity Entity Field Reference
2
2
 
3
+ ## Contents
4
+ - Commodity Scalar Fields
5
+ - Commodity Navigation Properties
6
+ - Commodity Collection Properties
7
+ - Commodity Computed/Resolved GraphQL Fields
8
+ - Commodity Container/Child Pattern (Self-Referencing)
9
+ - CommodityTrackingNumber Sub-Entity
10
+ - OrderCommodity Join Entity
11
+ - Commodity Enums
12
+ - Commodity CustomValues
13
+ - CommodityEvent (Bridge Entity)
14
+
3
15
  Field names as used in workflow expressions: `{{ entity.description }}`, `{{ entity.customValues.myField }}`.
4
16
 
5
17
  ## Scalar Fields
@@ -1,5 +1,15 @@
1
1
  # Contact Entity Field Reference
2
2
 
3
+ ## Contents
4
+ - Contact Scalar Fields
5
+ - Contact Navigation Properties
6
+ - Contact Collection Properties
7
+ - Contact Computed/Resolved GraphQL Fields
8
+ - ContactType Enum
9
+ - ContactAddress Sub-Entity
10
+ - Contact Other Related Enums
11
+ - Contact CustomValues
12
+
3
13
  Field names as used in workflow expressions: `{{ entity.name }}`, `{{ entity.customValues.myField }}`.
4
14
 
5
15
  ## Scalar Fields
@@ -1,6 +1,16 @@
1
1
  # Geography & Lookup Entity Reference
2
2
 
3
- Country, State, City, Port, Vessel, CustomCode, ModeOfTransportation.
3
+ ## Contents
4
+ - Country
5
+ - State
6
+ - City
7
+ - PostalCode
8
+ - Port
9
+ - Vessel
10
+ - CustomCode
11
+ - ModeOfTransportation
12
+
13
+ Country, State, City, PostalCode, Port, Vessel, CustomCode, ModeOfTransportation.
4
14
 
5
15
  ## Country
6
16
 
@@ -50,6 +60,29 @@ Composite key: `organizationId` + `countryCode` + `stateCode`.
50
60
 
51
61
  ---
52
62
 
63
+ ## PostalCode
64
+
65
+ PK: `id` (int, auto). Scoped per organization.
66
+
67
+ | Field | Type | Notes |
68
+ |-------|------|-------|
69
+ | `id` | `int` | PK |
70
+ | `organizationId` | `int` | |
71
+ | `code` | `string` | Postal/zip code value |
72
+ | `countryCode` | `string` | FK to Country |
73
+ | `placeName` | `string` | Place/city name |
74
+ | `stateCode` | `string?` | FK to State |
75
+ | `accuracy` | `AccuracyTypes?` | 1=Region, 2=Municipality, 3=Neighborhood, 4=Place, 5=Street, 6=Centroid |
76
+ | `timeZone` | `string?` | IANA timezone ID (e.g., `America/Chicago`) |
77
+ | `customValues` | `Dictionary` | jsonb |
78
+ | `location` | `Point?` | WGS 84 (SRID 4326). X=longitude, Y=latitude |
79
+
80
+ **Navigation:** `country`, `state`
81
+
82
+ **Mutations:** `ChangeCode`, `ChangePlaceName`, `ChangeCoordinates(lat, lng, accuracy)`, `ChangeCountry`/`ChangeCountryCode`, `ChangeState`/`ChangeStateCode`, `ChangeTimeZone`, `ChangeCustomValues`, `ChangeLatitude`, `ChangeLongitude`
83
+
84
+ ---
85
+
53
86
  ## Port
54
87
 
55
88
  String-based PK (e.g., UN/LOCODE).
@@ -1,5 +1,12 @@
1
1
  # Order Sub-Entity Field Reference
2
2
 
3
+ ## Contents
4
+ - OrderEntity
5
+ - TrackingEvent
6
+ - EventDefinition
7
+ - LinkedOrder
8
+ - OrderDocument
9
+
3
10
  Entities associated with orders: OrderEntity (parties), TrackingEvent, LinkedOrder, OrderDocument.
4
11
 
5
12
  ## OrderEntity
@@ -94,6 +101,12 @@ Template/type definition for tracking events.
94
101
  | `triggerConditionFields` | `string?` | |
95
102
  | `customValues` | `Dictionary` | jsonb |
96
103
 
104
+ ### GraphQL Resolvers
105
+
106
+ | Resolver | Arguments | Returns | Description |
107
+ |----------|-----------|---------|-------------|
108
+ | `getContact` | `customValuesKey: String!` | `Contact` | Looks up a Contact by ID stored in `customValues[key]` |
109
+
97
110
  ---
98
111
 
99
112
  ## LinkedOrder
@@ -1,5 +1,15 @@
1
1
  # Order Entity Field Reference
2
2
 
3
+ ## Contents
4
+ - Order Scalar Fields
5
+ - Order Navigation Properties
6
+ - Order Collection Properties
7
+ - Pre-filtered OrderEntity Collections (GraphQL)
8
+ - Order Computed/Resolved GraphQL Fields
9
+ - OrderTypes Enum
10
+ - EntityTypes Enum (for OrderEntity)
11
+ - Order CustomValues
12
+
3
13
  Field names as used in workflow expressions: `{{ entity.orderId }}`, `{{ entity.customValues.myField }}`.
4
14
 
5
15
  ## Scalar Fields
@@ -55,6 +65,8 @@ Field names as used in workflow expressions: `{{ entity.orderId }}`, `{{ entity.
55
65
  | `orderCarriers` | `[OrderCarrier]` | |
56
66
  | `allTags` | `[OrderAllTagsView]` | View: all tags including from commodities |
57
67
  | `allRelatedOrders` | `[OrderRelatedOrdersView]` | Orders sharing commodities |
68
+ | `attachmentsSummary` | `OrderAttachmentSummaryView?` | DB view: `.totalCount`, `.hasAny` (active attachments) |
69
+ | `notesSummary` | `OrderNoteSummaryView?` | DB view: `.totalCount`, `.hasAny` (non-deleted notes) |
58
70
  | `outgoingLinks` | `[LinkedOrder]` | |
59
71
  | `incomingLinks` | `[LinkedOrder]` | |
60
72
 
@@ -97,6 +109,8 @@ These are virtual fields that filter `orderEntities` by type:
97
109
  | `getChargesByChargeType(chargeType)` | `[Charge]` | Charges filtered by type |
98
110
  | `getOrderSummary(weightUnit, volumeUnit, dimensionsUnit)` | `OrderSummary` | |
99
111
  | `lastTrackingEvent(eventDefinitionName)` | `TrackingEvent` | Most recent |
112
+ | `attachmentsSummary` | `OrderAttachmentSummaryGqlDto` | `.totalCount` (int), `.hasAny` (bool) — batched DataLoader, backed by DB view |
113
+ | `notesSummary` | `OrderNoteSummaryGqlDto` | `.totalCount` (int), `.hasAny` (bool) — batched DataLoader, backed by DB view |
100
114
  | `notesCount(threadFilter)` | `int` | |
101
115
  | `changeHistory(startDate, endDate, maxResults)` | `[ChangeHistory]` | Audit trail |
102
116
  | `getCommoditiesWithRelatedOrder(orderType!, filter?)` | `[Commodity]` | Leaf commodities linked to related orders of specified type. Traverses commodity hierarchy, excludes wrappers. |
@@ -1,5 +1,13 @@
1
1
  # Rate, Pricing & Accounting Lookup Reference
2
2
 
3
+ ## Contents
4
+ - Rate
5
+ - Lane
6
+ - Discount
7
+ - AccountingItem
8
+ - AccountingAccount
9
+ - PaymentTerm
10
+
3
11
  ## Rate
4
12
 
5
13
  Carrier/vendor rates with tariff rules.
@@ -1,5 +1,14 @@
1
1
  # Shared Entity Reference
2
2
 
3
+ ## Contents
4
+ - Tag
5
+ - Attachment
6
+ - Division
7
+ - EquipmentType
8
+ - PackageType
9
+ - NoteThread
10
+ - Note
11
+
3
12
  Tag, Attachment, Division, EquipmentType, PackageType, Note/NoteThread.
4
13
 
5
14
  ## Tag
@@ -1,5 +1,10 @@
1
1
  # Warehouse & Inventory Entity Reference
2
2
 
3
+ ## Contents
4
+ - InventoryItem
5
+ - WarehouseLocation
6
+ - CargoMovement
7
+
3
8
  ## InventoryItem
4
9
 
5
10
  SKU-level inventory tracking.
@@ -0,0 +1,320 @@
1
+ # GraphQL Query Reference
2
+
3
+ ## CLI Query Command
4
+
5
+ ```bash
6
+ npx cxtms query '<graphql-query>' # Inline query
7
+ npx cxtms query my-query.graphql # From file
8
+ npx cxtms query '<query>' --vars '{"key":"v"}' # With variables
9
+ ```
10
+
11
+ Requires active login (`npx cxtms login`). Uses the active organization.
12
+
13
+ ## Query Arguments
14
+
15
+ All root entity queries follow this pattern:
16
+
17
+ ```graphql
18
+ orders(
19
+ organizationId: Int! # Required — active org ID
20
+ filter: String # Lucene query syntax (see below)
21
+ search: String # Full-text search across key fields
22
+ orderBy: String # Comma-separated sort fields
23
+ take: Int # Page size (alias: limit)
24
+ skip: Int # Offset (alias: offset)
25
+ )
26
+ ```
27
+
28
+ Entity-specific extras:
29
+ - `orders` — `includeDraft: Boolean` (default false)
30
+
31
+ Available root queries: `orders`, `contacts`, `commodities`, `accountingTransactions`, `jobs`, and others.
32
+
33
+ ## Filter Syntax (Lucene Query)
34
+
35
+ Filters use **Lucene Query syntax** (not OData, not NCalc).
36
+
37
+ ### Basic field matching
38
+ ```
39
+ filter: "orderId:196596"
40
+ filter: "orderType:ParcelShipment"
41
+ filter: "status:Active"
42
+ ```
43
+
44
+ ### Wildcards
45
+ ```
46
+ filter: "name:*pending*" # Contains
47
+ filter: "code:ABC*" # Starts with
48
+ filter: "status:*Active" # Ends with
49
+ ```
50
+
51
+ ### Logical operators
52
+ ```
53
+ filter: "countryCode:US AND name:Test"
54
+ filter: "status:Active OR status:Pending"
55
+ filter: "NOT customValues.po:123"
56
+ filter: "orderType:ParcelShipment AND (status:Active OR status:Pending)"
57
+ ```
58
+
59
+ ### Nested paths (dot notation)
60
+ ```
61
+ filter: "orderEntities.entityType:Consignee"
62
+ filter: "orderEntities.contactId:7128"
63
+ filter: "jobs.orders.orderNumber:16*"
64
+ ```
65
+
66
+ ### Range queries
67
+ ```
68
+ filter: "lastModified:[\"2026-01-01\" TO \"2026-03-15\"]"
69
+ filter: "lastModified:[\"2026-01-01\" TO *]" # >= date
70
+ filter: "amount:[100 TO 500]"
71
+ ```
72
+
73
+ ### NULL checks
74
+ ```
75
+ filter: "customValues.po:NULL"
76
+ ```
77
+
78
+ ### CustomValues (JSONB fields)
79
+ ```
80
+ filter: "customValues.fieldName:value"
81
+ filter: "customValues.fieldName:\"exact match\""
82
+ filter: "customValues.fieldName:NULL"
83
+ ```
84
+
85
+ ### Filtered collections (bracket notation)
86
+ ```
87
+ filter: "children[category:CatA].name:test"
88
+ ```
89
+
90
+ ## OrderBy Syntax
91
+
92
+ ```
93
+ orderBy: "orderNumber" # Ascending
94
+ orderBy: "-orderNumber" # Descending
95
+ orderBy: "-created,orderNumber" # Multi-field
96
+ orderBy: "customValues.fieldName" # Custom field sort
97
+ orderBy: "orderNumber~ToInt32" # Type conversion during sort
98
+ ```
99
+
100
+ ## Pagination
101
+
102
+ ```graphql
103
+ {
104
+ orders(organizationId: 1, take: 50, skip: 0) {
105
+ items { orderId orderNumber }
106
+ totalCount
107
+ pageInfo { hasNextPage hasPreviousPage }
108
+ }
109
+ }
110
+ ```
111
+
112
+ ## Audit Change History
113
+
114
+ ### Entity-level: `changeHistory` computed field
115
+
116
+ Available on: **Order**, **Contact**, **Commodity**, **AccountingTransaction**
117
+
118
+ ```graphql
119
+ {
120
+ orders(organizationId: 1, filter: "orderId:196596", take: 1) {
121
+ items {
122
+ orderId
123
+ changeHistory(maxResults: 20) {
124
+ entityName
125
+ hasMoreRecords
126
+ continuationToken
127
+ changes {
128
+ state # "Added" | "Modified" | "Deleted"
129
+ userId
130
+ timestamp
131
+ user {
132
+ fullName
133
+ email
134
+ }
135
+ changedFields {
136
+ fieldName
137
+ originalValue
138
+ currentValue
139
+ fieldType
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ Arguments: `startDate: DateTime`, `endDate: DateTime`, `maxResults: Int` (default 10)
149
+
150
+ ### Root-level: `auditChanges` query
151
+
152
+ Query audit changes directly without fetching the entity first:
153
+
154
+ ```graphql
155
+ {
156
+ auditChanges(
157
+ organizationId: 1
158
+ filter: "entityName:Order AND primaryKey:196596"
159
+ take: 20
160
+ ) {
161
+ items {
162
+ state
163
+ userId
164
+ timestamp
165
+ user { fullName email }
166
+ changedFields {
167
+ fieldName
168
+ originalValue
169
+ currentValue
170
+ fieldType
171
+ }
172
+ }
173
+ }
174
+ }
175
+ ```
176
+
177
+ Arguments: `organizationId: Int!`, `filter: String`, `search: String`, `take: Int`, `skip: Int`, `orderBy: String`
178
+
179
+ Filter fields: `entityName`, `primaryKey`, `userId`, `state`
180
+
181
+ ### Root-level: `auditChangeSummaries` query
182
+
183
+ High-level summary of changes (grouped by change event):
184
+
185
+ ```graphql
186
+ {
187
+ auditChangeSummaries(
188
+ organizationId: 1
189
+ startDate: "2026-03-01T00:00:00Z"
190
+ endDate: "2026-03-15T23:59:59Z"
191
+ maxResults: 50
192
+ ) {
193
+ items {
194
+ changeId
195
+ userId
196
+ timestamp
197
+ changePaths
198
+ organizationId
199
+ }
200
+ continuationToken
201
+ hasMoreRecords
202
+ }
203
+ }
204
+ ```
205
+
206
+ ### Root-level: `auditChange` — single change detail
207
+
208
+ ```graphql
209
+ {
210
+ auditChange(filePath: "<s3-file-path>") {
211
+ entityName
212
+ state
213
+ primaryKey
214
+ userId
215
+ timestamp
216
+ originalValues
217
+ currentValues
218
+ fields {
219
+ fieldName
220
+ originalValue
221
+ currentValue
222
+ fieldType
223
+ }
224
+ }
225
+ }
226
+ ```
227
+
228
+ ## GraphQL Type Reference
229
+
230
+ ### EntityAuditHistoryLightResult
231
+ | Field | Type |
232
+ |-------|------|
233
+ | `entityName` | `String` |
234
+ | `primaryKey` | `String` |
235
+ | `organizationId` | `Int` |
236
+ | `changes` | `[AuditChangeEntry!]!` |
237
+ | `continuationToken` | `String` |
238
+ | `hasMoreRecords` | `Boolean!` |
239
+
240
+ ### AuditChangeEntry
241
+ | Field | Type | Notes |
242
+ |-------|------|-------|
243
+ | `state` | `String` | "Added", "Modified", "Deleted" |
244
+ | `userId` | `String` | |
245
+ | `timestamp` | `DateTime!` | |
246
+ | `user` | `AuditUser` | Lazy-loaded resolver |
247
+ | `changedFields` | `[AuditChangeField!]!` | Lazy-loaded resolver |
248
+
249
+ ### AuditChangeField
250
+ | Field | Type |
251
+ |-------|------|
252
+ | `fieldName` | `String!` |
253
+ | `originalValue` | `Any` |
254
+ | `currentValue` | `Any` |
255
+ | `fieldType` | `String!` |
256
+
257
+ ### AuditUser
258
+ | Field | Type |
259
+ |-------|------|
260
+ | `id` | `String` |
261
+ | `firstName` | `String` |
262
+ | `lastName` | `String` |
263
+ | `fullName` | `String` |
264
+ | `userName` | `String` |
265
+ | `email` | `String` |
266
+
267
+ ## Discovering Fields
268
+
269
+ **Always discover field names before building a query.** Do not guess field names — use the tools below.
270
+
271
+ ### CLI: `cxtms gql` — schema exploration commands
272
+
273
+ ```bash
274
+ # List all query root fields (what you can query)
275
+ npx cxtms gql queries
276
+ npx cxtms gql queries --filter order
277
+
278
+ # List all mutation root fields
279
+ npx cxtms gql mutations
280
+ npx cxtms gql mutations --filter order
281
+
282
+ # List all types (filter by name)
283
+ npx cxtms gql types --filter audit
284
+ npx cxtms gql types --filter order
285
+
286
+ # Inspect a specific type — shows fields, arguments, input fields, enum values
287
+ npx cxtms gql type OrderGqlDto
288
+ npx cxtms gql type AuditChangeEntry
289
+ npx cxtms gql type EntityAuditHistoryLightResult
290
+ npx cxtms gql type CreateOrderInput
291
+ ```
292
+
293
+ ### TMS MCP: `graphql_schema` / `graphql_type` — equivalent MCP tools
294
+
295
+ When TMS MCP is available, the same discovery is available via MCP tools:
296
+
297
+ ```
298
+ graphql_schema(section: "queries", filter: "order")
299
+ graphql_schema(section: "types", filter: "audit")
300
+ graphql_type(typeName: "OrderGqlDto")
301
+ graphql_execute(query: "{ orders(organizationId: 1, take: 1) { items { orderId } } }")
302
+ ```
303
+
304
+ ### Workflow: discover → query
305
+
306
+ 1. **Find the type** — `cxtms gql types --filter order` to find type names
307
+ 2. **Inspect the type** — `cxtms gql type OrderGqlDto` to see all fields and their types
308
+ 3. **Check query args** — `cxtms gql queries --filter order` to see arguments
309
+ 4. **Build and run** — `cxtms query '<graphql-query>'`
310
+
311
+ ### Fallback: error-driven discovery
312
+
313
+ GraphQL error messages reveal valid field/type names:
314
+ - "The field `foo` does not exist on the type `BarType`" — tells you the type name
315
+ - "The argument `bar` does not exist" — tells you valid argument patterns
316
+
317
+ ### Other sources
318
+
319
+ - `npx cxtms schema <name>` — shows workflow/module JSON schema fields (not GraphQL)
320
+ - Entity reference files (`ref-entity-*.md`) — document common fields, computed properties, and enums