@salesforce/webapp-template-feature-react-file-upload-experimental 1.105.1 → 1.106.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.
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: salesforce-data-access
3
+ description: Salesforce data access patterns. Use when adding or modifying any code that fetches data from Salesforce (records, Chatter, Connect API, etc.).
4
+ paths:
5
+ - "**/*.ts"
6
+ - "**/*.tsx"
7
+ - "**/*.graphql"
8
+ ---
9
+
10
+ # Salesforce Data Access
11
+
12
+ Guidance for accessing Salesforce data from web apps. **All Salesforce data fetches MUST use the Data SDK** (`@salesforce/sdk-data`). The SDK provides authentication, CSRF handling, and correct base URL resolution — direct `fetch` or `axios` calls bypass these and are not allowed.
13
+
14
+ ## Mandatory: Use the Data SDK
15
+
16
+ > **Every Salesforce data fetch must go through the Data SDK.** Obtain it via `createDataSDK()`, then use `sdk.graphql?.()` or `sdk.fetch?.()`. Never call `fetch()` or `axios` directly for Salesforce endpoints.
17
+
18
+ ## Optional Chaining and Graceful Handling
19
+
20
+ **Always use optional chaining** when calling `sdk.graphql` or `sdk.fetch` — these methods may be undefined in some surfaces (e.g., Salesforce ACC, MCP Apps). Handle the case where they are not available gracefully:
21
+
22
+ ```typescript
23
+ const sdk = await createDataSDK();
24
+
25
+ // ✅ Use optional chaining
26
+ const response = await sdk.graphql?.(query);
27
+
28
+ // ✅ Check before using fetch
29
+ if (!sdk.fetch) {
30
+ throw new Error("Data SDK fetch is not available in this context");
31
+ }
32
+ const res = await sdk.fetch(url);
33
+ ```
34
+
35
+ For GraphQL, if `sdk.graphql` is undefined, the call returns `undefined` — handle that in your logic (e.g., throw a clear error or return a fallback). For `sdk.fetch`, check availability before calling when the operation is required.
36
+
37
+ ## Preference: GraphQL First
38
+
39
+ **GraphQL is the preferred method** for querying and mutating Salesforce records. Use it when:
40
+
41
+ - Querying records (Account, Contact, Opportunity, custom objects)
42
+ - Creating, updating, or deleting records (when GraphQL supports the operation)
43
+ - Fetching related data, filters, sorting, pagination
44
+
45
+ **Use `sdk.fetch` only when GraphQL is not sufficient.** For REST API usage, invoke the `salesforce-rest-api-fetch` skill, which documents:
46
+
47
+ - Chatter API (e.g., `/services/data/v65.0/chatter/users/me`)
48
+ - Connect REST API (e.g., `/services/data/v65.0/connect/file/upload/config`)
49
+ - Apex REST (e.g., `/services/apexrest/auth/login`)
50
+ - UI API REST (e.g., `/services/data/v65.0/ui-api/records/{recordId}`)
51
+ - Einstein LLM Gateway
52
+
53
+ ---
54
+
55
+ ## Getting the SDK
56
+
57
+ ```typescript
58
+ import { createDataSDK } from "@salesforce/sdk-data";
59
+
60
+ const sdk = await createDataSDK();
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Example 1: GraphQL (Preferred)
66
+
67
+ For record queries and mutations, use GraphQL via the Data SDK. Invoke the `salesforce-graphql` skill for the full workflow (schema exploration, query authoring, codegen, lint validate).
68
+
69
+ ```typescript
70
+ import { createDataSDK, gql } from "@salesforce/sdk-data";
71
+ import type { GetAccountsQuery } from "../graphql-operations-types";
72
+
73
+ const GET_ACCOUNTS = gql`
74
+ query GetAccounts {
75
+ uiapi {
76
+ query {
77
+ Account(first: 10) {
78
+ edges {
79
+ node {
80
+ Id
81
+ Name { value }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ `;
89
+
90
+ export async function getAccounts() {
91
+ const sdk = await createDataSDK();
92
+ const response = await sdk.graphql?.<GetAccountsQuery>(GET_ACCOUNTS);
93
+
94
+ if (response?.errors?.length) {
95
+ throw new Error(response.errors.map((e) => e.message).join("; "));
96
+ }
97
+
98
+ return response?.data?.uiapi?.query?.Account?.edges?.map((e) => e?.node) ?? [];
99
+ }
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Example 2: Fetch (When GraphQL Is Not Sufficient)
105
+
106
+ For REST endpoints that have no GraphQL equivalent, use `sdk.fetch`. **Invoke the `salesforce-rest-api-fetch` skill** for full documentation of Chatter, Connect REST, Apex REST, UI API REST, and Einstein LLM endpoints.
107
+
108
+ ```typescript
109
+ import { createDataSDK } from "@salesforce/sdk-data";
110
+
111
+ declare const __SF_API_VERSION__: string;
112
+ const API_VERSION = typeof __SF_API_VERSION__ !== "undefined" ? __SF_API_VERSION__ : "65.0";
113
+
114
+ export async function getCurrentUser() {
115
+ const sdk = await createDataSDK();
116
+ const response = await sdk.fetch?.(`/services/data/v${API_VERSION}/chatter/users/me`);
117
+
118
+ if (!response?.ok) throw new Error(`HTTP ${response?.status}`);
119
+ const data = await response.json();
120
+ return { id: data.id, name: data.name };
121
+ }
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Anti-Patterns (Forbidden)
127
+
128
+ ### Direct fetch to Salesforce
129
+
130
+ ```typescript
131
+ // ❌ FORBIDDEN — bypasses Data SDK auth and CSRF
132
+ const res = await fetch("/services/data/v65.0/chatter/users/me");
133
+ ```
134
+
135
+ ### Direct axios to Salesforce
136
+
137
+ ```typescript
138
+ // ❌ FORBIDDEN — bypasses Data SDK
139
+ const res = await axios.get("/services/data/v65.0/chatter/users/me");
140
+ ```
141
+
142
+ ### Correct approach
143
+
144
+ ```typescript
145
+ // ✅ CORRECT — use Data SDK
146
+ const sdk = await createDataSDK();
147
+ const res = await sdk.fetch?.("/services/data/v65.0/chatter/users/me");
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Decision Flow
153
+
154
+ 1. **Need to query or mutate Salesforce records?** → Use GraphQL via the Data SDK. Invoke the `salesforce-graphql` skill.
155
+ 2. **Need Chatter, Connect REST, Apex REST, UI API REST, or Einstein LLM?** → Use `sdk.fetch`. Invoke the `salesforce-rest-api-fetch` skill.
156
+ 3. **Never** use `fetch`, `axios`, or similar directly for Salesforce API calls.
157
+
158
+ ---
159
+
160
+ ## Reference
161
+
162
+ - GraphQL workflow: invoke the `salesforce-graphql` skill (`.a4drules/skills/salesforce-graphql/`)
163
+ - REST API via fetch: invoke the `salesforce-rest-api-fetch` skill (`.a4drules/skills/salesforce-rest-api-fetch/`)
164
+ - Data SDK package: `@salesforce/sdk-data` (`createDataSDK`, `gql`, `NodeOfConnection`)
165
+ - `createRecord` for UI API record creation: `@salesforce/webapp-experimental/api` (uses Data SDK internally)
@@ -0,0 +1,323 @@
1
+ ---
2
+ name: salesforce-graphql
3
+ description: Salesforce GraphQL data access. Use when the user asks to fetch, query, or mutate Salesforce data, or add a GraphQL operation for an object like Account, Contact, or Opportunity.
4
+ paths:
5
+ - "**/*.ts"
6
+ - "**/*.tsx"
7
+ - "**/*.graphql"
8
+ ---
9
+
10
+ # Salesforce GraphQL
11
+
12
+ Guidance for querying and mutating Salesforce data via the Salesforce GraphQL API. Use `createDataSDK()` + `sdk.graphql?.()` and codegen tooling.
13
+
14
+ ## When to Use
15
+
16
+ - User asks to "fetch data from Salesforce"
17
+ - User asks to "query" or "mutate" Salesforce records
18
+ - User wants to add a new GraphQL operation (query or mutation)
19
+ - User asks to add data access for a Salesforce object (Account, Contact, Opportunity, etc.)
20
+
21
+ ## Schema Access Policy (GREP ONLY)
22
+
23
+ > **GREP ONLY** — The `schema.graphql` file is very large (~265,000+ lines). All schema lookups **MUST** use the grep-only commands defined in the `salesforce-graphql-explore-schema` skill. Do NOT open, read, stream, or parse `./schema.graphql` with any tool other than grep.
24
+
25
+ ## Directory Context
26
+
27
+ The generated app has a two-level directory structure. Commands must run from the correct directory.
28
+
29
+ ```
30
+ <project-root>/ ← SFDX project root
31
+ ├── schema.graphql ← grep target
32
+ ├── sfdx-project.json
33
+ └── force-app/main/default/webapplications/<app-name>/ ← webapp dir
34
+ ├── package.json (npm scripts: graphql:schema, graphql:codegen, lint)
35
+ ├── eslint.config.js (schema ref: ../../../../../schema.graphql)
36
+ ├── codegen.yml (schema ref: ../../../../../schema.graphql)
37
+ └── src/ (source code, .graphql query files)
38
+ ```
39
+
40
+ | Command | Run from | Why |
41
+ | ------------------------- | ---------------- | -------------------------------------- |
42
+ | `npm run graphql:schema` | **webapp dir** | Script is in webapp's `package.json` |
43
+ | `npm run graphql:codegen` | **webapp dir** | Reads `codegen.yml` in webapp dir |
44
+ | `npx eslint <file>` | **webapp dir** | Reads `eslint.config.js` in webapp dir |
45
+ | `grep ... schema.graphql` | **project root** | `schema.graphql` lives at project root |
46
+ | `sf api request graphql` | **project root** | Needs `sfdx-project.json` |
47
+
48
+ > **Wrong directory = silent failures.** `npm run graphql:schema` from the project root will fail with "missing script." `grep ./schema.graphql` from the webapp dir will fail with "no such file."
49
+
50
+ ## Prerequisites
51
+
52
+ The base React app (`base-react-app`) ships with all GraphQL dependencies and tooling pre-configured:
53
+
54
+ - `@salesforce/sdk-data` — runtime SDK for `createDataSDK` and `gql`
55
+ - `@graphql-codegen/cli` + plugins — type generation from `.graphql` files and inline `gql` queries
56
+ - `@graphql-eslint/eslint-plugin` — validates `.graphql` files and `gql` template literals against `schema.graphql` (used as a query validation gate — see Step 6)
57
+ - `graphql` — shared by codegen, ESLint, and schema introspection
58
+
59
+ Before using this skill, ensure:
60
+
61
+ 1. The `@salesforce/sdk-data` package is available (provides `createDataSDK`, `gql`, `NodeOfConnection`)
62
+ 2. A `schema.graphql` file exists at the project root. If missing, generate it:
63
+ ```bash
64
+ # Run from webapp dir (force-app/main/default/webapplications/<app-name>/)
65
+ npm run graphql:schema
66
+ ```
67
+
68
+ ## npm Scripts
69
+
70
+ - **`npm run graphql:schema`** — _(run from webapp dir)_ Downloads the full GraphQL schema from a connected Salesforce org via introspection. Outputs `schema.graphql` to the project root.
71
+ - **`npm run graphql:codegen`** — _(run from webapp dir)_ Generates TypeScript types from `.graphql` files and inline `gql` queries. Outputs to `src/api/graphql-operations-types.ts`.
72
+
73
+ ## Workflow
74
+
75
+ ### Step 1: Download Schema
76
+
77
+ Ensure `schema.graphql` exists at the project root. If missing, run `npm run graphql:schema` from the webapp dir.
78
+
79
+ ### Step 2: Explore the Schema (grep-only)
80
+
81
+ Before writing any query, verify the target object and its fields exist in the schema.
82
+
83
+ **Invoke the `salesforce-graphql-explore-schema` skill** for the full exploration workflow and **mandatory grep-only access policy**.
84
+
85
+ > **GREP ONLY** — All schema lookups MUST use the grep commands defined in the `salesforce-graphql-explore-schema` skill. Do NOT open, read, stream, or parse `./schema.graphql` with any tool other than grep.
86
+
87
+ Key actions (all via grep):
88
+
89
+ - `type <ObjectName> implements Record` — find available fields
90
+ - `input <ObjectName>_Filter` — find filter options
91
+ - `input <ObjectName>_OrderBy` — find sorting options
92
+ - `input <ObjectName>CreateInput` / `<ObjectName>UpdateInput` — find mutation input types
93
+
94
+ ### Step 3: Choose the Query Pattern
95
+
96
+ **Pattern 1 — External `.graphql` file** (recommended for complex queries):
97
+
98
+ - Queries with variables, fragments, or shared across files
99
+ - Full codegen support, syntax highlighting, shareable
100
+ - Requires codegen step after changes
101
+ - See example: `api/utils/accounts.ts` + `api/utils/query/highRevenueAccountsQuery.graphql`
102
+
103
+ **Pattern 2 — Inline `gql` tag** (recommended for simple queries):
104
+
105
+ - Simple queries without variables; colocated with usage code
106
+ - Supports dynamic queries (field set varies at runtime)
107
+ - **MUST use `gql` tag** — plain template strings bypass `@graphql-eslint` validation
108
+ - See example: `api/utils/user.ts`
109
+
110
+ ### Step 4: Write the Query
111
+
112
+ For **Pattern 1**:
113
+
114
+ 1. Create a `.graphql` file under `src/api/utils/query/`
115
+ 2. Follow UIAPI structure: `query { uiapi { query { ObjectName(...) { edges { node { ... } } } } } }`
116
+ 3. For mutations, invoke the `salesforce-graphql-mutation-query` skill
117
+ 4. For read queries, invoke the `salesforce-graphql-read-query` skill
118
+
119
+ For **Pattern 2**:
120
+
121
+ 1. Define query inline using the `gql` template tag
122
+ 2. Ensure the query name matches what codegen expects
123
+
124
+ ### Step 5: Test Queries Against Live Org
125
+
126
+ Use the testing workflows in the `salesforce-graphql-read-query` and `salesforce-graphql-mutation-query` skills to validate queries against the connected org before integrating into the app.
127
+
128
+ ### Step 6: Generate Types
129
+
130
+ ```bash
131
+ # Run from webapp dir (force-app/main/default/webapplications/<app-name>/)
132
+ npm run graphql:codegen
133
+ ```
134
+
135
+ This updates `src/api/graphql-operations-types.ts` with `<OperationName>Query`/`<OperationName>Mutation` and `<OperationName>QueryVariables`/`<OperationName>MutationVariables`.
136
+
137
+ ### Step 7: Lint Validate
138
+
139
+ Run ESLint on the file containing the query to validate it against the schema **before** any live testing:
140
+
141
+ ```bash
142
+ # Run from webapp dir
143
+ npx eslint <path-to-file>
144
+ ```
145
+
146
+ The `@graphql-eslint/eslint-plugin` processor extracts GraphQL from `gql` template literals and validates them against `schema.graphql`. Fix all ESLint errors before proceeding.
147
+
148
+ ### Step 8: Implement and Verify
149
+
150
+ Implement the data access function using the pattern below. Use the Quality Checklist before completing.
151
+
152
+ ---
153
+
154
+ ## Core Types & Function Signatures
155
+
156
+ ### createDataSDK and graphql
157
+
158
+ ```typescript
159
+ import { createDataSDK } from "@salesforce/sdk-data";
160
+
161
+ const sdk = await createDataSDK();
162
+ const response = await sdk.graphql?.<ResponseType, VariablesType>(query, variables);
163
+ ```
164
+
165
+ `createDataSDK()` returns a `DataSDK` instance. The `graphql` method uses optional chaining (`?.`) because not all surfaces support GraphQL.
166
+
167
+ ### gql Template Tag
168
+
169
+ ```typescript
170
+ import { gql } from "@salesforce/sdk-data";
171
+
172
+ const MY_QUERY = gql`
173
+ query MyQuery {
174
+ uiapi { ... }
175
+ }
176
+ `;
177
+ ```
178
+
179
+ The `gql` tag enables ESLint validation against the schema. Plain template strings bypass validation.
180
+
181
+ ### Error Handling
182
+
183
+ Default: treat any errors as failure (Strategy A). For partial data tolerance, log errors but use data. For mutations where some return fields are inaccessible, use Strategy C (fail only when no data).
184
+
185
+ ```typescript
186
+ // Default: strict
187
+ if (response?.errors?.length) {
188
+ throw new Error(response.errors.map((e) => e.message).join("; "));
189
+ }
190
+ const result = response?.data;
191
+ ```
192
+
193
+ Responses follow `uiapi.query.ObjectName.edges[].node`; fields use `{ value }`.
194
+
195
+ ### NodeOfConnection
196
+
197
+ ```typescript
198
+ import { type NodeOfConnection } from "@salesforce/sdk-data";
199
+
200
+ type AccountNode = NodeOfConnection<GetHighRevenueAccountsQuery["uiapi"]["query"]["Account"]>;
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Pattern 1: External .graphql File
206
+
207
+ Create a `.graphql` file, run `npm run graphql:codegen`, import with `?raw` suffix, and use generated types.
208
+
209
+ **Required imports:**
210
+
211
+ ```typescript
212
+ import { createDataSDK, type NodeOfConnection } from "@salesforce/sdk-data";
213
+ import MY_QUERY from "./query/myQuery.graphql?raw"; // ← ?raw suffix required
214
+ import type { GetMyDataQuery, GetMyDataQueryVariables } from "../graphql-operations-types";
215
+ ```
216
+
217
+ **When to use:** Complex queries with variables, fragments, or shared across files. Does NOT support dynamic queries (field set varies at runtime).
218
+
219
+ ---
220
+
221
+ ## Pattern 2: Inline gql Tag
222
+
223
+ **Required imports:**
224
+
225
+ ```typescript
226
+ import { createDataSDK, gql } from "@salesforce/sdk-data";
227
+ import { type CurrentUserQuery } from "../graphql-operations-types";
228
+
229
+ const MY_QUERY = gql`
230
+ query CurrentUser {
231
+ uiapi { ... }
232
+ }
233
+ `;
234
+ ```
235
+
236
+ > **MUST use `gql` tag** — plain template strings bypass the `@graphql-eslint` processor entirely, meaning no lint validation against the schema.
237
+
238
+ **When to use:** Simple, colocated queries. Supports dynamic queries (field set varies at runtime).
239
+
240
+ ---
241
+
242
+ ## Conditional Field Selection
243
+
244
+ For dynamic fieldsets with **known** fields, use `@include(if: $condition)` and `@skip(if: $condition)` in `.graphql` files. See GraphQL spec for details.
245
+
246
+ ---
247
+
248
+ ## Anti-Patterns (Not Recommended)
249
+
250
+ ### Direct API Calls
251
+
252
+ ```typescript
253
+ // NOT RECOMMENDED: Direct axios/fetch calls for GraphQL
254
+ // PREFERRED: Use the Data SDK
255
+ const sdk = await createDataSDK();
256
+ const response = await sdk.graphql?.<ResponseType>(query, variables);
257
+ ```
258
+
259
+ ### Missing Type Definitions
260
+
261
+ ```typescript
262
+ // NOT RECOMMENDED: Untyped GraphQL calls
263
+ // PREFERRED: Provide response type
264
+ const response = await sdk.graphql?.<GetMyDataQuery>(query);
265
+ ```
266
+
267
+ ### Plain String Queries (Without gql Tag)
268
+
269
+ ```typescript
270
+ // NOT RECOMMENDED: Plain strings bypass ESLint validation
271
+ const query = `query { ... }`;
272
+
273
+ // PREFERRED: Use gql tag for inline queries
274
+ const QUERY = gql`query { ... }`;
275
+ ```
276
+
277
+ ---
278
+
279
+ ## Quality Checklist
280
+
281
+ > If you have not completed the workflow above, **stop and complete it first**. Invoke the skill workflow before using this checklist.
282
+
283
+ Before completing GraphQL data access code:
284
+
285
+ ### For Pattern 1 (.graphql files):
286
+
287
+ 1. [ ] All field names verified via grep against `schema.graphql` (invoke `salesforce-graphql-explore-schema`)
288
+ 2. [ ] Create `.graphql` file for the query/mutation
289
+ 3. [ ] Run `npm run graphql:codegen` to generate types
290
+ 4. [ ] Import query with `?raw` suffix
291
+ 5. [ ] Import generated types from `graphql-operations-types.ts`
292
+ 6. [ ] Use `sdk.graphql?.<ResponseType>()` with proper generic
293
+ 7. [ ] Handle `response.errors` and destructure `response.data`
294
+ 8. [ ] Use `NodeOfConnection` for cleaner node types when needed
295
+ 9. [ ] Run `npx eslint <file>` from webapp dir — fix all GraphQL errors
296
+
297
+ ### For Pattern 2 (inline with gql):
298
+
299
+ 1. [ ] All field names verified via grep against `schema.graphql`
300
+ 2. [ ] Define query using `gql` template tag (NOT a plain string)
301
+ 3. [ ] Ensure query name matches generated types in `graphql-operations-types.ts`
302
+ 4. [ ] Import generated types for the query
303
+ 5. [ ] Use `sdk.graphql?.<ResponseType>()` with proper generic
304
+ 6. [ ] Handle `response.errors` and destructure `response.data`
305
+ 7. [ ] Run `npx eslint <file>` from webapp dir — fix all GraphQL errors
306
+
307
+ ### General:
308
+
309
+ - [ ] Lint validation passes (`npx eslint <file>` reports no GraphQL errors)
310
+ - [ ] Query field names match the schema exactly (case-sensitive, confirmed via grep)
311
+ - [ ] Response type generic is provided to `sdk.graphql?.<T>()`
312
+ - [ ] Optional chaining is used for nested response data
313
+
314
+ ---
315
+
316
+ ## Reference
317
+
318
+ - Schema exploration: invoke the `salesforce-graphql-explore-schema` skill
319
+ - Read query generation: invoke the `salesforce-graphql-read-query` skill
320
+ - Mutation query generation: invoke the `salesforce-graphql-mutation-query` skill
321
+ - Shared GraphQL schema types: `shared-schema.graphqls` (in this skill directory)
322
+ - Schema download: `npm run graphql:schema` (run from webapp dir)
323
+ - Type generation: `npm run graphql:codegen` (run from webapp dir)
@@ -0,0 +1,160 @@
1
+ ---
2
+ name: salesforce-graphql-explore-schema
3
+ description: Explore the Salesforce GraphQL schema via grep-only lookups. Use before generating any GraphQL query — schema exploration must complete first.
4
+ paths:
5
+ - "**/*.ts"
6
+ - "**/*.tsx"
7
+ - "**/*.graphql"
8
+ ---
9
+
10
+ # Salesforce GraphQL Schema Exploration
11
+
12
+ Guidance for AI agents working with the Salesforce GraphQL API schema. **GREP ONLY** — the schema file is very large (~265,000+ lines). All lookups MUST use grep; do NOT open, read, stream, or parse the file.
13
+
14
+ ## Schema File Location
15
+
16
+ **Location:** `schema.graphql` at the **SFDX project root** (NOT inside the webapp dir). All grep commands **must be run from the project root** where `schema.graphql` lives.
17
+
18
+ > ⚠️ **Important (Access Policy - GREP ONLY)**: Do NOT open, view, stream, paginate, or parse the schema with any tool other than grep. All lookups MUST be done via grep using anchored patterns with minimal context as defined below.
19
+
20
+ If the file is not present, generate it by running (from the **webapp dir**, not the project root):
21
+
22
+ ```bash
23
+ # Run from webapp dir (force-app/main/default/webapplications/<app-name>/)
24
+ npm run graphql:schema
25
+ ```
26
+
27
+ **BEFORE generating any GraphQL query, you MUST:**
28
+
29
+ 1. **Check if schema exists**: Look for `schema.graphql` in the **SFDX project root**
30
+ 2. **If schema is missing**:
31
+ - `cd` to the **webapp dir** and run `npm run graphql:schema` to download it
32
+ - Wait for the command to complete successfully
33
+ - Then proceed with grep-only lookups as defined below.
34
+ 3. **If schema exists**: Proceed with targeted searches as described below
35
+
36
+ > ⚠️ **DO NOT** generate GraphQL queries without first having access to the schema. Standard field assumptions may not match the target org's configuration.
37
+
38
+ ## Schema Structure Overview
39
+
40
+ Main entry points: `Query { uiapi }` for reads; `Mutation { uiapi(input: ...) }` for creates/updates/deletes. Record queries use `uiapi.query.<ObjectName>`.
41
+
42
+ ## Allowed Lookups (grep-only)
43
+
44
+ Use ONLY these grep commands to locate specific definitions in schema.graphql. Do not use editors (VS Code/vim/nano), cat/less/more/head/tail, or programmatic parsers (node/python/awk/sed/jq).
45
+
46
+ - Always include:
47
+ - `-n` (line numbers) and `-E` (extended regex)
48
+ - Anchors (`^`) and word boundaries (`\b`)
49
+ - Minimal context with `-A N` (prefer the smallest N that surfaces the needed lines)
50
+
51
+ ### 1. Find Available Fields for a Record Type
52
+
53
+ Search for `type <ObjectName> implements Record` to find all queryable fields:
54
+
55
+ ```bash
56
+ # Example: Find Account fields (anchored, minimal context)
57
+ grep -nE '^type[[:space:]]+Account[[:space:]]+implements[[:space:]]+Record\b' ./schema.graphql -A 60
58
+ ```
59
+
60
+ ### 2. Find Filter Options for a Record Type
61
+
62
+ Search for `input <ObjectName>_Filter` to find filterable fields and operators:
63
+
64
+ ```bash
65
+ # Example: Find Account filter options (anchored)
66
+ grep -nE '^input[[:space:]]+Account_Filter\b' ./schema.graphql -A 40
67
+ ```
68
+
69
+ ### 3. Find OrderBy Options
70
+
71
+ Search for `input <ObjectName>_OrderBy` for sorting options:
72
+
73
+ ```bash
74
+ # Example: Find Account ordering options (anchored)
75
+ grep -nE '^input[[:space:]]+Account_OrderBy\b' ./schema.graphql -A 30
76
+ ```
77
+
78
+ ### 4. Find Mutation Operations
79
+
80
+ Search for operations in `UIAPIMutations`:
81
+
82
+ ```bash
83
+ # Example: Find Account mutations (extended regex)
84
+ grep -nE 'Account.*(Create|Update|Delete)' ./schema.graphql
85
+ ```
86
+
87
+ ### 5. Find Input Types for Mutations
88
+
89
+ Search for `input <ObjectName>CreateInput` or `input <ObjectName>UpdateInput`:
90
+
91
+ ```bash
92
+ # Example: Find Account create input (anchored)
93
+ grep -nE '^input[[:space:]]+AccountCreateInput\b' ./schema.graphql -A 30
94
+ ```
95
+
96
+ ## Common Operator Types
97
+
98
+ - **StringOperators**: `eq`, `ne`, `like`, `lt`, `gt`, `lte`, `gte`, `in`, `nin`
99
+ - **OrderByClause**: `order: ResultOrder` (ASC/DESC), `nulls: NullOrder` (FIRST/LAST)
100
+
101
+ ## Field Value Wrappers
102
+
103
+ Salesforce GraphQL returns field values wrapped in typed objects:
104
+
105
+ | Wrapper Type | Access Pattern |
106
+ | --------------- | ---------------------------------- |
107
+ | `StringValue` | `FieldName { value }` |
108
+ | `IntValue` | `FieldName { value }` |
109
+ | `BooleanValue` | `FieldName { value }` |
110
+ | `DateTimeValue` | `FieldName { value displayValue }` |
111
+ | `PicklistValue` | `FieldName { value displayValue }` |
112
+ | `CurrencyValue` | `FieldName { value displayValue }` |
113
+
114
+ ## Agent Workflow for Building Queries (grep-only)
115
+
116
+ **Pre-requisites (MANDATORY):**
117
+
118
+ - [ ] Verified `schema.graphql` exists in the **SFDX project root**
119
+ - [ ] If missing, ran `npm run graphql:schema` from the **webapp dir** and waited for completion
120
+ - [ ] Confirmed connection to correct Salesforce org (if downloading fresh schema)
121
+
122
+ **Workflow Steps:**
123
+
124
+ 1. **Identify the target object** (e.g., Account, Contact, Opportunity)
125
+ 2. **Run the "Find Available Fields" grep command** for your object (copy only the field names visible in the grep output; do not open the file)
126
+ 3. **Run the "Find Filter Options" grep command** (`<Object>_Filter`) to understand filtering options
127
+ 4. **Run the "Find OrderBy Options" grep command** (`<Object>_OrderBy`) for sorting capabilities
128
+ 5. **Build the query** following the patterns in the `salesforce-graphql-read-query` or `salesforce-graphql-mutation-query` skill using only values returned by grep
129
+ 6. **Validate field names** using grep matches (case-sensitive). Do not open or parse the file beyond grep.
130
+
131
+ ## Tips for Agents
132
+
133
+ - **Always verify field names** by running the specific grep commands; do not open the schema file
134
+ - **Use grep with anchors and minimal -A context** to explore the schema efficiently—never read or stream the file
135
+ - **Check relationships** by looking for `parentRelationship` and `childRelationship` comments in type definitions
136
+ - **Look for Connection types** (e.g., `AccountConnection`) via grep to understand pagination structure
137
+ - **Custom objects** end with `__c` (e.g., `CustomObject__c`)
138
+ - **Custom fields** also end with `__c` (e.g., `Custom_Field__c`)
139
+
140
+ ## Forbidden Operations
141
+
142
+ To prevent accidental large reads, the following are prohibited for schema.graphql:
143
+
144
+ - Opening in any editor (VS Code, vim, nano)
145
+ - Using cat, less, more, head, or tail
146
+ - Programmatic parsing (node, python, awk, sed, jq)
147
+ - Streaming or paginating through large portions of the file
148
+
149
+ If any of the above occurs, stop and replace the action with one of the Allowed Lookups (grep-only).
150
+
151
+ ## Output Minimization
152
+
153
+ - Prefer precise, anchored patterns with word boundaries
154
+ - Use the smallest `-A` context that surfaces required lines
155
+ - If results are noisy, refine the regex rather than increasing context
156
+
157
+ ## Related Skills
158
+
159
+ - For generating read queries, invoke the `salesforce-graphql-read-query` skill
160
+ - For generating mutation queries, invoke the `salesforce-graphql-mutation-query` skill