@cxtms/cx-schema 1.8.0 → 1.8.1
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/.claude/skills/cx-core/SKILL.md +38 -20
- package/.claude/skills/cx-core/ref-entity-accounting.md +0 -7
- package/.claude/skills/cx-core/ref-entity-commodity.md +0 -12
- package/.claude/skills/cx-core/ref-entity-contact.md +0 -10
- package/.claude/skills/cx-core/ref-entity-geography.md +1 -34
- package/.claude/skills/cx-core/ref-entity-notification.md +85 -0
- package/.claude/skills/cx-core/ref-entity-order-sub.md +7 -13
- package/.claude/skills/cx-core/ref-entity-order.md +1 -14
- package/.claude/skills/cx-core/ref-entity-rate.md +0 -8
- package/.claude/skills/cx-core/ref-entity-shared.md +20 -9
- package/.claude/skills/cx-core/ref-entity-warehouse.md +0 -5
- package/.claude/skills/cx-module/SKILL.md +28 -103
- package/.claude/skills/cx-module/ref-components-data.md +0 -7
- package/.claude/skills/cx-module/ref-components-display.md +0 -17
- package/.claude/skills/cx-module/ref-components-forms.md +2 -7
- package/.claude/skills/cx-module/ref-components-interactive.md +0 -11
- package/.claude/skills/cx-module/ref-components-layout.md +0 -11
- package/.claude/skills/cx-module/ref-components-specialized.md +0 -50
- package/.claude/skills/cx-workflow/SKILL.md +21 -130
- package/.claude/skills/cx-workflow/ref-communication.md +0 -8
- package/.claude/skills/cx-workflow/ref-entity.md +62 -43
- package/.claude/skills/cx-workflow/ref-expressions.md +272 -0
- package/.claude/skills/cx-workflow/ref-flow.md +6 -12
- package/.claude/skills/cx-workflow/ref-other.md +33 -14
- package/.claude/skills/cx-workflow/ref-utilities.md +87 -14
- package/README.md +34 -34
- package/dist/cli.js +166 -2394
- package/dist/cli.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/validator.d.ts +0 -8
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +2 -54
- package/dist/validator.js.map +1 -1
- package/dist/workflowValidator.d.ts +0 -4
- package/dist/workflowValidator.d.ts.map +1 -1
- package/dist/workflowValidator.js +2 -28
- package/dist/workflowValidator.js.map +1 -1
- package/package.json +2 -3
- package/schemas/actions/all.json +2 -1
- package/schemas/actions/clipboard.json +46 -0
- package/schemas/components/appComponent.json +0 -8
- package/schemas/components/module.json +2 -31
- package/schemas/components/timelineGrid.json +0 -4
- package/schemas/schemas.json +0 -12
- package/schemas/workflows/flow/entity.json +19 -0
- package/schemas/workflows/tasks/all.json +9 -0
- package/schemas/workflows/tasks/authentication.json +12 -26
- package/schemas/workflows/tasks/edi.json +93 -1
- package/schemas/workflows/tasks/httpRequest.json +4 -0
- package/schemas/workflows/tasks/order.json +45 -0
- package/schemas/workflows/tasks/resolve-timezone.json +65 -0
- package/schemas/workflows/tasks/transmission.json +1 -1
- package/schemas/workflows/tasks/unzip-file.json +68 -0
- package/schemas/workflows/variable.json +5 -1
- package/schemas/workflows/workflow.json +4 -0
- package/scripts/postinstall.js +1 -1
- package/templates/module-configuration.yaml +89 -23
- package/templates/module-form.yaml +3 -3
- package/templates/module-grid.yaml +3 -3
- package/templates/module-select.yaml +3 -3
- package/templates/module.yaml +2 -3
- package/templates/workflow-api-tracking.yaml +1 -1
- package/templates/workflow-basic.yaml +1 -1
- package/templates/workflow-document.yaml +1 -1
- package/templates/workflow-entity-trigger.yaml +1 -1
- package/templates/workflow-ftp-edi.yaml +1 -1
- package/templates/workflow-ftp-tracking.yaml +1 -1
- package/templates/workflow-mcp-tool.yaml +1 -1
- package/templates/workflow-public-api.yaml +1 -1
- package/templates/workflow-scheduled.yaml +1 -1
- package/templates/workflow-utility.yaml +1 -1
- package/templates/workflow-webhook.yaml +1 -1
- package/templates/workflow.yaml +1 -1
- package/.claude/skills/cx-core/ref-cli-auth.md +0 -120
- package/.claude/skills/cx-core/ref-graphql-query.md +0 -320
- package/.claude/skills/cx-workflow/ref-expressions-ncalc.md +0 -112
- package/.claude/skills/cx-workflow/ref-expressions-template.md +0 -149
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cx-core
|
|
3
|
-
description:
|
|
4
|
-
Provides shared CXTMS entity field reference — domain entities, field names, enums, and customValues patterns.
|
|
5
|
-
Use when the user asks about CX entity fields, enums, customValues, entity relationships, or needs domain reference for Orders, Contacts, Commodities, Jobs, etc.
|
|
3
|
+
description: Shared CargoXplorer entity field reference — domain entities, field names, enums, and customValues patterns
|
|
6
4
|
argument-hint: <entity name or question about fields>
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
Shared domain reference for CargoXplorer entities. Used by `cx-workflow` and `cx-module` skills for entity field names, types, navigation properties, enums, and customValues extension patterns.
|
|
10
8
|
|
|
11
|
-
## CX Server Authentication & Management
|
|
12
|
-
|
|
13
|
-
For CLI authentication, PAT tokens, org management, and releasing: see [ref-cli-auth.md](ref-cli-auth.md)
|
|
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
|
-
|
|
19
9
|
## Feature File Layout
|
|
20
10
|
|
|
21
11
|
All modules and workflows are organized under feature directories:
|
|
@@ -31,21 +21,49 @@ When creating new modules or workflows, always place them under the correct feat
|
|
|
31
21
|
- `features/<feature_name>/modules/<name>-module.yaml`
|
|
32
22
|
- `features/<feature_name>/workflows/<name>.yaml`
|
|
33
23
|
|
|
34
|
-
Use `--feature <feature_name>` with `
|
|
24
|
+
Use `--feature <feature_name>` with `cx-cli create` to automatically place files in the correct location.
|
|
35
25
|
|
|
36
26
|
## Entity Field Reference
|
|
37
27
|
|
|
38
|
-
|
|
28
|
+
### Primary Entities
|
|
29
|
+
|
|
30
|
+
!cat .claude/skills/cx-core/ref-entity-order.md
|
|
31
|
+
!cat .claude/skills/cx-core/ref-entity-contact.md
|
|
32
|
+
!cat .claude/skills/cx-core/ref-entity-commodity.md
|
|
33
|
+
!cat .claude/skills/cx-core/ref-entity-accounting.md
|
|
34
|
+
|
|
35
|
+
### Order Sub-Entities & Related
|
|
36
|
+
|
|
37
|
+
!cat .claude/skills/cx-core/ref-entity-order-sub.md
|
|
38
|
+
!cat .claude/skills/cx-core/ref-entity-job.md
|
|
39
|
+
|
|
40
|
+
### Pricing & Accounting Lookups
|
|
41
|
+
|
|
42
|
+
!cat .claude/skills/cx-core/ref-entity-rate.md
|
|
43
|
+
|
|
44
|
+
### Shared & Lookup Entities
|
|
45
|
+
|
|
46
|
+
!cat .claude/skills/cx-core/ref-entity-shared.md
|
|
47
|
+
!cat .claude/skills/cx-core/ref-entity-geography.md
|
|
48
|
+
|
|
49
|
+
### Warehouse & Inventory
|
|
50
|
+
|
|
51
|
+
!cat .claude/skills/cx-core/ref-entity-warehouse.md
|
|
52
|
+
|
|
53
|
+
### Notifications
|
|
54
|
+
|
|
55
|
+
!cat .claude/skills/cx-core/ref-entity-notification.md
|
|
39
56
|
|
|
40
57
|
| Category | Entities | Reference |
|
|
41
58
|
|----------|----------|-----------|
|
|
42
|
-
| **Primary** | Order, Contact, Commodity, AccountingTransaction |
|
|
43
|
-
| **Order sub** | OrderEntity, TrackingEvent, EventDefinition, LinkedOrder, OrderDocument |
|
|
44
|
-
| **Job** | Job, JobOrder, JobStatus |
|
|
45
|
-
| **Pricing** | Rate, Lane, Discount, AccountingItem, AccountingAccount, PaymentTerm |
|
|
46
|
-
| **Shared** | Tag, Attachment, Division, EquipmentType, PackageType, Note/NoteThread |
|
|
47
|
-
| **Geography** | Country, State, City, Port, Vessel, CustomCode, ModeOfTransportation |
|
|
48
|
-
| **Warehouse** | InventoryItem, WarehouseLocation, CargoMovement (Order variant) |
|
|
59
|
+
| **Primary** | Order, Contact, Commodity, AccountingTransaction | ref-entity-order/contact/commodity/accounting.md |
|
|
60
|
+
| **Order sub** | OrderEntity, TrackingEvent, EventDefinition, LinkedOrder, OrderDocument | ref-entity-order-sub.md |
|
|
61
|
+
| **Job** | Job, JobOrder, JobStatus | ref-entity-job.md |
|
|
62
|
+
| **Pricing** | Rate, Lane, Discount, AccountingItem, AccountingAccount, PaymentTerm | ref-entity-rate.md |
|
|
63
|
+
| **Shared** | Tag, Attachment, Division, EquipmentType, PackageType, Note/NoteThread | ref-entity-shared.md |
|
|
64
|
+
| **Geography** | Country, State, City, Port, Vessel, CustomCode, ModeOfTransportation | ref-entity-geography.md |
|
|
65
|
+
| **Warehouse** | InventoryItem, WarehouseLocation, CargoMovement (Order variant) | ref-entity-warehouse.md |
|
|
66
|
+
| **Notification** | Notification, UserNotification | ref-entity-notification.md |
|
|
49
67
|
|
|
50
68
|
## CustomValues Pattern
|
|
51
69
|
|
|
@@ -1,12 +1,5 @@
|
|
|
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
|
-
|
|
10
3
|
Field names as used in workflow expressions: `{{ entity.transactionNumber }}`, `{{ entity.customValues.myField }}`.
|
|
11
4
|
|
|
12
5
|
## AccountingTransaction Fields
|
|
@@ -1,17 +1,5 @@
|
|
|
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
|
-
|
|
15
3
|
Field names as used in workflow expressions: `{{ entity.description }}`, `{{ entity.customValues.myField }}`.
|
|
16
4
|
|
|
17
5
|
## Scalar Fields
|
|
@@ -1,15 +1,5 @@
|
|
|
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
|
-
|
|
13
3
|
Field names as used in workflow expressions: `{{ entity.name }}`, `{{ entity.customValues.myField }}`.
|
|
14
4
|
|
|
15
5
|
## Scalar Fields
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
# Geography & Lookup Entity Reference
|
|
2
2
|
|
|
3
|
-
|
|
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.
|
|
3
|
+
Country, State, City, Port, Vessel, CustomCode, ModeOfTransportation.
|
|
14
4
|
|
|
15
5
|
## Country
|
|
16
6
|
|
|
@@ -60,29 +50,6 @@ Composite key: `organizationId` + `countryCode` + `stateCode`.
|
|
|
60
50
|
|
|
61
51
|
---
|
|
62
52
|
|
|
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
|
-
|
|
86
53
|
## Port
|
|
87
54
|
|
|
88
55
|
String-based PK (e.g., UN/LOCODE).
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Notification Entity Reference
|
|
2
|
+
|
|
3
|
+
Real-time notification system. Notifications are org-scoped with per-user read tracking via `UserNotification`.
|
|
4
|
+
|
|
5
|
+
## Notification
|
|
6
|
+
|
|
7
|
+
| Field | Type | Notes |
|
|
8
|
+
|-------|------|-------|
|
|
9
|
+
| `notificationId` | `int` | PK |
|
|
10
|
+
| `organizationId` | `int` | FK to Organization |
|
|
11
|
+
| `title` | `string` | Required |
|
|
12
|
+
| `message` | `string?` | Body text, supports Markdown |
|
|
13
|
+
| `type` | `NotificationType` | System=0, OrderUpdate=1, TaskAssignment=2, Alert=3, Info=4 |
|
|
14
|
+
| `priority` | `NotificationPriority` | Low=0, Normal=1, High=2, Urgent=3 |
|
|
15
|
+
| `targetUserId` | `string?` | If set, targets one user; if null, broadcasts to all active org users |
|
|
16
|
+
| `entityType` | `string?` | Linked entity type (e.g. "Order", "Job") |
|
|
17
|
+
| `entityId` | `int?` | Linked entity PK |
|
|
18
|
+
| `expiresAt` | `DateTime?` | Optional expiration |
|
|
19
|
+
| `created` / `lastModified` | `DateTime` | Audit fields (from `AuditableEntity`) |
|
|
20
|
+
| `createdBy` / `lastModifiedBy` | `string` | Audit fields |
|
|
21
|
+
|
|
22
|
+
### Domain Methods
|
|
23
|
+
|
|
24
|
+
- `ChangeTitle(string)`, `ChangeMessage(string?)`, `ChangeType(NotificationType)`, `ChangePriority(NotificationPriority)`, `ChangeExpiresAt(DateTime?)`
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## UserNotification
|
|
29
|
+
|
|
30
|
+
Per-user read state join entity.
|
|
31
|
+
|
|
32
|
+
| Field | Type | Notes |
|
|
33
|
+
|-------|------|-------|
|
|
34
|
+
| `userNotificationId` | `int` | PK |
|
|
35
|
+
| `notificationId` | `int` | FK to Notification |
|
|
36
|
+
| `userId` | `string` | FK to ApplicationUser |
|
|
37
|
+
| `isRead` | `bool` | Default false |
|
|
38
|
+
| `readAt` | `DateTime?` | Set when marked read |
|
|
39
|
+
|
|
40
|
+
### Domain Methods
|
|
41
|
+
|
|
42
|
+
- `MarkAsRead()` — sets `IsRead = true`, `ReadAt = UtcNow`
|
|
43
|
+
- `MarkAsUnread()` — resets both
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## GraphQL
|
|
48
|
+
|
|
49
|
+
### Queries
|
|
50
|
+
|
|
51
|
+
- `getNotification(organizationId, notificationId)` → single notification for current user (projected from UserNotification)
|
|
52
|
+
- `getNotifications(organizationId, filter?, search?, orderBy?)` → offset-paged list for current user; default sort: `-notification.created`
|
|
53
|
+
- `getUnreadNotificationCount(organizationId)` → int
|
|
54
|
+
|
|
55
|
+
### Mutations
|
|
56
|
+
|
|
57
|
+
- `createNotification(organizationId, values)` → creates Notification + UserNotification rows; publishes to subscription topic per user
|
|
58
|
+
- `markNotificationRead(organizationId, notificationId)` → bool
|
|
59
|
+
- `markAllNotificationsRead(organizationId)` → int (count marked)
|
|
60
|
+
- `deleteNotification(organizationId, notificationId)` → DeleteResult
|
|
61
|
+
|
|
62
|
+
### Subscriptions
|
|
63
|
+
|
|
64
|
+
- `onNotificationReceived(organizationId, userId)` → real-time via PostgreSQL NOTIFY/LISTEN
|
|
65
|
+
- Topic: `{organizationId}_{userId}_notifications`
|
|
66
|
+
|
|
67
|
+
### GraphQL DTO (projected from UserNotification)
|
|
68
|
+
|
|
69
|
+
Flattens `Notification` + `UserNotification` into single DTO: `notificationId`, `organizationId`, `title`, `message`, `type`, `priority`, `targetUserId`, `entityType`, `entityId`, `expiresAt`, `isRead`, `readAt`, `created`, `createdBy`, `lastModified`, `lastModifiedBy`, plus resolved `createdUser` / `updatedUser`.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Targeting Logic
|
|
74
|
+
|
|
75
|
+
On `CreateNotification`:
|
|
76
|
+
1. If `targetUserId` is provided → single `UserNotification` row
|
|
77
|
+
2. If null → queries all active `UserEmployee` records in org → one `UserNotification` per user
|
|
78
|
+
3. After save, publishes `NotificationDto` to each user's subscription topic via `INotificationEventSender`
|
|
79
|
+
|
|
80
|
+
## Infrastructure
|
|
81
|
+
|
|
82
|
+
- `NotificationConfiguration` — EF Core config: title max length, indexes on `OrganizationId`, composite index on `(OrganizationId, Created DESC)` for paging
|
|
83
|
+
- `UserNotificationConfiguration` — indexes on `UserId`, `NotificationId`, composite on `(UserId, IsRead)`
|
|
84
|
+
- `NotificationEventSender` — uses HotChocolate `ITopicEventSender` to publish to subscription topics
|
|
85
|
+
- Real-time delivery: PostgreSQL `NOTIFY/LISTEN` channel (configured in `DependencyInjection`)
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# Order Sub-Entity Field Reference
|
|
2
2
|
|
|
3
|
-
## Contents
|
|
4
|
-
- OrderEntity
|
|
5
|
-
- TrackingEvent
|
|
6
|
-
- EventDefinition
|
|
7
|
-
- LinkedOrder
|
|
8
|
-
- OrderDocument
|
|
9
|
-
|
|
10
3
|
Entities associated with orders: OrderEntity (parties), TrackingEvent, LinkedOrder, OrderDocument.
|
|
11
4
|
|
|
12
5
|
## OrderEntity
|
|
@@ -40,6 +33,13 @@ Represents a party role (Shipper, Consignee, Carrier, etc.) on an order.
|
|
|
40
33
|
- `attachments` — filterable collection
|
|
41
34
|
- `getOrderEntityAttachments(idPropertyName, filter, orderBy, search)` — resolver
|
|
42
35
|
|
|
36
|
+
### Import Behavior (Order/Import)
|
|
37
|
+
|
|
38
|
+
When importing order entities via `Order/Import@1`:
|
|
39
|
+
- The `contact` and `contactAddress` nested objects are excluded from direct field mapping and processed separately.
|
|
40
|
+
- **ContactAddress matching** uses `ImportOrderOptions.ContactAddressMatchByFields` — scoped to organization and (when persisted) to the resolved contact. Supports Lucene filter-based matching on any ContactAddress field (e.g., `["addressLine", "postalCode"]`). If null/empty, falls back to matching by `contactAddressId` only.
|
|
41
|
+
- Both contacts and contact addresses are cached per import session to prevent duplicate creation.
|
|
42
|
+
|
|
43
43
|
### EntityTypes Enum
|
|
44
44
|
|
|
45
45
|
Shipper=0, Consignee=1, Carrier=2, Vendor=3, UltimateConsignee=4, NotifyParty=5, Intermediate=6, ForwardingAgent=7, DestinationAgent=8, PickupFrom=9, DeliverTo=10, DeliveryCarrier=11, ReceivedBy=12, USPPI=13
|
|
@@ -94,12 +94,6 @@ Template/type definition for tracking events.
|
|
|
94
94
|
| `triggerConditionFields` | `string?` | |
|
|
95
95
|
| `customValues` | `Dictionary` | jsonb |
|
|
96
96
|
|
|
97
|
-
### GraphQL Resolvers
|
|
98
|
-
|
|
99
|
-
| Resolver | Arguments | Returns | Description |
|
|
100
|
-
|----------|-----------|---------|-------------|
|
|
101
|
-
| `getContact` | `customValuesKey: String!` | `Contact` | Looks up a Contact by ID stored in `customValues[key]` |
|
|
102
|
-
|
|
103
97
|
---
|
|
104
98
|
|
|
105
99
|
## LinkedOrder
|
|
@@ -1,15 +1,5 @@
|
|
|
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
|
-
|
|
13
3
|
Field names as used in workflow expressions: `{{ entity.orderId }}`, `{{ entity.customValues.myField }}`.
|
|
14
4
|
|
|
15
5
|
## Scalar Fields
|
|
@@ -65,8 +55,6 @@ Field names as used in workflow expressions: `{{ entity.orderId }}`, `{{ entity.
|
|
|
65
55
|
| `orderCarriers` | `[OrderCarrier]` | |
|
|
66
56
|
| `allTags` | `[OrderAllTagsView]` | View: all tags including from commodities |
|
|
67
57
|
| `allRelatedOrders` | `[OrderRelatedOrdersView]` | Orders sharing commodities |
|
|
68
|
-
| `attachmentsSummary` | `OrderAttachmentSummaryView?` | DB view: `.totalCount`, `.hasAny` (active attachments) |
|
|
69
|
-
| `notesSummary` | `OrderNoteSummaryView?` | DB view: `.totalCount`, `.hasAny` (non-deleted notes) |
|
|
70
58
|
| `outgoingLinks` | `[LinkedOrder]` | |
|
|
71
59
|
| `incomingLinks` | `[LinkedOrder]` | |
|
|
72
60
|
|
|
@@ -109,10 +97,9 @@ These are virtual fields that filter `orderEntities` by type:
|
|
|
109
97
|
| `getChargesByChargeType(chargeType)` | `[Charge]` | Charges filtered by type |
|
|
110
98
|
| `getOrderSummary(weightUnit, volumeUnit, dimensionsUnit)` | `OrderSummary` | |
|
|
111
99
|
| `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 |
|
|
114
100
|
| `notesCount(threadFilter)` | `int` | |
|
|
115
101
|
| `changeHistory(startDate, endDate, maxResults)` | `[ChangeHistory]` | Audit trail |
|
|
102
|
+
| `getCommoditiesWithRelatedOrder(orderType!, filter?)` | `[Commodity]` | Leaf commodities linked to related orders of specified type. Traverses commodity hierarchy, excludes wrappers. |
|
|
116
103
|
|
|
117
104
|
## OrderTypes Enum
|
|
118
105
|
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
# Shared Entity Reference
|
|
2
2
|
|
|
3
|
-
## Contents
|
|
4
|
-
- Tag
|
|
5
|
-
- Attachment
|
|
6
|
-
- Division
|
|
7
|
-
- EquipmentType
|
|
8
|
-
- PackageType
|
|
9
|
-
- NoteThread
|
|
10
|
-
- Note
|
|
11
|
-
|
|
12
3
|
Tag, Attachment, Division, EquipmentType, PackageType, Note/NoteThread.
|
|
13
4
|
|
|
14
5
|
## Tag
|
|
@@ -154,3 +145,23 @@ No customValues. Linked to carriers via `CarrierEquipment` join.
|
|
|
154
145
|
| `isDeleted` | `bool` | Soft delete |
|
|
155
146
|
|
|
156
147
|
**Navigation:** `thread` (NoteThread)
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Secret
|
|
152
|
+
|
|
153
|
+
Encrypted key-value store for sensitive configuration (API keys, tokens, credentials). Encrypted at rest with AES-256; scoped to organizations via qualified naming.
|
|
154
|
+
|
|
155
|
+
| Field | Type | Notes |
|
|
156
|
+
|-------|------|-------|
|
|
157
|
+
| `id` | `int` | PK |
|
|
158
|
+
| `secretName` | `string` | Qualified name: `org/{organizationId}/{secretName}`. Unique index. Max 500 chars. |
|
|
159
|
+
| `encryptedValue` | `string` | AES-256 encrypted, base64-encoded (random IV prepended) |
|
|
160
|
+
| `createdAt` | `DateTime` | |
|
|
161
|
+
| `updatedAt` | `DateTime` | |
|
|
162
|
+
|
|
163
|
+
**Table:** `secrets` (snake_case columns)
|
|
164
|
+
**Provider:** `PostgresSecretManager` (default) or `AzureKeyVault` via `SecretManager:Provider` config.
|
|
165
|
+
|
|
166
|
+
**GraphQL mutations:** `setSecret(organizationId, secretName, secretValue)`, `deleteSecret(organizationId, secretName)`.
|
|
167
|
+
**Org scoping:** Commands validate user org membership; qualified name `org/{orgId}/{name}` is built by the command handler.
|
|
@@ -1,36 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cx-module
|
|
3
|
-
description:
|
|
4
|
-
Works with CXTMS app module YAML files — creates, modifies, fixes, validates, and deploys UI screens, forms, grids, and routes.
|
|
5
|
-
Use when the user asks to create, modify, or fix a module YAML file, references *-module.yaml files, or asks about UI components/forms/grids/routes in a CX project.
|
|
6
|
-
Not for workflow YAML files, TypeScript code, or non-YAML tasks.
|
|
3
|
+
description: Generate schema-valid CargoXplorer app module YAML files (UI screens, forms, grids, routes)
|
|
7
4
|
argument-hint: <description of what to build>
|
|
8
5
|
---
|
|
9
6
|
|
|
10
7
|
You are a CargoXplorer module YAML builder. You generate schema-valid YAML for CX app modules — UI screens, forms, data grids, routes, and components. All output must conform to the JSON schemas in `.cx-schema/`.
|
|
11
8
|
|
|
12
|
-
**IMPORTANT — use `
|
|
13
|
-
- **Scaffold**: `npx
|
|
14
|
-
- **Scaffold with fields**: `npx
|
|
15
|
-
- **Validate**: `npx
|
|
16
|
-
- **Schema lookup**: `npx
|
|
17
|
-
- **Examples**: `npx
|
|
18
|
-
- **List schemas**: `npx
|
|
19
|
-
- **Extract**: `npx
|
|
20
|
-
- **Feature folder**: `npx
|
|
21
|
-
- **Deploy to server**: `npx cxtms appmodule deploy <file.yaml> --org <id>` — creates or updates module on the CX server
|
|
22
|
-
- **Undeploy from server**: `npx cxtms appmodule undeploy <appModuleId> --org <id>` — removes a module by UUID
|
|
23
|
-
- **Publish all**: `npx cxtms publish [--feature <name>] --org <id>` — deploy all modules and workflows to the server
|
|
9
|
+
**IMPORTANT — use `cx-cli` for all module operations:**
|
|
10
|
+
- **Scaffold**: `npx cx-cli create module <name> --template <template>` — generates a schema-valid YAML file. ALWAYS run this first, then read the generated file, then customize. Do NOT write YAML from scratch or copy templates manually.
|
|
11
|
+
- **Scaffold with fields**: `npx cx-cli create module <name> --template <template> --options '<json>'`
|
|
12
|
+
- **Validate**: `npx cx-cli <file.yaml>` — run after every change
|
|
13
|
+
- **Schema lookup**: `npx cx-cli schema <component>` — e.g., `cx-cli schema form`, `cx-cli schema dataGrid`
|
|
14
|
+
- **Examples**: `npx cx-cli example <component>` — show example YAML
|
|
15
|
+
- **List schemas**: `npx cx-cli list`
|
|
16
|
+
- **Extract**: `npx cx-cli extract <source> <component> --to <target>` — move components between modules
|
|
17
|
+
- **Feature folder**: `npx cx-cli create module <name> --template <template> --feature <feature-name>`
|
|
24
18
|
|
|
25
19
|
## Generation Workflow
|
|
26
20
|
|
|
27
21
|
### Step 1: Scaffold via CLI — MANDATORY
|
|
28
22
|
|
|
29
|
-
**You MUST run `
|
|
23
|
+
**You MUST run `cx-cli create module` to generate the initial file.** Do not skip this step. Do not write YAML from scratch. Do not read template files and copy them manually. The CLI generates correct UUIDs, file paths, and structure.
|
|
30
24
|
|
|
31
25
|
```bash
|
|
32
|
-
npx
|
|
33
|
-
npx
|
|
26
|
+
npx cx-cli create module <name> --template <template>
|
|
27
|
+
npx cx-cli create module <name> --template <template> --options '<json>'
|
|
34
28
|
```
|
|
35
29
|
|
|
36
30
|
| Template | Use Case |
|
|
@@ -58,7 +52,7 @@ npx cxtms create module <name> --template <template> --options '<json>'
|
|
|
58
52
|
### Step 4: Validate
|
|
59
53
|
|
|
60
54
|
```bash
|
|
61
|
-
npx
|
|
55
|
+
npx cx-cli <generated-file.yaml>
|
|
62
56
|
```
|
|
63
57
|
|
|
64
58
|
---
|
|
@@ -70,7 +64,7 @@ Customize generated modules at scaffold time with `--options`. Accepts inline JS
|
|
|
70
64
|
### Field Array Format (all templates)
|
|
71
65
|
|
|
72
66
|
```bash
|
|
73
|
-
npx
|
|
67
|
+
npx cx-cli create module "Tariff" --template grid --options '[
|
|
74
68
|
{"name": "code", "type": "text", "label": "Tariff Code", "required": true},
|
|
75
69
|
{"name": "rate", "type": "number", "label": "Rate %"},
|
|
76
70
|
{"name": "effectiveDate", "type": "date"},
|
|
@@ -81,7 +75,7 @@ npx cxtms create module "Tariff" --template grid --options '[
|
|
|
81
75
|
### Object Format (with entityName)
|
|
82
76
|
|
|
83
77
|
```bash
|
|
84
|
-
npx
|
|
78
|
+
npx cx-cli create module "Country" --template select --options '{
|
|
85
79
|
"entityName": "Country",
|
|
86
80
|
"fields": [
|
|
87
81
|
{"name": "countryCode", "type": "text", "label": "Country Code"},
|
|
@@ -113,18 +107,13 @@ npx cxtms create module "Country" --template select --options '{
|
|
|
113
107
|
|
|
114
108
|
## Extract Command
|
|
115
109
|
|
|
116
|
-
Move
|
|
110
|
+
Move a component (and its routes) from one module into another. Useful for splitting large modules into smaller, focused ones.
|
|
117
111
|
|
|
118
112
|
```bash
|
|
119
|
-
|
|
120
|
-
cxtms extract <source-file> <component-name> --to <target-file> --copy
|
|
113
|
+
cx-cli extract <source-file> <component-name> --to <target-file>
|
|
121
114
|
```
|
|
122
115
|
|
|
123
|
-
###
|
|
124
|
-
- `--to <file>` — target module file (required)
|
|
125
|
-
- `--copy` — copy instead of move (source keeps the component, target gets a higher-priority copy)
|
|
126
|
-
|
|
127
|
-
### What Gets Moved/Copied
|
|
116
|
+
### What Gets Moved
|
|
128
117
|
- The component matching the exact `name` field
|
|
129
118
|
- Any routes whose `component` field matches the component name
|
|
130
119
|
- Permissions and entities are **NOT** moved
|
|
@@ -132,14 +121,11 @@ cxtms extract <source-file> <component-name> --to <target-file> --copy
|
|
|
132
121
|
### Examples
|
|
133
122
|
|
|
134
123
|
```bash
|
|
135
|
-
#
|
|
136
|
-
npx
|
|
137
|
-
|
|
138
|
-
# Copy a component (source unchanged, target gets higher priority)
|
|
139
|
-
npx cxtms extract modules/orders.yaml Orders/CreateItem --to modules/order-create.yaml --copy
|
|
124
|
+
# Extract to a new file (creates module scaffold automatically)
|
|
125
|
+
npx cx-cli extract modules/orders.yaml Orders/CreateItem --to modules/order-create.yaml
|
|
140
126
|
|
|
141
127
|
# Extract to an existing module
|
|
142
|
-
npx
|
|
128
|
+
npx cx-cli extract modules/main.yaml Dashboard --to modules/dashboard.yaml
|
|
143
129
|
```
|
|
144
130
|
|
|
145
131
|
### New Target Scaffold
|
|
@@ -152,7 +138,7 @@ When the target file doesn't exist, a new module is created with:
|
|
|
152
138
|
### Workflow
|
|
153
139
|
1. Run `extract` to move the component
|
|
154
140
|
2. Manually move any related permissions/entities if needed
|
|
155
|
-
3. Validate both files: `npx
|
|
141
|
+
3. Validate both files: `npx cx-cli <source>` and `npx cx-cli <target>`
|
|
156
142
|
|
|
157
143
|
---
|
|
158
144
|
|
|
@@ -212,7 +198,7 @@ module:
|
|
|
212
198
|
description:
|
|
213
199
|
en-US: "Module description"
|
|
214
200
|
application: "CargoXplorer" # Required
|
|
215
|
-
|
|
201
|
+
fileName: "modules/<name>-module.yaml" # File path in repo
|
|
216
202
|
|
|
217
203
|
entities:
|
|
218
204
|
- name: <EntityName>
|
|
@@ -238,15 +224,6 @@ permissions:
|
|
|
238
224
|
displayName: { en-US: "..." }
|
|
239
225
|
roles: ["Admin", "Manager"]
|
|
240
226
|
|
|
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
|
-
|
|
250
227
|
routes:
|
|
251
228
|
- name: "routeName"
|
|
252
229
|
path: "/module-path" # Supports :params
|
|
@@ -407,61 +384,9 @@ Reusable select components (e.g., `Countries/Select`, `Ports/Select`) follow thi
|
|
|
407
384
|
|
|
408
385
|
---
|
|
409
386
|
|
|
410
|
-
## Server Module Commands
|
|
411
|
-
|
|
412
|
-
Deploy, undeploy, and release commands are listed in the CLI section at the top of this file. For authentication setup (login, PAT tokens, org management): see [cx-core/ref-cli-auth.md](.claude/skills/cx-core/ref-cli-auth.md)
|
|
413
|
-
|
|
414
|
-
### Releasing App to GitHub
|
|
415
|
-
|
|
416
|
-
Use `app release` to release modified modules and workflows from the CX server to a GitHub repository. This creates a branch and pull request — it does NOT push directly to the target branch.
|
|
417
|
-
|
|
418
|
-
```bash
|
|
419
|
-
# Release all unpublished changes to GitHub (creates a PR) — message is required
|
|
420
|
-
npx cxtms app release -m "Add warehouse locations module"
|
|
421
|
-
|
|
422
|
-
# Release specific modules and/or workflows by YAML file
|
|
423
|
-
npx cxtms app release -m "Fix country module" modules/my-module.yaml
|
|
424
|
-
npx cxtms app release -m "Update billing" modules/a.yaml workflows/b.yaml
|
|
425
|
-
|
|
426
|
-
# Force release all modules and workflows (not just unpublished ones)
|
|
427
|
-
npx cxtms app release -m "Full republish" --force
|
|
428
|
-
|
|
429
|
-
# Release with explicit org
|
|
430
|
-
npx cxtms app release -m "Add warehouse locations module" --org 42
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
**What `app release` does:**
|
|
434
|
-
1. Reads `app.yaml` for the `id` (appManifestId), repository, and branch
|
|
435
|
-
2. Increments the app version (patch bump)
|
|
436
|
-
3. Creates a `publish/{app-name}-v{version}-{timestamp}` branch on GitHub
|
|
437
|
-
4. Commits `app.yaml` + selected module/workflow YAML files to the branch
|
|
438
|
-
5. Creates a pull request from the publish branch to the target branch
|
|
439
|
-
6. Marks published modules and workflows as `hasUnpublishedChanges: false`
|
|
440
|
-
|
|
441
|
-
**This is a release-to-git operation** — it commits the current server-side YAML directly to GitHub via the API. No local git repo is involved. The modules and workflows being released are taken from the CX server database, not from local files. The YAML file arguments only identify *which* items to include by their IDs.
|
|
442
|
-
|
|
443
|
-
**Important:** Modules and workflows must be deployed to the TMS server before they can be released. Use `cxtms appmodule deploy` or `cxtms workflow deploy` first, then `cxtms app release` to commit them to GitHub.
|
|
444
|
-
|
|
445
|
-
**Do NOT run `app release` automatically.** Only release when the user explicitly requests it. Releasing creates a branch and PR on GitHub, so it should be done once when all changes are ready — not after every deploy.
|
|
446
|
-
|
|
447
|
-
**Prerequisites:**
|
|
448
|
-
- `app.yaml` must exist with a valid `id` field
|
|
449
|
-
- The app manifest must be installed on the server (`app install` first)
|
|
450
|
-
- The server must have a GitHub token configured for the organization
|
|
451
|
-
- The repository and branch must be set on the app manifest
|
|
452
|
-
|
|
453
|
-
**Related commands:**
|
|
454
|
-
- `npx cxtms app install` — install/refresh app from GitHub into the server
|
|
455
|
-
- `npx cxtms app install --force` — force reinstall even if same version
|
|
456
|
-
- `npx cxtms app install --branch develop` — install from a specific branch
|
|
457
|
-
- `npx cxtms app install --skip-changed` — skip modules with local changes
|
|
458
|
-
- `npx cxtms app list` — list installed app manifests on the server
|
|
459
|
-
|
|
460
|
-
---
|
|
461
|
-
|
|
462
387
|
# Generation Rules
|
|
463
388
|
|
|
464
|
-
1. **Always scaffold via `
|
|
389
|
+
1. **Always scaffold via `cx-cli create module` first** — never write YAML from scratch, never copy templates manually
|
|
465
390
|
2. **Use localized strings** `{ en-US: "..." }` for all user-visible text
|
|
466
391
|
3. **Follow naming conventions**:
|
|
467
392
|
- Module names: PascalCase (e.g., `WarehouseLocations`)
|
|
@@ -469,9 +394,9 @@ npx cxtms app release -m "Add warehouse locations module" --org 42
|
|
|
469
394
|
- Route paths: kebab-case (e.g., `/warehouse-locations`)
|
|
470
395
|
- Permission names: PascalCase with slashes (e.g., `WarehouseLocations/Read`, `System/Contacts/Update`)
|
|
471
396
|
4. **Template expressions** use `{{ expression }}` syntax (double curly braces)
|
|
472
|
-
5. **Include
|
|
397
|
+
5. **Include fileName** property pointing to the YAML file location
|
|
473
398
|
6. **Set proper entityKind** when defining entities (Order, Contact, OrderEntity, AccountingTransaction, Calendar, CalendarEvent, Other)
|
|
474
399
|
7. **DataGrid options** requires ALL properties: query, rootEntityName, entityKeys, navigationType, enableDynamicGrid, enableViews, enableSearch, enablePagination, enableColumns, enableFilter, defaultView, onRowClick
|
|
475
400
|
8. **Form component** requires `validationSchema` in props
|
|
476
|
-
9. **Do not change `appModuleId` or `
|
|
477
|
-
10. **Always validate** the final YAML: `npx
|
|
401
|
+
9. **Do not change `appModuleId` or `fileName`** — set correctly by CLI scaffold
|
|
402
|
+
10. **Always validate** the final YAML: `npx cx-cli <file.yaml>`
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# Data & Collection Components
|
|
2
2
|
|
|
3
|
-
## Contents
|
|
4
|
-
- Collection component
|
|
5
|
-
- List component
|
|
6
|
-
- ListItem component
|
|
7
|
-
- Datasource component
|
|
8
|
-
- Script component
|
|
9
|
-
|
|
10
3
|
## collection
|
|
11
4
|
|
|
12
5
|
Iterates over data items and renders children as templates. Supports drag-and-drop reordering.
|