@schandlergarcia/sf-web-components 1.9.88 → 2.1.0
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/.a4drules/features/command-center-dashboard-rule.md +1 -1
- package/.a4drules/skills/command-center-builder/SKILL.md +33 -36
- package/.a4drules/skills/command-center-builder/getting-started.md +64 -104
- package/.a4drules/skills/command-center-builder/improved-build-process.md +28 -34
- package/.a4drules/skills/command-center-guide/SKILL.md +9 -9
- package/.a4drules/skills/command-center-project/SKILL.md +4 -5
- package/.a4drules/skills/component-library/SKILL.md +8 -10
- package/.a4drules/skills/component-library/card-components.md +3 -3
- package/.a4drules/skills/component-library/chat-data.md +4 -6
- package/.a4drules/troubleshooting/codegen-overwrites-types.md +21 -162
- package/.a4drules/troubleshooting/graphql-introspection-failure.md +13 -264
- package/.a4drules/validation-requirements.md +3 -5
- package/.a4drules/webapp-data.md +1 -1
- package/CHANGELOG.md +33 -0
- package/CLAUDE.md +42 -39
- package/brands/engine/brand.css +40 -0
- package/brands/engine/global.css +234 -0
- package/dist/components/library/cards/ActivityCard.js +9 -9
- package/dist/components/library/cards/ActivityCard.js.map +1 -1
- package/dist/styles/base.css +112 -27
- package/dist/styles/global.css +15 -30
- package/package.json +7 -4
- package/scripts/apply-brand.mjs +178 -0
- package/scripts/postinstall.mjs +24 -201
- package/scripts/reset-command-center.sh +53 -411
- package/scripts/validate-dashboard.sh +4 -4
- package/src/components/library/cards/ActivityCard.jsx +2 -2
- package/src/styles/base.css +223 -0
- package/src/styles/global.css +223 -0
- package/src/templates/config/vite.config.ts.template +0 -18
- package/.a4drules/features/engine-dashboard-rule.md +0 -63
- package/.a4drules/features/phase2-data-pattern.md +0 -15
- package/data/README.md +0 -202
- package/data/USAGE.md +0 -81
- package/data/copy-to-webapp.sh +0 -61
- package/scripts/generate-schema-from-sample.mjs +0 -370
- /package/{data → brands/engine}/agentApiConfig.ts +0 -0
- /package/{data → brands/engine}/engine-command-center-prd.md +0 -0
- /package/{data → brands/engine}/engine-live-data.js +0 -0
- /package/{data → brands/engine}/engine-sample-data.js +0 -0
- /package/{assets/images → brands/engine}/engine_logo.png +0 -0
- /package/{data → brands/engine}/schema.graphql +0 -0
- /package/{data → brands/engine}/useEngineLiveData.ts +0 -0
- /package/{data → brands/engine}/useEvaAgent.ts +0 -0
package/data/README.md
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
# Data Assets
|
|
2
|
-
|
|
3
|
-
This directory contains pre-packaged data assets for demo builds and prototyping.
|
|
4
|
-
|
|
5
|
-
## Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
data/
|
|
9
|
-
├── engine-sample-data.js # Engine Travel Command Center sample data
|
|
10
|
-
├── schema.graphql # Pre-built GraphQL schema from sample data
|
|
11
|
-
└── README.md # This file
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Engine Travel Command Center Sample Data
|
|
15
|
-
|
|
16
|
-
**Purpose:** Pre-seeded, dashboard-ready data for the Engine Travel demo. All field names match the Salesforce org schema (Trip__c, Flight__c, Booking__c, Disruption__c, Rebooking_Action__c, Travel_Policy__c) so switching from sample → live queries requires only a data-source swap.
|
|
17
|
-
|
|
18
|
-
**Exports:**
|
|
19
|
-
|
|
20
|
-
Raw Salesforce-shaped records:
|
|
21
|
-
- `AIRPORTS` — Airport reference data with coordinates
|
|
22
|
-
- `TRAVELERS` — Contact records (travelers)
|
|
23
|
-
- `TRIPS` — Trip__c records
|
|
24
|
-
- `FLIGHTS` — Flight__c records with real-time status
|
|
25
|
-
- `HOTELS` — Hotel reservation records
|
|
26
|
-
- `DISRUPTIONS` — Disruption__c records (delays, weather, closures)
|
|
27
|
-
- `BOOKINGS` — Upcoming booking records
|
|
28
|
-
- `REBOOKING_ACTIONS` — Rebooking_Action__c records (Eva activity)
|
|
29
|
-
- `TRAVEL_POLICIES` — Travel_Policy__c records
|
|
30
|
-
- `ACCOUNT` — Account stats
|
|
31
|
-
- `MONTHLY_SPEND` — Spend history aggregated by month
|
|
32
|
-
|
|
33
|
-
Dashboard-ready derivatives (pre-computed for immediate use):
|
|
34
|
-
- `MAP_MARKERS` — City markers for GeoMap
|
|
35
|
-
- `MAP_ARCS` — Flight arcs with progress & danger flags
|
|
36
|
-
- `MAP_OVERLAYS` — Weather/disruption overlay circles
|
|
37
|
-
- `FLIGHT_STATUS_LIST` — Glass strip flight status data
|
|
38
|
-
- `TRAVELER_CARDS` — Traveler card props
|
|
39
|
-
- `DISRUPTION_CARDS` — Disruption card props
|
|
40
|
-
- `EVA_ACTIONS` — Eva activity feed items
|
|
41
|
-
- `BOOKING_ROWS` — Booking table rows
|
|
42
|
-
- `POLICY_ITEMS` — Policy status items
|
|
43
|
-
- `DESTINATION_CHART_DATA` — Destination bar chart data
|
|
44
|
-
- `SPEND_CHART_DATA` — Spend trend line data
|
|
45
|
-
- `METRICS` — Computed KPI metrics (active travelers, spend MTD, compliance rate, etc.)
|
|
46
|
-
|
|
47
|
-
**Installation:**
|
|
48
|
-
|
|
49
|
-
Automatically installed to `src/data/engine-sample-data.js` by postinstall script.
|
|
50
|
-
|
|
51
|
-
**Import in components:**
|
|
52
|
-
|
|
53
|
-
```javascript
|
|
54
|
-
import {
|
|
55
|
-
MAP_MARKERS,
|
|
56
|
-
MAP_ARCS,
|
|
57
|
-
MAP_OVERLAYS,
|
|
58
|
-
FLIGHT_STATUS_LIST,
|
|
59
|
-
TRAVELER_CARDS,
|
|
60
|
-
DISRUPTION_CARDS,
|
|
61
|
-
EVA_ACTIONS,
|
|
62
|
-
BOOKING_ROWS,
|
|
63
|
-
POLICY_ITEMS,
|
|
64
|
-
DESTINATION_CHART_DATA,
|
|
65
|
-
SPEND_CHART_DATA,
|
|
66
|
-
METRICS,
|
|
67
|
-
} from '@/data/engine-sample-data';
|
|
68
|
-
|
|
69
|
-
// Use directly in components
|
|
70
|
-
<GeoMap markers={MAP_MARKERS} arcs={MAP_ARCS} overlays={MAP_OVERLAYS} />
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Switching to live Data Cloud:**
|
|
74
|
-
|
|
75
|
-
The sample data uses the same field names as your Salesforce org schema. When you're ready to switch to live data:
|
|
76
|
-
|
|
77
|
-
1. Query the objects using GraphQL or REST:
|
|
78
|
-
- Trip__c
|
|
79
|
-
- Flight__c
|
|
80
|
-
- Booking__c
|
|
81
|
-
- Disruption__c
|
|
82
|
-
- Rebooking_Action__c
|
|
83
|
-
- Travel_Policy__c
|
|
84
|
-
|
|
85
|
-
2. Transform the query results using the same shape as the dashboard-ready exports
|
|
86
|
-
|
|
87
|
-
3. Replace the imports — your components don't need to change
|
|
88
|
-
|
|
89
|
-
**Field mapping reference:**
|
|
90
|
-
|
|
91
|
-
All sample data uses Salesforce API field names:
|
|
92
|
-
- Standard fields: `Id`, `Name`, `CreatedDate`
|
|
93
|
-
- Custom fields: `Trip__c`, `Flight_Number__c`, `Departure_Airport__c`, `Status__c`, etc.
|
|
94
|
-
- Relationships: `Contact__c`, `Trip__c`, `Impacted_Flight__c`
|
|
95
|
-
|
|
96
|
-
## GraphQL Schema
|
|
97
|
-
|
|
98
|
-
**Purpose:** Pre-built GraphQL schema for Engine Travel Command Center. Works even when org introspection is broken.
|
|
99
|
-
|
|
100
|
-
**Problem it solves:**
|
|
101
|
-
|
|
102
|
-
Org introspection can fail with "cannot invoke FieldDataType.equals(Object) because the return value of Field.getDataType() is null". This breaks:
|
|
103
|
-
- `npm run graphql:schema` (introspection query)
|
|
104
|
-
- IDE autocomplete that queries org directly
|
|
105
|
-
- GraphQL codegen from org schema
|
|
106
|
-
|
|
107
|
-
But **queries still work** - introspection is just metadata.
|
|
108
|
-
|
|
109
|
-
**IMPORTANT: Codegen Auto-Run Disabled**
|
|
110
|
-
|
|
111
|
-
This schema is **minimal** - it only contains Engine objects (Trip__c, Flight__c, etc.), not standard objects (Account, Contact, etc.).
|
|
112
|
-
|
|
113
|
-
If you run `npm run graphql:codegen`, it will generate types from this minimal schema, which will be missing standard object types like `NullOrder`.
|
|
114
|
-
|
|
115
|
-
**The vite.config.ts template has codegen auto-run disabled** to prevent this:
|
|
116
|
-
- `runOnStart: false` - Won't run when you start dev server
|
|
117
|
-
- `runOnBuild: false` - Won't run during build
|
|
118
|
-
- `enableWatcher: false` - Won't watch for changes
|
|
119
|
-
|
|
120
|
-
**Only run codegen manually** when you specifically want to regenerate from the minimal schema.
|
|
121
|
-
|
|
122
|
-
See `.a4drules/troubleshooting/codegen-overwrites-types.md` for details.
|
|
123
|
-
|
|
124
|
-
**Solution:**
|
|
125
|
-
|
|
126
|
-
Pre-generate schema from sample data field names:
|
|
127
|
-
1. Sample data already has correct Salesforce field names
|
|
128
|
-
2. Generate `schema.graphql` from those field names
|
|
129
|
-
3. Check schema into repo (automatically installed)
|
|
130
|
-
4. GraphQL skills use the pre-built schema
|
|
131
|
-
5. Queries execute normally using the same field names
|
|
132
|
-
|
|
133
|
-
**Installation:**
|
|
134
|
-
|
|
135
|
-
Automatically installed to `schema.graphql` (webapp root) by postinstall script.
|
|
136
|
-
|
|
137
|
-
**Contents:**
|
|
138
|
-
|
|
139
|
-
```graphql
|
|
140
|
-
schema {
|
|
141
|
-
query: Query
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
type Query {
|
|
145
|
-
uiapi: UIAPI!
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
type UIAPI {
|
|
149
|
-
query: UIAPIQuery!
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
type UIAPIQuery {
|
|
153
|
-
Contact(first: Int, after: String, where: ContactFilter): ContactConnection
|
|
154
|
-
Trip__c(first: Int, after: String, where: Trip__cFilter): Trip__cConnection
|
|
155
|
-
Flight__c(first: Int, after: String, where: Flight__cFilter): Flight__cConnection
|
|
156
|
-
Booking__c(first: Int, after: String, where: Booking__cFilter): Booking__cConnection
|
|
157
|
-
Disruption__c(first: Int, after: String, where: Disruption__cFilter): Disruption__cConnection
|
|
158
|
-
Rebooking_Action__c(first: Int, after: String, where: Rebooking_Action__cFilter): Rebooking_Action__cConnection
|
|
159
|
-
Travel_Policy__c(first: Int, after: String, where: Travel_Policy__cFilter): Travel_Policy__cConnection
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
# ... Full schema with all types, connections, filters
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
**What this enables:**
|
|
166
|
-
|
|
167
|
-
- ✅ `exploring-webapp-graphql-schema` skill works normally
|
|
168
|
-
- ✅ `generating-webapp-graphql-read-query` skill works normally
|
|
169
|
-
- ✅ `using-webapp-graphql` skill works normally
|
|
170
|
-
- ✅ IDE autocomplete and validation
|
|
171
|
-
- ✅ GraphQL codegen
|
|
172
|
-
- ✅ Normal Phase 3 workflow without manual workarounds
|
|
173
|
-
- ✅ Works in CI/CD without org access
|
|
174
|
-
|
|
175
|
-
**Regenerating:**
|
|
176
|
-
|
|
177
|
-
If you add new fields to sample data:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
# From the webapp directory
|
|
181
|
-
npm run graphql:schema:sample
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
This regenerates `schema.graphql` from the current sample data file. Then commit the updated schema to git.
|
|
185
|
-
|
|
186
|
-
## Adding New Data Assets
|
|
187
|
-
|
|
188
|
-
When adding new sample data:
|
|
189
|
-
|
|
190
|
-
1. Create a new `.js` file in this directory
|
|
191
|
-
2. Use Salesforce API field names throughout
|
|
192
|
-
3. Export both raw records AND dashboard-ready derivatives
|
|
193
|
-
4. Document the exports in this README
|
|
194
|
-
5. Include transformation functions if needed
|
|
195
|
-
|
|
196
|
-
## Guidelines
|
|
197
|
-
|
|
198
|
-
- **Field names must match Salesforce schema** — this makes the live data swap seamless
|
|
199
|
-
- **Pre-compute dashboard derivatives** — components should receive ready-to-render data
|
|
200
|
-
- **Include realistic variety** — different statuses, edge cases, empty states
|
|
201
|
-
- **Use ISO dates** — easier to parse and localize
|
|
202
|
-
- **Keep data fresh** — dates relative to current time where relevant
|
package/data/USAGE.md
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# Using Sample Data from the Package
|
|
2
|
-
|
|
3
|
-
When you install `@schandlergarcia/sf-web-components`, the sample data is included in the package.
|
|
4
|
-
|
|
5
|
-
## Quick Copy Command
|
|
6
|
-
|
|
7
|
-
From your webapp directory:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Copy sample data to your webapp's src/data directory
|
|
11
|
-
cp node_modules/@schandlergarcia/sf-web-components/data/engine-sample-data.js src/data/
|
|
12
|
-
|
|
13
|
-
# Or use the included copy script
|
|
14
|
-
bash node_modules/@schandlergarcia/sf-web-components/data/copy-to-webapp.sh .
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Manual Copy
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# Create data directory if it doesn't exist
|
|
21
|
-
mkdir -p src/data
|
|
22
|
-
|
|
23
|
-
# Copy the sample data file
|
|
24
|
-
cp node_modules/@schandlergarcia/sf-web-components/data/engine-sample-data.js src/data/
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Import in Your Components
|
|
28
|
-
|
|
29
|
-
Once copied to `src/data/`, import the data:
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
import {
|
|
33
|
-
MAP_MARKERS,
|
|
34
|
-
MAP_ARCS,
|
|
35
|
-
MAP_OVERLAYS,
|
|
36
|
-
FLIGHT_STATUS_LIST,
|
|
37
|
-
TRAVELER_CARDS,
|
|
38
|
-
DISRUPTION_CARDS,
|
|
39
|
-
EVA_ACTIONS,
|
|
40
|
-
BOOKING_ROWS,
|
|
41
|
-
POLICY_ITEMS,
|
|
42
|
-
DESTINATION_CHART_DATA,
|
|
43
|
-
SPEND_CHART_DATA,
|
|
44
|
-
METRICS,
|
|
45
|
-
} from '@/data/engine-sample-data';
|
|
46
|
-
|
|
47
|
-
// Use in components
|
|
48
|
-
<GeoMap markers={MAP_MARKERS} arcs={MAP_ARCS} overlays={MAP_OVERLAYS} />
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## What's Included
|
|
52
|
-
|
|
53
|
-
See the [README.md](./README.md) for full documentation of available data exports.
|
|
54
|
-
|
|
55
|
-
**Raw Salesforce records:**
|
|
56
|
-
- AIRPORTS, TRAVELERS, TRIPS, FLIGHTS, HOTELS, DISRUPTIONS, BOOKINGS, etc.
|
|
57
|
-
|
|
58
|
-
**Dashboard-ready derivatives:**
|
|
59
|
-
- MAP_MARKERS, MAP_ARCS, FLIGHT_STATUS_LIST, TRAVELER_CARDS, etc.
|
|
60
|
-
|
|
61
|
-
All data uses real Salesforce API field names, making it easy to swap for live data later.
|
|
62
|
-
|
|
63
|
-
## Why Copy Instead of Import Directly?
|
|
64
|
-
|
|
65
|
-
The data file is intentionally designed to be copied to your `src/` directory rather than imported directly from `node_modules` because:
|
|
66
|
-
|
|
67
|
-
1. **Customization** - You can modify the sample data to match your specific use case
|
|
68
|
-
2. **Version control** - Your data lives in your repo, not tied to package updates
|
|
69
|
-
3. **Build optimization** - Some bundlers work better with files in `src/`
|
|
70
|
-
4. **Switching to live data** - When ready, you replace the file with live queries
|
|
71
|
-
|
|
72
|
-
## Switching to Live Data
|
|
73
|
-
|
|
74
|
-
When you're ready to use live Salesforce data:
|
|
75
|
-
|
|
76
|
-
1. Create a new file `src/data/live-data.js`
|
|
77
|
-
2. Query the Salesforce objects (Trip__c, Flight__c, etc.) using GraphQL
|
|
78
|
-
3. Transform the results to match the same shape as the sample data
|
|
79
|
-
4. Update your imports from `engine-sample-data` to `live-data`
|
|
80
|
-
|
|
81
|
-
Your components don't need to change - just the data source!
|
package/data/copy-to-webapp.sh
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# Copy sample data to webapp src directory
|
|
4
|
-
#
|
|
5
|
-
# Usage:
|
|
6
|
-
# ./data/copy-to-webapp.sh [webapp-path]
|
|
7
|
-
#
|
|
8
|
-
# Examples:
|
|
9
|
-
# ./data/copy-to-webapp.sh force-app/main/default/webapplications/enginewebexperience
|
|
10
|
-
# ./data/copy-to-webapp.sh /path/to/your/webapp
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
set -e
|
|
14
|
-
|
|
15
|
-
# Get the directory where this script lives
|
|
16
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
-
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
18
|
-
|
|
19
|
-
# Default webapp path (Engine Travel Command Center)
|
|
20
|
-
DEFAULT_WEBAPP="force-app/main/default/webapplications/enginewebexperience"
|
|
21
|
-
|
|
22
|
-
# Use provided path or default
|
|
23
|
-
WEBAPP_PATH="${1:-$DEFAULT_WEBAPP}"
|
|
24
|
-
|
|
25
|
-
# Make it absolute if relative
|
|
26
|
-
if [[ ! "$WEBAPP_PATH" = /* ]]; then
|
|
27
|
-
WEBAPP_PATH="$PROJECT_ROOT/$WEBAPP_PATH"
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
# Verify webapp exists
|
|
31
|
-
if [ ! -d "$WEBAPP_PATH" ]; then
|
|
32
|
-
echo "❌ Error: Webapp directory not found: $WEBAPP_PATH"
|
|
33
|
-
echo ""
|
|
34
|
-
echo "Usage: $0 [webapp-path]"
|
|
35
|
-
echo ""
|
|
36
|
-
echo "Examples:"
|
|
37
|
-
echo " $0"
|
|
38
|
-
echo " $0 force-app/main/default/webapplications/enginewebexperience"
|
|
39
|
-
echo " $0 /absolute/path/to/webapp"
|
|
40
|
-
exit 1
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
# Create src/data directory if it doesn't exist
|
|
44
|
-
DATA_DIR="$WEBAPP_PATH/src/data"
|
|
45
|
-
mkdir -p "$DATA_DIR"
|
|
46
|
-
|
|
47
|
-
# Copy the sample data file
|
|
48
|
-
echo "📦 Copying sample data to webapp..."
|
|
49
|
-
cp "$SCRIPT_DIR/engine-sample-data.js" "$DATA_DIR/engine-sample-data.js"
|
|
50
|
-
|
|
51
|
-
echo "✅ Sample data copied to: $DATA_DIR/engine-sample-data.js"
|
|
52
|
-
echo ""
|
|
53
|
-
echo "Import in your components:"
|
|
54
|
-
echo ""
|
|
55
|
-
echo " import {"
|
|
56
|
-
echo " MAP_MARKERS,"
|
|
57
|
-
echo " MAP_ARCS,"
|
|
58
|
-
echo " TRAVELER_CARDS,"
|
|
59
|
-
echo " // ... etc"
|
|
60
|
-
echo " } from '@/data/engine-sample-data';"
|
|
61
|
-
echo ""
|
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a minimal GraphQL schema from sample data when introspection is broken.
|
|
3
|
-
*
|
|
4
|
-
* This is a workaround for orgs where schema introspection fails due to fields
|
|
5
|
-
* with null data types. It creates a schema.graphql file by analyzing the sample
|
|
6
|
-
* data structure instead of querying the org.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* node scripts/generate-schema-from-sample.mjs
|
|
10
|
-
*/
|
|
11
|
-
import { writeFileSync } from 'node:fs';
|
|
12
|
-
import { resolve, dirname } from 'node:path';
|
|
13
|
-
import { fileURLToPath } from 'node:url';
|
|
14
|
-
|
|
15
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
-
const __dirname = dirname(__filename);
|
|
17
|
-
|
|
18
|
-
// Import sample data to extract field names
|
|
19
|
-
const TRAVELERS_FIELDS = [
|
|
20
|
-
'Id',
|
|
21
|
-
'FirstName',
|
|
22
|
-
'LastName',
|
|
23
|
-
'Department',
|
|
24
|
-
'Home_Airport__c',
|
|
25
|
-
'Travel_Policy_Tier__c',
|
|
26
|
-
'Is_Active_Traveler__c',
|
|
27
|
-
'Role__c',
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
const TRIPS_FIELDS = [
|
|
31
|
-
'Id',
|
|
32
|
-
'Trip_Name__c',
|
|
33
|
-
'Contact__c',
|
|
34
|
-
'Origin_City__c',
|
|
35
|
-
'Origin_Airport__c',
|
|
36
|
-
'Destination_City__c',
|
|
37
|
-
'Destination_Airport__c',
|
|
38
|
-
'Start_Date__c',
|
|
39
|
-
'End_Date__c',
|
|
40
|
-
'Status__c',
|
|
41
|
-
'Total_Cost__c',
|
|
42
|
-
'In_Policy__c',
|
|
43
|
-
'Has_Disruption__c',
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
const FLIGHTS_FIELDS = [
|
|
47
|
-
'Id',
|
|
48
|
-
'Flight_Number__c',
|
|
49
|
-
'Airline__c',
|
|
50
|
-
'Departure_Airport__c',
|
|
51
|
-
'Departure_City__c',
|
|
52
|
-
'Departure_Longitude__c',
|
|
53
|
-
'Departure_Latitude__c',
|
|
54
|
-
'Arrival_Airport__c',
|
|
55
|
-
'Arrival_City__c',
|
|
56
|
-
'Arrival_Longitude__c',
|
|
57
|
-
'Arrival_Latitude__c',
|
|
58
|
-
'Departure_DateTime__c',
|
|
59
|
-
'Flight_Status__c',
|
|
60
|
-
'Delay_Minutes__c',
|
|
61
|
-
'Cabin_Class__c',
|
|
62
|
-
'Contact__c',
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
const BOOKINGS_FIELDS = [
|
|
66
|
-
'Id',
|
|
67
|
-
'Contact__c',
|
|
68
|
-
'Booking_Type__c',
|
|
69
|
-
'Status__c',
|
|
70
|
-
'Cost__c',
|
|
71
|
-
'In_Policy__c',
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
const DISRUPTIONS_FIELDS = [
|
|
75
|
-
'Id',
|
|
76
|
-
'Flight_Number__c',
|
|
77
|
-
'Disruption_Type__c',
|
|
78
|
-
'Severity__c',
|
|
79
|
-
'Status__c',
|
|
80
|
-
'Impacted_Flight__c',
|
|
81
|
-
'Trip__c',
|
|
82
|
-
'City__c',
|
|
83
|
-
'Affected_Traveler_Count__c',
|
|
84
|
-
'Auto_Rebook_Eligible__c',
|
|
85
|
-
'Recommended_Action__c',
|
|
86
|
-
'Description__c',
|
|
87
|
-
];
|
|
88
|
-
|
|
89
|
-
const REBOOKING_ACTIONS_FIELDS = [
|
|
90
|
-
'Id',
|
|
91
|
-
'Action_Type__c',
|
|
92
|
-
'Status__c',
|
|
93
|
-
'Handled_By__c',
|
|
94
|
-
'Contact__c',
|
|
95
|
-
'Original_Flight__c',
|
|
96
|
-
'New_Flight__c',
|
|
97
|
-
'Cost_Difference__c',
|
|
98
|
-
'Notes__c',
|
|
99
|
-
'Created_DateTime__c',
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
const TRAVEL_POLICIES_FIELDS = [
|
|
103
|
-
'Id',
|
|
104
|
-
'Name',
|
|
105
|
-
'Description__c',
|
|
106
|
-
'Active__c',
|
|
107
|
-
'Policy_Tier__c',
|
|
108
|
-
'Max_Flight_Cost__c',
|
|
109
|
-
'Max_Hotel_Rate__c',
|
|
110
|
-
'Advance_Booking_Days__c',
|
|
111
|
-
'Preferred_Airlines__c',
|
|
112
|
-
'Preferred_Hotel_Chains__c',
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
function inferType(fieldName) {
|
|
116
|
-
if (fieldName === 'Id') return 'ID';
|
|
117
|
-
if (fieldName.includes('Count') || fieldName.includes('Cost') || fieldName.includes('Rate') || fieldName.includes('Days')) {
|
|
118
|
-
return 'Float';
|
|
119
|
-
}
|
|
120
|
-
if (fieldName.includes('Date') || fieldName.includes('DateTime')) {
|
|
121
|
-
return 'String'; // Dates come as ISO strings
|
|
122
|
-
}
|
|
123
|
-
if (fieldName.includes('Is_') || fieldName.includes('Has_') || fieldName.includes('Active') || fieldName.includes('In_Policy') || fieldName.includes('Eligible')) {
|
|
124
|
-
return 'Boolean';
|
|
125
|
-
}
|
|
126
|
-
if (fieldName.includes('Longitude') || fieldName.includes('Latitude') || fieldName.includes('Delay_Minutes')) {
|
|
127
|
-
return 'Float';
|
|
128
|
-
}
|
|
129
|
-
return 'String';
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function generateFieldType(fieldName, indent = ' ') {
|
|
133
|
-
const type = inferType(fieldName);
|
|
134
|
-
if (fieldName === 'Id') {
|
|
135
|
-
return `${indent}${fieldName}: ${type}!`;
|
|
136
|
-
}
|
|
137
|
-
// All non-ID fields are wrapped in value object for FLS
|
|
138
|
-
return `${indent}${fieldName}: FieldValue${type}`;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function generateObjectType(objectName, fields) {
|
|
142
|
-
const fieldDefs = fields.map(f => generateFieldType(f, ' ')).join('\n');
|
|
143
|
-
return `type ${objectName} {\n${fieldDefs}\n}`;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const schema = `"""
|
|
147
|
-
Generated schema for Engine Travel Command Center
|
|
148
|
-
Source: src/data/engine-sample-data.js field names
|
|
149
|
-
Note: This is a minimal schema for GraphQL tooling when introspection is broken
|
|
150
|
-
"""
|
|
151
|
-
|
|
152
|
-
schema {
|
|
153
|
-
query: Query
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
type Query {
|
|
157
|
-
uiapi: UIAPI!
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
type UIAPI {
|
|
161
|
-
query: UIAPIQuery!
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
type UIAPIQuery {
|
|
165
|
-
Contact(first: Int, after: String, where: ContactFilter): ContactConnection
|
|
166
|
-
Trip__c(first: Int, after: String, where: Trip__cFilter): Trip__cConnection
|
|
167
|
-
Flight__c(first: Int, after: String, where: Flight__cFilter): Flight__cConnection
|
|
168
|
-
Booking__c(first: Int, after: String, where: Booking__cFilter): Booking__cConnection
|
|
169
|
-
Disruption__c(first: Int, after: String, where: Disruption__cFilter): Disruption__cConnection
|
|
170
|
-
Rebooking_Action__c(first: Int, after: String, where: Rebooking_Action__cFilter): Rebooking_Action__cConnection
|
|
171
|
-
Travel_Policy__c(first: Int, after: String, where: Travel_Policy__cFilter): Travel_Policy__cConnection
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
# Field value wrappers for FLS
|
|
175
|
-
type FieldValueString {
|
|
176
|
-
value: String
|
|
177
|
-
displayValue: String
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
type FieldValueFloat {
|
|
181
|
-
value: Float
|
|
182
|
-
displayValue: String
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
type FieldValueBoolean {
|
|
186
|
-
value: Boolean
|
|
187
|
-
displayValue: String
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
type FieldValueID {
|
|
191
|
-
value: ID
|
|
192
|
-
displayValue: String
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
# Contact (Travelers)
|
|
196
|
-
${generateObjectType('Contact', TRAVELERS_FIELDS)}
|
|
197
|
-
|
|
198
|
-
type ContactEdge {
|
|
199
|
-
node: Contact!
|
|
200
|
-
cursor: String!
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
type ContactConnection {
|
|
204
|
-
edges: [ContactEdge!]!
|
|
205
|
-
pageInfo: PageInfo!
|
|
206
|
-
totalCount: Int
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
input ContactFilter {
|
|
210
|
-
Id: IDFilter
|
|
211
|
-
FirstName: StringFilter
|
|
212
|
-
LastName: StringFilter
|
|
213
|
-
Department: StringFilter
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
# Trip__c
|
|
217
|
-
${generateObjectType('Trip__c', TRIPS_FIELDS)}
|
|
218
|
-
|
|
219
|
-
type Trip__cEdge {
|
|
220
|
-
node: Trip__c!
|
|
221
|
-
cursor: String!
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
type Trip__cConnection {
|
|
225
|
-
edges: [Trip__cEdge!]!
|
|
226
|
-
pageInfo: PageInfo!
|
|
227
|
-
totalCount: Int
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
input Trip__cFilter {
|
|
231
|
-
Id: IDFilter
|
|
232
|
-
Trip_Name__c: StringFilter
|
|
233
|
-
Status__c: StringFilter
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
# Flight__c
|
|
237
|
-
${generateObjectType('Flight__c', FLIGHTS_FIELDS)}
|
|
238
|
-
|
|
239
|
-
type Flight__cEdge {
|
|
240
|
-
node: Flight__c!
|
|
241
|
-
cursor: String!
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
type Flight__cConnection {
|
|
245
|
-
edges: [Flight__cEdge!]!
|
|
246
|
-
pageInfo: PageInfo!
|
|
247
|
-
totalCount: Int
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
input Flight__cFilter {
|
|
251
|
-
Id: IDFilter
|
|
252
|
-
Flight_Number__c: StringFilter
|
|
253
|
-
Flight_Status__c: StringFilter
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
# Booking__c
|
|
257
|
-
${generateObjectType('Booking__c', BOOKINGS_FIELDS)}
|
|
258
|
-
|
|
259
|
-
type Booking__cEdge {
|
|
260
|
-
node: Booking__c!
|
|
261
|
-
cursor: String!
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
type Booking__cConnection {
|
|
265
|
-
edges: [Booking__cEdge!]!
|
|
266
|
-
pageInfo: PageInfo!
|
|
267
|
-
totalCount: Int
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
input Booking__cFilter {
|
|
271
|
-
Id: IDFilter
|
|
272
|
-
Status__c: StringFilter
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
# Disruption__c
|
|
276
|
-
${generateObjectType('Disruption__c', DISRUPTIONS_FIELDS)}
|
|
277
|
-
|
|
278
|
-
type Disruption__cEdge {
|
|
279
|
-
node: Disruption__c!
|
|
280
|
-
cursor: String!
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
type Disruption__cConnection {
|
|
284
|
-
edges: [Disruption__cEdge!]!
|
|
285
|
-
pageInfo: PageInfo!
|
|
286
|
-
totalCount: Int
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
input Disruption__cFilter {
|
|
290
|
-
Id: IDFilter
|
|
291
|
-
Severity__c: StringFilter
|
|
292
|
-
Status__c: StringFilter
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
# Rebooking_Action__c
|
|
296
|
-
${generateObjectType('Rebooking_Action__c', REBOOKING_ACTIONS_FIELDS)}
|
|
297
|
-
|
|
298
|
-
type Rebooking_Action__cEdge {
|
|
299
|
-
node: Rebooking_Action__c!
|
|
300
|
-
cursor: String!
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
type Rebooking_Action__cConnection {
|
|
304
|
-
edges: [Rebooking_Action__cEdge!]!
|
|
305
|
-
pageInfo: PageInfo!
|
|
306
|
-
totalCount: Int
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
input Rebooking_Action__cFilter {
|
|
310
|
-
Id: IDFilter
|
|
311
|
-
Status__c: StringFilter
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
# Travel_Policy__c
|
|
315
|
-
${generateObjectType('Travel_Policy__c', TRAVEL_POLICIES_FIELDS)}
|
|
316
|
-
|
|
317
|
-
type Travel_Policy__cEdge {
|
|
318
|
-
node: Travel_Policy__c!
|
|
319
|
-
cursor: String!
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
type Travel_Policy__cConnection {
|
|
323
|
-
edges: [Travel_Policy__cEdge!]!
|
|
324
|
-
pageInfo: PageInfo!
|
|
325
|
-
totalCount: Int
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
input Travel_Policy__cFilter {
|
|
329
|
-
Id: IDFilter
|
|
330
|
-
Policy_Tier__c: StringFilter
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
# Pagination
|
|
334
|
-
type PageInfo {
|
|
335
|
-
hasNextPage: Boolean!
|
|
336
|
-
hasPreviousPage: Boolean!
|
|
337
|
-
startCursor: String
|
|
338
|
-
endCursor: String
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
# Filter input types
|
|
342
|
-
input IDFilter {
|
|
343
|
-
eq: ID
|
|
344
|
-
ne: ID
|
|
345
|
-
in: [ID!]
|
|
346
|
-
nin: [ID!]
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
input StringFilter {
|
|
350
|
-
eq: String
|
|
351
|
-
ne: String
|
|
352
|
-
like: String
|
|
353
|
-
in: [String!]
|
|
354
|
-
nin: [String!]
|
|
355
|
-
}
|
|
356
|
-
`;
|
|
357
|
-
|
|
358
|
-
// Determine output path - write to current working directory (where the script was called from)
|
|
359
|
-
const outputPath = resolve(process.cwd(), 'schema.graphql');
|
|
360
|
-
|
|
361
|
-
try {
|
|
362
|
-
writeFileSync(outputPath, schema);
|
|
363
|
-
console.log(`✅ Schema generated successfully at ${outputPath}`);
|
|
364
|
-
console.log(` Source: Sample data field names`);
|
|
365
|
-
console.log(` Objects: Contact, Trip__c, Flight__c, Booking__c, Disruption__c, Rebooking_Action__c, Travel_Policy__c`);
|
|
366
|
-
console.log(`\nNote: This is a minimal schema for tooling. It may not include all fields or types from the actual org.`);
|
|
367
|
-
} catch (error) {
|
|
368
|
-
console.error('❌ Failed to write schema:', error.message);
|
|
369
|
-
process.exit(1);
|
|
370
|
-
}
|
|
File without changes
|
|
File without changes
|