Parcourir la source

:recycle: moving profile creation and list to the user route | custom validation for http errors based on status code

tags/0.0.1
j il y a 4 ans
Parent
révision
d298d334ff

+ 0
- 4
backend/lib/plugins/profile.js Voir le fichier

6
 
6
 
7
 const ProfileService = require('../services/profile')
7
 const ProfileService = require('../services/profile')
8
 
8
 
9
-const ProfileProfilesRoute = require('../routes/profile/profiles')
10
 const ProfileScoreRoute = require('../routes/profile/score')
9
 const ProfileScoreRoute = require('../routes/profile/score')
11
-const ProfileCreateRoute = require('../routes/profile/create')
12
 const ProfileUpdateRoute = require('../routes/profile/update')
10
 const ProfileUpdateRoute = require('../routes/profile/update')
13
 
11
 
14
 module.exports = {
12
 module.exports = {
27
         await server.register(Schmervice)
25
         await server.register(Schmervice)
28
         server.registerService(ProfileService)
26
         server.registerService(ProfileService)
29
 
27
 
30
-        await server.route(ProfileProfilesRoute)
31
         await server.route(ProfileScoreRoute)
28
         await server.route(ProfileScoreRoute)
32
-        await server.route(ProfileCreateRoute)
33
         await server.route(ProfileUpdateRoute)
29
         await server.route(ProfileUpdateRoute)
34
     },
30
     },
35
 }
31
 }

+ 4
- 1
backend/lib/plugins/user.js Voir le fichier

7
 const UserModel = require('../models/user')
7
 const UserModel = require('../models/user')
8
 
8
 
9
 const UserCurrentRoute = require('../routes/user/current')
9
 const UserCurrentRoute = require('../routes/user/current')
10
+const UserProfileCreateRoute = require('../routes/user/create-profile')
11
+const UserProfilesListRoute = require('../routes/user/list-profiles')
10
 const UserLoginRoute = require('../routes/user/login')
12
 const UserLoginRoute = require('../routes/user/login')
11
 
13
 
12
-const MembershipService = require('../services/membership')
13
 const UserService = require('../services/user')
14
 const UserService = require('../services/user')
14
 const DisplayService = require('../services/display')
15
 const DisplayService = require('../services/display')
15
 
16
 
39
 
40
 
40
         await server.route(UserCurrentRoute)
41
         await server.route(UserCurrentRoute)
41
         await server.route(UserLoginRoute)
42
         await server.route(UserLoginRoute)
43
+        await server.route(UserProfileCreateRoute)
44
+        await server.route(UserProfilesListRoute)
42
     },
45
     },
43
 }
46
 }

+ 0
- 88
backend/lib/routes/profile/create.js Voir le fichier

1
-'use strict'
2
-
3
-const Joi = require('joi')
4
-
5
-const pluginConfig = {
6
-    handlerType: 'profile',
7
-    docs: {
8
-        description: 'Create profile',
9
-        notes: 'Create a profile associated with this user',
10
-    },
11
-}
12
-
13
-const validators = {
14
-    /** Validate the header (cookie check) */
15
-    // headers: true,
16
-
17
-    /** Validate the route params (/active/{thing}) */
18
-    params: Joi.object({ user_id: Joi.number() }),
19
-
20
-    /** Validate the route query (/active/{thing}?limit=10&offset=10) */
21
-    // query: true,
22
-    /** Validate the incoming payload (POST method) */
23
-    payload: Joi.array().items(
24
-        Joi.object({
25
-            response_key_id: Joi.number().required(),
26
-            val: Joi.string().required(),
27
-        }),
28
-    ),
29
-}
30
-
31
-const responseSchemas = {
32
-    response: Joi.object({
33
-        profile_id: Joi.number(),
34
-        user_id: Joi.number(),
35
-    }),
36
-}
37
-
38
-module.exports = {
39
-    method: 'POST',
40
-    path: '/{user_id}/create',
41
-    options: {
42
-        ...pluginConfig.docs,
43
-        tags: ['api'],
44
-        /** Protect this route with authentication? */
45
-        auth: false,
46
-
47
-        handler: async function (request) {
48
-            const { profileService } = request.services()
49
-            const userId = request.params.user_id
50
-
51
-            /** Grab payload info */
52
-            const res = request.payload
53
-
54
-            const profile = await profileService.saveResponsesCreateProfileFor(
55
-                userId,
56
-                res,
57
-            )
58
-            try {
59
-                return {
60
-                    ok: true,
61
-                    handler: pluginConfig.handlerType,
62
-                    data: profile,
63
-                }
64
-            } catch (err) {
65
-                return {
66
-                    ok: false,
67
-                    handler: pluginConfig.handlerType,
68
-                    data: { error: `${err}` },
69
-                }
70
-            }
71
-        },
72
-
73
-        /** Validate based on validators object */
74
-        validate: {
75
-            ...validators,
76
-            failAction: 'log',
77
-        },
78
-
79
-        /** Validate the server response */
80
-        response: {
81
-            schema: Joi.object({
82
-                ok: Joi.bool(),
83
-                handler: Joi.string(),
84
-                data: responseSchemas.response,
85
-            }),
86
-        },
87
-    },
88
-}

+ 5
- 4
backend/lib/routes/profile/score.js Voir le fichier

16
 
16
 
17
     /** Validate the route params (/active/{thing}) */
17
     /** Validate the route params (/active/{thing}) */
18
     params: Joi.object({
18
     params: Joi.object({
19
-        user_id: Joi.number(),
19
+        profile_id: Joi.number(),
20
     }),
20
     }),
21
 
21
 
22
     /** Validate the route query (/active/{thing}?limit=10&offset=10) */
22
     /** Validate the route query (/active/{thing}?limit=10&offset=10) */
29
 
29
 
30
 module.exports = {
30
 module.exports = {
31
     method: 'GET',
31
     method: 'GET',
32
-    path: '/score/{user_id}',
32
+    path: '/{profile_id}/score',
33
     options: {
33
     options: {
34
         ...pluginConfig.docs,
34
         ...pluginConfig.docs,
35
         tags: ['api'],
35
         tags: ['api'],
38
 
38
 
39
         handler: async function (request, h) {
39
         handler: async function (request, h) {
40
             const { profileService } = request.services()
40
             const { profileService } = request.services()
41
-            const userId = request.params.user_id
42
-            const profiles = await profileService.scoreProfilesFor(userId)
41
+            const profileId = request.params.profile_id
42
+            const profiles = await profileService.scoreProfilesFor(profileId)
43
+
43
             try {
44
             try {
44
                 return {
45
                 return {
45
                     ok: true,
46
                     ok: true,

+ 114
- 0
backend/lib/routes/user/create-profile.js Voir le fichier

1
+'use strict'
2
+
3
+const Joi = require('joi')
4
+
5
+const pluginConfig = {
6
+    handlerType: 'user',
7
+    docs: {
8
+        description: 'Create profile for user',
9
+        notes: 'Create a profile associated with this user',
10
+    },
11
+}
12
+
13
+const validators = {
14
+    /** Validate the header (cookie check) */
15
+    // headers: true,
16
+
17
+    /** Validate the route params (/active/{thing}) */
18
+    params: Joi.object({ user_id: Joi.number() }),
19
+
20
+    /** Validate the route query (/active/{thing}?limit=10&offset=10) */
21
+    // query: true,
22
+    /** Validate the incoming payload (POST method) */
23
+    payload: Joi.array().items(
24
+        Joi.object({
25
+            response_key_id: Joi.number().required(),
26
+            val: Joi.string().required(),
27
+        }),
28
+    ),
29
+}
30
+
31
+const responseSchemas = {
32
+    response: Joi.object({
33
+        profile_id: Joi.number(),
34
+        user_id: Joi.number(),
35
+    }),
36
+    error: Joi.object({
37
+        error: Joi.string(),
38
+    }),
39
+}
40
+
41
+module.exports = {
42
+    method: 'POST',
43
+    path: '/{user_id}/profile',
44
+    options: {
45
+        ...pluginConfig.docs,
46
+        tags: ['api'],
47
+        /** Protect this route with authentication? */
48
+        auth: false,
49
+
50
+        handler: async function (request, h) {
51
+            const { userService, profileService } = request.server.services()
52
+            const userId = request.params.user_id
53
+            const user = await userService.findById(userId)
54
+            const type = user.is_poster == 1 ? 'poster' : 'seeker'
55
+
56
+            const profiles = await profileService.getCompleteProfilesFor(
57
+                userId,
58
+                type,
59
+            )
60
+
61
+            try {
62
+                if (type === 'seeker' && profiles.length > 0) {
63
+                    throw new RangeError(
64
+                        'Job seekers may only have ONE profile',
65
+                    )
66
+                }
67
+                /** Grab payload info */
68
+                const res = request.payload
69
+                const profile =
70
+                    await profileService.saveResponsesCreateProfileFor(
71
+                        userId,
72
+                        res,
73
+                    )
74
+                return h
75
+                    .response({
76
+                        ok: true,
77
+                        handler: pluginConfig.handlerType,
78
+                        data: profile,
79
+                    })
80
+                    .code(201)
81
+            } catch (err) {
82
+                return h
83
+                    .response({
84
+                        ok: false,
85
+                        handler: pluginConfig.handlerType,
86
+                        data: { error: `${err}` },
87
+                    })
88
+                    .code(500)
89
+            }
90
+        },
91
+
92
+        /** Validate based on validators object */
93
+        validate: {
94
+            ...validators,
95
+            failAction: 'log',
96
+        },
97
+
98
+        /** Validate the server response */
99
+        response: {
100
+            status: {
101
+                201: Joi.object({
102
+                    ok: Joi.bool(),
103
+                    handler: Joi.string(),
104
+                    data: responseSchemas.response,
105
+                }),
106
+                500: Joi.object({
107
+                    ok: Joi.bool(),
108
+                    handler: Joi.string(),
109
+                    data: responseSchemas.error,
110
+                }),
111
+            },
112
+        },
113
+    },
114
+}

backend/lib/routes/profile/profiles.js → backend/lib/routes/user/list-profiles.js Voir le fichier

3
 const Joi = require('joi')
3
 const Joi = require('joi')
4
 
4
 
5
 const pluginConfig = {
5
 const pluginConfig = {
6
-    handlerType: 'profile',
6
+    handlerType: 'user',
7
     docs: {
7
     docs: {
8
         description: 'profiles',
8
         description: 'profiles',
9
         notes: 'A list of profiles associated with this user',
9
         notes: 'A list of profiles associated with this user',
16
 
16
 
17
     /** Validate the route params (/active/{thing}) */
17
     /** Validate the route params (/active/{thing}) */
18
     params: Joi.object({
18
     params: Joi.object({
19
-        user_type: Joi.string(),
20
         user_id: Joi.number(),
19
         user_id: Joi.number(),
21
     }),
20
     }),
22
 
21
 
40
         ),
39
         ),
41
         user_type: Joi.string().required(),
40
         user_type: Joi.string().required(),
42
     }),
41
     }),
42
+    error: Joi.object({
43
+        error: Joi.string(),
44
+    }),
43
 }
45
 }
44
 
46
 
45
 module.exports = {
47
 module.exports = {
46
     method: 'GET',
48
     method: 'GET',
47
-    path: '/{user_type}/{user_id}',
49
+    path: '/{user_id}/profiles',
48
     options: {
50
     options: {
49
         ...pluginConfig.docs,
51
         ...pluginConfig.docs,
50
         tags: ['api'],
52
         tags: ['api'],
52
         auth: false,
54
         auth: false,
53
 
55
 
54
         handler: async function (request, h) {
56
         handler: async function (request, h) {
55
-            const { profileService } = request.services()
57
+            const { userService, profileService } = request.server.services()
56
             const userId = request.params.user_id
58
             const userId = request.params.user_id
57
-            const type = request.params.user_type
59
+            const user = await userService.findById(userId)
60
+            const type = user.is_poster == 1 ? 'poster' : 'seeker'
58
             const profiles = await profileService.getCompleteProfilesFor(
61
             const profiles = await profileService.getCompleteProfilesFor(
59
                 userId,
62
                 userId,
60
                 type,
63
                 type,
82
 
85
 
83
         /** Validate the server response */
86
         /** Validate the server response */
84
         response: {
87
         response: {
85
-            schema: Joi.object({
86
-                ok: Joi.bool(),
87
-                handler: Joi.string(),
88
-                data: Joi.array().items(responseSchemas.profilesList),
89
-            }),
88
+            status: {
89
+                200: Joi.object({
90
+                    ok: Joi.bool(),
91
+                    handler: Joi.string(),
92
+                    data: Joi.array().items(responseSchemas.profilesList),
93
+                }),
94
+                500: Joi.object({
95
+                    ok: Joi.bool(),
96
+                    handler: Joi.string(),
97
+                    data: responseSchemas.error,
98
+                }),
99
+            },
90
         },
100
         },
91
     },
101
     },
92
 }
102
 }

+ 2
- 1
backend/lib/services/match-maker.js Voir le fichier

6
         const seekerResponseValues = seeker.profileResponses.map(res =>
6
         const seekerResponseValues = seeker.profileResponses.map(res =>
7
             parseInt(Object.values(res)),
7
             parseInt(Object.values(res)),
8
         )
8
         )
9
+        console.log(seeker)
9
         const potentialMatchResponseValues =
10
         const potentialMatchResponseValues =
10
             potentialMatch.profileResponses.map(res =>
11
             potentialMatch.profileResponses.map(res =>
11
                 parseInt(Object.values(res)),
12
                 parseInt(Object.values(res)),
51
     }
52
     }
52
     scoreProfiles(profiles) {
53
     scoreProfiles(profiles) {
53
         const matchScores = []
54
         const matchScores = []
54
-        for (const profile in this.profiles) {
55
+        for (const profile in profiles) {
55
             const scored = this.keeper.score(profile)
56
             const scored = this.keeper.score(profile)
56
             matchScores.push(scored)
57
             matchScores.push(scored)
57
         }
58
         }

+ 5
- 4
backend/lib/services/profile.js Voir le fichier

9
         }
9
         }
10
 
10
 
11
     const checkValCb = res => {
11
     const checkValCb = res => {
12
-        const val = parseInt(Object.values(res))
12
+        const val = parseInt(res.val)
13
         return isNaN(val) ? 0 : val
13
         return isNaN(val) ? 0 : val
14
     }
14
     }
15
+
15
     return Math.floor(
16
     return Math.floor(
16
         cosineSimilarity(
17
         cosineSimilarity(
17
             seeker.responses.map(checkValCb),
18
             seeker.responses.map(checkValCb),
142
 
143
 
143
     /**
144
     /**
144
      * Score a profile
145
      * Score a profile
145
-     * @param {number} userId
146
+     * @param {number} profileId
146
      * @returns {Array} Ordered and scored Profiles
147
      * @returns {Array} Ordered and scored Profiles
147
      */
148
      */
148
-    async scoreProfilesFor(userId) {
149
+    async scoreProfilesFor(profileId) {
149
         const { Profile } = this.server.models()
150
         const { Profile } = this.server.models()
150
 
151
 
151
         // Our User Profile to score for
152
         // Our User Profile to score for
152
         const userProfile = await Profile.query()
153
         const userProfile = await Profile.query()
153
-            .findOne('user_id', userId)
154
+            .findOne('profile_id', profileId)
154
             .withGraphFetched('responses')
155
             .withGraphFetched('responses')
155
             .withGraphFetched('user')
156
             .withGraphFetched('user')
156
 
157
 

+ 5
- 2
backend/lib/services/user.js Voir le fichier

28
      */
28
      */
29
     async findById(id, txn) {
29
     async findById(id, txn) {
30
         const { User } = this.server.models()
30
         const { User } = this.server.models()
31
-        return await User.query(txn).throwIfNotFound().findById(id)
31
+        return await User.query(txn)
32
+            .throwIfNotFound()
33
+            .first()
34
+            .where({ user_id: id })
32
     }
35
     }
33
 
36
 
34
     /**
37
     /**
43
         return await User.query(txn)
46
         return await User.query(txn)
44
             .throwIfNotFound()
47
             .throwIfNotFound()
45
             .first()
48
             .first()
46
-            .where({ username })
49
+            .where({ user_name: username })
47
     }
50
     }
48
 
51
 
49
     /**
52
     /**

Chargement…
Annuler
Enregistrer