@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.
- package/dist/cjs/components/AutoPatternsApp/AutoPatternsApp.js +1 -1
- package/dist/cjs/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js +73 -19
- package/dist/cjs/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js.map +1 -1
- package/dist/cjs/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.js +1 -1
- package/dist/cjs/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js +1 -1
- package/dist/cjs/components/AutoPatternsCollectionPageContent/SkeletonCollection.js +1 -1
- package/dist/cjs/components/AutoPatternsCollectionPageFooter/AutoPatternsCollectionPageFooter.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js +42 -11
- package/dist/cjs/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js.map +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/EditModeEntityPage.js +13 -9
- package/dist/cjs/components/AutoPatternsEntityPage/EditModeEntityPage.js.map +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/Checkbox.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/DateInput.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/DateTime.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/FormFieldInput.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/ImageInput.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/LongText.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/Number.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/ShortText.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/Fields/Url.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/RenderLayout/RenderLayoutCard.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/RenderLayout/RenderLayoutContent.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/RenderLayout/RenderViewField.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/SkeletonEntity.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/ViewEntityPage/RenderViewLayoutCard.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/ViewEntityPage/RenderViewLayoutContent.js +1 -1
- package/dist/cjs/components/AutoPatternsEntityPage/ViewModeEntityPage.js +1 -1
- package/dist/cjs/components/AutoPatternsGrid/AutoPatternsGrid.js +9 -6
- package/dist/cjs/components/AutoPatternsGrid/AutoPatternsGrid.js.map +1 -1
- package/dist/cjs/components/AutoPatternsRoute/AutoPatternsPage.js +51 -15
- package/dist/cjs/components/AutoPatternsRoute/AutoPatternsPage.js.map +1 -1
- package/dist/cjs/components/AutoPatternsRoute/AutoPatternsRoutes.js +1 -1
- package/dist/cjs/components/AutoPatternsTable/AutoPatternsTable.js +11 -6
- package/dist/cjs/components/AutoPatternsTable/AutoPatternsTable.js.map +1 -1
- package/dist/cjs/components/AutoPatternsTableGridSwitch/AutoPatternsTableGridSwitch.js +1 -1
- package/dist/cjs/components/DynamicIcon.js +1 -1
- package/dist/cjs/components/ModalRenderer.js +1 -1
- package/dist/cjs/components/filters/DynamicCollectionFilter.js +1 -1
- package/dist/cjs/components/filters/StaticCollectionFilter.js +1 -1
- package/dist/cjs/components/modals/actions/BulkDeleteModal.js +28 -10
- package/dist/cjs/components/modals/actions/BulkDeleteModal.js.map +1 -1
- package/dist/cjs/components/modals/actions/CreateModal.js +1 -1
- package/dist/cjs/components/modals/actions/EditModal.js +1 -1
- package/dist/cjs/counter.js +1 -1
- package/dist/cjs/dataSourceAdapters/cms/filterUtils.js +3 -2
- package/dist/cjs/dataSourceAdapters/cms/filterUtils.js.map +1 -1
- package/dist/cjs/dataSourceAdapters/cms/sortUtils.js +2 -1
- package/dist/cjs/dataSourceAdapters/cms/sortUtils.js.map +1 -1
- package/dist/cjs/hooks/useBaseTableFeatures.js +6 -3
- package/dist/cjs/hooks/useBaseTableFeatures.js.map +1 -1
- package/dist/cjs/hooks/useBulkActionToolbar.js +1 -1
- package/dist/cjs/hooks/useCollectionPageActions.js +1 -1
- package/dist/cjs/hooks/useColumns.js +1 -1
- package/dist/cjs/hooks/useCommonCollectionFeatures.js +1 -1
- package/dist/cjs/hooks/useDataExtensionProps.js +30 -0
- package/dist/cjs/hooks/useDataExtensionProps.js.map +1 -0
- package/dist/cjs/hooks/useDragAndDropBaseProps.js +30 -0
- package/dist/cjs/hooks/useDragAndDropBaseProps.js.map +1 -0
- package/dist/cjs/hooks/useEmptyStates.js +1 -1
- package/dist/cjs/hooks/useEntityPageActions.js +1 -1
- package/dist/cjs/hooks/useFilters.js +1 -1
- package/dist/cjs/hooks/useGridDragAndDrop.js +17 -0
- package/dist/cjs/hooks/useGridDragAndDrop.js.map +1 -0
- package/dist/cjs/hooks/useGridFeatures.js +4 -1
- package/dist/cjs/hooks/useGridFeatures.js.map +1 -1
- package/dist/cjs/hooks/useTableDragAndDrop.js +17 -0
- package/dist/cjs/hooks/useTableDragAndDrop.js.map +1 -0
- package/dist/cjs/hooks/useTableFeatures.js +7 -2
- package/dist/cjs/hooks/useTableFeatures.js.map +1 -1
- package/dist/cjs/hooks/useTableGridSwitchDragAndDrop.js +17 -0
- package/dist/cjs/hooks/useTableGridSwitchDragAndDrop.js.map +1 -0
- package/dist/cjs/hooks/useTableGridSwitchFeatures.js +7 -2
- package/dist/cjs/hooks/useTableGridSwitchFeatures.js.map +1 -1
- package/dist/cjs/providers/AppConfigContext.js +1 -1
- package/dist/cjs/providers/AppContext.js +1 -1
- package/dist/cjs/providers/AppContextData.js +1 -1
- package/dist/cjs/providers/AutoPatternsOverridesContext.js +2 -2
- package/dist/cjs/providers/AutoPatternsOverridesContext.js.map +1 -1
- package/dist/cjs/providers/ErrorContext.js +1 -1
- package/dist/cjs/providers/ItemsContext.js +1 -1
- package/dist/cjs/providers/ModalContext.js +1 -1
- package/dist/cjs/providers/OptimisticActionsContext.js +1 -1
- package/dist/cjs/providers/RootAppProvider.js +1 -1
- package/dist/cjs/providers/SchemaContext.js +1 -1
- package/dist/cjs/providers/SchemaRegistryContext.js +1 -1
- package/dist/cjs/types/CollectionPageConfig.js.map +1 -1
- package/dist/cjs/types/DeepPartial.js +4 -0
- package/dist/cjs/types/DeepPartial.js.map +1 -0
- package/dist/cjs/types/actions/base.js.map +1 -1
- package/dist/cjs/types/types.js.map +1 -1
- package/dist/cjs/utils/actions/bulkDeleteAction.js +1 -1
- package/dist/cjs/utils/actions/createAction.js +1 -1
- package/dist/cjs/utils/actions/deleteAction.js +1 -1
- package/dist/cjs/utils/actions/updateAction.js +1 -1
- package/dist/esm/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js +28 -10
- package/dist/esm/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js.map +1 -1
- package/dist/esm/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js +18 -6
- package/dist/esm/components/AutoPatternsEntityPage/AutoPatternsEntityPage.js.map +1 -1
- package/dist/esm/components/AutoPatternsEntityPage/EditModeEntityPage.js +4 -0
- package/dist/esm/components/AutoPatternsEntityPage/EditModeEntityPage.js.map +1 -1
- package/dist/esm/components/AutoPatternsGrid/AutoPatternsGrid.js +7 -4
- package/dist/esm/components/AutoPatternsGrid/AutoPatternsGrid.js.map +1 -1
- package/dist/esm/components/AutoPatternsRoute/AutoPatternsPage.js +16 -6
- package/dist/esm/components/AutoPatternsRoute/AutoPatternsPage.js.map +1 -1
- package/dist/esm/components/AutoPatternsTable/AutoPatternsTable.js +9 -4
- package/dist/esm/components/AutoPatternsTable/AutoPatternsTable.js.map +1 -1
- package/dist/esm/components/modals/actions/BulkDeleteModal.js +20 -3
- package/dist/esm/components/modals/actions/BulkDeleteModal.js.map +1 -1
- package/dist/esm/dataSourceAdapters/cms/filterUtils.js +3 -2
- package/dist/esm/dataSourceAdapters/cms/filterUtils.js.map +1 -1
- package/dist/esm/dataSourceAdapters/cms/sortUtils.js +2 -1
- package/dist/esm/dataSourceAdapters/cms/sortUtils.js.map +1 -1
- package/dist/esm/hooks/useBaseTableFeatures.js +4 -1
- package/dist/esm/hooks/useBaseTableFeatures.js.map +1 -1
- package/dist/esm/hooks/useDataExtensionProps.js +18 -0
- package/dist/esm/hooks/useDataExtensionProps.js.map +1 -0
- package/dist/esm/hooks/useDragAndDropBaseProps.js +27 -0
- package/dist/esm/hooks/useDragAndDropBaseProps.js.map +1 -0
- package/dist/esm/hooks/useGridDragAndDrop.js +13 -0
- package/dist/esm/hooks/useGridDragAndDrop.js.map +1 -0
- package/dist/esm/hooks/useGridFeatures.js +4 -1
- package/dist/esm/hooks/useGridFeatures.js.map +1 -1
- package/dist/esm/hooks/useTableDragAndDrop.js +13 -0
- package/dist/esm/hooks/useTableDragAndDrop.js.map +1 -0
- package/dist/esm/hooks/useTableFeatures.js +7 -2
- package/dist/esm/hooks/useTableFeatures.js.map +1 -1
- package/dist/esm/hooks/useTableGridSwitchDragAndDrop.js +13 -0
- package/dist/esm/hooks/useTableGridSwitchDragAndDrop.js.map +1 -0
- package/dist/esm/hooks/useTableGridSwitchFeatures.js +7 -2
- package/dist/esm/hooks/useTableGridSwitchFeatures.js.map +1 -1
- package/dist/esm/providers/AutoPatternsOverridesContext.js.map +1 -1
- package/dist/esm/types/CollectionPageConfig.js.map +1 -1
- package/dist/esm/types/DeepPartial.js +2 -0
- package/dist/esm/types/DeepPartial.js.map +1 -0
- package/dist/esm/types/actions/base.js.map +1 -1
- package/dist/esm/types/types.js.map +1 -1
- package/dist/types/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.d.ts +1 -1
- package/dist/types/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.d.ts.map +1 -1
- package/dist/types/components/AutoPatternsEntityPage/AutoPatternsEntityPage.d.ts.map +1 -1
- package/dist/types/components/AutoPatternsEntityPage/EditModeEntityPage.d.ts.map +1 -1
- package/dist/types/components/AutoPatternsGrid/AutoPatternsGrid.d.ts.map +1 -1
- package/dist/types/components/AutoPatternsRoute/AutoPatternsPage.d.ts.map +1 -1
- package/dist/types/components/AutoPatternsTable/AutoPatternsTable.d.ts.map +1 -1
- package/dist/types/components/modals/actions/BulkDeleteModal.d.ts.map +1 -1
- package/dist/types/hooks/useBaseTableFeatures.d.ts +10 -0
- package/dist/types/hooks/useBaseTableFeatures.d.ts.map +1 -1
- package/dist/types/hooks/useDataExtensionProps.d.ts +8 -0
- package/dist/types/hooks/useDataExtensionProps.d.ts.map +1 -0
- package/dist/types/hooks/useDragAndDropBaseProps.d.ts +4 -0
- package/dist/types/hooks/useDragAndDropBaseProps.d.ts.map +1 -0
- package/dist/types/hooks/useGridDragAndDrop.d.ts +24 -0
- package/dist/types/hooks/useGridDragAndDrop.d.ts.map +1 -0
- package/dist/types/hooks/useGridFeatures.d.ts +22 -0
- package/dist/types/hooks/useGridFeatures.d.ts.map +1 -1
- package/dist/types/hooks/useTableDragAndDrop.d.ts +3 -0
- package/dist/types/hooks/useTableDragAndDrop.d.ts.map +1 -0
- package/dist/types/hooks/useTableFeatures.d.ts +2 -0
- package/dist/types/hooks/useTableFeatures.d.ts.map +1 -1
- package/dist/types/hooks/useTableGridSwitchDragAndDrop.d.ts +27 -0
- package/dist/types/hooks/useTableGridSwitchDragAndDrop.d.ts.map +1 -0
- package/dist/types/hooks/useTableGridSwitchFeatures.d.ts +24 -0
- package/dist/types/hooks/useTableGridSwitchFeatures.d.ts.map +1 -1
- package/dist/types/providers/AutoPatternsOverridesContext.d.ts +6 -0
- package/dist/types/providers/AutoPatternsOverridesContext.d.ts.map +1 -1
- package/dist/types/types/CollectionPageConfig.d.ts +15 -0
- package/dist/types/types/CollectionPageConfig.d.ts.map +1 -1
- package/dist/types/types/DeepPartial.d.ts +4 -0
- package/dist/types/types/DeepPartial.d.ts.map +1 -0
- package/dist/types/types/actions/base.d.ts +5 -0
- package/dist/types/types/actions/base.d.ts.map +1 -1
- package/dist/types/types/types.d.ts +24 -1
- package/dist/types/types/types.d.ts.map +1 -1
- package/docs/GETTING_STARTED.md +6 -2
- package/mcp-docs/app_config_structure.md +14 -1
- package/mcp-docs/auto-patterns-guide.md +282 -80
- package/mcp-docs/bulk_actions.md +60 -0
- package/mcp-docs/custom_overrides.md +134 -54
- package/mcp-docs/schema_config.md +74 -25
- package/mcp-docs/wix_fqdn_custom_data_source.md +377 -158
- package/package.json +13 -13
|
@@ -1,28 +1,63 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
90
|
+
### What you will build
|
|
56
91
|
|
|
57
|
-
|
|
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
|
-
|
|
61
|
-
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 1) Discover schema and SDK with Business Schema MCP
|
|
62
97
|
|
|
63
|
-
|
|
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
|
-
|
|
100
|
+
```text
|
|
101
|
+
Call client_lib with: "wix.contacts.v4.contact" -> returns: @wix/crm
|
|
70
102
|
|
|
71
|
-
|
|
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
|
-
|
|
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
|
-
|
|
130
|
+
For other FQDNs, install the package returned by `client_lib`.
|
|
78
131
|
|
|
79
|
-
|
|
132
|
+
---
|
|
80
133
|
|
|
81
|
-
|
|
134
|
+
## 2) Map FQDN fields to SchemaConfig
|
|
82
135
|
|
|
83
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
244
|
+
## 3) Implement SchemaConfig actions
|
|
120
245
|
|
|
121
|
-
|
|
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
|
-
|
|
248
|
+
**⚠️ IMPORTANT**: You have two implementation approaches available:
|
|
124
249
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
279
|
+
function fromApiContact(api) {
|
|
280
|
+
// Map API response to the fields you exposed in SchemaConfig
|
|
130
281
|
return {
|
|
131
|
-
id:
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
241
|
-
"
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
"id": "
|
|
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
|
-
|
|
438
|
+
---
|
|
252
439
|
|
|
253
|
-
|
|
440
|
+
## 6) Building queries, filters and sorts
|
|
254
441
|
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
474
|
+
---
|
|
274
475
|
|
|
275
|
-
## FQDN-Specific Implementation Checklist
|
|
476
|
+
## 9) FQDN-Specific Implementation Checklist
|
|
276
477
|
|
|
277
478
|
### Core Requirements (Always Required)
|
|
278
|
-
|
|
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
|
|
489
|
+
✅ **Custom Data Source Structure**: Followed proper folder structure and registration
|
|
285
490
|
✅ **Hook Implementation**: Created useCustomDataSources hook for accessing React context
|
|
286
|
-
✅
|
|
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
|
-
|
|
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
|
+
|