@wix/auto-patterns 1.37.0 → 1.39.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 (180) hide show
  1. package/dist/cjs/components/AutoPatternsApp/AutoPatternsApp.js +1 -1
  2. package/dist/cjs/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js +73 -19
  3. package/dist/cjs/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js.map +1 -1
  4. package/dist/cjs/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.js +1 -1
  5. package/dist/cjs/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js +1 -1
  6. package/dist/cjs/components/AutoPatternsCollectionPageContent/SkeletonCollection.js +1 -1
  7. package/dist/cjs/components/AutoPatternsCollectionPageFooter/AutoPatternsCollectionPageFooter.js +1 -1
  8. package/dist/cjs/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js +42 -11
  9. package/dist/cjs/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js.map +1 -1
  10. package/dist/cjs/components/AutoPatternsEntityPage/EditModeEntityPage.js +13 -9
  11. package/dist/cjs/components/AutoPatternsEntityPage/EditModeEntityPage.js.map +1 -1
  12. package/dist/cjs/components/AutoPatternsEntityPage/Fields/Checkbox.js +1 -1
  13. package/dist/cjs/components/AutoPatternsEntityPage/Fields/DateInput.js +1 -1
  14. package/dist/cjs/components/AutoPatternsEntityPage/Fields/DateTime.js +1 -1
  15. package/dist/cjs/components/AutoPatternsEntityPage/Fields/FormFieldInput.js +1 -1
  16. package/dist/cjs/components/AutoPatternsEntityPage/Fields/ImageInput.js +1 -1
  17. package/dist/cjs/components/AutoPatternsEntityPage/Fields/LongText.js +1 -1
  18. package/dist/cjs/components/AutoPatternsEntityPage/Fields/Number.js +1 -1
  19. package/dist/cjs/components/AutoPatternsEntityPage/Fields/ShortText.js +1 -1
  20. package/dist/cjs/components/AutoPatternsEntityPage/Fields/Url.js +1 -1
  21. package/dist/cjs/components/AutoPatternsEntityPage/RenderLayout/RenderLayoutCard.js +1 -1
  22. package/dist/cjs/components/AutoPatternsEntityPage/RenderLayout/RenderLayoutContent.js +1 -1
  23. package/dist/cjs/components/AutoPatternsEntityPage/RenderLayout/RenderViewField.js +1 -1
  24. package/dist/cjs/components/AutoPatternsEntityPage/SkeletonEntity.js +1 -1
  25. package/dist/cjs/components/AutoPatternsEntityPage/ViewEntityPage/RenderViewLayoutCard.js +1 -1
  26. package/dist/cjs/components/AutoPatternsEntityPage/ViewEntityPage/RenderViewLayoutContent.js +1 -1
  27. package/dist/cjs/components/AutoPatternsEntityPage/ViewModeEntityPage.js +1 -1
  28. package/dist/cjs/components/AutoPatternsGrid/AutoPatternsGrid.js +9 -6
  29. package/dist/cjs/components/AutoPatternsGrid/AutoPatternsGrid.js.map +1 -1
  30. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsPage.js +51 -15
  31. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsPage.js.map +1 -1
  32. package/dist/cjs/components/AutoPatternsRoute/AutoPatternsRoutes.js +1 -1
  33. package/dist/cjs/components/AutoPatternsTable/AutoPatternsTable.js +11 -6
  34. package/dist/cjs/components/AutoPatternsTable/AutoPatternsTable.js.map +1 -1
  35. package/dist/cjs/components/AutoPatternsTableGridSwitch/AutoPatternsTableGridSwitch.js +1 -1
  36. package/dist/cjs/components/DynamicIcon.js +1 -1
  37. package/dist/cjs/components/ModalRenderer.js +1 -1
  38. package/dist/cjs/components/filters/DynamicCollectionFilter.js +1 -1
  39. package/dist/cjs/components/filters/StaticCollectionFilter.js +1 -1
  40. package/dist/cjs/components/modals/actions/BulkDeleteModal.js +28 -10
  41. package/dist/cjs/components/modals/actions/BulkDeleteModal.js.map +1 -1
  42. package/dist/cjs/components/modals/actions/CreateModal.js +1 -1
  43. package/dist/cjs/components/modals/actions/EditModal.js +1 -1
  44. package/dist/cjs/counter.js +1 -1
  45. package/dist/cjs/dataSourceAdapters/cms/filterUtils.js +3 -2
  46. package/dist/cjs/dataSourceAdapters/cms/filterUtils.js.map +1 -1
  47. package/dist/cjs/dataSourceAdapters/cms/sortUtils.js +2 -1
  48. package/dist/cjs/dataSourceAdapters/cms/sortUtils.js.map +1 -1
  49. package/dist/cjs/hooks/useBaseTableFeatures.js +6 -3
  50. package/dist/cjs/hooks/useBaseTableFeatures.js.map +1 -1
  51. package/dist/cjs/hooks/useBulkActionToolbar.js +1 -1
  52. package/dist/cjs/hooks/useCollectionPageActions.js +1 -1
  53. package/dist/cjs/hooks/useColumns.js +1 -1
  54. package/dist/cjs/hooks/useCommonCollectionFeatures.js +1 -1
  55. package/dist/cjs/hooks/useDataExtensionProps.js +30 -0
  56. package/dist/cjs/hooks/useDataExtensionProps.js.map +1 -0
  57. package/dist/cjs/hooks/useDragAndDropBaseProps.js +30 -0
  58. package/dist/cjs/hooks/useDragAndDropBaseProps.js.map +1 -0
  59. package/dist/cjs/hooks/useEmptyStates.js +1 -1
  60. package/dist/cjs/hooks/useEntityPageActions.js +1 -1
  61. package/dist/cjs/hooks/useFilters.js +1 -1
  62. package/dist/cjs/hooks/useGridDragAndDrop.js +17 -0
  63. package/dist/cjs/hooks/useGridDragAndDrop.js.map +1 -0
  64. package/dist/cjs/hooks/useGridFeatures.js +4 -1
  65. package/dist/cjs/hooks/useGridFeatures.js.map +1 -1
  66. package/dist/cjs/hooks/useTableDragAndDrop.js +17 -0
  67. package/dist/cjs/hooks/useTableDragAndDrop.js.map +1 -0
  68. package/dist/cjs/hooks/useTableFeatures.js +7 -2
  69. package/dist/cjs/hooks/useTableFeatures.js.map +1 -1
  70. package/dist/cjs/hooks/useTableGridSwitchDragAndDrop.js +17 -0
  71. package/dist/cjs/hooks/useTableGridSwitchDragAndDrop.js.map +1 -0
  72. package/dist/cjs/hooks/useTableGridSwitchFeatures.js +7 -2
  73. package/dist/cjs/hooks/useTableGridSwitchFeatures.js.map +1 -1
  74. package/dist/cjs/providers/AppConfigContext.js +1 -1
  75. package/dist/cjs/providers/AppContext.js +1 -1
  76. package/dist/cjs/providers/AppContextData.js +1 -1
  77. package/dist/cjs/providers/AutoPatternsOverridesContext.js +2 -2
  78. package/dist/cjs/providers/AutoPatternsOverridesContext.js.map +1 -1
  79. package/dist/cjs/providers/ErrorContext.js +1 -1
  80. package/dist/cjs/providers/ItemsContext.js +1 -1
  81. package/dist/cjs/providers/ModalContext.js +1 -1
  82. package/dist/cjs/providers/OptimisticActionsContext.js +1 -1
  83. package/dist/cjs/providers/RootAppProvider.js +1 -1
  84. package/dist/cjs/providers/SchemaContext.js +1 -1
  85. package/dist/cjs/providers/SchemaRegistryContext.js +1 -1
  86. package/dist/cjs/types/CollectionPageConfig.js.map +1 -1
  87. package/dist/cjs/types/DeepPartial.js +4 -0
  88. package/dist/cjs/types/DeepPartial.js.map +1 -0
  89. package/dist/cjs/types/actions/base.js.map +1 -1
  90. package/dist/cjs/types/types.js.map +1 -1
  91. package/dist/cjs/utils/actions/bulkDeleteAction.js +1 -1
  92. package/dist/cjs/utils/actions/createAction.js +1 -1
  93. package/dist/cjs/utils/actions/deleteAction.js +1 -1
  94. package/dist/cjs/utils/actions/updateAction.js +1 -1
  95. package/dist/esm/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js +28 -10
  96. package/dist/esm/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js.map +1 -1
  97. package/dist/esm/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js +18 -6
  98. package/dist/esm/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js.map +1 -1
  99. package/dist/esm/components/AutoPatternsEntityPage/EditModeEntityPage.js +4 -0
  100. package/dist/esm/components/AutoPatternsEntityPage/EditModeEntityPage.js.map +1 -1
  101. package/dist/esm/components/AutoPatternsGrid/AutoPatternsGrid.js +7 -4
  102. package/dist/esm/components/AutoPatternsGrid/AutoPatternsGrid.js.map +1 -1
  103. package/dist/esm/components/AutoPatternsRoute/AutoPatternsPage.js +16 -6
  104. package/dist/esm/components/AutoPatternsRoute/AutoPatternsPage.js.map +1 -1
  105. package/dist/esm/components/AutoPatternsTable/AutoPatternsTable.js +9 -4
  106. package/dist/esm/components/AutoPatternsTable/AutoPatternsTable.js.map +1 -1
  107. package/dist/esm/components/modals/actions/BulkDeleteModal.js +20 -3
  108. package/dist/esm/components/modals/actions/BulkDeleteModal.js.map +1 -1
  109. package/dist/esm/dataSourceAdapters/cms/filterUtils.js +3 -2
  110. package/dist/esm/dataSourceAdapters/cms/filterUtils.js.map +1 -1
  111. package/dist/esm/dataSourceAdapters/cms/sortUtils.js +2 -1
  112. package/dist/esm/dataSourceAdapters/cms/sortUtils.js.map +1 -1
  113. package/dist/esm/hooks/useBaseTableFeatures.js +4 -1
  114. package/dist/esm/hooks/useBaseTableFeatures.js.map +1 -1
  115. package/dist/esm/hooks/useDataExtensionProps.js +18 -0
  116. package/dist/esm/hooks/useDataExtensionProps.js.map +1 -0
  117. package/dist/esm/hooks/useDragAndDropBaseProps.js +27 -0
  118. package/dist/esm/hooks/useDragAndDropBaseProps.js.map +1 -0
  119. package/dist/esm/hooks/useGridDragAndDrop.js +13 -0
  120. package/dist/esm/hooks/useGridDragAndDrop.js.map +1 -0
  121. package/dist/esm/hooks/useGridFeatures.js +4 -1
  122. package/dist/esm/hooks/useGridFeatures.js.map +1 -1
  123. package/dist/esm/hooks/useTableDragAndDrop.js +13 -0
  124. package/dist/esm/hooks/useTableDragAndDrop.js.map +1 -0
  125. package/dist/esm/hooks/useTableFeatures.js +7 -2
  126. package/dist/esm/hooks/useTableFeatures.js.map +1 -1
  127. package/dist/esm/hooks/useTableGridSwitchDragAndDrop.js +13 -0
  128. package/dist/esm/hooks/useTableGridSwitchDragAndDrop.js.map +1 -0
  129. package/dist/esm/hooks/useTableGridSwitchFeatures.js +7 -2
  130. package/dist/esm/hooks/useTableGridSwitchFeatures.js.map +1 -1
  131. package/dist/esm/providers/AutoPatternsOverridesContext.js.map +1 -1
  132. package/dist/esm/types/CollectionPageConfig.js.map +1 -1
  133. package/dist/esm/types/DeepPartial.js +2 -0
  134. package/dist/esm/types/DeepPartial.js.map +1 -0
  135. package/dist/esm/types/actions/base.js.map +1 -1
  136. package/dist/esm/types/types.js.map +1 -1
  137. package/dist/types/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.d.ts +1 -1
  138. package/dist/types/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.d.ts.map +1 -1
  139. package/dist/types/components/AutoPatternsEntityPage/AutoPatternsEntityPage.d.ts.map +1 -1
  140. package/dist/types/components/AutoPatternsEntityPage/EditModeEntityPage.d.ts.map +1 -1
  141. package/dist/types/components/AutoPatternsGrid/AutoPatternsGrid.d.ts.map +1 -1
  142. package/dist/types/components/AutoPatternsRoute/AutoPatternsPage.d.ts.map +1 -1
  143. package/dist/types/components/AutoPatternsTable/AutoPatternsTable.d.ts.map +1 -1
  144. package/dist/types/components/modals/actions/BulkDeleteModal.d.ts.map +1 -1
  145. package/dist/types/hooks/useBaseTableFeatures.d.ts +10 -0
  146. package/dist/types/hooks/useBaseTableFeatures.d.ts.map +1 -1
  147. package/dist/types/hooks/useDataExtensionProps.d.ts +8 -0
  148. package/dist/types/hooks/useDataExtensionProps.d.ts.map +1 -0
  149. package/dist/types/hooks/useDragAndDropBaseProps.d.ts +4 -0
  150. package/dist/types/hooks/useDragAndDropBaseProps.d.ts.map +1 -0
  151. package/dist/types/hooks/useGridDragAndDrop.d.ts +24 -0
  152. package/dist/types/hooks/useGridDragAndDrop.d.ts.map +1 -0
  153. package/dist/types/hooks/useGridFeatures.d.ts +22 -0
  154. package/dist/types/hooks/useGridFeatures.d.ts.map +1 -1
  155. package/dist/types/hooks/useTableDragAndDrop.d.ts +3 -0
  156. package/dist/types/hooks/useTableDragAndDrop.d.ts.map +1 -0
  157. package/dist/types/hooks/useTableFeatures.d.ts +2 -0
  158. package/dist/types/hooks/useTableFeatures.d.ts.map +1 -1
  159. package/dist/types/hooks/useTableGridSwitchDragAndDrop.d.ts +27 -0
  160. package/dist/types/hooks/useTableGridSwitchDragAndDrop.d.ts.map +1 -0
  161. package/dist/types/hooks/useTableGridSwitchFeatures.d.ts +24 -0
  162. package/dist/types/hooks/useTableGridSwitchFeatures.d.ts.map +1 -1
  163. package/dist/types/providers/AutoPatternsOverridesContext.d.ts +6 -0
  164. package/dist/types/providers/AutoPatternsOverridesContext.d.ts.map +1 -1
  165. package/dist/types/types/CollectionPageConfig.d.ts +15 -0
  166. package/dist/types/types/CollectionPageConfig.d.ts.map +1 -1
  167. package/dist/types/types/DeepPartial.d.ts +4 -0
  168. package/dist/types/types/DeepPartial.d.ts.map +1 -0
  169. package/dist/types/types/actions/base.d.ts +5 -0
  170. package/dist/types/types/actions/base.d.ts.map +1 -1
  171. package/dist/types/types/types.d.ts +24 -1
  172. package/dist/types/types/types.d.ts.map +1 -1
  173. package/docs/GETTING_STARTED.md +6 -2
  174. package/mcp-docs/app_config_structure.md +14 -1
  175. package/mcp-docs/auto-patterns-guide.md +282 -80
  176. package/mcp-docs/bulk_actions.md +60 -0
  177. package/mcp-docs/custom_overrides.md +134 -54
  178. package/mcp-docs/schema_config.md +74 -25
  179. package/mcp-docs/wix_fqdn_custom_data_source.md +377 -158
  180. package/package.json +13 -13
@@ -1,28 +1,63 @@
1
- # FQDN-Based Custom Data Source Implementation
1
+ ## Build a Custom Data Source from a Wix Business API FQDN (with Contacts v4 example)
2
2
 
3
3
  **🛑 CRITICAL PREREQUISITE**: This guide explains a specialized feature that exists within the broader auto-patterns framework. You **CANNOT** implement this guide without first having the complete content of the WixAutoPatternsGuide.
4
4
 
5
5
  **📋 MANDATORY FIRST STEP**: Before proceeding with this FQDN-specific implementation:
6
+
6
7
  1. **You MUST call the `WixAutoPatternsGuide` tool first** to get the foundational auto-patterns knowledge
7
8
  2. **This document is NOT standalone** - it's an advanced feature guide that builds upon the core auto-patterns concepts
8
9
  3. **Without the WixAutoPatternsGuide content**, you will not understand the basic concepts, component structure, or implementation patterns required for this FQDN implementation
9
10
 
10
- When implementing a custom data source based on a Wix Business API FQDN, you'll need to understand several key concepts and follow specific implementation patterns. This guide covers the complete process from schema extraction to creating a foundation structure that **you will need to complete**.
11
+ This guide shows how to build an Auto-Patterns custom data source backed by a Wix Business API entity identified by its FQDN. You will:
12
+
13
+ - Discover schema and client library via the Business Schema MCP
14
+ - Map the FQDN schema to a `SchemaConfig` (see `schema_config.md` for the full interface)
15
+ - Implement actions (CRUD + find)
16
+ - Wire the custom data source into your Auto-Patterns page
11
17
 
12
- **⚠️ IMPORTANT**: This guide creates a foundation with helpful comments and unimplemented actions that throw exceptions. The actual data source implementation (CRUD operations) must be completed by you using the appropriate Wix Business API client library.
18
+ > IMPORTANT: Always use the Business Schema MCP as the source of truth for your target FQDN.
19
+ > - Run `client_lib` to determine the exact SDK/ambassador package to install and import
20
+ > - Run `fqdn_info` to see available actions, pagination mode, and request/response structure
21
+ > - (Optional) Run `fqdn_schema` for precise field shapes
22
+ > Do not rely on this example without verifying all details for your specific FQDN via MCP.
13
23
 
14
24
  **📝 MINIMAL IMPLEMENTATION APPROACH**: This guide focuses on creating a basic, functional dashboard page. Custom overrides (actions, columns, components, etc.) should only be implemented when explicitly requested by the user. A simple dashboard page requires only the core custom data source implementation without any additional overrides.
15
25
 
16
- ## Prerequisites: Required Tools and Knowledge
26
+ ### Non‑negotiable requirements (LLM guardrails)
27
+
28
+ - You **MUST** derive the SDK package, action names, required fields, and pagination mode from Business Schema MCP.
29
+ - You **MUST** install the package returned by `client_lib` before importing/using it.
30
+ - You **MUST** map API snake_case field segments to camelCase segments in `SchemaConfig`, preserving dot paths.
31
+ - You **MUST** set `supportedQueryOperators: []` for all fields in custom data sources.
32
+ - You **MUST** return the correct pagination shape from `actions.find` based on the API’s paging mode.
33
+ - You **MUST** pass required concurrency/identity fields (e.g., `revision` on Contacts v4 updates) exactly as specified by MCP.
34
+ - You **MUST** fully implement `SchemaConfig` (fields and actions). Do not leave placeholders; do not use `as any` to bypass typing.
35
+ - You **MUST NOT** create new custom entity types. Use SDK-exported types (from the ambassador/SDK package) or rely on inference. Avoid `any` that suppresses type errors.
36
+
37
+ ### LLM Quick‑Start Execution Plan (follow in order)
38
+
39
+ 1. **MUST** run `client_lib` on your FQDN and note the exact package name.
40
+ 2. **MUST** install that package (npm/yarn/pnpm) and import the correct client entry point.
41
+ 3. **MUST** run `fqdn_info` to list actions, required fields, and pagination type; use it to draft your actions.
42
+ 4. **MUST** run `fqdn_schema` if you need concrete field shapes; map fields to `SchemaConfig` with segment-wise snake_case→camelCase and preserved dot paths.
43
+ 5. **MUST** implement `actions` using the exact method names and payloads from MCP; add robust error handling.
44
+ 6. **MUST** implement `find` to return the correct pagination shape (cursor vs offset) per MCP.
45
+ 7. **MUST** register the custom data source and set matching `custom.id` in AppConfig.
46
+ 8. **MUST** keep `supportedQueryOperators: []` for all fields.
47
+
48
+ ### Prerequisites: Required Tools and Knowledge
17
49
 
18
50
  **🛑 ABSOLUTE REQUIREMENT - WixAutoPatternsGuide Content**:
51
+
19
52
  - **You MUST have the complete WixAutoPatternsGuide content** before starting this implementation
20
53
  - **This FQDN guide is NOT self-contained** - it's a specialized extension of the main auto-patterns guide
21
54
  - **If you haven't called the `WixAutoPatternsGuide` tool yet**, stop now and call it first
22
55
  - **This guide will reference concepts, components, and patterns** that are only explained in the main guide
23
56
 
24
57
  **🛑 CRITICAL**: Before proceeding with this guide, you must have the following tools available:
58
+
25
59
  - `WixAutoPatternsGuide` tool for understanding auto-patterns fundamentals and implementation patterns (**MANDATORY FIRST STEP**)
60
+ - `fqdn_info` tool for extracting action information from FQDNs
26
61
  - `fqdn_schema` tool for extracting schema information from FQDNs
27
62
  - `client_lib` tool for determining the correct client library package
28
63
 
@@ -30,6 +65,7 @@ When implementing a custom data source based on a Wix Business API FQDN, you'll
30
65
 
31
66
  **Auto-Patterns Context Requirement:**
32
67
  If you haven't already used the `WixAutoPatternsGuide` tool in this conversation, you MUST call it first to understand:
68
+
33
69
  - How AutoPatternsApp works
34
70
  - AppConfig structure and requirements
35
71
  - Custom data source implementation patterns
@@ -39,51 +75,65 @@ If you haven't already used the `WixAutoPatternsGuide` tool in this conversation
39
75
 
40
76
  **Without this foundational knowledge, you cannot successfully implement FQDN-based custom data sources.**
41
77
 
42
- To add these tools, you need to install the **business-schema-mcp** server:
43
-
44
- **Installation Instructions:**
45
- 1. Follow the setup instructions at: https://github.com/wix-private/mcp-servers/tree/master/packages/business-schema-mcp
46
- 2. Configure the MCP server according to the documentation
47
- 3. Restart your development environment to load the new tools
48
- 4. Return to this guide once the tools are available
78
+ **Tool Installation:**
79
+ - Business Schema MCP installed and available in your environment
80
+ - Tools used: `fqdn_info`, `fqdn_schema`, `client_lib`
81
+ - Installation: see the Business Schema MCP README (internal)
49
82
 
50
83
  **Tool Verification:**
51
84
  Before continuing, verify that you have access to:
85
+
86
+ - `fqdn_info` tool - for extracting action and pagination information from FQDNs
52
87
  - `fqdn_schema` tool - for extracting entity schema from FQDNs
53
88
  - `client_lib` tool - for determining the correct SDK package to use
54
89
 
55
- ## Step 1: Extract Schema Information
90
+ ### What you will build
56
91
 
57
- First, use the fqdn_schema tool to understand the structure of your target entity:
92
+ We'll create a custom data source for Contacts using `wix.contacts.v4.contact` as an example. The same steps apply to any other FQDN.
58
93
 
59
- ```
60
- Use fqdn_schema tool with your FQDN (e.g., "wix.bookings.v1.sessions")
61
- ```
94
+ ---
95
+
96
+ ## 1) Discover schema and SDK with Business Schema MCP
62
97
 
63
- This will provide you with:
64
- - Entity field definitions
65
- - Available actions/operations
66
- - Field types and constraints
67
- - Relationships and references
98
+ Use the MCP tools to examine the entity and determine which SDK package to use.
68
99
 
69
- ## Step 2: Determine Client Library
100
+ ```text
101
+ Call client_lib with: "wix.contacts.v4.contact" -> returns: @wix/crm
70
102
 
71
- Use the client_lib tool to identify the correct package for your FQDN:
103
+ Call fqdn_info with: "wix.contacts.v4.contact" -> see common methods like CreateContact, GetContact, UpdateContact, DeleteContact, QueryContacts (offset-based)
72
104
 
105
+ Optionally call fqdn_schema for message shapes (Contact, CreateContactRequest, etc.)
73
106
  ```
74
- Use client_lib tool with your FQDN to get the appropriate SDK package
107
+
108
+ Notes for Contacts v4:
109
+ - Paging for `QueryContacts` is offset-based
110
+ - Identifier in routes is `id` or `contactId` depending on the action; the entity carries an `id` field
111
+
112
+ Using other FQDNs: always run `client_lib` to get the exact package. Some entities use an ambassador package (e.g., `@wix/ambassador-<product>-<version>-<resource>`); install and import accordingly.
113
+
114
+ LLM notes:
115
+ - You **MUST NOT** guess method names or shapes; copy them from `fqdn_info`.
116
+ - You **MUST NOT** assume pagination type; read it from `fqdn_info` and implement accordingly.
117
+
118
+ ### Install the SDK package
119
+
120
+ For the Contacts v4 example:
121
+
122
+ ```bash
123
+ npm i @wix/crm
124
+ # or
125
+ yarn add @wix/crm
126
+ # or
127
+ pnpm add @wix/crm
75
128
  ```
76
129
 
77
- This will tell you which library to import for your custom data source implementation.
130
+ For other FQDNs, install the package returned by `client_lib`.
78
131
 
79
- ## Step 3: Map FQDN Schema to SchemaConfig
132
+ ---
80
133
 
81
- Transform the FQDN schema from Step 1 into a AutoPatterns-compatible SchemaConfig by mapping the FQDN field types to AutoPatterns field types. Identify appropriate fields for `displayField` and `idField` based on your FQDN schema.
134
+ ## 2) Map FQDN fields to SchemaConfig
82
135
 
83
- **🛑 MANDATORY - Query Operators Must Be Empty Array**: When implementing a custom data source, you **MUST** set `supportedQueryOperators: []` (empty array) for all fields. This is required because:
84
- - Custom data sources handle all query operations directly through your implementation
85
- - You don't need to specify individual operators for each field
86
- - The custom data source `find` action will receive all queries regardless of declared operators
136
+ See `schema_config.md` for the interface. Derive your field list and types from Business Schema MCP (`fqdn_schema` / `fqdn_info`) for YOUR FQDN, then apply these **MUST** rules:
87
137
 
88
138
  ### ⚠️ CRITICAL: Field ID Conversion from snake_case to camelCase
89
139
 
@@ -94,141 +144,276 @@ Transform the FQDN schema from Step 1 into a AutoPatterns-compatible SchemaConfi
94
144
  - **In API calls**: Use the original snake_case field names (e.g., `primary_info.email`, `created_date`, `last_activity.activity_date`)
95
145
 
96
146
  **Field Path Conversion Examples:**
147
+
97
148
  - `primary_info.email` → `primaryInfo.email` (NOT `primaryEmail`)
98
149
  - `last_activity.activity_date` → `lastActivity.activityDate` (NOT `lastActivityDate`)
99
150
  - `job_title` → `jobTitle`
100
151
  - `created_date` → `createdDate`
152
+ - `info.job_title` → `info.jobTitle`
153
+ - `info.name.first` → `info.name.first` (already camelCase, no change needed)
154
+ - `info.name.last` → `info.name.last` (already camelCase, no change needed)
101
155
 
102
156
  This conversion ensures:
157
+
103
158
  - **Consistent JavaScript naming conventions** in your AutoPatterns configuration
104
159
  - **Preserved field path structure** for nested object access
105
160
  - **Proper field mapping** between configuration and data source
106
161
  - **Seamless integration** with AutoPatterns components
107
162
 
108
- For the complete SchemaConfig interface, field definitions, and implementation details, refer to the "Schema Config" section.
163
+ **🛑 MANDATORY - Query Operators Must Be Empty Array**: When implementing a custom data source, you **MUST** set `supportedQueryOperators: []` (empty array) for all fields. This is required because:
164
+
165
+ - Custom data sources handle all query operations directly through your implementation
166
+ - You don't need to specify individual operators for each field
167
+ - The custom data source `find` action will receive all queries regardless of declared operators
109
168
 
110
- ## Step 4: Set Up Custom Data Source Structure
169
+ **Additional Rules:**
170
+ - You **MUST** choose:
171
+ - `idField`: typically `id`
172
+ - `displayField`: a meaningful label, e.g., `displayName`, or build from name fields
173
+
174
+ Minimal example for a subset of Contacts fields:
175
+
176
+ ```ts
177
+ import type { SchemaConfig } from "@wix/auto-patterns"; // refer to your local types
178
+
179
+ const fields: SchemaConfig["fields"] = {
180
+ id: {
181
+ id: "id",
182
+ displayName: "ID",
183
+ type: "SHORT_TEXT",
184
+ validation: { required: true },
185
+ capabilities: { supportedQueryOperators: [], sortable: true }
186
+ },
187
+ displayName: {
188
+ id: "displayName",
189
+ displayName: "Display Name",
190
+ type: "SHORT_TEXT",
191
+ validation: { required: false },
192
+ capabilities: { supportedQueryOperators: [], sortable: true }
193
+ },
194
+ createdDate: {
195
+ id: "createdDate", // from created_date
196
+ displayName: "Created Date",
197
+ type: "DATETIME",
198
+ validation: { required: false },
199
+ capabilities: { supportedQueryOperators: [], sortable: true }
200
+ },
201
+ updatedDate: {
202
+ id: "updatedDate", // from updated_date
203
+ displayName: "Updated Date",
204
+ type: "DATETIME",
205
+ validation: { required: false },
206
+ capabilities: { supportedQueryOperators: [], sortable: true }
207
+ },
208
+ "name.first": {
209
+ id: "name.first",
210
+ displayName: "First Name",
211
+ type: "SHORT_TEXT",
212
+ validation: { required: false },
213
+ capabilities: { supportedQueryOperators: [], sortable: true }
214
+ },
215
+ "name.last": {
216
+ id: "name.last",
217
+ displayName: "Last Name",
218
+ type: "SHORT_TEXT",
219
+ validation: { required: false },
220
+ capabilities: { supportedQueryOperators: [], sortable: true }
221
+ },
222
+ "email.email": {
223
+ id: "email.email",
224
+ displayName: "Email",
225
+ type: "SHORT_TEXT",
226
+ validation: { required: false },
227
+ capabilities: { supportedQueryOperators: [], sortable: true }
228
+ },
229
+ "phone.phone": {
230
+ id: "phone.phone",
231
+ displayName: "Phone",
232
+ type: "SHORT_TEXT",
233
+ validation: { required: false },
234
+ capabilities: { supportedQueryOperators: [], sortable: true }
235
+ }
236
+ };
111
237
 
112
- Follow the complete custom data source implementation guide in the "Custom Overrides" section. The key FQDN-specific considerations are:
238
+ // Field mapping example ends here.
239
+ // You MUST NOT ship a partial SchemaConfig. Implement the full SchemaConfig with actions (see section 3).
240
+ ```
113
241
 
114
- 1. **Import the client library** identified in Step 2
115
- 2. **Use the field mappings** from Step 3 in your SchemaConfig
116
- 3. **⚠️ CRITICAL: DO NOT IMPLEMENT THE ACTIONS** - Instead, add guidance comments explaining how to use the imported client library for each CRUD operation, then throw an "unimplemented exception" error
117
- 4. **⚠️ CRITICAL: Add Error Handling** - When implementing the actions, you MUST wrap all HTTP requests with proper error handling using `errorHandler` from `@wix/essentials` (see "Error Handling for HTTP Requests" section)
242
+ ---
118
243
 
119
- **Important**: The schema actions should contain helpful comments but NOT actual implementations. Each action should throw an error indicating it's unimplemented and needs to be implemented by the user.
244
+ ## 3) Implement SchemaConfig actions
120
245
 
121
- ### Custom Data Source Hook Implementation
246
+ Actions **MUST** call the correct Wix client library returned by `client_lib`. For Contacts v4 use `@wix/crm`. For any other FQDN, use MCP (`client_lib`, `fqdn_info`) to get the exact package and method names, then adapt the calls accordingly.
122
247
 
123
- Create your custom data source with the hook pattern:
248
+ **⚠️ IMPORTANT**: You have two implementation approaches available:
124
249
 
125
- In `components/customDataSources/myCustomDataSource.ts`:
126
- ```typescript
127
- import { errorHandler } from '@wix/essentials';
250
+ 1. **Full Implementation** (recommended for production): Complete working implementation with actual API calls
251
+ 2. **Foundation with Guidance** (recommended for scaffolding): Unimplemented actions with helpful comments and error throwing
252
+
253
+ ### Implementation Approach 1: Full Implementation
254
+
255
+ Implementation **MUSTs**:
256
+ - You **MUST** wrap HTTP calls with consistent error handling (e.g., `errorHandler` from `@wix/essentials`).
257
+ - You **MUST** map outgoing payloads from camelCase (SchemaConfig/AppConfig) to API snake_case when required, and map responses back.
258
+ - You **MUST** respect pagination mode:
259
+ - Cursor-based APIs: return `{ items, cursor, total? }`
260
+ - Offset-based APIs (Contacts v4): return `{ items, hasNext, total? }`
261
+ - For Contacts v4 updates, you **MUST** pass both `contactId` and the latest `revision`.
262
+
263
+ #### Example implementation (Contacts v4, offset-based):
264
+
265
+ ```ts
266
+ import { contacts } from "@wix/crm";
267
+ import type { SchemaConfig, Query } from "@wix/auto-patterns";
268
+ // import { errorHandler } from "@wix/essentials"; // if used in your app shell
269
+
270
+ // NOTE: Some SDKs expose methods directly off the named export (no client instantiation).
271
+ // Always verify import/method patterns in MCP `client_lib` docs/examples.
272
+
273
+ function toApiContact(input) {
274
+ // Map camelCase fields used in forms/UI back to API shapes as needed.
275
+ // Example only – adapt to your fields. Many v4 fields are snake_case.
276
+ return input;
277
+ }
128
278
 
129
- export const myCustomDataSource = async (collectionId: string, context: any) => {
279
+ function fromApiContact(api) {
280
+ // Map API response to the fields you exposed in SchemaConfig
130
281
  return {
131
- id: 'myCustomCollection',
132
- fields: {
133
- // Field definitions based on your FQDN schema mapping
282
+ id: api.id ?? api._id,
283
+ displayName: api.display_name ?? api.displayName ?? api.info?.name?.first ?? api.info?.name?.last,
284
+ createdDate: api.created_date ?? api.createdDate,
285
+ updatedDate: api.updated_date ?? api.updatedDate,
286
+ primaryInfo: api.primary_info ?? api.primaryInfo,
287
+ info: api.info
288
+ };
289
+ }
290
+
291
+ export const contactsSchemaWithActions: SchemaConfig = {
292
+ id: "Contacts",
293
+ idField: "id",
294
+ displayField: "displayName",
295
+ // Provide the full fields object from section 2 in your implementation
296
+ fields,
297
+ actions: {
298
+ async get(entityId: string) {
299
+ const res = await contacts.getContact({ id: entityId });
300
+ // Some SDKs return the entity at the root (res) instead of res.contact — verify via MCP
301
+ return fromApiContact(res.contact ?? res);
302
+ },
303
+
304
+ async create(newEntity) {
305
+ const res = await contacts.createContact({ info: toApiContact(newEntity).info });
306
+ return fromApiContact(res.contact ?? res);
307
+ },
308
+
309
+ async update(updatedEntity) {
310
+ // v4 requires id and revision on updates
311
+ const { id, revision, info } = toApiContact(updatedEntity);
312
+ const res = await contacts.updateContact({ contactId: id, revision, info });
313
+ return fromApiContact(res.contact ?? res);
314
+ },
315
+
316
+ async delete(entityId: string) {
317
+ await contacts.deleteContact({ contactId: entityId });
318
+ return { id: entityId };
134
319
  },
135
- displayField: 'name',
136
- idField: 'id',
137
- actions: {
138
- get: async (entityId: string) => {
139
- // TODO: Implement using your FQDN client library
140
- // Example:
141
- // return errorHandler.withErrorHandler(
142
- // async () => {
143
- // return yourFQDNClient.getEntity(entityId);
144
- // },
145
- // {}
146
- // );
147
- // Remember to map the response fields from snake_case to camelCase
148
- throw new Error('get action not implemented - user must implement this method');
149
- },
150
- create: async (newEntity: any) => {
151
- // TODO: Implement using your FQDN client library
152
- // Example:
153
- // return errorHandler.withErrorHandler(
154
- // async () => {
155
- // return yourFQDNClient.createEntity(newEntity);
156
- // },
157
- // {}
158
- // );
159
- // Remember to map the request fields from camelCase to snake_case
160
- throw new Error('create action not implemented - user must implement this method');
161
- },
162
- update: async (updatedEntity: any) => {
163
- // TODO: Implement using your FQDN client library
164
- // Example:
165
- // return errorHandler.withErrorHandler(
166
- // async () => {
167
- // return yourFQDNClient.updateEntity(updatedEntity);
168
- // },
169
- // {}
170
- // );
171
- // Remember to map the request fields from camelCase to snake_case
172
- throw new Error('update action not implemented - user must implement this method');
173
- },
174
- delete: async (entityId: string) => {
175
- // TODO: Implement using your FQDN client library
176
- // Example:
177
- // return errorHandler.withErrorHandler(
178
- // async () => {
179
- // return yourFQDNClient.deleteEntity(entityId);
180
- // },
181
- // {}
182
- // );
183
- throw new Error('delete action not implemented - user must implement this method');
184
- },
185
- bulkDelete: async (entityIds: string[]) => {
186
- // TODO: Implement using your FQDN client library
187
- // Example:
188
- // return errorHandler.withErrorHandler(
189
- // async () => {
190
- // return yourFQDNClient.bulkDeleteEntities(entityIds);
191
- // },
192
- // {}
193
- // );
194
- throw new Error('bulkDelete action not implemented - user must implement this method');
195
- },
196
- find: async (query: Query, options?: any) => {
197
- // TODO: Implement using your FQDN client library
198
- // Example:
199
- // return errorHandler.withErrorHandler(
200
- // async () => {
201
- // return yourFQDNClient.queryEntities(query, options);
202
- // },
203
- // {}
204
- // );
205
- // Remember to map the response fields from snake_case to camelCase
206
- // IMPORTANT: Return shape depends on pagination mode.
207
- // Detect by presence of query.cursor (cursor mode) vs. query.offset/page (offset mode):
208
- // - Cursor mode: return { items, cursor, total? }
209
- // - Offset mode (default): return { items, hasNext, total? }
210
- throw new Error('find action not implemented - user must implement this method');
211
- }
320
+
321
+ async bulkDelete(entityIds: string[]) {
322
+ // If bulk delete API is not available, fall back to per-entity updates as defined by MCP
323
+ await contacts.bulkDeleteContacts?.({ contactIds: entityIds })
324
+ ?? Promise.all(entityIds.map((id) => contacts.deleteContact({ contactId: id })));
325
+ return { ids: entityIds };
326
+ },
327
+
328
+ async find(query: Query) {
329
+ // Use QueryContacts (offset-based). Map Auto-Patterns Query to API query
330
+ const limit = query.limit ?? 25;
331
+ const offset = query.offset ?? (query.page ? (query.page - 1) * limit : 0);
332
+ const res = await contacts.queryContacts({
333
+ query: {
334
+ paging: { limit, offset },
335
+ // Map filters/sort/search into the API query as needed
336
+ filter: /* build from query.filters */ undefined,
337
+ sort: /* build from query.sort */ undefined,
338
+ search: query.search ?? undefined
339
+ }
340
+ });
341
+ const items = (res.contacts ?? []).map(fromApiContact);
342
+ const hasNext = res.paging?.hasNext ?? (items.length === limit);
343
+ return { items, hasNext, total: null };
212
344
  }
213
- };
345
+ }
346
+ };
347
+ ```
348
+
349
+ Notes:
350
+ - Update requires the latest `revision`. Make sure your UI carries it and you pass it when updating.
351
+ - If you target other FQDNs, import and call the methods from the package returned by `client_lib`, and adapt pagination (cursor vs offset) accordingly.
352
+ - **Validation warning**: You **MUST** verify that each method you plan to call exists in the SDK for your FQDN. Replace non-existent operations with the supported alternatives per MCP (for example, use `update*` to set an `archived` flag if no `archive*` exists).
353
+ - **⚠️ CRITICAL: Add Error Handling** - When implementing the actions, you MUST wrap all HTTP requests with proper error handling using `errorHandler` from `@wix/essentials`
354
+
355
+ ---
356
+
357
+ ## 4) Set Up Custom Data Source Structure and Hook Pattern
358
+
359
+ ### Custom Data Source Hook Implementation
360
+
361
+ Create your custom data source with the hook pattern for better React integration:
362
+
363
+ In `components/customDataSources/contactsDataSource.ts`:
364
+
365
+ ```typescript
366
+ import { SchemaConfig } from '@wix/auto-patterns/types';
367
+ import { contacts } from "@wix/crm";
368
+ // Choose your implementation approach from section 3 above
369
+
370
+ export const contactsDataSource = async (
371
+ collectionId: string,
372
+ context: any,
373
+ ): Promise<SchemaConfig> => {
374
+ return contactsSchemaWithActions; // Your SchemaConfig from section 3
214
375
  };
215
376
  ```
216
377
 
217
378
  In `components/customDataSources/index.tsx`:
379
+
218
380
  ```typescript
219
- import { myCustomDataSource } from './myCustomDataSource';
381
+ import { contactsDataSource } from './contactsDataSource';
220
382
 
221
383
  export const useCustomDataSources = () => {
222
384
  // You can access React context and other hooks here
223
385
  return {
224
- myCustomDataSource
386
+ contactsFqdn: contactsDataSource,
225
387
  };
226
388
  };
227
389
  ```
228
390
 
229
391
  For detailed implementation patterns, folder structure, and registration steps, refer to the **Custom Data Sources** section in "Custom Overrides".
230
392
 
231
- ## Step 5: Update AppConfig
393
+ ## 5) Register the custom data source and wire AppConfig
394
+
395
+ You **MUST** register the custom data source and reference it from AppConfig.
396
+
397
+ ### Register Custom Data Source
398
+
399
+ In your main page component, use the hook to register your custom data source:
400
+
401
+ ```tsx
402
+ import { AutoPatternsApp, AutoPatternsOverridesProvider } from "@wix/auto-patterns"; // adjust import path in your monorepo
403
+ import { useCustomDataSources } from '../components/customDataSources';
404
+
405
+ export function Page() {
406
+ const customDataSources = useCustomDataSources();
407
+
408
+ return (
409
+ <AutoPatternsOverridesProvider value={{ customDataSources }}>
410
+ <AutoPatternsApp configuration={config} />
411
+ </AutoPatternsOverridesProvider>
412
+ );
413
+ }
414
+ ```
415
+
416
+ ### Update AppConfig
232
417
 
233
418
  Configure your AppConfig to use the custom data source by setting:
234
419
 
@@ -236,66 +421,87 @@ Configure your AppConfig to use the custom data source by setting:
236
421
  - `custom.id` matching your custom data source identifier from Step 4
237
422
 
238
423
  **Key FQDN-specific configuration:**
424
+
239
425
  ```json
240
- "collection": {
241
- "collectionId": "yourCustomCollectionId",
242
- "entityTypeSource": "custom",
243
- "custom": {
244
- "id": "yourCustomDataSourceId"
426
+ {
427
+ "collection": {
428
+ "collectionId": "Contacts",
429
+ "entityTypeSource": "custom",
430
+ "custom": { "id": "contactsFqdn" },
431
+ "paginationMode": "offset" // v4 uses offset; use "cursor" for cursor-based APIs
245
432
  }
246
433
  }
247
434
  ```
248
435
 
249
436
  For complete AppConfig structure, configuration rules, and advanced options, refer to the "App Config Structure" section.
250
437
 
251
- ## Step 6: Register Custom Data Source
438
+ ---
252
439
 
253
- In your main page component, use the hook to register your custom data source:
440
+ ## 6) Building queries, filters and sorts
254
441
 
255
- ```tsx
256
- import { useCustomDataSources } from '../components/customDataSources';
442
+ - Keep `supportedQueryOperators: []` on fields. Build server-side WQL/search inside `actions.find`
443
+ - Map `Query.filters` to the API’s filter object
444
+ - Map `Query.sort` to API sorting
257
445
 
258
- export default function YourPage() {
259
- const customDataSources = useCustomDataSources();
446
+ For Contacts v4, you **MUST** use `QueryContacts` (WQL) and map your UI query object to the API query. For other entities, use their recommended query/search method per MCP and map accordingly.
260
447
 
261
- return (
262
- <AutoPatternsOverridesProvider value={{ customDataSources }}>
263
- <AutoPatternsApp configuration={config} />
264
- </AutoPatternsOverridesProvider>
265
- );
266
- }
267
- ```
448
+ ---
449
+
450
+ ## 7) Error handling and robustness
451
+
452
+ - Wrap all HTTP requests with a consistent error handler (e.g., `errorHandler` from `@wix/essentials`) in your app shell
453
+ - Surface meaningful messages using your `displayField`
454
+ - Handle retries or specific application codes (duplicate, permission, invalid argument) when appropriate
455
+
456
+ ---
268
457
 
269
- ## Step 7: Implement Custom Actions (Only if Explicitly Requested)
458
+ ## 8) Contacts v4 field mapping reference (subset)
459
+
460
+ Examples derived from `fqdn_info` and query/search patterns:
461
+
462
+ - `id` → `id`
463
+ - `display_name` → `displayName`
464
+ - `created_date` → `createdDate`
465
+ - `updated_date` → `updatedDate`
466
+ - `info.name.first` → `info.name.first`
467
+ - `info.name.last` → `info.name.last`
468
+ - `primary_info.email` → `primaryInfo.email`
469
+ - `info.job_title` → `info.jobTitle`
470
+ - `last_activity.activity_date` → `lastActivity.activityDate`
270
471
 
271
- **⚠️ IMPORTANT**: Custom actions should only be implemented when the user explicitly requests them. A basic dashboard page with standard CRUD operations does not require custom actions.
472
+ Follow the snake_case-to-camelCase-per-segment rule and preserve dot paths. Use the original API field names when calling the SDK; use the camelCased paths in `SchemaConfig`/AppConfig.
272
473
 
273
- If the user specifically requests custom actions for your FQDN-based data source, follow the action implementation patterns from the "Custom Overrides" section. Your custom actions will have access to the same SDK utilities, but remember that they will need to interact with your FQDN-based API directly since the SchemaConfig actions from Step 4 are left unimplemented for you to complete.
474
+ ---
274
475
 
275
- ## FQDN-Specific Implementation Checklist
476
+ ## 9) FQDN-Specific Implementation Checklist
276
477
 
277
478
  ### Core Requirements (Always Required)
278
- ✅ **Schema Extraction**: Used fqdn_schema tool to understand entity structure
479
+
480
+ ✅ **Schema Extraction**: Used fqdn_info and/or fqdn_schema tools to understand entity structure
279
481
  ✅ **Client Library**: Used client_lib tool to identify correct SDK package
280
482
  ✅ **Field Mapping**: Mapped FQDN field types to AutoPatterns field types
281
483
  ✅ **🛑 MANDATORY: Empty Query Operators**: Set `supportedQueryOperators: []` for ALL fields to avoid TypeScript errors
282
484
  ✅ **⚠️ CRITICAL: Field ID Conversion**: Converted individual field segments from snake_case to camelCase while preserving field path structure in SchemaConfig and AppConfig
485
+ ✅ **Package Installation**: Installed the exact SDK package reported by `client_lib` (e.g., `@wix/crm` for Contacts v4)
486
+ ✅ **Implementation Choice**: Chose either full implementation or foundation with guidance approach
487
+ ✅ **Pagination Shape**: Return the correct pagination shape from `find` (cursor vs offset per MCP)
283
488
  ✅ **AppConfig Update**: Set `entityTypeSource: "custom"` and provided custom.id
284
- ✅ **Custom Data Source Structure**: Followed "Custom Overrides" section for folder structure and registration
489
+ ✅ **Custom Data Source Structure**: Followed proper folder structure and registration
285
490
  ✅ **Hook Implementation**: Created useCustomDataSources hook for accessing React context
286
- **⚠️ CRITICAL: Unimplemented Actions**: All schema actions contain helpful comments but throw unimplemented exceptions - **user must implement these actions themselves**
491
+ **Registration**: Registered the custom data source in `AutoPatternsOverridesProvider`
492
+ ✅ **Matching IDs**: Used matching `custom.id` in AppConfig
287
493
 
288
494
  ### Optional Enhancements (Only When Explicitly Requested)
495
+
289
496
  ⚠️ **Custom Actions**: Only implement if user specifically requests custom actions beyond standard CRUD
290
497
  ⚠️ **Column Overrides**: Only implement if user requests custom column rendering
291
498
  ⚠️ **Custom Components**: Only implement if user requests custom entity page components
292
499
  ⚠️ **Bulk Operations**: Only implement if user requests custom bulk actions beyond standard bulk delete
293
500
 
294
- ## Common FQDN-Specific Pitfalls to Avoid
501
+ ## 10) Common FQDN-Specific Pitfalls to Avoid
295
502
 
296
503
  - **⚠️ CRITICAL: Implementing Unnecessary Overrides**: Do NOT implement custom actions, column overrides, or custom components unless explicitly requested by the user - a basic dashboard page only needs the core custom data source
297
504
  - **⚠️ CRITICAL: Inconsistent Field ID Casing**: Failing to convert individual field segments from snake_case to camelCase while preserving field path structure in SchemaConfig and AppConfig - this is the most common mistake and will cause field mapping failures
298
- - **⚠️ CRITICAL: Implementing Actions**: DO NOT implement the schema actions - they should contain helpful comments and throw unimplemented exceptions for the user to complete
299
505
  - **🛑 CRITICAL: Query Operators MUST Be Empty Array**: You **MUST** use `supportedQueryOperators: []` (empty array) for all fields - attempting to specify actual operators will cause TypeScript compilation errors and is not supported for custom data sources
300
506
  - **Mismatched Field Types**: Ensure FQDN field types are correctly mapped to AutoPatterns types
301
507
  - **Wrong Client Library**: Use the exact client library returned by the client_lib tool
@@ -303,14 +509,20 @@ If the user specifically requests custom actions for your FQDN-based data source
303
509
  - **Display Field Selection**: Choose a display field that provides meaningful identification from your FQDN schema
304
510
  - **Custom Data Source ID Mismatch**: Ensure the custom.id in AppConfig matches your custom data source identifier
305
511
  - **Hook Registration**: Don't forget to register the custom data source through the useCustomDataSources hook
512
+ - **Mixing snake_case and camelCase**: In `SchemaConfig`/AppConfig field ids
513
+ - **Returning the wrong pagination shape**: From `find` action
514
+ - **Forgetting to pass `revision`**: On updates (especially v4/v5 APIs)
515
+ - **Using the wrong client library**: Always trust `client_lib` result
516
+ - **Missing error handling**: When implementing actions, wrap HTTP calls with proper error handling
306
517
 
307
- For general implementation pitfalls, refer to the "Custom Overrides" section.
518
+ ---
308
519
 
309
- ## Advanced Customization (Only When Explicitly Requested)
520
+ ## 11) Advanced Customization (Only When Explicitly Requested)
310
521
 
311
522
  **⚠️ IMPORTANT**: The following customizations should only be implemented when the user explicitly requests them. A basic dashboard page does not require these advanced features.
312
523
 
313
524
  For advanced customization options when specifically requested, refer to these sections:
525
+
314
526
  - "Collection Page Actions" - For custom collection-level actions
315
527
  - "Action Cell" - For custom row-level actions
316
528
  - "Bulk Actions" - For custom bulk operations
@@ -318,3 +530,10 @@ For advanced customization options when specifically requested, refer to these s
318
530
  - "Custom Overrides" - For column overrides and custom components
319
531
 
320
532
  By following these steps, you'll successfully implement a custom data source that integrates seamlessly with AutoPatternsApp while leveraging Wix Business APIs through their FQDNs.
533
+
534
+ ## 12) See also
535
+
536
+ - `schema_config.md` – Full `SchemaConfig` interface and field types
537
+ - `auto-patterns-guide.md` – End-to-end Auto-Patterns overview
538
+
539
+