abmp-npm 1.9.7 → 1.9.9
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/backend/contacts-methods.js +1 -6
- package/backend/daily-pull/bulk-process-methods.js +14 -3
- package/backend/daily-pull/consts.js +11 -0
- package/backend/daily-pull/process-member-methods.js +20 -7
- package/backend/daily-pull/sync-to-cms-methods.js +7 -1
- package/backend/elevated-modules.js +1 -1
- package/backend/index.js +0 -1
- package/backend/members-data-methods.js +15 -2
- package/backend/utils.js +15 -4
- package/package.json +1 -1
- package/public/Utils/homePage.js +2 -0
- package/CONTACT_EMAIL_UPDATE_DEBUG.md +0 -313
- package/DEBUG_QUICKSTART.md +0 -133
- package/backend/contacts-methods-DEBUG.js +0 -237
- package/backend/contacts-methods-TEST.js +0 -271
- package/backend/test-methods.js +0 -118
|
@@ -17,15 +17,10 @@ async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
19
|
const contact = await elevatedGetContact(contactId);
|
|
20
|
-
console.log('debug contact', contact);
|
|
21
20
|
const currentInfo = contact.info;
|
|
22
|
-
console.log('debug currentInfo', currentInfo);
|
|
23
21
|
const updatedInfo = updateInfoCallback(currentInfo);
|
|
24
|
-
console.log('debug updatedInfo', updatedInfo);
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
console.log('debug result', result);
|
|
28
|
-
return result;
|
|
23
|
+
await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
|
|
29
24
|
} catch (error) {
|
|
30
25
|
console.error(`Error in ${operationName}:`, error);
|
|
31
26
|
throw new Error(`Failed to ${operationName}: ${error.message}`);
|
|
@@ -5,11 +5,18 @@ const { changeWixMembersEmails } = require('./utils');
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Processes and saves multiple member records in bulk
|
|
8
|
+
* @param {Object} options - The options object
|
|
9
|
+
* @param {Array} options.memberDataList - Array of member data from API
|
|
10
|
+
* @param {number} options.currentPageNumber - Current page number being processed
|
|
11
|
+
* @param {boolean} [options.addInterests=true] - Whether to add interests to the member data
|
|
8
12
|
* @param {Array} memberDataList - Array of member data from API
|
|
9
|
-
* @param {number} currentPageNumber - Current page number being processed
|
|
10
13
|
* @returns {Promise<Object>} - Bulk save operation result with statistics
|
|
11
14
|
*/
|
|
12
|
-
const bulkProcessAndSaveMemberData = async (
|
|
15
|
+
const bulkProcessAndSaveMemberData = async ({
|
|
16
|
+
memberDataList,
|
|
17
|
+
currentPageNumber,
|
|
18
|
+
addInterests = true,
|
|
19
|
+
}) => {
|
|
13
20
|
if (!Array.isArray(memberDataList) || memberDataList.length === 0) {
|
|
14
21
|
throw new Error('Invalid member data list provided');
|
|
15
22
|
}
|
|
@@ -18,7 +25,11 @@ const bulkProcessAndSaveMemberData = async (memberDataList, currentPageNumber) =
|
|
|
18
25
|
|
|
19
26
|
try {
|
|
20
27
|
const processedMemberDataPromises = memberDataList.map(memberData =>
|
|
21
|
-
generateUpdatedMemberData(
|
|
28
|
+
generateUpdatedMemberData({
|
|
29
|
+
inputMemberData: memberData,
|
|
30
|
+
currentPageNumber,
|
|
31
|
+
addInterests,
|
|
32
|
+
})
|
|
22
33
|
);
|
|
23
34
|
|
|
24
35
|
const processedMemberDataList = await Promise.all(processedMemberDataPromises);
|
|
@@ -24,8 +24,19 @@ const DEFAULT_MEMBER_DISPLAY_SETTINGS = {
|
|
|
24
24
|
showWixUrl: true,
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
const PAC_ASSOCIATIONS = {
|
|
28
|
+
ABMP: 'ABMP',
|
|
29
|
+
ASCP: 'ASCP',
|
|
30
|
+
ANP: 'ANP',
|
|
31
|
+
AHP: 'AHP',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const SITES_WITH_INTERESTS_TO_MIGRATE = [PAC_ASSOCIATIONS.ABMP];
|
|
35
|
+
|
|
27
36
|
module.exports = {
|
|
28
37
|
MEMBER_ACTIONS,
|
|
29
38
|
ADDRESS_VISIBILITY_OPTIONS,
|
|
30
39
|
DEFAULT_MEMBER_DISPLAY_SETTINGS,
|
|
40
|
+
PAC_ASSOCIATIONS,
|
|
41
|
+
SITES_WITH_INTERESTS_TO_MIGRATE,
|
|
31
42
|
};
|
|
@@ -60,11 +60,17 @@ const ensureUniqueUrl = async ({ url, memberId, fullName }) => {
|
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Generates complete updated member data by combining existing and migration data
|
|
63
|
-
* @param {Object}
|
|
64
|
-
* @param {
|
|
63
|
+
* @param {Object} options - The options object
|
|
64
|
+
* @param {Object} options.inputMemberData - Raw member data from API
|
|
65
|
+
* @param {string} options.addInterests - Site association of the member
|
|
66
|
+
* @param {number} options.currentPageNumber - Current page number being processed
|
|
65
67
|
* @returns {Promise<Object|null>} - Complete updated member data or null if validation fails
|
|
66
68
|
*/
|
|
67
|
-
async function generateUpdatedMemberData(
|
|
69
|
+
async function generateUpdatedMemberData({
|
|
70
|
+
inputMemberData,
|
|
71
|
+
addInterests = true,
|
|
72
|
+
currentPageNumber,
|
|
73
|
+
}) {
|
|
68
74
|
if (!validateCoreMemberData(inputMemberData)) {
|
|
69
75
|
throw new Error(
|
|
70
76
|
'Invalid member data: memberid, email (valid string), and memberships (array) are required'
|
|
@@ -86,7 +92,11 @@ async function generateUpdatedMemberData(inputMemberData, currentPageNumber) {
|
|
|
86
92
|
|
|
87
93
|
// Only enrich with migration and address data for new members
|
|
88
94
|
if (!existingDbMember) {
|
|
89
|
-
enrichWithMigrationData(
|
|
95
|
+
enrichWithMigrationData({
|
|
96
|
+
memberDataToUpdate: updatedMemberData,
|
|
97
|
+
migrationData: inputMemberData.migrationData,
|
|
98
|
+
addInterests,
|
|
99
|
+
});
|
|
90
100
|
|
|
91
101
|
enrichWithAddressData(
|
|
92
102
|
updatedMemberData,
|
|
@@ -196,10 +206,13 @@ async function getNewMemberOnlyFields(inputMemberData, existingDbMember) {
|
|
|
196
206
|
}
|
|
197
207
|
/**
|
|
198
208
|
* Enriches member data with optional migration properties
|
|
199
|
-
* @param {Object}
|
|
209
|
+
* @param {Object} options - The options object
|
|
210
|
+
* @param {Object} options.memberDataToUpdate - Member data object to enhance
|
|
211
|
+
* @param {Object} options.migrationData - Migration data containing optional properties
|
|
212
|
+
* @param {boolean} [options.addInterests=true] - Whether to add interests to the member data
|
|
200
213
|
* @param {Object} migrationData - Migration data containing optional properties
|
|
201
214
|
*/
|
|
202
|
-
function enrichWithMigrationData(memberDataToUpdate, migrationData) {
|
|
215
|
+
function enrichWithMigrationData({ memberDataToUpdate, migrationData, addInterests = true }) {
|
|
203
216
|
if (!migrationData) return;
|
|
204
217
|
|
|
205
218
|
memberDataToUpdate.addressInfo = migrationData.addressinfo;
|
|
@@ -209,7 +222,7 @@ function enrichWithMigrationData(memberDataToUpdate, migrationData) {
|
|
|
209
222
|
memberDataToUpdate.showWebsite = true;
|
|
210
223
|
}
|
|
211
224
|
|
|
212
|
-
if (migrationData.interests) {
|
|
225
|
+
if (addInterests && migrationData.interests) {
|
|
213
226
|
memberDataToUpdate.areasOfPractices = processInterests(migrationData.interests);
|
|
214
227
|
}
|
|
215
228
|
}
|
|
@@ -6,6 +6,7 @@ const { TASKS_NAMES } = require('../tasks/consts');
|
|
|
6
6
|
const { getSiteConfigs } = require('../utils');
|
|
7
7
|
|
|
8
8
|
const { bulkProcessAndSaveMemberData } = require('./bulk-process-methods');
|
|
9
|
+
const { SITES_WITH_INTERESTS_TO_MIGRATE } = require('./consts');
|
|
9
10
|
const { isUpdatedMember, isSiteAssociatedMember } = require('./utils');
|
|
10
11
|
|
|
11
12
|
async function syncMembersDataPerAction(action) {
|
|
@@ -79,6 +80,7 @@ async function synchronizeSinglePage(taskObject) {
|
|
|
79
80
|
getSiteConfigs(CONFIG_KEYS.SITE_ASSOCIATION),
|
|
80
81
|
fetchPACMembers(pageNumber, action),
|
|
81
82
|
]);
|
|
83
|
+
const addInterests = SITES_WITH_INTERESTS_TO_MIGRATE.includes(siteAssociation);
|
|
82
84
|
if (
|
|
83
85
|
!memberDataResponse ||
|
|
84
86
|
!memberDataResponse.results ||
|
|
@@ -98,7 +100,11 @@ async function synchronizeSinglePage(taskObject) {
|
|
|
98
100
|
message: `No to be updated, or members of association: '${siteAssociation}' found`,
|
|
99
101
|
};
|
|
100
102
|
}
|
|
101
|
-
const result = await bulkProcessAndSaveMemberData(
|
|
103
|
+
const result = await bulkProcessAndSaveMemberData({
|
|
104
|
+
memberDataList: toSyncMembers,
|
|
105
|
+
currentPageNumber: pageNumber,
|
|
106
|
+
addInterests,
|
|
107
|
+
});
|
|
102
108
|
|
|
103
109
|
return {
|
|
104
110
|
success: true,
|
|
@@ -12,7 +12,7 @@ const wixData = {
|
|
|
12
12
|
get: auth.elevate(items.get),
|
|
13
13
|
truncate: auth.elevate(items.truncate),
|
|
14
14
|
bulkSave: auth.elevate(items.bulkSave),
|
|
15
|
+
search: auth.elevate(items.search),
|
|
15
16
|
//TODO: add other methods here as needed
|
|
16
17
|
};
|
|
17
|
-
|
|
18
18
|
module.exports = { wixData };
|
package/backend/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
normalizeUrlForComparison,
|
|
11
11
|
queryAllItems,
|
|
12
12
|
generateGeoHash,
|
|
13
|
+
searchAllItems,
|
|
13
14
|
} = require('./utils');
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -121,7 +122,7 @@ async function getMemberBySlug({
|
|
|
121
122
|
if (!slug) return null;
|
|
122
123
|
|
|
123
124
|
try {
|
|
124
|
-
let query = wixData.
|
|
125
|
+
let query = wixData.search(COLLECTIONS.MEMBERS_DATA).expression(slug);
|
|
125
126
|
|
|
126
127
|
if (excludeDropped) {
|
|
127
128
|
query = query.ne('action', 'drop');
|
|
@@ -131,11 +132,23 @@ async function getMemberBySlug({
|
|
|
131
132
|
query = query.ne('memberId', memberId);
|
|
132
133
|
}
|
|
133
134
|
query = query.limit(1000);
|
|
134
|
-
const
|
|
135
|
+
const searchResult = await searchAllItems(query);
|
|
136
|
+
console.log('searchResult type:', Array.isArray(searchResult) ? 'array' : typeof searchResult);
|
|
137
|
+
console.log('searchResult length:', searchResult?.length);
|
|
138
|
+
const membersList = searchResult.filter(item => item.url && item.url.includes(slug)); //replacement for contains
|
|
139
|
+
console.log('membersList type:', Array.isArray(membersList) ? 'array' : typeof membersList);
|
|
140
|
+
console.log('membersList length:', membersList?.length);
|
|
135
141
|
let matchingMembers = membersList.filter(
|
|
136
142
|
item => item.url && item.url.toLowerCase() === slug.toLowerCase()
|
|
137
143
|
);
|
|
144
|
+
console.log(
|
|
145
|
+
'matchingMembers type:',
|
|
146
|
+
Array.isArray(matchingMembers) ? 'array' : typeof matchingMembers
|
|
147
|
+
);
|
|
148
|
+
console.log('matchingMembers length:', matchingMembers?.length);
|
|
138
149
|
if (normalizeSlugForComparison) {
|
|
150
|
+
console.log('normalizeSlugForComparison is true, about to filter membersList');
|
|
151
|
+
console.log('membersList before normalize filter:', membersList);
|
|
139
152
|
matchingMembers = membersList
|
|
140
153
|
.filter(
|
|
141
154
|
//remove trailing "-1", "-2", etc.
|
package/backend/utils.js
CHANGED
|
@@ -107,18 +107,28 @@ function getAddressesByStatus(addresses = [], addressDisplayOption = []) {
|
|
|
107
107
|
})
|
|
108
108
|
.filter(Boolean);
|
|
109
109
|
}
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
let oldResults = await query.find();
|
|
110
|
+
const getAllItems = async querySearchResult => {
|
|
111
|
+
let oldResults = querySearchResult;
|
|
113
112
|
console.log(`found items: ${oldResults.items.length}`);
|
|
114
113
|
const allItems = oldResults.items;
|
|
115
114
|
while (oldResults.hasNext()) {
|
|
116
115
|
oldResults = await oldResults.next();
|
|
117
116
|
allItems.push(...oldResults.items);
|
|
118
117
|
}
|
|
119
|
-
console.log(`all items: ${allItems.length}`);
|
|
118
|
+
console.log(`all items count : ${allItems.length}`);
|
|
120
119
|
return allItems;
|
|
121
120
|
};
|
|
121
|
+
const searchAllItems = async searchQuery => {
|
|
122
|
+
console.log('start search');
|
|
123
|
+
const searchResults = await searchQuery.run();
|
|
124
|
+
return getAllItems(searchResults);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const queryAllItems = async query => {
|
|
128
|
+
console.log('start query');
|
|
129
|
+
const queryResults = await query.find();
|
|
130
|
+
return getAllItems(queryResults);
|
|
131
|
+
};
|
|
122
132
|
/**
|
|
123
133
|
* Chunks large arrays into smaller chunks for processing
|
|
124
134
|
* @param {Array} array - Array to chunk
|
|
@@ -206,4 +216,5 @@ module.exports = {
|
|
|
206
216
|
formatDateOnly,
|
|
207
217
|
getAddressesByStatus,
|
|
208
218
|
isPAC_STAFF,
|
|
219
|
+
searchAllItems,
|
|
209
220
|
};
|
package/package.json
CHANGED
package/public/Utils/homePage.js
CHANGED
|
@@ -127,6 +127,8 @@ const createHomepageUtils = (_$w, filterProfiles) => {
|
|
|
127
127
|
|
|
128
128
|
paginateSearchResults(searchResults, pagination);
|
|
129
129
|
await updateUrlParams(filter, pagination);
|
|
130
|
+
|
|
131
|
+
_$w('#resultsStateBox').scrollTo();
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
async function onChangeMultiCheckbox({
|
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
# Contact Email Update Investigation Guide
|
|
2
|
-
|
|
3
|
-
## Problem Description
|
|
4
|
-
|
|
5
|
-
Contact email updates in Wix CRM are not working after migration to npm package:
|
|
6
|
-
|
|
7
|
-
- ✅ Members data in Wix DB updates correctly
|
|
8
|
-
- ❌ Contact email in Wix CRM does not update
|
|
9
|
-
- ❌ No errors appear in logs
|
|
10
|
-
- ✅ Old implementation (before npm) works fine
|
|
11
|
-
|
|
12
|
-
## Key Differences Found
|
|
13
|
-
|
|
14
|
-
### OLD Implementation (Working)
|
|
15
|
-
|
|
16
|
-
```javascript
|
|
17
|
-
// From: src/backend/api.web.js (before npm migration)
|
|
18
|
-
import { contacts } from 'wix-crm.v2'; // ← Old package
|
|
19
|
-
import { elevate } from 'wix-auth'; // ← Old import style
|
|
20
|
-
|
|
21
|
-
// Elevated functions created INSIDE the function
|
|
22
|
-
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
23
|
-
const elevatedGetContact = elevate(contacts.getContact);
|
|
24
|
-
const elevatedUpdateContact = elevate(contacts.updateContact);
|
|
25
|
-
|
|
26
|
-
const currentContact = await elevatedGetContact(contactId);
|
|
27
|
-
const updatedInfo = updateInfoCallback(currentContact.info);
|
|
28
|
-
|
|
29
|
-
// Passes updatedInfo DIRECTLY (not wrapped)
|
|
30
|
-
const result = await elevatedUpdateContact(
|
|
31
|
-
contactId,
|
|
32
|
-
updatedInfo, // ← Direct info object
|
|
33
|
-
currentContact.revision
|
|
34
|
-
);
|
|
35
|
-
return result;
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### NEW Implementation (Not Working)
|
|
40
|
-
|
|
41
|
-
```javascript
|
|
42
|
-
// From: abmp-npm/backend/contacts-methods.js
|
|
43
|
-
const { contacts } = require('@wix/crm'); // ← New package
|
|
44
|
-
const { auth } = require('@wix/essentials'); // ← New import style
|
|
45
|
-
|
|
46
|
-
// Elevated functions created at MODULE LEVEL
|
|
47
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
48
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
49
|
-
|
|
50
|
-
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
51
|
-
const contact = await elevatedGetContact(contactId);
|
|
52
|
-
const updatedInfo = updateInfoCallback(contact.info);
|
|
53
|
-
|
|
54
|
-
// Wraps updatedInfo in { info: }
|
|
55
|
-
await elevatedUpdateContact(
|
|
56
|
-
contactId,
|
|
57
|
-
{ info: updatedInfo }, // ← Wrapped in { info: }
|
|
58
|
-
contact.revision
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Potential Issues
|
|
64
|
-
|
|
65
|
-
### 1. Package Change: `wix-crm.v2` → `@wix/crm`
|
|
66
|
-
|
|
67
|
-
The API signature might have changed between these packages:
|
|
68
|
-
|
|
69
|
-
- **Old**: `updateContact(contactId, infoObject, revision)`
|
|
70
|
-
- **New**: `updateContact(contactId, { info: infoObject }, revision)` or `updateContact(contactId, contactObject, { revision })`
|
|
71
|
-
|
|
72
|
-
### 2. Elevation Scope
|
|
73
|
-
|
|
74
|
-
- **Old**: Functions elevated inside the function (per-call elevation)
|
|
75
|
-
- **New**: Functions elevated at module level (shared elevation)
|
|
76
|
-
|
|
77
|
-
This could cause issues with permissions or context.
|
|
78
|
-
|
|
79
|
-
### 3. Silent Failures
|
|
80
|
-
|
|
81
|
-
If the CRM update throws an error but it's being caught and not logged, it would appear to work but not actually update.
|
|
82
|
-
|
|
83
|
-
## Investigation Steps
|
|
84
|
-
|
|
85
|
-
I've created three debugging files for you:
|
|
86
|
-
|
|
87
|
-
### File 1: `contacts-methods-DEBUG.js`
|
|
88
|
-
|
|
89
|
-
This is your current implementation with extensive logging. It will show:
|
|
90
|
-
|
|
91
|
-
- Every step of the update process
|
|
92
|
-
- All data being passed
|
|
93
|
-
- Any errors (even if they're being caught)
|
|
94
|
-
- Success confirmations
|
|
95
|
-
|
|
96
|
-
### File 2: `contacts-methods-TEST.js`
|
|
97
|
-
|
|
98
|
-
This contains 4 different implementations to test:
|
|
99
|
-
|
|
100
|
-
- **V1**: Current style (wrapped in `{ info: }`)
|
|
101
|
-
- **V2**: Old style (direct info object)
|
|
102
|
-
- **V3**: Minimal payload (only changed fields)
|
|
103
|
-
- **V4**: Revision in options object
|
|
104
|
-
- **Elevation Test**: Checks if elevation is working at all
|
|
105
|
-
|
|
106
|
-
### File 3: `test-methods.js`
|
|
107
|
-
|
|
108
|
-
Web method wrappers you can call from the frontend to run the tests.
|
|
109
|
-
|
|
110
|
-
## How to Use
|
|
111
|
-
|
|
112
|
-
### Step 1: Update Backend Index
|
|
113
|
-
|
|
114
|
-
Add the test methods to your npm package exports:
|
|
115
|
-
|
|
116
|
-
```javascript
|
|
117
|
-
// In abmp-npm/backend/index.js
|
|
118
|
-
module.exports = {
|
|
119
|
-
...require('./forms-methods'),
|
|
120
|
-
...require('./search-filters-methods'),
|
|
121
|
-
...require('./jobs'),
|
|
122
|
-
...require('./utils'),
|
|
123
|
-
...require('./daily-pull'),
|
|
124
|
-
...require('./pac-api-methods'),
|
|
125
|
-
...require('./members-area-methods'),
|
|
126
|
-
...require('./members-data-methods'),
|
|
127
|
-
...require('./cms-data-methods'),
|
|
128
|
-
...require('./routers-methods'),
|
|
129
|
-
...require('./test-methods'), // ← Add this
|
|
130
|
-
};
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Step 2: Expose in Host Site
|
|
134
|
-
|
|
135
|
-
Add these web methods to your host site:
|
|
136
|
-
|
|
137
|
-
```javascript
|
|
138
|
-
// In abmp/src/backend/web-methods.web.js
|
|
139
|
-
import { Permissions, webMethod } from 'wix-web-module';
|
|
140
|
-
import {
|
|
141
|
-
// ... existing imports
|
|
142
|
-
runContactUpdateTests as _runContactUpdateTests,
|
|
143
|
-
testContactElevation as _testContactElevation,
|
|
144
|
-
testUpdateMemberContactInfo as _testUpdateMemberContactInfo,
|
|
145
|
-
} from 'abmp-npm/backend';
|
|
146
|
-
|
|
147
|
-
// ... existing exports
|
|
148
|
-
|
|
149
|
-
export const runContactUpdateTests = webMethod(Permissions.SiteMember, _runContactUpdateTests);
|
|
150
|
-
|
|
151
|
-
export const testContactElevation = webMethod(Permissions.SiteMember, _testContactElevation);
|
|
152
|
-
|
|
153
|
-
export const testUpdateMemberContactInfo = webMethod(
|
|
154
|
-
Permissions.SiteMember,
|
|
155
|
-
_testUpdateMemberContactInfo
|
|
156
|
-
);
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Step 3: Run Tests from Frontend
|
|
160
|
-
|
|
161
|
-
Option A - Test all variations:
|
|
162
|
-
|
|
163
|
-
```javascript
|
|
164
|
-
import { runContactUpdateTests } from 'backend/web-methods.web';
|
|
165
|
-
import wixData from 'wix-data';
|
|
166
|
-
|
|
167
|
-
// Get your member data (you need the contactId)
|
|
168
|
-
const memberData = await wixData.get('Members/PrivateMembersData', 'YOUR_MEMBER_ID');
|
|
169
|
-
const contactId = memberData.contactId;
|
|
170
|
-
|
|
171
|
-
// Run all test variations
|
|
172
|
-
const results = await runContactUpdateTests(contactId, 'newemail@test.com');
|
|
173
|
-
console.log('Test results:', results);
|
|
174
|
-
|
|
175
|
-
// Check Wix Site Monitoring logs for detailed output
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
Option B - Test elevation only:
|
|
179
|
-
|
|
180
|
-
```javascript
|
|
181
|
-
import { testContactElevation } from 'backend/web-methods.web';
|
|
182
|
-
|
|
183
|
-
const results = await testContactElevation(contactId);
|
|
184
|
-
console.log('Elevation test results:', results);
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Option C - Test with DEBUG logging (using your actual saveRegistrationData flow):
|
|
188
|
-
|
|
189
|
-
```javascript
|
|
190
|
-
import { testUpdateMemberContactInfo } from 'backend/web-methods.web';
|
|
191
|
-
import wixData from 'wix-data';
|
|
192
|
-
|
|
193
|
-
// Get existing member data
|
|
194
|
-
const existingData = await wixData.get('Members/PrivateMembersData', 'YOUR_MEMBER_ID');
|
|
195
|
-
|
|
196
|
-
// Create update data (as it would come from your form)
|
|
197
|
-
const updateData = {
|
|
198
|
-
...existingData,
|
|
199
|
-
contactFormEmail: 'newemail@test.com', // Change the email
|
|
200
|
-
firstName: existingData.firstName,
|
|
201
|
-
lastName: existingData.lastName,
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
// Test with DEBUG logging
|
|
205
|
-
const results = await testUpdateMemberContactInfo(updateData, existingData);
|
|
206
|
-
console.log('Debug test results:', results);
|
|
207
|
-
|
|
208
|
-
// Check Wix Site Monitoring logs for extensive output
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Step 4: Check Logs
|
|
212
|
-
|
|
213
|
-
Go to your Wix Site Monitoring (Logs) and look for entries starting with:
|
|
214
|
-
|
|
215
|
-
- `[DEBUG]` - From the debug version
|
|
216
|
-
- `[TEST V1]`, `[TEST V2]`, etc. - From different test implementations
|
|
217
|
-
- `[TEST ELEVATION]` - From elevation tests
|
|
218
|
-
- `[TEST RUNNER]` - From the test runner
|
|
219
|
-
|
|
220
|
-
## What to Look For
|
|
221
|
-
|
|
222
|
-
### 1. Elevation Issues
|
|
223
|
-
|
|
224
|
-
If you see errors like:
|
|
225
|
-
|
|
226
|
-
- "Insufficient permissions"
|
|
227
|
-
- "Unauthorized"
|
|
228
|
-
- "Forbidden"
|
|
229
|
-
|
|
230
|
-
Then elevation is not working correctly.
|
|
231
|
-
|
|
232
|
-
### 2. API Signature Issues
|
|
233
|
-
|
|
234
|
-
If you see errors like:
|
|
235
|
-
|
|
236
|
-
- "Invalid parameter"
|
|
237
|
-
- "Expected object of type Contact"
|
|
238
|
-
- "Unexpected argument"
|
|
239
|
-
|
|
240
|
-
Then the API signature has changed between packages.
|
|
241
|
-
|
|
242
|
-
### 3. Silent Success
|
|
243
|
-
|
|
244
|
-
If all tests show "success" but the email still doesn't update in CRM:
|
|
245
|
-
|
|
246
|
-
- Check if the contact actually exists in CRM
|
|
247
|
-
- Check if there are any CRM automation rules blocking updates
|
|
248
|
-
- Check if the email field is locked/read-only
|
|
249
|
-
|
|
250
|
-
### 4. Which Version Works
|
|
251
|
-
|
|
252
|
-
If one of the test versions (V1, V2, V3, V4) works:
|
|
253
|
-
|
|
254
|
-
- That tells us the correct API signature to use
|
|
255
|
-
- Update the actual `contacts-methods.js` to match the working version
|
|
256
|
-
|
|
257
|
-
## Quick Fix Hypothesis
|
|
258
|
-
|
|
259
|
-
Based on the code comparison, my best guess is that the issue is with the API call signature. Try this fix first:
|
|
260
|
-
|
|
261
|
-
### Option 1: Use Old Style (Direct Info Object)
|
|
262
|
-
|
|
263
|
-
```javascript
|
|
264
|
-
// In contacts-methods.js, line 23
|
|
265
|
-
// CHANGE FROM:
|
|
266
|
-
await elevatedUpdateContact(contactId, { info: updatedInfo }, contact.revision);
|
|
267
|
-
|
|
268
|
-
// CHANGE TO:
|
|
269
|
-
await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Option 2: Move Elevation Inside Function
|
|
273
|
-
|
|
274
|
-
```javascript
|
|
275
|
-
// In contacts-methods.js
|
|
276
|
-
// CHANGE FROM:
|
|
277
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
278
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
279
|
-
|
|
280
|
-
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
281
|
-
// ...
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// CHANGE TO:
|
|
285
|
-
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
286
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
287
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
288
|
-
// ...
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## Next Steps
|
|
293
|
-
|
|
294
|
-
1. ✅ Add test files to npm package (already created)
|
|
295
|
-
2. ⬜ Release new npm version with test methods
|
|
296
|
-
3. ⬜ Install new version in host site
|
|
297
|
-
4. ⬜ Expose test web methods in host site
|
|
298
|
-
5. ⬜ Run tests from frontend
|
|
299
|
-
6. ⬜ Check logs to see which version works
|
|
300
|
-
7. ⬜ Apply the working solution to the actual code
|
|
301
|
-
8. ⬜ Remove test files and release final version
|
|
302
|
-
|
|
303
|
-
## Need More Help?
|
|
304
|
-
|
|
305
|
-
If the tests don't reveal the issue, we can:
|
|
306
|
-
|
|
307
|
-
1. Add even more detailed logging
|
|
308
|
-
2. Test with the actual Wix CRM dashboard to verify the contact exists
|
|
309
|
-
3. Check if there are any CRM automation rules or webhooks interfering
|
|
310
|
-
4. Test with a different contact to rule out data-specific issues
|
|
311
|
-
5. Compare the exact bytes being sent in the old vs new implementation
|
|
312
|
-
|
|
313
|
-
Let me know what the test results show!
|
package/DEBUG_QUICKSTART.md
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
# Contact Email Update Investigation - Quick Start
|
|
2
|
-
|
|
3
|
-
## 🔍 Problem Summary
|
|
4
|
-
|
|
5
|
-
After migrating to npm package, contact email updates fail silently:
|
|
6
|
-
|
|
7
|
-
- ✅ Wix DB updates work
|
|
8
|
-
- ❌ CRM contact email doesn't update
|
|
9
|
-
- ❌ No errors in logs
|
|
10
|
-
|
|
11
|
-
## 🎯 Key Finding
|
|
12
|
-
|
|
13
|
-
The old code used `wix-crm.v2` while the new code uses `@wix/crm`. These have **different API signatures**!
|
|
14
|
-
|
|
15
|
-
**Old (Working)**:
|
|
16
|
-
|
|
17
|
-
```javascript
|
|
18
|
-
elevatedUpdateContact(contactId, infoObject, revision);
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**New (Not Working?)**:
|
|
22
|
-
|
|
23
|
-
```javascript
|
|
24
|
-
elevatedUpdateContact(contactId, { info: infoObject }, revision);
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## 🚀 Quick Steps to Investigate
|
|
28
|
-
|
|
29
|
-
### 1. I've created 4 files for you:
|
|
30
|
-
|
|
31
|
-
- ✅ `contacts-methods-DEBUG.js` - Your code with extensive logging
|
|
32
|
-
- ✅ `contacts-methods-TEST.js` - 4 different API call variations
|
|
33
|
-
- ✅ `test-methods.js` - Web methods to run tests
|
|
34
|
-
- ✅ `CONTACT_EMAIL_UPDATE_DEBUG.md` - Full documentation
|
|
35
|
-
|
|
36
|
-
### 2. Release this version to test:
|
|
37
|
-
|
|
38
|
-
The test methods are already exported in `backend/index.js`.
|
|
39
|
-
You just need to:
|
|
40
|
-
|
|
41
|
-
1. Release new npm version
|
|
42
|
-
2. Expose test methods in host site `web-methods.web.js`
|
|
43
|
-
3. Run tests from frontend
|
|
44
|
-
4. Check logs to see which variation works
|
|
45
|
-
|
|
46
|
-
### 3. Expose test methods in host site:
|
|
47
|
-
|
|
48
|
-
Add to `abmp/src/backend/web-methods.web.js`:
|
|
49
|
-
|
|
50
|
-
```javascript
|
|
51
|
-
import {
|
|
52
|
-
// ... your existing imports
|
|
53
|
-
runContactUpdateTests as _runContactUpdateTests,
|
|
54
|
-
testContactElevation as _testContactElevation,
|
|
55
|
-
testUpdateMemberContactInfo as _testUpdateMemberContactInfo,
|
|
56
|
-
} from 'abmp-npm/backend';
|
|
57
|
-
|
|
58
|
-
// ... existing exports
|
|
59
|
-
|
|
60
|
-
export const runContactUpdateTests = webMethod(Permissions.SiteMember, _runContactUpdateTests);
|
|
61
|
-
|
|
62
|
-
export const testContactElevation = webMethod(Permissions.SiteMember, _testContactElevation);
|
|
63
|
-
|
|
64
|
-
export const testUpdateMemberContactInfo = webMethod(
|
|
65
|
-
Permissions.SiteMember,
|
|
66
|
-
_testUpdateMemberContactInfo
|
|
67
|
-
);
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### 4. Run tests from frontend:
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
import { runContactUpdateTests } from 'backend/web-methods.web';
|
|
74
|
-
import wixData from 'wix-data';
|
|
75
|
-
|
|
76
|
-
// Get your contact ID from member data
|
|
77
|
-
const memberData = await wixData.get('Members/PrivateMembersData', 'YOUR_MEMBER_ID');
|
|
78
|
-
|
|
79
|
-
// Run all test variations
|
|
80
|
-
const results = await runContactUpdateTests(memberData.contactId, 'test@newemail.com');
|
|
81
|
-
|
|
82
|
-
console.log('Results:', results);
|
|
83
|
-
// Then check Wix Site Monitoring logs for detailed output
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### 5. Check which test works:
|
|
87
|
-
|
|
88
|
-
In Wix Site Monitoring, look for:
|
|
89
|
-
|
|
90
|
-
- ✅ `[TEST V1]` - Current implementation
|
|
91
|
-
- ✅ `[TEST V2]` - Old style (direct info object) ← **Most likely to work**
|
|
92
|
-
- ✅ `[TEST V3]` - Minimal payload
|
|
93
|
-
- ✅ `[TEST V4]` - Revision in options
|
|
94
|
-
|
|
95
|
-
### 6. Apply the fix:
|
|
96
|
-
|
|
97
|
-
Once you know which version works, update `contacts-methods.js` to match that signature.
|
|
98
|
-
|
|
99
|
-
## 🔧 Most Likely Fix
|
|
100
|
-
|
|
101
|
-
Based on the code comparison, try this first:
|
|
102
|
-
|
|
103
|
-
### Change line 23 in `contacts-methods.js`:
|
|
104
|
-
|
|
105
|
-
**FROM:**
|
|
106
|
-
|
|
107
|
-
```javascript
|
|
108
|
-
await elevatedUpdateContact(contactId, { info: updatedInfo }, contact.revision);
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**TO:**
|
|
112
|
-
|
|
113
|
-
```javascript
|
|
114
|
-
await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
This matches the old working implementation and might be the correct signature for the new package.
|
|
118
|
-
|
|
119
|
-
## 📖 Full Documentation
|
|
120
|
-
|
|
121
|
-
See `CONTACT_EMAIL_UPDATE_DEBUG.md` for complete details, analysis, and troubleshooting steps.
|
|
122
|
-
|
|
123
|
-
## ✅ What's Already Done
|
|
124
|
-
|
|
125
|
-
- ✅ Debugging files created
|
|
126
|
-
- ✅ Test variations created
|
|
127
|
-
- ✅ Test methods exported
|
|
128
|
-
- ⬜ Release new npm version
|
|
129
|
-
- ⬜ Expose in host site
|
|
130
|
-
- ⬜ Run tests
|
|
131
|
-
- ⬜ Apply fix
|
|
132
|
-
|
|
133
|
-
Let me know what the tests reveal!
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
const { contacts } = require('@wix/crm');
|
|
2
|
-
const { auth } = require('@wix/essentials');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* DEBUG VERSION with extensive logging
|
|
6
|
-
* This file helps investigate why contact email updates aren't working
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
10
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Generic contact update helper function - DEBUG VERSION
|
|
14
|
-
* @param {string} contactId - The contact ID in Wix CRM
|
|
15
|
-
* @param {function} updateInfoCallback - Function that returns the updated info object
|
|
16
|
-
* @param {string} operationName - Name of the operation for logging
|
|
17
|
-
*/
|
|
18
|
-
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
19
|
-
console.log(`[DEBUG] Starting ${operationName}`);
|
|
20
|
-
console.log(`[DEBUG] contactId:`, contactId);
|
|
21
|
-
|
|
22
|
-
if (!contactId) {
|
|
23
|
-
console.error(`[DEBUG] ERROR: Contact ID is missing`);
|
|
24
|
-
throw new Error('Contact ID is required');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
console.log(`[DEBUG] Attempting to fetch contact...`);
|
|
29
|
-
const contact = await elevatedGetContact(contactId);
|
|
30
|
-
console.log(`[DEBUG] Contact fetched successfully:`, JSON.stringify(contact, null, 2));
|
|
31
|
-
|
|
32
|
-
const currentInfo = contact.info;
|
|
33
|
-
console.log(`[DEBUG] Current contact info:`, JSON.stringify(currentInfo, null, 2));
|
|
34
|
-
|
|
35
|
-
const updatedInfo = updateInfoCallback(currentInfo);
|
|
36
|
-
console.log(`[DEBUG] Updated info to send:`, JSON.stringify(updatedInfo, null, 2));
|
|
37
|
-
|
|
38
|
-
console.log(`[DEBUG] Contact revision:`, contact.revision);
|
|
39
|
-
console.log(`[DEBUG] Attempting to update contact...`);
|
|
40
|
-
|
|
41
|
-
// Try the new way (wrapping in { info: })
|
|
42
|
-
const result = await elevatedUpdateContact(contactId, { info: updatedInfo }, contact.revision);
|
|
43
|
-
console.log(`[DEBUG] Update result:`, JSON.stringify(result, null, 2));
|
|
44
|
-
|
|
45
|
-
console.log(`[DEBUG] ✅ ${operationName} completed successfully`);
|
|
46
|
-
return result;
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.error(`[DEBUG] ❌ Error in ${operationName}:`, error);
|
|
49
|
-
console.error(`[DEBUG] Error name:`, error.name);
|
|
50
|
-
console.error(`[DEBUG] Error message:`, error.message);
|
|
51
|
-
console.error(`[DEBUG] Error stack:`, error.stack);
|
|
52
|
-
console.error(`[DEBUG] Full error object:`, JSON.stringify(error, null, 2));
|
|
53
|
-
throw new Error(`Failed to ${operationName}: ${error.message}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Updates contact email in Wix CRM - DEBUG VERSION
|
|
59
|
-
* @param {string} contactId - The contact ID in Wix CRM
|
|
60
|
-
* @param {string} newEmail - The new email address
|
|
61
|
-
*/
|
|
62
|
-
async function updateContactEmail(contactId, newEmail) {
|
|
63
|
-
console.log(`[DEBUG] updateContactEmail called`);
|
|
64
|
-
console.log(`[DEBUG] contactId:`, contactId);
|
|
65
|
-
console.log(`[DEBUG] newEmail:`, newEmail);
|
|
66
|
-
|
|
67
|
-
if (!newEmail) {
|
|
68
|
-
console.error(`[DEBUG] ERROR: New email is missing`);
|
|
69
|
-
throw new Error('New email is required');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return await updateContactInfo(
|
|
73
|
-
contactId,
|
|
74
|
-
currentInfo => {
|
|
75
|
-
console.log(`[DEBUG] Building email update object...`);
|
|
76
|
-
const result = {
|
|
77
|
-
...currentInfo,
|
|
78
|
-
emails: {
|
|
79
|
-
items: [
|
|
80
|
-
{
|
|
81
|
-
email: newEmail,
|
|
82
|
-
primary: true,
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
console.log(`[DEBUG] Email update object built:`, JSON.stringify(result, null, 2));
|
|
88
|
-
return result;
|
|
89
|
-
},
|
|
90
|
-
'update contact email'
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Updates contact names in Wix CRM - DEBUG VERSION
|
|
96
|
-
* @param {string} contactId - The contact ID in Wix CRM
|
|
97
|
-
* @param {string} firstName - The new first name
|
|
98
|
-
* @param {string} lastName - The new last name
|
|
99
|
-
*/
|
|
100
|
-
async function updateContactNames(contactId, firstName, lastName) {
|
|
101
|
-
console.log(`[DEBUG] updateContactNames called`);
|
|
102
|
-
console.log(`[DEBUG] contactId:`, contactId);
|
|
103
|
-
console.log(`[DEBUG] firstName:`, firstName);
|
|
104
|
-
console.log(`[DEBUG] lastName:`, lastName);
|
|
105
|
-
|
|
106
|
-
if (!firstName && !lastName) {
|
|
107
|
-
console.error(`[DEBUG] ERROR: Both names are missing`);
|
|
108
|
-
throw new Error('At least one name field is required');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return await updateContactInfo(
|
|
112
|
-
contactId,
|
|
113
|
-
currentInfo => {
|
|
114
|
-
console.log(`[DEBUG] Building names update object...`);
|
|
115
|
-
const result = {
|
|
116
|
-
...currentInfo,
|
|
117
|
-
name: {
|
|
118
|
-
first: firstName || currentInfo?.name?.first || '',
|
|
119
|
-
last: lastName || currentInfo?.name?.last || '',
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
console.log(`[DEBUG] Names update object built:`, JSON.stringify(result, null, 2));
|
|
123
|
-
return result;
|
|
124
|
-
},
|
|
125
|
-
'update contact names'
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Update fields if they have changed - DEBUG VERSION
|
|
131
|
-
* @param {Array} existingValues - Current values for comparison
|
|
132
|
-
* @param {Array} newValues - New values to compare against
|
|
133
|
-
* @param {Function} updater - Function to call if values changed
|
|
134
|
-
* @param {Function} argsBuilder - Function to build arguments for updater
|
|
135
|
-
*/
|
|
136
|
-
const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
|
|
137
|
-
console.log(`[DEBUG] updateIfChanged called`);
|
|
138
|
-
console.log(`[DEBUG] existingValues:`, JSON.stringify(existingValues));
|
|
139
|
-
console.log(`[DEBUG] newValues:`, JSON.stringify(newValues));
|
|
140
|
-
|
|
141
|
-
const hasChanged = existingValues.some((val, idx) => {
|
|
142
|
-
const changed = val !== newValues[idx];
|
|
143
|
-
if (changed) {
|
|
144
|
-
console.log(`[DEBUG] Value changed at index ${idx}: "${val}" -> "${newValues[idx]}"`);
|
|
145
|
-
}
|
|
146
|
-
return changed;
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
console.log(`[DEBUG] hasChanged:`, hasChanged);
|
|
150
|
-
|
|
151
|
-
if (!hasChanged) {
|
|
152
|
-
console.log(`[DEBUG] No changes detected, skipping update`);
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
console.log(`[DEBUG] Changes detected, calling updater with args:`, argsBuilder(newValues));
|
|
157
|
-
return updater(...argsBuilder(newValues));
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Updates member contact information in CRM if fields have changed - DEBUG VERSION
|
|
162
|
-
* @param {Object} data - New member data
|
|
163
|
-
* @param {Object} existingMemberData - Existing member data
|
|
164
|
-
*/
|
|
165
|
-
const updateMemberContactInfo = async (data, existingMemberData) => {
|
|
166
|
-
console.log(`[DEBUG] ========================================`);
|
|
167
|
-
console.log(`[DEBUG] updateMemberContactInfo called`);
|
|
168
|
-
console.log(`[DEBUG] data:`, JSON.stringify(data, null, 2));
|
|
169
|
-
console.log(`[DEBUG] existingMemberData:`, JSON.stringify(existingMemberData, null, 2));
|
|
170
|
-
console.log(`[DEBUG] ========================================`);
|
|
171
|
-
|
|
172
|
-
const { contactId } = existingMemberData;
|
|
173
|
-
console.log(`[DEBUG] Extracted contactId:`, contactId);
|
|
174
|
-
|
|
175
|
-
if (!contactId) {
|
|
176
|
-
console.error(`[DEBUG] ERROR: contactId is missing from existingMemberData`);
|
|
177
|
-
throw new Error('contactId is required in existingMemberData');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const updateConfig = [
|
|
181
|
-
{
|
|
182
|
-
fields: ['contactFormEmail'],
|
|
183
|
-
updater: updateContactEmail,
|
|
184
|
-
args: ([email]) => [contactId, email],
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
fields: ['firstName', 'lastName'],
|
|
188
|
-
updater: updateContactNames,
|
|
189
|
-
args: ([firstName, lastName]) => [contactId, firstName, lastName],
|
|
190
|
-
},
|
|
191
|
-
];
|
|
192
|
-
|
|
193
|
-
console.log(`[DEBUG] Processing update config...`);
|
|
194
|
-
|
|
195
|
-
const updatePromises = updateConfig
|
|
196
|
-
.map(({ fields, updater, args }, index) => {
|
|
197
|
-
console.log(`[DEBUG] Config ${index}: fields=${JSON.stringify(fields)}`);
|
|
198
|
-
const existingValues = fields.map(field => {
|
|
199
|
-
const value = existingMemberData[field];
|
|
200
|
-
console.log(`[DEBUG] Existing ${field}:`, value);
|
|
201
|
-
return value;
|
|
202
|
-
});
|
|
203
|
-
const newValues = fields.map(field => {
|
|
204
|
-
const value = data[field];
|
|
205
|
-
console.log(`[DEBUG] New ${field}:`, value);
|
|
206
|
-
return value;
|
|
207
|
-
});
|
|
208
|
-
return updateIfChanged(existingValues, newValues, updater, args);
|
|
209
|
-
})
|
|
210
|
-
.filter(Boolean);
|
|
211
|
-
|
|
212
|
-
console.log(`[DEBUG] Number of updates to perform:`, updatePromises.length);
|
|
213
|
-
|
|
214
|
-
if (updatePromises.length === 0) {
|
|
215
|
-
console.log(`[DEBUG] No updates needed, returning early`);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
console.log(`[DEBUG] Executing ${updatePromises.length} update(s) in parallel...`);
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
const results = await Promise.all(updatePromises);
|
|
223
|
-
console.log(`[DEBUG] All updates completed successfully`);
|
|
224
|
-
console.log(`[DEBUG] Results:`, JSON.stringify(results, null, 2));
|
|
225
|
-
console.log(`[DEBUG] ========================================`);
|
|
226
|
-
} catch (error) {
|
|
227
|
-
console.error(`[DEBUG] ❌ Error in Promise.all:`, error);
|
|
228
|
-
console.error(`[DEBUG] Error details:`, JSON.stringify(error, null, 2));
|
|
229
|
-
throw error;
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
module.exports = {
|
|
234
|
-
updateMemberContactInfo,
|
|
235
|
-
updateContactEmail, // Export for individual testing
|
|
236
|
-
updateContactNames, // Export for individual testing
|
|
237
|
-
};
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
const { contacts } = require('@wix/crm');
|
|
2
|
-
const { auth } = require('@wix/essentials');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* TEST FILE - Multiple approaches to debug contact email updates
|
|
6
|
-
*
|
|
7
|
-
* This file contains different implementations to test and compare
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// ============================================================================
|
|
11
|
-
// APPROACH 1: Current implementation (from npm package)
|
|
12
|
-
// ============================================================================
|
|
13
|
-
const elevatedGetContact_v1 = auth.elevate(contacts.getContact);
|
|
14
|
-
const elevatedUpdateContact_v1 = auth.elevate(contacts.updateContact);
|
|
15
|
-
|
|
16
|
-
async function updateContactEmail_v1(contactId, newEmail) {
|
|
17
|
-
console.log(`[TEST V1] Starting - contactId: ${contactId}, email: ${newEmail}`);
|
|
18
|
-
|
|
19
|
-
const contact = await elevatedGetContact_v1(contactId);
|
|
20
|
-
console.log(`[TEST V1] Fetched contact:`, contact);
|
|
21
|
-
|
|
22
|
-
const updatedInfo = {
|
|
23
|
-
...contact.info,
|
|
24
|
-
emails: {
|
|
25
|
-
items: [{ email: newEmail, primary: true }],
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
console.log(`[TEST V1] Calling updateContact with:`, {
|
|
29
|
-
contactId,
|
|
30
|
-
payload: { info: updatedInfo },
|
|
31
|
-
revision: contact.revision,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const result = await elevatedUpdateContact_v1(contactId, { info: updatedInfo }, contact.revision);
|
|
35
|
-
console.log(`[TEST V1] Result:`, result);
|
|
36
|
-
return result;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// ============================================================================
|
|
40
|
-
// APPROACH 2: Old working implementation style
|
|
41
|
-
// ============================================================================
|
|
42
|
-
async function updateContactEmail_v2(contactId, newEmail) {
|
|
43
|
-
console.log(`[TEST V2] Starting - contactId: ${contactId}, email: ${newEmail}`);
|
|
44
|
-
|
|
45
|
-
// Create elevated functions inside the function (like old code)
|
|
46
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
47
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
48
|
-
|
|
49
|
-
const contact = await elevatedGetContact(contactId);
|
|
50
|
-
console.log(`[TEST V2] Fetched contact:`, contact);
|
|
51
|
-
|
|
52
|
-
const updatedInfo = {
|
|
53
|
-
...contact.info,
|
|
54
|
-
emails: {
|
|
55
|
-
items: [{ email: newEmail, primary: true }],
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
console.log(`[TEST V2] Calling updateContact with updatedInfo directly (old style):`, {
|
|
59
|
-
contactId,
|
|
60
|
-
payload: updatedInfo,
|
|
61
|
-
revision: contact.revision,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Try passing updatedInfo directly (old style)
|
|
65
|
-
const result = await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
|
|
66
|
-
console.log(`[TEST V2] Result:`, result);
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ============================================================================
|
|
71
|
-
// APPROACH 3: Minimal update (only changed fields)
|
|
72
|
-
// ============================================================================
|
|
73
|
-
async function updateContactEmail_v3(contactId, newEmail) {
|
|
74
|
-
console.log(`[TEST V3] Starting - contactId: ${contactId}, email: ${newEmail}`);
|
|
75
|
-
|
|
76
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
77
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
78
|
-
|
|
79
|
-
const contact = await elevatedGetContact(contactId);
|
|
80
|
-
console.log(`[TEST V3] Fetched contact:`, contact);
|
|
81
|
-
|
|
82
|
-
// Only send the fields being updated (minimal approach)
|
|
83
|
-
const updatePayload = {
|
|
84
|
-
info: {
|
|
85
|
-
emails: {
|
|
86
|
-
items: [{ email: newEmail, primary: true }],
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
console.log(`[TEST V3] Calling updateContact with minimal payload:`, {
|
|
91
|
-
contactId,
|
|
92
|
-
payload: updatePayload,
|
|
93
|
-
revision: contact.revision,
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const result = await elevatedUpdateContact(contactId, updatePayload, contact.revision);
|
|
97
|
-
console.log(`[TEST V3] Result:`, result);
|
|
98
|
-
return result;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// ============================================================================
|
|
102
|
-
// APPROACH 4: Using revision in options object
|
|
103
|
-
// ============================================================================
|
|
104
|
-
async function updateContactEmail_v4(contactId, newEmail) {
|
|
105
|
-
console.log(`[TEST V4] Starting - contactId: ${contactId}, email: ${newEmail}`);
|
|
106
|
-
|
|
107
|
-
const elevatedGetContact = auth.elevate(contacts.getContact);
|
|
108
|
-
const elevatedUpdateContact = auth.elevate(contacts.updateContact);
|
|
109
|
-
|
|
110
|
-
const contact = await elevatedGetContact(contactId);
|
|
111
|
-
console.log(`[TEST V4] Fetched contact:`, contact);
|
|
112
|
-
|
|
113
|
-
const updatedInfo = {
|
|
114
|
-
...contact.info,
|
|
115
|
-
emails: {
|
|
116
|
-
items: [{ email: newEmail, primary: true }],
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
console.log(`[TEST V4] Calling updateContact with revision in options:`, {
|
|
120
|
-
contactId,
|
|
121
|
-
payload: { info: updatedInfo },
|
|
122
|
-
options: { revision: contact.revision },
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// Try passing revision as part of an options object
|
|
126
|
-
const result = await elevatedUpdateContact(
|
|
127
|
-
contactId,
|
|
128
|
-
{ info: updatedInfo },
|
|
129
|
-
{ revision: contact.revision }
|
|
130
|
-
);
|
|
131
|
-
console.log(`[TEST V4] Result:`, result);
|
|
132
|
-
return result;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// ============================================================================
|
|
136
|
-
// APPROACH 5: Check if elevation is working at all
|
|
137
|
-
// ============================================================================
|
|
138
|
-
async function testElevation(contactId) {
|
|
139
|
-
console.log(`[TEST ELEVATION] Testing if elevation works at all...`);
|
|
140
|
-
console.log(`[TEST ELEVATION] contactId:`, contactId);
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
// Test 1: Non-elevated getContact (should fail if user doesn't have permission)
|
|
144
|
-
console.log(`[TEST ELEVATION] Test 1: Non-elevated getContact`);
|
|
145
|
-
try {
|
|
146
|
-
const nonElevatedResult = await contacts.getContact(contactId);
|
|
147
|
-
console.log(
|
|
148
|
-
`[TEST ELEVATION] ❓ Non-elevated getContact succeeded (unexpected?):`,
|
|
149
|
-
nonElevatedResult
|
|
150
|
-
);
|
|
151
|
-
} catch (error) {
|
|
152
|
-
console.log(`[TEST ELEVATION] ✓ Non-elevated getContact failed as expected:`, error.message);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Test 2: Elevated getContact (should succeed)
|
|
156
|
-
console.log(`[TEST ELEVATION] Test 2: Elevated getContact (module-level)`);
|
|
157
|
-
const elevatedResult = await elevatedGetContact_v1(contactId);
|
|
158
|
-
console.log(`[TEST ELEVATION] ✓ Elevated getContact succeeded:`, elevatedResult);
|
|
159
|
-
|
|
160
|
-
// Test 3: Elevated getContact (function-level)
|
|
161
|
-
console.log(`[TEST ELEVATION] Test 3: Elevated getContact (function-level)`);
|
|
162
|
-
const elevatedGetContactLocal = auth.elevate(contacts.getContact);
|
|
163
|
-
const elevatedResultLocal = await elevatedGetContactLocal(contactId);
|
|
164
|
-
console.log(`[TEST ELEVATION] ✓ Elevated getContact (local) succeeded:`, elevatedResultLocal);
|
|
165
|
-
|
|
166
|
-
return { success: true };
|
|
167
|
-
} catch (error) {
|
|
168
|
-
console.error(`[TEST ELEVATION] ❌ Error during elevation test:`, error);
|
|
169
|
-
return { success: false, error };
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// ============================================================================
|
|
174
|
-
// Test runner
|
|
175
|
-
// ============================================================================
|
|
176
|
-
async function runAllTests(contactId, newEmail) {
|
|
177
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
178
|
-
console.log(`STARTING CONTACT EMAIL UPDATE TESTS`);
|
|
179
|
-
console.log(`Contact ID: ${contactId}`);
|
|
180
|
-
console.log(`New Email: ${newEmail}`);
|
|
181
|
-
console.log(`${'='.repeat(80)}\n`);
|
|
182
|
-
|
|
183
|
-
const results = {
|
|
184
|
-
elevation: null,
|
|
185
|
-
v1: null,
|
|
186
|
-
v2: null,
|
|
187
|
-
v3: null,
|
|
188
|
-
v4: null,
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
// Test elevation first
|
|
192
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
193
|
-
console.log(`TEST: Elevation Check`);
|
|
194
|
-
console.log(`${'='.repeat(80)}`);
|
|
195
|
-
try {
|
|
196
|
-
results.elevation = await testElevation(contactId);
|
|
197
|
-
console.log(`✓ Elevation test completed`);
|
|
198
|
-
} catch (error) {
|
|
199
|
-
console.error(`✗ Elevation test failed:`, error);
|
|
200
|
-
results.elevation = { success: false, error: error.message };
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Only run update tests if elevation works
|
|
204
|
-
if (results.elevation?.success) {
|
|
205
|
-
// Test V1: Current implementation
|
|
206
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
207
|
-
console.log(`TEST V1: Current Implementation (wrapped in { info: })`);
|
|
208
|
-
console.log(`${'='.repeat(80)}`);
|
|
209
|
-
try {
|
|
210
|
-
results.v1 = await updateContactEmail_v1(contactId, newEmail);
|
|
211
|
-
console.log(`✓ V1 completed successfully`);
|
|
212
|
-
} catch (error) {
|
|
213
|
-
console.error(`✗ V1 failed:`, error);
|
|
214
|
-
results.v1 = { error: error.message };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Test V2: Old style
|
|
218
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
219
|
-
console.log(`TEST V2: Old Style (direct info object)`);
|
|
220
|
-
console.log(`${'='.repeat(80)}`);
|
|
221
|
-
try {
|
|
222
|
-
results.v2 = await updateContactEmail_v2(contactId, newEmail);
|
|
223
|
-
console.log(`✓ V2 completed successfully`);
|
|
224
|
-
} catch (error) {
|
|
225
|
-
console.error(`✗ V2 failed:`, error);
|
|
226
|
-
results.v2 = { error: error.message };
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Test V3: Minimal payload
|
|
230
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
231
|
-
console.log(`TEST V3: Minimal Payload`);
|
|
232
|
-
console.log(`${'='.repeat(80)}`);
|
|
233
|
-
try {
|
|
234
|
-
results.v3 = await updateContactEmail_v3(contactId, newEmail);
|
|
235
|
-
console.log(`✓ V3 completed successfully`);
|
|
236
|
-
} catch (error) {
|
|
237
|
-
console.error(`✗ V3 failed:`, error);
|
|
238
|
-
results.v3 = { error: error.message };
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Test V4: Revision in options
|
|
242
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
243
|
-
console.log(`TEST V4: Revision in Options Object`);
|
|
244
|
-
console.log(`${'='.repeat(80)}`);
|
|
245
|
-
try {
|
|
246
|
-
results.v4 = await updateContactEmail_v4(contactId, newEmail);
|
|
247
|
-
console.log(`✓ V4 completed successfully`);
|
|
248
|
-
} catch (error) {
|
|
249
|
-
console.error(`✗ V4 failed:`, error);
|
|
250
|
-
results.v4 = { error: error.message };
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Summary
|
|
255
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
256
|
-
console.log(`TEST RESULTS SUMMARY`);
|
|
257
|
-
console.log(`${'='.repeat(80)}`);
|
|
258
|
-
console.log(JSON.stringify(results, null, 2));
|
|
259
|
-
console.log(`${'='.repeat(80)}\n`);
|
|
260
|
-
|
|
261
|
-
return results;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
module.exports = {
|
|
265
|
-
updateContactEmail_v1,
|
|
266
|
-
updateContactEmail_v2,
|
|
267
|
-
updateContactEmail_v3,
|
|
268
|
-
updateContactEmail_v4,
|
|
269
|
-
testElevation,
|
|
270
|
-
runAllTests,
|
|
271
|
-
};
|
package/backend/test-methods.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DEBUG WEB METHOD
|
|
3
|
-
*
|
|
4
|
-
* Instructions for use:
|
|
5
|
-
*
|
|
6
|
-
* 1. Import this in your host site's web-methods.web.js:
|
|
7
|
-
* import { runContactUpdateTests, testContactElevation } from 'abmp-npm/backend/test-methods';
|
|
8
|
-
* import { Permissions, webMethod } from 'wix-web-module';
|
|
9
|
-
*
|
|
10
|
-
* export const runContactUpdateTests = webMethod(Permissions.SiteMember, _runContactUpdateTests);
|
|
11
|
-
* export const testContactElevation = webMethod(Permissions.SiteMember, _testContactElevation);
|
|
12
|
-
*
|
|
13
|
-
* 2. Call from frontend console or page code:
|
|
14
|
-
* import { runContactUpdateTests } from 'backend/web-methods.web';
|
|
15
|
-
*
|
|
16
|
-
* // Get your contactId from your member data
|
|
17
|
-
* const results = await runContactUpdateTests('YOUR_CONTACT_ID', 'newemail@test.com');
|
|
18
|
-
* console.log('Test results:', results);
|
|
19
|
-
*
|
|
20
|
-
* 3. Check the Wix logs (Site Monitoring) for detailed output
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
const { updateMemberContactInfo } = require('./contacts-methods-DEBUG');
|
|
24
|
-
const { runAllTests, testElevation } = require('./contacts-methods-TEST');
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Run all contact update test variations
|
|
28
|
-
*/
|
|
29
|
-
async function runContactUpdateTests(contactId, newEmail) {
|
|
30
|
-
console.log(`[TEST RUNNER] Starting tests for contactId: ${contactId}, email: ${newEmail}`);
|
|
31
|
-
|
|
32
|
-
if (!contactId) {
|
|
33
|
-
throw new Error('contactId is required');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (!newEmail) {
|
|
37
|
-
throw new Error('newEmail is required');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const results = await runAllTests(contactId, newEmail);
|
|
42
|
-
return {
|
|
43
|
-
success: true,
|
|
44
|
-
message: 'Tests completed - check logs for details',
|
|
45
|
-
results,
|
|
46
|
-
};
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.error(`[TEST RUNNER] Error:`, error);
|
|
49
|
-
return {
|
|
50
|
-
success: false,
|
|
51
|
-
error: error.message,
|
|
52
|
-
stack: error.stack,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Test if elevation is working correctly
|
|
59
|
-
*/
|
|
60
|
-
async function testContactElevation(contactId) {
|
|
61
|
-
console.log(`[TEST RUNNER] Testing elevation for contactId: ${contactId}`);
|
|
62
|
-
|
|
63
|
-
if (!contactId) {
|
|
64
|
-
throw new Error('contactId is required');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
const results = await testElevation(contactId);
|
|
69
|
-
return {
|
|
70
|
-
success: true,
|
|
71
|
-
message: 'Elevation test completed - check logs for details',
|
|
72
|
-
results,
|
|
73
|
-
};
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error(`[TEST RUNNER] Error:`, error);
|
|
76
|
-
return {
|
|
77
|
-
success: false,
|
|
78
|
-
error: error.message,
|
|
79
|
-
stack: error.stack,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Test the debug version of updateMemberContactInfo
|
|
86
|
-
*/
|
|
87
|
-
async function testUpdateMemberContactInfo(data, existingMemberData) {
|
|
88
|
-
console.log(`[TEST RUNNER] Testing updateMemberContactInfo with DEBUG logging`);
|
|
89
|
-
|
|
90
|
-
if (!data) {
|
|
91
|
-
throw new Error('data is required');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!existingMemberData) {
|
|
95
|
-
throw new Error('existingMemberData is required');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
await updateMemberContactInfo(data, existingMemberData);
|
|
100
|
-
return {
|
|
101
|
-
success: true,
|
|
102
|
-
message: 'updateMemberContactInfo completed - check logs for details',
|
|
103
|
-
};
|
|
104
|
-
} catch (error) {
|
|
105
|
-
console.error(`[TEST RUNNER] Error:`, error);
|
|
106
|
-
return {
|
|
107
|
-
success: false,
|
|
108
|
-
error: error.message,
|
|
109
|
-
stack: error.stack,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
module.exports = {
|
|
115
|
-
runContactUpdateTests,
|
|
116
|
-
testContactElevation,
|
|
117
|
-
testUpdateMemberContactInfo,
|
|
118
|
-
};
|