Ver código fonte

:construction: Continued filtering logic for initial survey answers

tags/0.0.4
tomit4 2 anos atrás
pai
commit
1ff7fe78d2

+ 1
- 53
backend/db/data-generator/mock.js Ver arquivo

@@ -431,7 +431,7 @@ module.exports = {
431 431
         // TODO: remove from mock data once bare bones matching logic can show poorly matched matches...
432 432
         {
433 433
             tag_association_id: 50,
434
-            profile_id: 136,
434
+            profile_id: 139,
435 435
             grouping_id: 2,
436 436
             tag_id: 7,
437 437
             is_deleted: false,
@@ -682,18 +682,6 @@ module.exports = {
682 682
             can_edit: false,
683 683
             is_active: true,
684 684
         },
685
-        // NOTE: profile_id 147 is chosen based off of GENERATED data,
686
-        // after running 'npm run generate', replace 147 in mock to next profile_id to be genearted
687
-        // i.e. last profile_id number + 1
688
-        // TODO: remove from mock data once bare bones matching logic can show poorly matched matches...
689
-        {
690
-            membership_id: 3,
691
-            profile_id: 147,
692
-            grouping_id: 2,
693
-            membership_type: 'participant',
694
-            can_edit: false,
695
-            is_active: true,
696
-        },
697 685
         {
698 686
             membership_id: 4,
699 687
             profile_id: 46,
@@ -768,45 +756,5 @@ module.exports = {
768 756
             target_id: 46,
769 757
             is_deleted: false,
770 758
         },
771
-        // NOTE: profile_id 147 is chosen based off of GENERATED data,
772
-        // after running 'npm run generate', replace 147 in mock to next profile_id to be generated
773
-        // i.e. last profile_id number + 1
774
-        // TODO: remove from mock data once bare bones matching logic can show poorly matched matches...
775
-        {
776
-            match_queue_id: 17,
777
-            profile_id: 147,
778
-            target_id: 46,
779
-            is_deleted: false,
780
-        },
781
-        {
782
-            match_queue_id: 18,
783
-            profile_id: 147,
784
-            target_id: 46,
785
-            is_deleted: false,
786
-        },
787
-        {
788
-            match_queue_id: 19,
789
-            profile_id: 147,
790
-            target_id: 44,
791
-            is_deleted: false,
792
-        },
793
-        {
794
-            match_queue_id: 20,
795
-            profile_id: 147,
796
-            target_id: 43,
797
-            is_deleted: false,
798
-        },
799
-        {
800
-            match_queue_id: 21,
801
-            profile_id: 147,
802
-            target_id: 42,
803
-            is_deleted: false,
804
-        },
805
-        {
806
-            match_queue_id: 22,
807
-            profile_id: 147,
808
-            target_id: 41,
809
-            is_deleted: false,
810
-        },
811 759
     ],
812 760
 }

+ 9
- 9
backend/db/seeds/04-responses.js Ver arquivo

@@ -12,24 +12,24 @@ for (let name of fileNames) {
12 12
         responses = [...responses, ...data.responses]
13 13
     }
14 14
 }
15
-
16 15
 /**
17 16
  * Prevent seeding responses for
18 17
  * profile ids so we can test oboarding
19 18
  */
20
-responses = dataSort(responses, 'response_id').filter(
21
-    response => !ignore.includes(response.profile_id),
22
-)
19
+// responses = dataSort(responses, 'response_id').filter(
20
+// response => !ignore.includes(response.profile_id),
21
+// )
23 22
 
24 23
 exports.seed = async knex => {
25 24
     await knex('responses').del()
26 25
     let responsesToPush = []
27
-    let len = responses.length
26
+    const len = responses.length
28 27
     for (let i = 1; i <= len; i += 1) {
29 28
         responsesToPush.push(responses.shift())
30
-        if (i % batchSize === 0 || i > responses.length) {
31
-            // await knex('responses').insert(responsesToPush)
32
-            responsesToPush = []
33
-        }
29
+        // if (i % batchSize === 0 || i > responses.length) {
30
+        // await knex('responses').insert(responsesToPush)
31
+        // responsesToPush = []
32
+        // }
34 33
     }
34
+    await knex('responses').insert(responsesToPush)
35 35
 }

+ 26
- 17
backend/lib/routes/filter/get.js Ver arquivo

@@ -1,5 +1,7 @@
1 1
 'use strict'
2 2
 
3
+// NOTE: Current Implementation does not require this route
4
+// (see Auth.vue in components/onboarding and queue route with filter.js)
3 5
 const Joi = require('joi')
4 6
 const apiSchema = require('../../schemas/api')
5 7
 const errorSchema = require('../../schemas/errors')
@@ -10,27 +12,27 @@ const pluginConfig = {
10 12
     handlerType: 'filter',
11 13
     docs: {
12 14
         description: 'Filter match pool',
13
-        notes: 'Returns filtered subset of match pool'
14
-    }
15
+        notes: 'Returns filtered subset of match pool',
16
+    },
15 17
 }
16 18
 
17 19
 const validators = {
18 20
     query: Joi.object({
19 21
         match_pool: Joi.array().items(profileSchema.single),
20 22
         distance: Joi.string(),
21
-        presence: Joi.string()
22
-    })
23
+        presence: Joi.string(),
24
+    }),
23 25
 }
24 26
 
25 27
 const responseSchemas = {
26 28
     filteredMatchPool: filterSchema.matchPool, // array of profiles
27
-    error: errorSchema.single
29
+    error: errorSchema.single,
28 30
 }
29 31
 
30 32
 module.exports = {
31 33
     method: 'GET',
32 34
     path: '/',
33
-    options:{
35
+    options: {
34 36
         ...pluginConfig.docs,
35 37
         tags: ['api'],
36 38
         auth: false,
@@ -38,28 +40,35 @@ module.exports = {
38 40
         handler: async function (request, h) {
39 41
             const { filterService } = request.server.services()
40 42
             let matchPool = request.query.match_pool
41
-            matchPool = filterService.byDistance(matchPool, request.query.distance)
42
-            matchPool = filterService.byPresence(matchPool, request.query.presence)
43
-      
43
+            matchPool = filterService.byDistance(
44
+                matchPool,
45
+                request.query.distance,
46
+            )
47
+            matchPool = filterService.byPresence(
48
+                matchPool,
49
+                request.query.presence,
50
+            )
44 51
             try {
45
-                return h.response(({
46
-                    ok:true,
47
-                    handler: pluginConfig.handlerType,
48
-                    data: matchPool
49
-                })).code(200)
52
+                return h
53
+                    .response({
54
+                        ok: true,
55
+                        handler: pluginConfig.handlerType,
56
+                        data: matchPool,
57
+                    })
58
+                    .code(200)
50 59
             } catch (err) {
51 60
                 return h
52 61
                     .response({
53 62
                         ok: false,
54 63
                         handler: pluginConfig.handlerType,
55
-                        data: {error: `${err}`}
64
+                        data: { error: `${err}` },
56 65
                     })
57 66
                     .code(409)
58 67
             }
59 68
         },
60 69
         validate: {
61 70
             ...validators,
62
-            failAction: 'log'
71
+            failAction: 'log',
63 72
         },
64 73
 
65 74
         response: {
@@ -77,4 +86,4 @@ module.exports = {
77 86
             },
78 87
         },
79 88
     },
80
-}
89
+}

+ 7
- 3
backend/lib/routes/profile/score.js Ver arquivo

@@ -53,10 +53,14 @@ module.exports = {
53 53
             const distanceUnit = request.query.unit
54 54
                 ? request.query.unit
55 55
                 : 'mile'
56
-            const duration = request.query.duration
57
-            const presence = request.query.presence
56
+            const duration = request.query.duration.includes('-')
57
+                ? request.query.duration.split('-')[0]
58
+                : request.query.duration
59
+            const presence =
60
+                request.query.presence === 'in_person'
61
+                    ? 'onsite'
62
+                    : request.query.presence
58 63
             const certifications = request.query.certifications
59
-
60 64
             const scoredProfiles = await profileService.scoreProfilesFor(
61 65
                 profileId,
62 66
                 maxDistanceMiles,

+ 32
- 16
backend/lib/services/filter.js Ver arquivo

@@ -29,24 +29,40 @@ module.exports = class FilterService extends Schmervice.Service {
29 29
         })
30 30
     }
31 31
 
32
-    byDuration(profileList, duration) {
33
-        return profileList.filter(profile => {
34
-            // TODO find duration
35
-            return profile.duration === duration
36
-        })
37
-    }
38
-
39 32
     byPresence(profileList, presence) {
40
-        return profileList.filter(profile => {
41
-            // TODO find presence
42
-            return profile.presence === presence
43
-        })
33
+        const matchingProfiles = []
34
+        for (const profile of profileList) {
35
+            for (const response of profile.responses) {
36
+                if (
37
+                    response.response_key_id === 15 &&
38
+                    response.val === presence
39
+                ) {
40
+                    matchingProfiles.push(profile)
41
+                }
42
+            }
43
+        }
44
+        return matchingProfiles
44 45
     }
45 46
 
46
-    byCertifications(profileList, certifications) {
47
-        return profileList.filter(profile => {
48
-            // TODO find certifications
49
-            return profile.certifications === certifications
50
-        })
47
+    byDuration(profileList, duration) {
48
+        const matchingProfiles = []
49
+        for (const profile of profileList) {
50
+            for (const response of profile.responses) {
51
+                if (
52
+                    response.response_key_id === 14 &&
53
+                    response.val === duration
54
+                ) {
55
+                    matchingProfiles.push(profile)
56
+                }
57
+            }
58
+        }
59
+        return matchingProfiles
51 60
     }
61
+
62
+    // TODO: Implement filtering by matching certification
63
+    // byCertifications(profileList, certifications) {
64
+    // return profileList.filter(profile => {
65
+    // return profile.certifications === certifications
66
+    // })
67
+    // }
52 68
 }

+ 24
- 13
backend/lib/services/profile/index.js Ver arquivo

@@ -4,7 +4,8 @@ const config = require('../../../db/data-generator/config.json')
4 4
 const profiler = require('./profiler')
5 5
 const scoring = require('./scorer')
6 6
 const zipcoder = require('./zipcoder')
7
-const filter = require('../filter')
7
+const Filter = require('../filter')
8
+const filter = new Filter()
8 9
 
9 10
 module.exports = class ProfileService extends Schmervice.Service {
10 11
     constructor(...args) {
@@ -251,7 +252,6 @@ module.exports = class ProfileService extends Schmervice.Service {
251 252
         certifications,
252 253
     ) {
253 254
         const { Profile } = this.server.models()
254
-
255 255
         await this._setScoreLookup()
256 256
 
257 257
         // Our User Profile to score for
@@ -275,10 +275,12 @@ module.exports = class ProfileService extends Schmervice.Service {
275 275
             distanceUnit,
276 276
             userZip,
277 277
         )
278
+
278 279
         matchPool = filter.byDistance(matchPool, maxDistance)
279 280
         matchPool = filter.byDuration(matchPool, duration)
280 281
         matchPool = filter.byPresence(matchPool, presence)
281
-        matchPool = filter.byCertifications(matchPool, certifications)
282
+        // TODO: Incorporate filtering by certifications (see filter.js)
283
+        // matchPool = filter.byCertifications(matchPool, certifications)
282 284
 
283 285
         const scoredProfilesWithDistance = scoring.scoreAll(
284 286
             matchPool,
@@ -292,12 +294,11 @@ module.exports = class ProfileService extends Schmervice.Service {
292 294
     }
293 295
 
294 296
     async calcProfileDistances(matchPool, distanceUnit, userZip) {
295
-        await Promise.all(
297
+        const returnVal = await Promise.all(
296 298
             matchPool.map(async profile => {
297 299
                 const targetZip = zipcoder.getZipCodeFromProfile(profile)
298 300
                 if (!userZip || !targetZip)
299 301
                     return { ...profile, distance: [9999, distanceUnit] }
300
-
301 302
                 const distance = await this._compareDistance(
302 303
                     userZip,
303 304
                     targetZip,
@@ -309,6 +310,7 @@ module.exports = class ProfileService extends Schmervice.Service {
309 310
                 }
310 311
             }),
311 312
         )
313
+        return returnVal
312 314
     }
313 315
 
314 316
     /**
@@ -323,11 +325,14 @@ module.exports = class ProfileService extends Schmervice.Service {
323 325
             parseInt(zipCode),
324 326
         )
325 327
         if (!zipInfo) {
326
-            console.error('zip:', zipCode)
327
-        }
328
-        return {
329
-            latitude: parseFloat(zipInfo.latitude),
330
-            longitude: parseFloat(zipInfo.longitude),
328
+            throw new Error(
329
+                `ERROR :=> no zipInfo found for zipCode: ${zipCode}`,
330
+            )
331
+        } else {
332
+            return {
333
+                latitude: parseFloat(zipInfo.latitude),
334
+                longitude: parseFloat(zipInfo.longitude),
335
+            }
331 336
         }
332 337
     }
333 338
     /**
@@ -338,7 +343,13 @@ module.exports = class ProfileService extends Schmervice.Service {
338 343
      * @param {number} distance in miles
339 344
      */
340 345
     async _compareDistance(start_zip, end_zip, distanceUnit) {
341
-        if (!start_zip || !end_zip || isNaN(start_zip) || isNaN(end_zip)) return
346
+        if (
347
+            !start_zip ||
348
+            !end_zip ||
349
+            Number.isNaN(start_zip) ||
350
+            Number.isNaN(end_zip)
351
+        )
352
+            return
342 353
         const start = await this._latLonForZip(start_zip)
343 354
         const end = await this._latLonForZip(end_zip)
344 355
         return haversine(start, end, { unit: distanceUnit })
@@ -355,8 +366,8 @@ module.exports = class ProfileService extends Schmervice.Service {
355 366
         await this._setTagLookup()
356 367
         let associations = groupingId
357 368
             ? await TagAssociation.query()
358
-                .where('grouping_id', groupingId)
359
-                .andWhere('profile_id', profileId)
369
+                  .where('grouping_id', groupingId)
370
+                  .andWhere('profile_id', profileId)
360 371
             : await TagAssociation.query().andWhere('profile_id', profileId)
361 372
         return associations
362 373
             .map(assoc => ({

+ 32
- 1
frontend/src/components/onboarding/Auth.vue Ver arquivo

@@ -8,6 +8,7 @@
8 8
 import { authenticator } from '../../services/auth.service.js'
9 9
 import { createProfileForUserId } from '../../services/profile.service'
10 10
 import { signupUser } from '../../services/user.service.js'
11
+import { scoreSurveyByProfileId } from '@/services'
11 12
 
12 13
 export default {
13 14
     name: 'Auth',
@@ -81,7 +82,37 @@ export default {
81 82
         },
82 83
         async createProfileForNewUser(userId, responses) {
83 84
             try {
84
-                await createProfileForUserId(userId, responses)
85
+                const newProfileForNewUser = await createProfileForUserId(
86
+                    userId,
87
+                    responses,
88
+                )
89
+                if (!newProfileForNewUser)
90
+                    throw Error(
91
+                        `ERROR: Unable to create newProfile for userId: ${userId}`,
92
+                    )
93
+
94
+                // NOTE: Populates matchQueue table with bare bone
95
+                // minimum filtered results of possible matches
96
+                // Based off of initial survey answers
97
+                const createdProfileId = newProfileForNewUser.profile_id
98
+                const maxDistance = this.responses
99
+                    .find(response => {
100
+                        return response.response_key_id === 19
101
+                    })
102
+                    .val.split(' ')[0]
103
+                const presence = this.responses.find(response => {
104
+                    return response.response_key_id === 15
105
+                }).val
106
+
107
+                // NOTE: duration hard coded for now as bare bones
108
+                // survey doesn't have duration as one of its steps...
109
+                const duration = 'full-time'
110
+                await scoreSurveyByProfileId(
111
+                    createdProfileId,
112
+                    maxDistance,
113
+                    duration,
114
+                    presence,
115
+                )
85 116
             } catch (err) {
86 117
                 throw new Error(err)
87 118
             }

+ 0
- 3
frontend/src/services/auth.service.js Ver arquivo

@@ -1,9 +1,6 @@
1 1
 import { db } from '../utils/db.js'
2 2
 
3 3
 class Authenticator {
4
-    constructor() {
5
-        this.currentUser = null
6
-    }
7 4
     async sendEmail(answered) {
8 5
         return await db.post('/user/send-email/', answered)
9 6
     }

+ 7
- 1
frontend/src/views/SurveyCompleteView.vue Ver arquivo

@@ -109,7 +109,10 @@ export default {
109 109
         },
110 110
         // changeAnswers() {},
111 111
     },
112
-    /*
112
+    /* 
113
+    NOTE: Incomplete logic for adjusting matchQueue results based 
114
+    off of further completion of survey, commented out for now as 
115
+    to not overwrite methods
113 116
     methods: {
114 117
         changeAnswers(){
115 118
             console.log('change answers')
@@ -131,7 +134,10 @@ export default {
131 134
                 survey,
132 135
             )
133 136
             if (!userProfile) return
137
+<<<<<<< HEAD
134 138
 
139
+=======
140
+>>>>>>> 9966fff (:construction: Continued filtering logic for initial survey answers)
135 141
             this._setLoginForProfile(userProfile)
136 142
 
137 143
             this.$router.push({ name: 'HomeView' })

Carregando…
Cancelar
Salvar