|
|
@@ -2,9 +2,14 @@ const Schmervice = require('@hapipal/schmervice')
|
|
2
|
2
|
const haversine = require('haversine')
|
|
3
|
3
|
const config = require('../../db/data-generator/config.json')
|
|
4
|
4
|
|
|
5
|
|
-// Keys that are profile data responses
|
|
6
|
|
-const _TEMP_RES_KEYS = [1, 2, 3, 4, 5, 6]
|
|
7
|
|
-const _ZIPCODEKEY = 7
|
|
|
5
|
+const _isScorableResponse = res_key_id => {
|
|
|
6
|
+ let isScorable = false
|
|
|
7
|
+ if(config.resKeys.includes(res_key_id)) {
|
|
|
8
|
+ isScorable = true
|
|
|
9
|
+ }
|
|
|
10
|
+ return isScorable
|
|
|
11
|
+}
|
|
|
12
|
+
|
|
8
|
13
|
const scoreResponses = (seeker, potentialMatch, prescoreLookup) => {
|
|
9
|
14
|
if (seeker.responses.length != potentialMatch.responses.length)
|
|
10
|
15
|
return {
|
|
|
@@ -12,10 +17,10 @@ const scoreResponses = (seeker, potentialMatch, prescoreLookup) => {
|
|
12
|
17
|
}
|
|
13
|
18
|
|
|
14
|
19
|
const aRes = seeker.responses.filter(
|
|
15
|
|
- res => _TEMP_RES_KEYS.includes(res.response_key_id)
|
|
|
20
|
+ res => _isScorableResponse(res.response_key_id)
|
|
16
|
21
|
)
|
|
17
|
22
|
const bRes = potentialMatch.responses.filter(
|
|
18
|
|
- res => _TEMP_RES_KEYS.includes(res.response_key_id)
|
|
|
23
|
+ res => _isScorableResponse(res.response_key_id)
|
|
19
|
24
|
)
|
|
20
|
25
|
|
|
21
|
26
|
const composite = []
|
|
|
@@ -56,15 +61,9 @@ const scoreAll = (profileList, userProfile, prescoreLookup) => {
|
|
56
|
61
|
*/
|
|
57
|
62
|
const getZipCodeFromProfile = profile => {
|
|
58
|
63
|
// There should only be one zip code entry per profile
|
|
59
|
|
- let zipRes = profile.responses.filter(
|
|
60
|
|
- // Whatever the zipcode questions is
|
|
61
|
|
- response => response.response_key_id == _ZIPCODEKEY,
|
|
62
|
|
- )[0]
|
|
63
|
|
-
|
|
64
|
|
- const responseIndexForZip = profile.responses.indexOf(zipRes)
|
|
65
|
|
- if (responseIndexForZip >= 0) {
|
|
66
|
|
- profile.responses.splice(responseIndexForZip, 1)
|
|
67
|
|
- }
|
|
|
64
|
+ let zipRes = profile.responses.find(
|
|
|
65
|
+ res => res.response_key_id == 7
|
|
|
66
|
+ )
|
|
68
|
67
|
return zipRes.val
|
|
69
|
68
|
}
|
|
70
|
69
|
|
|
|
@@ -106,21 +105,18 @@ class CompleteProfile {
|
|
106
|
105
|
this.profile_languages = []
|
|
107
|
106
|
this.profile_prefs = {}
|
|
108
|
107
|
if (profile?.responses?.length) {
|
|
109
|
|
- this.responses = profile.responses.filter(
|
|
110
|
|
- res => !_TEMP_RES_KEYS.includes(res.response_key_id),
|
|
111
|
|
- ) // [] of all responses
|
|
112
|
|
- const [image, language, duration, location, description] =
|
|
113
|
|
- profile.responses.filter(res =>
|
|
114
|
|
- _TEMP_RES_KEYS.includes(res.response_key_id),
|
|
115
|
|
- )
|
|
116
|
|
- this.profile_prefs.location = location.val
|
|
117
|
|
- this.profile_prefs.duration = duration.val
|
|
118
|
|
- this.profile_prefs.zip = profile.responses.filter(
|
|
119
|
|
- res => res.response_key_id == 7,
|
|
120
|
|
- )[0].val // [] of all responses
|
|
121
|
|
- this.profile_description = description.val
|
|
122
|
|
- this.profile_media.push(image.val)
|
|
123
|
|
- this.profile_languages.push(language.val)
|
|
|
108
|
+ // [] of all "profile" responses
|
|
|
109
|
+ this.responses = profile.responses
|
|
|
110
|
+ // image, language, duration, presence, blurb, urgency, role, pronouns, distance
|
|
|
111
|
+ const prefs = ['presence', 'duration', 'zipcode']
|
|
|
112
|
+ prefs.forEach(pref => {
|
|
|
113
|
+ this.profile_prefs[pref] = this.responses.filter(
|
|
|
114
|
+ r => r.response_key_prompt === pref
|
|
|
115
|
+ )[0]
|
|
|
116
|
+ })
|
|
|
117
|
+ this.profile_description = this.responses.filter(r=> r.response_key_prompt === 'blurb')[0]
|
|
|
118
|
+ this.profile_media = this.responses.filter(r => r.response_key_prompt === 'image')
|
|
|
119
|
+ this.profile_languages = this.responses.filter(r => r.response_key_prompt === 'language')
|
|
124
|
120
|
}
|
|
125
|
121
|
}
|
|
126
|
122
|
}
|
|
|
@@ -261,10 +257,24 @@ module.exports = class ProfileService extends Schmervice.Service {
|
|
261
|
257
|
user_id: userId,
|
|
262
|
258
|
})
|
|
263
|
259
|
for (const responseToSave of responses) {
|
|
|
260
|
+ /**
|
|
|
261
|
+ * Convert indexes to actual score values
|
|
|
262
|
+ * Using using the input and converting to index
|
|
|
263
|
+ * of the generated possible prescore array in config
|
|
|
264
|
+ * DUPLICATE:See saveResponseForProfile() line 343
|
|
|
265
|
+ */
|
|
|
266
|
+ let convertedResponse = responseToSave
|
|
|
267
|
+ if(_isScorableResponse(responseToSave.response_key_id)) {
|
|
|
268
|
+ // Convert -3 to 0, 0 to 3, 3 to 6
|
|
|
269
|
+ const offset = (config.scoreVals.length - 1) / 2
|
|
|
270
|
+ const indexFromInput = parseInt(responseToSave.val) + offset
|
|
|
271
|
+ convertedResponse.val = config.scoreVals[indexFromInput].toString()
|
|
|
272
|
+ }
|
|
|
273
|
+
|
|
264
|
274
|
const responseInfo = {
|
|
265
|
275
|
profile_id: profile.id,
|
|
266
|
|
- response_key_id: responseToSave.response_key_id,
|
|
267
|
|
- val: responseToSave.val,
|
|
|
276
|
+ response_key_id: convertedResponse.response_key_id,
|
|
|
277
|
+ val: convertedResponse.val,
|
|
268
|
278
|
}
|
|
269
|
279
|
await Response.query(txn).insert(responseInfo)
|
|
270
|
280
|
}
|
|
|
@@ -332,11 +342,11 @@ module.exports = class ProfileService extends Schmervice.Service {
|
|
332
|
342
|
* of the generated possible prescore array in config
|
|
333
|
343
|
*/
|
|
334
|
344
|
let convertedResponse = responseToSave
|
|
335
|
|
- if(_TEMP_RES_KEYS.includes(responseToSave.response_key_id)) {
|
|
|
345
|
+ if(_isScorableResponse(responseToSave.response_key_id)) {
|
|
336
|
346
|
// Convert -3 to 0, 0 to 3, 3 to 6
|
|
337
|
347
|
const offset = (config.scoreVals.length - 1) / 2
|
|
338
|
348
|
const indexFromInput = parseInt(responseToSave.val) + offset
|
|
339
|
|
- convertedResponse.val = config.scoreVals[indexFromInput]
|
|
|
349
|
+ convertedResponse.val = config.scoreVals[indexFromInput].toString()
|
|
340
|
350
|
}
|
|
341
|
351
|
|
|
342
|
352
|
await Response.query().insert(convertedResponse)
|
|
|
@@ -375,7 +385,7 @@ module.exports = class ProfileService extends Schmervice.Service {
|
|
375
|
385
|
.findOne('profile_id', profileId)
|
|
376
|
386
|
.withGraphFetched('responses')
|
|
377
|
387
|
.withGraphFetched('user')
|
|
378
|
|
-
|
|
|
388
|
+
|
|
379
|
389
|
// Move unneeded responses
|
|
380
|
390
|
const userZip = getZipCodeFromProfile(userProfile)
|
|
381
|
391
|
|
|
|
@@ -387,18 +397,13 @@ module.exports = class ProfileService extends Schmervice.Service {
|
|
387
|
397
|
|
|
388
|
398
|
// TODO: Let Objection optimize this
|
|
389
|
399
|
const isPosterOpposite = userProfile.user.is_poster == 1 ? 0 : 1
|
|
390
|
|
- profileIdsOfOppositeType = profileIdsOfOppositeType.filter(
|
|
391
|
|
- profile => profile.user.is_poster == isPosterOpposite,
|
|
392
|
|
- )
|
|
393
|
|
-
|
|
394
|
|
- // Only include profiles that included zipcode response
|
|
395
|
400
|
profileIdsOfOppositeType = profileIdsOfOppositeType.filter(profile => {
|
|
396
|
|
- const zipcodeResponses = profile.responses.filter(
|
|
397
|
|
- res => res.response_key_id == _ZIPCODEKEY,
|
|
398
|
|
- )
|
|
399
|
|
- return zipcodeResponses.length > 0
|
|
|
401
|
+ return profile.user.is_poster == isPosterOpposite
|
|
|
402
|
+ }).filter(profile => {
|
|
|
403
|
+ // Only include profiles that included zipcode response
|
|
|
404
|
+ return getZipCodeFromProfile(profile) ? true : false
|
|
400
|
405
|
})
|
|
401
|
|
-
|
|
|
406
|
+
|
|
402
|
407
|
const profilePlusDistance = await Promise.all(
|
|
403
|
408
|
profileIdsOfOppositeType.map(async profile => {
|
|
404
|
409
|
const targetZip = getZipCodeFromProfile(profile)
|
|
|
@@ -417,12 +422,10 @@ module.exports = class ProfileService extends Schmervice.Service {
|
|
417
|
422
|
}
|
|
418
|
423
|
}),
|
|
419
|
424
|
)
|
|
420
|
|
-
|
|
421
|
425
|
const distanceFilteredProfiles = filterByDistance(
|
|
422
|
426
|
profilePlusDistance,
|
|
423
|
427
|
maxDistance,
|
|
424
|
428
|
)
|
|
425
|
|
-
|
|
426
|
429
|
const scoredProfilesWithDistance = scoreAll(
|
|
427
|
430
|
distanceFilteredProfiles,
|
|
428
|
431
|
userProfile,
|