@salesforce/webapp-template-feature-react-file-upload-experimental 1.55.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.
Files changed (126) hide show
  1. package/LICENSE.txt +82 -0
  2. package/README.md +102 -0
  3. package/dist/.a4drules/README.md +35 -0
  4. package/dist/.a4drules/a4d-webapp-generate.md +27 -0
  5. package/dist/.a4drules/build-validation.md +78 -0
  6. package/dist/.a4drules/code-quality.md +137 -0
  7. package/dist/.a4drules/graphql/tools/knowledge/lds-explore-graphql-schema.md +227 -0
  8. package/dist/.a4drules/graphql/tools/knowledge/lds-generate-graphql-mutationquery.md +212 -0
  9. package/dist/.a4drules/graphql/tools/knowledge/lds-generate-graphql-readquery.md +185 -0
  10. package/dist/.a4drules/graphql/tools/knowledge/lds-guide-graphql.md +205 -0
  11. package/dist/.a4drules/graphql/tools/schemas/shared.graphqls +1150 -0
  12. package/dist/.a4drules/graphql.md +409 -0
  13. package/dist/.a4drules/images.md +13 -0
  14. package/dist/.a4drules/react.md +387 -0
  15. package/dist/.a4drules/react_image_processing.md +45 -0
  16. package/dist/.a4drules/typescript.md +224 -0
  17. package/dist/.a4drules/ui-layout.md +23 -0
  18. package/dist/.a4drules/webapp-nav-and-placeholders.md +33 -0
  19. package/dist/.a4drules/webapp-no-node-e.md +25 -0
  20. package/dist/.a4drules/webapp-ui-first.md +32 -0
  21. package/dist/.a4drules/webapp.md +75 -0
  22. package/dist/.forceignore +15 -0
  23. package/dist/.husky/pre-commit +4 -0
  24. package/dist/.prettierignore +11 -0
  25. package/dist/.prettierrc +17 -0
  26. package/dist/AGENT.md +75 -0
  27. package/dist/CHANGELOG.md +803 -0
  28. package/dist/README.md +18 -0
  29. package/dist/config/project-scratch-def.json +13 -0
  30. package/dist/force-app/main/default/webapplications/feature-react-file-upload/.graphqlrc.yml +2 -0
  31. package/dist/force-app/main/default/webapplications/feature-react-file-upload/.prettierignore +9 -0
  32. package/dist/force-app/main/default/webapplications/feature-react-file-upload/.prettierrc +11 -0
  33. package/dist/force-app/main/default/webapplications/feature-react-file-upload/build/vite.config.d.ts +2 -0
  34. package/dist/force-app/main/default/webapplications/feature-react-file-upload/build/vite.config.js +93 -0
  35. package/dist/force-app/main/default/webapplications/feature-react-file-upload/codegen.yml +94 -0
  36. package/dist/force-app/main/default/webapplications/feature-react-file-upload/e2e/app.spec.ts +17 -0
  37. package/dist/force-app/main/default/webapplications/feature-react-file-upload/eslint.config.js +141 -0
  38. package/dist/force-app/main/default/webapplications/feature-react-file-upload/feature-react-file-upload.webapplication-meta.xml +7 -0
  39. package/dist/force-app/main/default/webapplications/feature-react-file-upload/index.html +13 -0
  40. package/dist/force-app/main/default/webapplications/feature-react-file-upload/package-lock.json +18396 -0
  41. package/dist/force-app/main/default/webapplications/feature-react-file-upload/package.json +66 -0
  42. package/dist/force-app/main/default/webapplications/feature-react-file-upload/playwright.config.ts +24 -0
  43. package/dist/force-app/main/default/webapplications/feature-react-file-upload/scripts/get-graphql-schema.mjs +68 -0
  44. package/dist/force-app/main/default/webapplications/feature-react-file-upload/scripts/rewrite-e2e-assets.mjs +23 -0
  45. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/api/fileUpload.ts +154 -0
  46. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/api/graphql-operations-types.ts +116 -0
  47. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/api/utils/accounts.ts +41 -0
  48. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/api/utils/query/highRevenueAccountsQuery.graphql +29 -0
  49. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/app.tsx +22 -0
  50. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/appLayout.tsx +9 -0
  51. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/icons/book.svg +3 -0
  52. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/icons/copy.svg +4 -0
  53. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/icons/rocket.svg +3 -0
  54. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/icons/star.svg +3 -0
  55. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/images/codey-1.png +0 -0
  56. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/images/codey-2.png +0 -0
  57. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/images/codey-3.png +0 -0
  58. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/images/vibe-codey.svg +194 -0
  59. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/symbols.svg +1 -0
  60. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/assets/utility.svg +1 -0
  61. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUpload.tsx +83 -0
  62. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadDialog.tsx +79 -0
  63. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadDropZone.tsx +82 -0
  64. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadFileItem.tsx +99 -0
  65. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadIcons.tsx +58 -0
  66. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/alert.tsx +69 -0
  67. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/button.tsx +67 -0
  68. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/card.tsx +92 -0
  69. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/dialog.tsx +143 -0
  70. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/field.tsx +222 -0
  71. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/index.ts +84 -0
  72. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/input.tsx +19 -0
  73. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/label.tsx +19 -0
  74. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/pagination.tsx +112 -0
  75. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/select.tsx +183 -0
  76. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/separator.tsx +26 -0
  77. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/skeleton.tsx +14 -0
  78. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/spinner.tsx +15 -0
  79. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/table.tsx +87 -0
  80. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components/ui/tabs.tsx +78 -0
  81. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/components.json +18 -0
  82. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/hooks/useFileUpload.ts +299 -0
  83. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/hooks/useFileUploadDialog.ts +70 -0
  84. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/index.ts +56 -0
  85. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/lib/utils.ts +6 -0
  86. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/navigationMenu.tsx +80 -0
  87. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/pages/Home.tsx +25 -0
  88. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/pages/NotFound.tsx +18 -0
  89. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/router-utils.tsx +35 -0
  90. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/routes.tsx +22 -0
  91. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/styles/global.css +135 -0
  92. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/types/fileUpload.ts +26 -0
  93. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/utils/fileUploadUtils.ts +44 -0
  94. package/dist/force-app/main/default/webapplications/feature-react-file-upload/src/utils/labels.ts +21 -0
  95. package/dist/force-app/main/default/webapplications/feature-react-file-upload/tsconfig.json +36 -0
  96. package/dist/force-app/main/default/webapplications/feature-react-file-upload/tsconfig.node.json +13 -0
  97. package/dist/force-app/main/default/webapplications/feature-react-file-upload/vite-env.d.ts +1 -0
  98. package/dist/force-app/main/default/webapplications/feature-react-file-upload/vite.config.ts +43 -0
  99. package/dist/force-app/main/default/webapplications/feature-react-file-upload/vitest-env.d.ts +2 -0
  100. package/dist/force-app/main/default/webapplications/feature-react-file-upload/vitest.config.ts +11 -0
  101. package/dist/force-app/main/default/webapplications/feature-react-file-upload/vitest.setup.ts +1 -0
  102. package/dist/force-app/main/default/webapplications/feature-react-file-upload/webapplication.json +7 -0
  103. package/dist/jest.config.js +6 -0
  104. package/dist/package.json +38 -0
  105. package/dist/scripts/apex/hello.apex +10 -0
  106. package/dist/scripts/soql/account.soql +6 -0
  107. package/dist/sfdx-project.json +12 -0
  108. package/package.json +53 -0
  109. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/api/fileUpload.ts +154 -0
  110. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/appLayout.tsx +9 -0
  111. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/assets/symbols.svg +1 -0
  112. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/assets/utility.svg +1 -0
  113. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUpload.tsx +83 -0
  114. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadDialog.tsx +79 -0
  115. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadDropZone.tsx +82 -0
  116. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadFileItem.tsx +99 -0
  117. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/components/FileUploadIcons.tsx +58 -0
  118. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/hooks/useFileUpload.ts +299 -0
  119. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/hooks/useFileUploadDialog.ts +70 -0
  120. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/index.ts +56 -0
  121. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/pages/Home.tsx +25 -0
  122. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/routes.tsx +17 -0
  123. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/types/fileUpload.ts +26 -0
  124. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/utils/fileUploadUtils.ts +44 -0
  125. package/src/force-app/main/default/webapplications/feature-react-file-upload/src/utils/labels.ts +21 -0
  126. package/src/force-app/main/default/webapplications/feature-react-file-upload/vite.config.ts +43 -0
@@ -0,0 +1,387 @@
1
+ # AI Customization Rule: React Web App (SFDX)
2
+
3
+ This rule consolidates React web application guidelines, data access rules, security standards, anti-patterns, and project integration requirements for consistent AI-generated code.
4
+
5
+ ## Targets (File Pattern Matching)
6
+
7
+ Apply these rules to the React web app files under the SFDX package directory:
8
+
9
+ - `force-app/main/default/webapplications/*/**/*.js`
10
+ - `force-app/main/default/webapplications/*/**/*.jsx`
11
+ - `force-app/main/default/webapplications/*/**/*.ts`
12
+ - `force-app/main/default/webapplications/*/**/*.tsx`
13
+
14
+ ## Rule Objectives
15
+
16
+ - Enforce secure, performant, and maintainable patterns for Salesforce data access.
17
+ - Standardize UI with shadcn/ui and Tailwind.
18
+ - Prevent prohibited patterns that break React or Salesforce constraints.
19
+
20
+ ## UI / layout edits (MANDATORY — read before any UI change)
21
+
22
+ **When the user asks for UI changes** (new components, pages, navigation, header, footer, sidebar, theme, or “layout”):
23
+ **You MUST open and update `src/appLayout.tsx`** (the theme layout) whenever the change affects how the app shell looks or behaves.
24
+ Do not only edit pages or components and leave `appLayout.tsx` unchanged.
25
+ If in doubt, **edit appLayout.tsx as well**.
26
+ The layout file is: `force-app/main/default/webapplications/<appName>/src/appLayout.tsx` (or the app’s `appLayout.tsx` used by `routes.tsx`).
27
+
28
+ **Navigation menu and placeholder name/design:** In `appLayout.tsx`, always replace the **default navigation menu** (items and labels) with app-specific links and names, and replace the **placeholder app name** (header, nav brand, footer) and **placeholder design** with the actual app name and intentional styling. Do not leave template nav or "React App"–style branding. See **webapp-nav-and-placeholders.md**.
29
+
30
+ ## Project & Entry Points
31
+
32
+ - React web app root: `force-app/main/default/webapplications/<appName>/`
33
+ - Main entry component: `force-app/main/default/webapplications/<appName>/src/App.tsx`
34
+ - **Theme/layout shell**: `force-app/main/default/webapplications/<appName>/src/appLayout.tsx` — wraps all routed content (navigation, header, sidebar, outlet). Routes use `<AppLayout />` as the layout element; page content renders inside it via `<Outlet />`. When making UI edits that affect global layout, navigation, header, footer, sidebar, or theme, **you must consider and edit appLayout.tsx** in addition to page or component files; do not only edit individual pages and omit the layout.
35
+ - Running Development Server (from the web app directory):
36
+ - `npm run dev` — starts the Vite dev server
37
+ - You can generally assume the dev server is already running and don't need to start it.
38
+ - Build (from the web app directory):
39
+ - `npm run build` — TypeScript check + Vite build
40
+ - Deploy and open in Salesforce are done from the **SFDX project root** (e.g. via Salesforce CLI or the IDE), not via the web app's package.json. Keep the app buildable so deploy workflows continue to work.
41
+
42
+ ## Component Library (MANDATORY)
43
+
44
+ - Use shadcn/ui for UI components (Buttons, Cards, Inputs, Dialogs, etc.).
45
+ - Import patterns:
46
+
47
+ ```javascript
48
+ import { Button } from '@/components/ui/button';
49
+ import { Card, CardHeader, CardContent } from '@/components/ui/card';
50
+ import { Input } from '@/components/ui/input';
51
+ ```
52
+
53
+ ## Styling Standards
54
+
55
+ - Use Tailwind CSS utility classes.
56
+ - Follow consistent spacing, color, and typography conventions.
57
+
58
+ ## React & TypeScript Standards
59
+
60
+ - Component Architecture: Prefer functional components with hooks.
61
+ - File Naming: Use PascalCase for components (e.g., `Button.tsx`) and camelCase for hooks (e.g., `useAuth.ts`).
62
+ - Imports: Use absolute paths (e.g., `@/components/...`) if the `tsconfig.json` or `vite.config.ts` supports it.
63
+ - State: Default to `useState` for local state; avoid adding global state libraries unless requested.
64
+
65
+ ## Layout and theme (appLayout.tsx) — CRITICAL for UI edits
66
+
67
+ - **appLayout.tsx** is the application shell: it wraps every page and typically contains the main navigation (e.g. `NavigationMenu`), header, sidebar, and `<Outlet />` for child routes. It defines the global look and structure of the app.
68
+ - **MANDATORY:** When asked to change the UI in ways that affect the **overall layout**, **navigation**, **header**, **footer**, **sidebar**, or **theme** (e.g. add a top bar, change nav items, add a sidebar, apply a theme wrapper), you **MUST** edit `appLayout.tsx` (or the app’s layout file) as part of the same change. Do not only edit individual pages or components and leave the layout unchanged.
69
+ - **Before finishing any UI edit:** Ask yourself: “Does this touch layout, nav, header, footer, sidebar, or theme?” If yes, **you must have modified appLayout.tsx** (or the layout file used by routes). If you did not, add that edit before considering the task done.
70
+ - If the project uses feature inheritance (e.g. `__inherit__appLayout`), the editable layout may live in the app or feature at `src/appLayout.tsx`; ensure you modify the correct file that is actually used by `routes.tsx`.
71
+
72
+ ## Module & Platform Restrictions
73
+
74
+ - React apps must NOT import or rely on Salesforce platform modules; do not use:
75
+ - `@salesforce/*`
76
+ - `lightning/*`
77
+ - `@wire` (LWC-only)
78
+ - Use standard web APIs and npm packages only.
79
+
80
+ ## LWC MCP Server Integration (Data Access Guidance)
81
+
82
+ The LWC MCP server (via Agentforce Vibes extension) provides framework-agnostic data access guidance for UI API and GraphQL patterns.
83
+
84
+ ### Primary Tool: `orchestrate_lds_data_requirements`
85
+
86
+ The `orchestrate_lds_data_requirements` tool analyzes data requirements and routes to appropriate guidance tools (UI API or GraphQL). **Note:** Tool names may change, but the purpose remains orchestrating LDS data requirements.
87
+
88
+ **Important for React Applications:** If the MCP tool recommends Apex REST, React applications should ignore this recommendation. Apex REST is not available in React applications. Follow the [Apex REST Strategy](#data-access-priority-order) section above to evaluate whether GraphQL can handle the requirement, or inform the user that the feature is not currently supported in React.
89
+
90
+ ### Tool Availability Check (MANDATORY)
91
+
92
+ Before implementing data access, **MUST** verify `orchestrate_lds_data_requirements` is available. If unavailable:
93
+
94
+ 1. Notify user: "LWC MCP data access tools not enabled. Add 'lwc-experts' to --toolsets in a4d_mcp_settings.json"
95
+ 2. Offer to update the file if you have write access
96
+ 3. Otherwise, provide manual instructions
97
+
98
+ **Configuration:** Add `"lwc-experts"` to `--toolsets` in `a4d_mcp_settings.json` (typically at `{VSCode/Cursor globalStorage}/salesforce.salesforcedx-einstein-gpt/settings/a4d_mcp_settings.json`). Example: `"metadata,lwc-experts"` in the args array.
99
+
100
+ ### LWC MCP Server Tool Usage Restrictions (CRITICAL)
101
+
102
+ **This rule applies when building React applications. Do NOT create LWC components or use LWC-specific development tools.**
103
+
104
+ **Allowed MCP Tools (Data Access Only):**
105
+
106
+ - `orchestrate_lds_data_requirements` - Primary tool for data access guidance
107
+ - Any data access guidance tools referenced by `orchestrate_lds_data_requirements` (e.g., UI API or GraphQL guidance tools)
108
+
109
+ **Note:** If the MCP tool recommends Apex REST guidance tools, React applications should ignore these recommendations as Apex REST is not available in React.
110
+
111
+ **Prohibited MCP Tools (LWC Component Development):**
112
+
113
+ - `guide_lwc_development` - LWC component development guidance
114
+ - `orchestrate_lwc_component_creation` - LWC component creation orchestration
115
+ - `create_lwc_component_from_prd` - LWC component creation from PRD
116
+ - Any other LWC component creation, development, or framework-specific tools
117
+
118
+ **Enforcement:**
119
+
120
+ - **NEVER** call LWC component creation or development tools from the LWC MCP server
121
+ - **ONLY** use data access related tools that provide framework-agnostic guidance
122
+ - If you encounter a request to create LWC components, remind the user that you are building a React app and redirect them to use React patterns instead
123
+
124
+ ## Data Access Rules (CRITICAL)
125
+
126
+ - MANDATORY: Use `axios` for all API calls from React.
127
+
128
+ ### Data Access Workflow (MANDATORY)
129
+
130
+ **Before implementing any data access functionality:**
131
+
132
+ 1. **Proactively check** for LWC MCP server tool availability (see [LWC MCP Server Integration](#lwc-mcp-server-integration-data-access-guidance) section above)
133
+ 2. **Use the LWC MCP server's `orchestrate_lds_data_requirements` tool** to get guidance on the appropriate data access pattern
134
+ 3. The MCP tool will analyze your requirements and guide you to the appropriate Salesforce data access pattern (GraphQL or UI API)
135
+ 4. **Follow the MCP tool's recommendations** when implementing data access code, prioritizing GraphQL for all operations
136
+ 5. **If the tool recommends Apex REST**, ignore this recommendation and follow the [Apex REST Strategy](#data-access-priority-order) to evaluate if GraphQL can handle the requirement
137
+
138
+ **Note:** The code examples below serve as reference patterns, but your implementation should be informed by the MCP tool's guidance, which provides the most up-to-date best practices and framework-agnostic patterns.
139
+
140
+ ### Data Access Priority Order
141
+
142
+ The LWC MCP server's `orchestrate_lds_data_requirements` tool follows this priority order when recommending data access patterns:
143
+
144
+ 1. **GraphQL** (queries & mutations) - Preferred for all data operations including reads, writes, complex queries, relationships, and multi-entity operations
145
+ 2. **Salesforce UI API** - For standard CRUD operations when GraphQL is not suitable
146
+
147
+ **Apex REST Strategy (CRITICAL):**
148
+
149
+ - **Apex REST is NOT available in React applications.** If the MCP tool recommends Apex REST, or if you believe Apex is needed:
150
+ 1. **Reflect** on why Apex seems necessary
151
+ 2. **Evaluate** whether GraphQL queries or mutations can accomplish the task
152
+ 3. **If GraphQL cannot handle the requirement**, inform the user that the feature is not currently supported in React applications
153
+ 4. **Do NOT** implement Apex REST endpoints or attempt to call them from React
154
+
155
+ **Note:** For AI/generative features, see the [Einstein LLM Gateway](#einstein-llm-gateway-aigenerative-features) section below.
156
+
157
+ ### Reference Code Examples
158
+
159
+ The following code examples serve as reference patterns for React applications. **Always consult the LWC MCP server's `orchestrate_lds_data_requirements` tool first** to ensure you're using the most appropriate pattern and latest best practices for your specific use case.
160
+
161
+ UI API example (read):
162
+
163
+ ```javascript
164
+ async function fetchRecord(recordId) {
165
+ try {
166
+ const res = await axios.get(
167
+ `/services/data/v62.0/ui-api/records/${recordId}`
168
+ );
169
+ return res.data;
170
+ } catch (error) {
171
+ const text = error.message;
172
+ throw new Error(`UI API failed: ${error.status} ${text}`);
173
+ }
174
+ }
175
+ ```
176
+
177
+ GraphQL utility (supports both queries and mutations):
178
+
179
+ ```javascript
180
+ export async function sfGraphQL(query, variables = {}) {
181
+ try {
182
+ const res = await axios.post('/services/data/v62.0/graphql', {
183
+ query,
184
+ variables,
185
+ });
186
+ const json = res.data;
187
+ if (Array.isArray(json.errors) && json.errors.length) {
188
+ throw new Error(json.errors.map(e => e.message).join('; '));
189
+ }
190
+ return json.data;
191
+ } catch (error) {
192
+ throw new Error(`GraphQL error: ${error.status}`);
193
+ }
194
+ }
195
+ ```
196
+
197
+ GraphQL query example:
198
+
199
+ ```javascript
200
+ const GET_ACCOUNT = `
201
+ query GetAccount($id: ID!) {
202
+ uiapi {
203
+ query {
204
+ Account(where: { Id: { eq: $id } }) {
205
+ edges {
206
+ node {
207
+ Id
208
+ Name {
209
+ value
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+ `;
218
+
219
+ const account = await sfGraphQL(GET_ACCOUNT, { id: '001...' });
220
+ ```
221
+
222
+ GraphQL mutation example:
223
+
224
+ ```javascript
225
+ const UPDATE_ACCOUNT = `
226
+ mutation UpdateAccount($id: ID!, $name: String!) {
227
+ uiapi {
228
+ AccountUpdate(input: {
229
+ Id: $id
230
+ Account: {
231
+ Name: { value: $name }
232
+ }
233
+ }) {
234
+ Record {
235
+ Id
236
+ Name {
237
+ value
238
+ }
239
+ }
240
+ }
241
+ }
242
+ }
243
+ `;
244
+
245
+ const result = await sfGraphQL(UPDATE_ACCOUNT, {
246
+ id: '001...',
247
+ name: 'New Name',
248
+ });
249
+ ```
250
+
251
+ ## Einstein LLM Gateway (AI/Generative Features)
252
+
253
+ Einstein LLM Gateway provides AI and generative capabilities for your React application. Use this service when you want to add features such as:
254
+
255
+ - Text generation
256
+ - Prompt-based AI responses
257
+ - LLM-powered content creation
258
+ - AI-assisted workflows
259
+
260
+ ### Einstein LLM Gateway Pattern
261
+
262
+ ```javascript
263
+ async function callEinsteinGenerations({ prompt, model = 'gpt-4', signal }) {
264
+ const url = '/services/data/v62.0/einstein/llm/prompt/generations';
265
+ try {
266
+ const resp = await axios.post(
267
+ url,
268
+ {
269
+ additionalConfig: {
270
+ applicationName: 'PromptTemplateGenerationsInvocable',
271
+ model,
272
+ },
273
+ promptTextorId: prompt,
274
+ },
275
+ {
276
+ signal,
277
+ }
278
+ );
279
+ const data = resp.data;
280
+ return data?.generations?.[0]?.text || '';
281
+ } catch (error) {
282
+ throw new Error(
283
+ error.message || `Einstein LLM request failed (${error.status})`
284
+ );
285
+ }
286
+ }
287
+ ```
288
+
289
+ ## Error Handling Pattern
290
+
291
+ - Always implement robust try/catch for async operations.
292
+ - Provide useful but safe error messages (no sensitive data leakage).
293
+
294
+ ```javascript
295
+ async function safeFetch(recordId) {
296
+ try {
297
+ const data = await fetchRecord(recordId);
298
+ return data;
299
+ } catch (err) {
300
+ console.error('Salesforce UI API Error:', err);
301
+ throw err;
302
+ }
303
+ }
304
+ ```
305
+
306
+ ## Anti-Patterns (Do NOT do these)
307
+
308
+ - **Do NOT make UI/layout/theme/nav changes without updating appLayout.tsx** — If you add or change navigation, header, footer, sidebar, or overall layout, you must also edit the layout shell (`src/appLayout.tsx`). Leaving appLayout.tsx untouched while editing only pages or components is an error.
309
+ - **Apex REST is not available in React applications** - Do NOT attempt to use or call Apex REST endpoints from React code
310
+ - Unnecessary Apex controllers for simple UI API/GraphQL operations
311
+ - Missing error handling for async operations
312
+ - Hardcoded Salesforce URLs, IDs, or sensitive data
313
+ - Ignoring field-level security and permission checks
314
+ - Direct DOM manipulation in React components
315
+ - Using LWC-specific patterns (`@wire`, LDS) or `@salesforce/*` modules in React
316
+
317
+ ## Security Standards (CRITICAL)
318
+
319
+ - Validate user permissions before data operations.
320
+ - Respect record sharing rules and field-level security.
321
+ - Never hardcode credentials or secrets in client code.
322
+ - Sanitize all user inputs.
323
+ - Use HTTPS for all API calls.
324
+
325
+ ### Authentication Error Handling (MANDATORY)
326
+
327
+ - All axios clients MUST include response interceptors that handle 401/403 errors.
328
+ - When a 401 (Unauthorized) or 403 (Forbidden) response is received, trigger a page refresh with `window.location.reload()` to redirect to login.
329
+ - Always return `Promise.reject(error)` after handling authentication errors to maintain proper error flow.
330
+
331
+ ### Notes
332
+
333
+ - avoid swallowing errors.
334
+
335
+ Input sanitization example:
336
+
337
+ ```javascript
338
+ function sanitizeInput(input) {
339
+ if (typeof input !== 'string') return '';
340
+ return input
341
+ .trim()
342
+ .replace(/<script[^>]*>.*?<\/script>/gi, '')
343
+ .replace(/javascript:/gi, '')
344
+ .slice(0, 255);
345
+ }
346
+ ```
347
+
348
+ ## Performance Standards
349
+
350
+ - Implement client-side caching (e.g., RTK Query or React Query) for API data.
351
+ - Use `React.memo`, `useMemo`, and `useCallback` where appropriate.
352
+ - Implement proper loading and error states.
353
+
354
+ ## TypeScript Standards
355
+
356
+ - Prefer TypeScript for React components and utilities.
357
+ - Define clear and explicit interfaces for props and API data.
358
+
359
+ ## Testing Requirements
360
+
361
+ - Use Jest + React Testing Library for UI tests.
362
+ - Test loading, success, and error states for data-fetching components.
363
+
364
+ ## Application Generation Rules
365
+
366
+ - When requested to generate a new application:
367
+ - Replace existing template content; do not append to the starter.
368
+ - Preserve the entry point and routes under `force-app/main/default/webapplications/<appName>/src/`.
369
+ - Keep existing build and deploy commands working.
370
+ - Follow the Data Access and Security standards above.
371
+
372
+ ## Debugging Guidance
373
+
374
+ - Use React DevTools for component inspection.
375
+ - Monitor the browser Network tab for REST/GraphQL calls and auth headers.
376
+ - Implement Error Boundaries for unhandled exceptions.
377
+
378
+ ## Quality Checklist (for generated code)
379
+
380
+ - Entry point maintained (`App.tsx` or `App.js` present and wired in routes/pages).
381
+ - **Layout maintained (MANDATORY for UI work):** For any change that affects global layout, nav, header, footer, sidebar, or theme, you **must** have edited `appLayout.tsx`. If you did not open or modify appLayout.tsx, the change is incomplete — go back and update the layout file.
382
+ - Uses shadcn/ui and Tailwind for UI.
383
+ - Follows Data Access rules with proper auth and error handling.
384
+ - Enforces Security standards and input sanitization.
385
+ - Includes loading and error states.
386
+ - Performance optimizations present where reasonable.
387
+ - Tests cover core UI and data interactions.
@@ -0,0 +1,45 @@
1
+ #Goal
2
+
3
+ - You are configuring image usage for React applications generated through Vibe Coding.
4
+ - Your goal is to ensure Unsplash is used as the default image source unless the developer provides their own images.
5
+
6
+ # AI Customization Rule: React Image Processing
7
+
8
+ Image handling standards for React web apps (SFDX): CSP compliance, accessibility, and proper image sources.
9
+
10
+ ## Targets (File Pattern Matching)
11
+
12
+ - `force-app/main/default/webapplications/*/**/*.tsx`
13
+ - `force-app/main/default/webapplications/*/**/*.ts`
14
+ - `force-app/main/default/webapplications/*/**/*.jsx`
15
+ - `force-app/main/default/webapplications/*/**/*.js`
16
+ - `force-app/main/default/webapplications/*/**/*.html`
17
+
18
+ ## Core Rules
19
+
20
+ ### Default Image Source: Unsplash
21
+
22
+ Use Unsplash by default (pre-configured in CSP):
23
+
24
+ ```
25
+ https://images.unsplash.com/photo-{PHOTO_ID}?w={WIDTH}&h={HEIGHT}&fit=crop&q=80
26
+ ```
27
+
28
+ Sample Photo IDs: `1557683316-973673baf926` (tech), `1506905925346-21bda4d32df4` (nature)
29
+
30
+ ### Alternative Sources
31
+
32
+ If user requests another source (Pexels, custom):
33
+
34
+ - Use requested source
35
+ - Inform user: "Add CSP Trusted Site in Setup → Security → CSP Trusted Sites"
36
+
37
+ ### Accessibility (MANDATORY)
38
+
39
+ - Always include descriptive `alt` text
40
+ - Use `alt=""` for decorative images only
41
+
42
+ ### Avoid (CSP Violations)
43
+
44
+ - Avoid until requested `placeholder.com`, `picsum.photos`, `via.placeholder.com`
45
+ - Pre-configured: `images.unsplash.com`, `source.unsplash.com`, `images.pexels.com`
@@ -0,0 +1,224 @@
1
+ # AI Rule: TypeScript Standards
2
+
3
+ Enforces strict TypeScript standards for type-safe React applications.
4
+
5
+ ## Targets
6
+ - `**/*.ts`
7
+ - `**/*.tsx`
8
+
9
+ ## MANDATORY Configuration
10
+ - `strict: true` - Enable all strict type checking
11
+ - `noUncheckedIndexedAccess: true` - Prevent unsafe array/object access
12
+ - `noUnusedLocals: true` - Report unused variables
13
+ - `noUnusedParameters: true` - Report unused parameters
14
+
15
+ ## Function Return Types (REQUIRED)
16
+ ```typescript
17
+ // Always specify return types
18
+ function fetchUserData(id: string): Promise<User> {
19
+ return api.get(`/users/${id}`);
20
+ }
21
+
22
+ const calculateTotal = (items: Item[]): number => {
23
+ return items.reduce((sum, item) => sum + item.price, 0);
24
+ };
25
+ ```
26
+
27
+ ## Interface Definitions (REQUIRED)
28
+ ```typescript
29
+ // Data structures
30
+ interface User {
31
+ id: string;
32
+ name: string;
33
+ email: string;
34
+ createdAt: Date;
35
+ }
36
+
37
+ // React component props
38
+ interface ButtonProps {
39
+ variant: 'primary' | 'secondary';
40
+ onClick: () => void;
41
+ disabled?: boolean;
42
+ children: React.ReactNode;
43
+ }
44
+
45
+ export const Button: React.FC<ButtonProps> = ({ variant, onClick, disabled, children }) => {
46
+ // Implementation
47
+ };
48
+ ```
49
+
50
+ ## Type Safety Rules
51
+
52
+ ### Never Use `any`
53
+ ```typescript
54
+ // FORBIDDEN
55
+ const data: any = await fetchData();
56
+
57
+ // REQUIRED: Proper typing
58
+ interface ApiResponse {
59
+ data: User[];
60
+ status: 'success' | 'error';
61
+ }
62
+ const response: ApiResponse = await fetchData();
63
+
64
+ // ACCEPTABLE: Unknown when type is truly unknown
65
+ const parseJson = (input: string): unknown => JSON.parse(input);
66
+ ```
67
+
68
+ ### Null Safety
69
+ ```typescript
70
+ // Handle null/undefined explicitly
71
+ interface UserProfile {
72
+ user: User | null;
73
+ loading: boolean;
74
+ error: string | null;
75
+ }
76
+
77
+ // Use optional chaining and nullish coalescing
78
+ const displayName = user?.name ?? 'Anonymous';
79
+ const avatarUrl = user?.profile?.avatar ?? '/default-avatar.png';
80
+ ```
81
+
82
+ ## React TypeScript Patterns
83
+
84
+ ### Event Handlers
85
+ ```typescript
86
+ const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
87
+ event.preventDefault();
88
+ };
89
+
90
+ const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
91
+ setInputValue(event.target.value);
92
+ };
93
+
94
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>): void => {
95
+ console.log('Button clicked');
96
+ };
97
+ ```
98
+
99
+ ### State and Hooks
100
+ ```typescript
101
+ // Type useState properly
102
+ const [user, setUser] = useState<User | null>(null);
103
+ const [loading, setLoading] = useState<boolean>(false);
104
+ const [errors, setErrors] = useState<string[]>([]);
105
+
106
+ // Type custom hooks
107
+ interface UseApiResult<T> {
108
+ data: T | null;
109
+ loading: boolean;
110
+ error: string | null;
111
+ refetch: () => Promise<void>;
112
+ }
113
+
114
+ function useApi<T>(url: string): UseApiResult<T> {
115
+ const [data, setData] = useState<T | null>(null);
116
+ const [loading, setLoading] = useState<boolean>(false);
117
+ const [error, setError] = useState<string | null>(null);
118
+
119
+ return { data, loading, error, refetch };
120
+ }
121
+ ```
122
+
123
+ ## API Types
124
+
125
+ ### Salesforce Records
126
+ ```typescript
127
+ interface SalesforceRecord {
128
+ Id: string;
129
+ attributes: { type: string; url: string };
130
+ }
131
+
132
+ interface Account extends SalesforceRecord {
133
+ Name: { value: string };
134
+ Industry?: { value: string | null };
135
+ }
136
+
137
+ // Type API functions
138
+ async function fetchAccount(id: string): Promise<Account> {
139
+ const response = await axios.get<Account>(`/services/data/v62.0/ui-api/records/${id}`);
140
+ return response.data;
141
+ }
142
+ ```
143
+
144
+ ### GraphQL
145
+ ```typescript
146
+ interface GraphQLResponse<T> {
147
+ data: T;
148
+ errors?: Array<{ message: string; locations?: Array<{ line: number; column: number }> }>;
149
+ }
150
+
151
+ async function executeGraphQL<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
152
+ const response = await axios.post<GraphQLResponse<T>>('/services/data/v62.0/graphql', {
153
+ query,
154
+ variables,
155
+ });
156
+
157
+ if (response.data.errors?.length) {
158
+ throw new Error(response.data.errors.map(e => e.message).join('; '));
159
+ }
160
+
161
+ return response.data.data;
162
+ }
163
+ ```
164
+
165
+ ## Error Handling Types
166
+ ```typescript
167
+ interface ApiError {
168
+ message: string;
169
+ status: number;
170
+ code?: string;
171
+ }
172
+
173
+ class CustomError extends Error {
174
+ constructor(message: string, public readonly status: number, public readonly code?: string) {
175
+ super(message);
176
+ this.name = 'CustomError';
177
+ }
178
+ }
179
+ ```
180
+
181
+ ## Anti-Patterns (FORBIDDEN)
182
+
183
+ ### Type Assertions
184
+ ```typescript
185
+ // FORBIDDEN: Unsafe assertions
186
+ const user = data as User;
187
+
188
+ // REQUIRED: Type guards
189
+ function isUser(obj: unknown): obj is User {
190
+ return typeof obj === 'object' && obj !== null && typeof (obj as User).id === 'string';
191
+ }
192
+
193
+ if (isUser(data)) {
194
+ console.log(data.name); // Now safely typed
195
+ }
196
+ ```
197
+
198
+ ### Missing Return Types
199
+ ```typescript
200
+ // FORBIDDEN: No return type
201
+ const fetchData = async (id: string) => {
202
+ return await api.get(`/data/${id}`);
203
+ };
204
+
205
+ // REQUIRED: Explicit return type
206
+ const fetchData = async (id: string): Promise<ApiResponse> => {
207
+ return await api.get(`/data/${id}`);
208
+ };
209
+ ```
210
+
211
+ ## Quality Checklist
212
+ Before completing TypeScript code:
213
+ 1. All functions have explicit return types
214
+ 2. All interfaces are properly defined
215
+ 3. No `any` types used (use `unknown` if necessary)
216
+ 4. Null/undefined handling is explicit
217
+ 5. React components are properly typed
218
+ 6. API calls have proper type definitions
219
+ 7. `tsc -b` compiles without errors
220
+
221
+ ## Enforcement
222
+ - TypeScript errors MUST be fixed before any commit
223
+ - NEVER disable TypeScript strict mode
224
+ - Code reviews MUST check for proper typing
@@ -0,0 +1,23 @@
1
+ # UI layout: always update appLayout.tsx (MANDATORY)
2
+
3
+ **Build navigation into the app layout:** The app layout (e.g. `appLayout.tsx`) must **include** the navigation—header nav, sidebar, or both—so that every routed page is wrapped by the same shell and nav. Do not omit nav from the layout or rely on per-page nav only.
4
+
5
+ ## Targets (File Pattern Matching)
6
+
7
+ Apply this rule when editing React UI or layout:
8
+
9
+ - `force-app/main/default/webapplications/*/src/appLayout.tsx`
10
+ - `force-app/main/default/webapplications/*/src/**/*.tsx`
11
+ - `force-app/main/default/webapplications/*/src/**/*.jsx`
12
+
13
+ ## Rule (CRITICAL)
14
+
15
+ **When making any UI change** that affects navigation, header, footer, sidebar, theme, or overall layout:
16
+
17
+ 1. **You MUST also edit `src/appLayout.tsx`** (the theme layout used by `routes.tsx`).
18
+ 2. Do not only edit pages or components and leave `appLayout.tsx` unchanged.
19
+ 3. Before finishing: confirm you opened and modified `appLayout.tsx` if the change touches layout/nav/theme. If you did not, the task is incomplete — update the layout file.
20
+
21
+ **Navigation menu and placeholder name/design (often missed):** When editing the layout, **always** update (1) the **navigation menu**—replace default nav items and labels with app-specific links and names; do not leave template "Home"/"About" or placeholder links; (2) the **app name** in header/nav brand/footer and in `index.html` `<title>`—use the actual app name, not the template placeholder; (3) any **placeholder design** in the shell so it matches the app. See **webapp-nav-and-placeholders.md**.
22
+
23
+ Path: `force-app/main/default/webapplications/<appName>/src/appLayout.tsx` (or the app's layout file that `routes.tsx` imports). (or the app’s layout file that `routes.tsx` imports).