@cxtms/cx-schema 1.7.11 → 1.7.13
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.
|
@@ -12,6 +12,10 @@ Shared domain reference for CargoXplorer entities. Used by `cx-workflow` and `cx
|
|
|
12
12
|
|
|
13
13
|
For CLI authentication, PAT tokens, org management, and publishing: see [ref-cli-auth.md](ref-cli-auth.md)
|
|
14
14
|
|
|
15
|
+
## GraphQL Querying & Audit History
|
|
16
|
+
|
|
17
|
+
For running GraphQL queries via CLI, filter syntax (Lucene), pagination, audit change history, and field discovery: see [ref-graphql-query.md](ref-graphql-query.md)
|
|
18
|
+
|
|
15
19
|
## Feature File Layout
|
|
16
20
|
|
|
17
21
|
All modules and workflows are organized under feature directories:
|
|
@@ -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
|
|
@@ -238,6 +238,15 @@ permissions:
|
|
|
238
238
|
displayName: { en-US: "..." }
|
|
239
239
|
roles: ["Admin", "Manager"]
|
|
240
240
|
|
|
241
|
+
configurations: # Optional: org-level config definitions
|
|
242
|
+
- configName: "apps.myFeature" # Unique config key
|
|
243
|
+
displayName: { en-US: "My Feature Settings" }
|
|
244
|
+
description: { en-US: "Configure my feature" }
|
|
245
|
+
component: "ModuleName/ConfigComponent" # Component that renders the config UI
|
|
246
|
+
defaultValue: # Optional default values
|
|
247
|
+
enabled: true
|
|
248
|
+
limit: 100
|
|
249
|
+
|
|
241
250
|
routes:
|
|
242
251
|
- name: "routeName"
|
|
243
252
|
path: "/module-path" # Supports :params
|
|
@@ -18,7 +18,7 @@ You are a CargoXplorer workflow YAML builder. You generate schema-valid YAML for
|
|
|
18
18
|
- **Feature folder**: `npx cxtms create workflow <name> --template <template> --feature <feature-name>`
|
|
19
19
|
- **Deploy to server**: `npx cxtms workflow deploy <file.yaml> --org <id>` — creates or updates workflow on the CX server
|
|
20
20
|
- **Undeploy from server**: `npx cxtms workflow undeploy <workflowId> --org <id>` — removes a workflow by UUID
|
|
21
|
-
- **Execute**: `npx cxtms workflow execute <workflowId|file.yaml> --org <id> [--vars '<json>']` — trigger a workflow execution
|
|
21
|
+
- **Execute**: `npx cxtms workflow execute <workflowId|file.yaml> --org <id> [--vars '<json>'] [--file varName=path]` — trigger a workflow execution (--file uploads a local file and passes the URL as a variable)
|
|
22
22
|
- **List logs**: `npx cxtms workflow logs <workflowId|file.yaml> --org <id> [--from YYYY-MM-DD] [--to YYYY-MM-DD]` — list executions with log availability
|
|
23
23
|
- **Download log**: `npx cxtms workflow log <executionId> --org <id> [--json] [--console] [--output <file>]` — download execution log
|
|
24
24
|
- **Publish all**: `npx cxtms publish [--feature <name>] --org <id>` — push all modules and workflows to the server
|
|
@@ -380,8 +380,16 @@ npx cxtms workflow execute workflows/my-workflow.yaml
|
|
|
380
380
|
|
|
381
381
|
# Pass input variables as JSON
|
|
382
382
|
npx cxtms workflow execute <workflowId> --vars '{"city": "London", "count": 5}'
|
|
383
|
+
|
|
384
|
+
# Upload a local file and pass its URL as a workflow variable
|
|
385
|
+
npx cxtms workflow execute workflow.yaml --file importFile=/path/to/data.csv
|
|
386
|
+
|
|
387
|
+
# Combine variables and file uploads
|
|
388
|
+
npx cxtms workflow execute workflow.yaml --vars '{"mode": "preview"}' --file importFile=data.csv --file templateFile=template.xlsx
|
|
383
389
|
```
|
|
384
390
|
|
|
391
|
+
`--file varName=path` uploads the local file to the server via presigned URL and sets the resulting URL as the named variable. Can be specified multiple times.
|
|
392
|
+
|
|
385
393
|
Returns execution result including `executionId`, `isAsync`, `outputs` (for Sync workflows).
|
|
386
394
|
|
|
387
395
|
### Execution Logs
|
|
@@ -417,6 +425,7 @@ npx cxtms workflow log <executionId> --json --console
|
|
|
417
425
|
- Text logs show step-by-step execution trace with timestamps
|
|
418
426
|
- Sync workflow executions may not appear in `workflow logs` — they return results inline
|
|
419
427
|
- Use `workflow execute --vars` to test workflows with specific inputs
|
|
428
|
+
- Use `workflow execute --file varName=path` to upload local files for workflows that expect file URL inputs
|
|
420
429
|
|
|
421
430
|
---
|
|
422
431
|
|