Просмотр исходного кода

:bug: simplifying notifications | fixing up some membership and grouping bugs

tags/0.0.1^2
J 3 лет назад
Родитель
Сommit
81f8f2abb6

+ 23
- 15
backend/db/data-generator/mock.js Просмотреть файл

100
         {
100
         {
101
             response_key_id: 2,
101
             response_key_id: 2,
102
             response_key_category: 'openness',
102
             response_key_category: 'openness',
103
-            response_key_prompt: 'are you open with your emotions with everyone',
103
+            response_key_prompt:
104
+                'are you open with your emotions with everyone',
104
             response_key_description: 'first round draft scoring question',
105
             response_key_description: 'first round draft scoring question',
105
         },
106
         },
106
         {
107
         {
107
             response_key_id: 3,
108
             response_key_id: 3,
108
             response_key_category: 'bravery',
109
             response_key_category: 'bravery',
109
-            response_key_prompt: 'do you speak-up when you feel something is wrong',
110
+            response_key_prompt:
111
+                'do you speak-up when you feel something is wrong',
110
             response_key_description: 'first round draft scoring question',
112
             response_key_description: 'first round draft scoring question',
111
         },
113
         },
112
         {
114
         {
119
         {
121
         {
120
             response_key_id: 5,
122
             response_key_id: 5,
121
             response_key_category: 'honesty',
123
             response_key_category: 'honesty',
122
-            response_key_prompt: 'when telling a story do you exaggerate for dramatic effect',
124
+            response_key_prompt:
125
+                'when telling a story do you exaggerate for dramatic effect',
123
             response_key_description: 'first round draft scoring question',
126
             response_key_description: 'first round draft scoring question',
124
         },
127
         },
125
         {
128
         {
126
             response_key_id: 6,
129
             response_key_id: 6,
127
             response_key_category: 'respect',
130
             response_key_category: 'respect',
128
-            response_key_prompt: 'do you treat difficult people as well as you treat your close friends',
131
+            response_key_prompt:
132
+                'do you treat difficult people as well as you treat your close friends',
129
             response_key_description: 'first round draft scoring question',
133
             response_key_description: 'first round draft scoring question',
130
         },
134
         },
131
         {
135
         {
144
             response_key_id: 9,
148
             response_key_id: 9,
145
             response_key_category: 'profile',
149
             response_key_category: 'profile',
146
             response_key_prompt: 'language',
150
             response_key_prompt: 'language',
147
-            response_key_description: 'programming and spoken language preference',
151
+            response_key_description:
152
+                'programming and spoken language preference',
148
         },
153
         },
149
         {
154
         {
150
             response_key_id: 10,
155
             response_key_id: 10,
151
             response_key_category: 'profile',
156
             response_key_category: 'profile',
152
             response_key_prompt: 'duration',
157
             response_key_prompt: 'duration',
153
-            response_key_description: 'duration preference for hours able to dedicate to work',
158
+            response_key_description:
159
+                'duration preference for hours able to dedicate to work',
154
         },
160
         },
155
         {
161
         {
156
             response_key_id: 11,
162
             response_key_id: 11,
157
             response_key_category: 'profile',
163
             response_key_category: 'profile',
158
             response_key_prompt: 'presence',
164
             response_key_prompt: 'presence',
159
-            response_key_description: 'location preference for where work happens',
165
+            response_key_description:
166
+                'location preference for where work happens',
160
         },
167
         },
161
         {
168
         {
162
             response_key_id: 12,
169
             response_key_id: 12,
186
             response_key_id: 16,
193
             response_key_id: 16,
187
             response_key_category: 'profile',
194
             response_key_category: 'profile',
188
             response_key_prompt: 'distance',
195
             response_key_prompt: 'distance',
189
-            response_key_description: 'preference for commuting distance cutoff',
196
+            response_key_description:
197
+                'preference for commuting distance cutoff',
190
         },
198
         },
191
     ],
199
     ],
192
     responses: [],
200
     responses: [],
193
-    memberships: [
194
-
195
-    ],
196
-    groupings: [
197
-
198
-    ],
201
+    memberships: [],
202
+    groupings: [],
199
     messages: [],
203
     messages: [],
200
     match_queues: [
204
     match_queues: [
201
         { match_queue_id: 1, profile_id: 45, target_id: 62, is_deleted: false },
205
         { match_queue_id: 1, profile_id: 45, target_id: 62, is_deleted: false },
202
-        { match_queue_id: 2, profile_id: 62, target_id: 45, is_deleted: false }
206
+        { match_queue_id: 2, profile_id: 62, target_id: 45, is_deleted: false },
207
+        { match_queue_id: 3, profile_id: 62, target_id: 46, is_deleted: false },
208
+        { match_queue_id: 4, profile_id: 46, target_id: 62, is_deleted: false },
209
+        { match_queue_id: 5, profile_id: 45, target_id: 46, is_deleted: false },
210
+        { match_queue_id: 6, profile_id: 46, target_id: 45, is_deleted: false },
203
     ],
211
     ],
204
 }
212
 }

+ 24
- 9
backend/lib/routes/membership/join.js Просмотреть файл

31
     error: errorSchema.single,
31
     error: errorSchema.single,
32
 }
32
 }
33
 
33
 
34
+const notifyMembers = (profileId, targetId, noticationCb, h) => {
35
+    noticationCb(
36
+        `${profileId}.stonk`,
37
+        {
38
+            name: `${targetId} Match Fffound`,
39
+            type: 'info',
40
+        },
41
+        h,
42
+    )
43
+    noticationCb(
44
+        `${targetId}.stonk`,
45
+        {
46
+            name: `${profileId} Match Fffound`,
47
+            type: 'info',
48
+        },
49
+        h,
50
+    )
51
+}
52
+
34
 module.exports = {
53
 module.exports = {
35
     method: 'POST',
54
     method: 'POST',
36
     path: '/{profile_id}/join',
55
     path: '/{profile_id}/join',
73
                     groupingToWrite,
92
                     groupingToWrite,
74
                     role,
93
                     role,
75
                 )
94
                 )
76
-                // console.log(memberships)
95
+
77
                 const hasMatch = memberships.every(
96
                 const hasMatch = memberships.every(
78
                     membership => membership.is_active == true,
97
                     membership => membership.is_active == true,
79
                 )
98
                 )
80
                 if (hasMatch) {
99
                 if (hasMatch) {
81
-                    request.server.methods.notify(
82
-                        `${profileId}.match`,
83
-                        {
84
-                            name: 'Match Fffound',
85
-                            target: res.target_id,
86
-                            type: 'info',
87
-                        },
100
+                    notifyMembers(
101
+                        profileId,
102
+                        res.target_id,
103
+                        request.server.notify,
88
                         h,
104
                         h,
89
                     )
105
                     )
90
                 }
106
                 }
91
-
92
                 return h
107
                 return h
93
                     .response({
108
                     .response({
94
                         ok: true,
109
                         ok: true,

+ 3
- 2
backend/lib/services/matchqueue.js Просмотреть файл

74
      */
74
      */
75
     async markAsDeleted(profileId, targetId, reinsert) {
75
     async markAsDeleted(profileId, targetId, reinsert) {
76
         const { MatchQueue } = this.server.models()
76
         const { MatchQueue } = this.server.models()
77
+        /** Always set row to deleted */
77
         await MatchQueue.query()
78
         await MatchQueue.query()
79
+            .where('profile_id', profileId)
80
+            .andWhere('target_id', targetId)
78
             .patch({
81
             .patch({
79
                 is_deleted: true,
82
                 is_deleted: true,
80
             })
83
             })
81
-            .where('profile_id', profileId)
82
-            .andWhere('target_id', targetId)
83
             .first()
84
             .first()
84
 
85
 
85
         if (reinsert) {
86
         if (reinsert) {

+ 8
- 6
backend/lib/services/membership.js Просмотреть файл

101
         const dedupedTargetGroupingIds = await this._getGroupingIdsForProfileId(
101
         const dedupedTargetGroupingIds = await this._getGroupingIdsForProfileId(
102
             targetId,
102
             targetId,
103
         )
103
         )
104
-
105
-        /** Return true if both people have a group in common */
106
-        return dedupedUserGroupingIds.filter(groupingId =>
107
-            dedupedTargetGroupingIds.includes(groupingId),
108
-        )
104
+        const common = []
105
+        const uids = dedupedUserGroupingIds.toString().split(',').map(Number)
106
+        const tids = dedupedTargetGroupingIds.toString().split(',').map(Number)
107
+        for (let i in uids) {
108
+            if (tids.indexOf(uids[i]) !== -1) common.push(uids[i])
109
+        }
110
+        return common.sort((x, y) => x - y)
109
     }
111
     }
110
     async _patchMembership(memberships, profileId, patch) {
112
     async _patchMembership(memberships, profileId, patch) {
111
         const { Membership } = this.server.models()
113
         const { Membership } = this.server.models()
114
         for (let membershipInfo of memberships) {
116
         for (let membershipInfo of memberships) {
115
             await Membership.query()
117
             await Membership.query()
116
                 .where('membership_id', membershipInfo.membership_id)
118
                 .where('membership_id', membershipInfo.membership_id)
117
-                .where('user_id', profileId)
119
+                .where('profile_id', profileId)
118
                 .patch(patch)
120
                 .patch(patch)
119
         }
121
         }
120
     }
122
     }

+ 5
- 11
frontend/src/App.vue Просмотреть файл

1
 <template lang="pug">
1
 <template lang="pug">
2
 w-app
2
 w-app
3
-    div.nav(style="display: flex; justify-content: space-between;")
3
+    div.nav(v-if="getPid" style="display: flex; justify-content: space-between;")
4
         header
4
         header
5
             h2 home - profile: {{ getPid }}
5
             h2 home - profile: {{ getPid }}
6
         w-drawer(v-model="openDrawer")
6
         w-drawer(v-model="openDrawer")
12
         w-button(@click="openDrawer = true" outline="")
12
         w-button(@click="openDrawer = true" outline="")
13
             | Active Chats
13
             | Active Chats
14
     RouterView(
14
     RouterView(
15
+        v-if="getPid"
15
         :pid="getPid"
16
         :pid="getPid"
16
         @updatePid="setPid"
17
         @updatePid="setPid"
17
         @show-sidebar="showSidebar = !showSidebar"
18
         @show-sidebar="showSidebar = !showSidebar"
36
         openDrawer: false,
37
         openDrawer: false,
37
     }),
38
     }),
38
     computed: {
39
     computed: {
39
-        getPid: () => (currentProfile.id.value ? currentProfile.id.value : 999),
40
+        getPid: () =>
41
+            currentProfile.id.value ? currentProfile.id.value : null,
40
     },
42
     },
41
     async created() {
43
     async created() {
42
         /** Get questions so we can compare against profile responses */
44
         /** Get questions so we can compare against profile responses */
60
             if (currentProfile.isLoggedIn) {
62
             if (currentProfile.isLoggedIn) {
61
                 currentProfile.logout()
63
                 currentProfile.logout()
62
             }
64
             }
63
-            await currentProfile.login(profileId)
64
-
65
-            if (currentProfile.isLoggedIn) {
66
-                console.warn(
67
-                    `setting up Chatter and Toaster for ${this.getPid}...`,
68
-                )
69
-                currentProfile.setupChatter()
70
-                currentProfile.setupToaster(this.$waveui.notify)
71
-            }
65
+            await currentProfile.login(profileId, this.$waveui.notify)
72
             console.log('---')
66
             console.log('---')
73
             //  step 3: subscribe to the this.subscriptions array
67
             //  step 3: subscribe to the this.subscriptions array
74
             // view current subscriptions on the currentProfile.chatter.subscriptions
68
             // view current subscriptions on the currentProfile.chatter.subscriptions

+ 8
- 9
frontend/src/services/chat.service.js Просмотреть файл

1
 import PubNub from 'pubnub'
1
 import PubNub from 'pubnub'
2
 
2
 
3
-// custom services 
4
-import {fetchMembershipsByProfileId} from '../services/grouping.service'
3
+// custom services
4
+import { fetchMembershipsByProfileId } from '../services/grouping.service'
5
 
5
 
6
 /**
6
 /**
7
  * Provider method holder
7
  * Provider method holder
98
     async setup(uuid) {
98
     async setup(uuid) {
99
         this.uuid = `${uuid}`
99
         this.uuid = `${uuid}`
100
         this.provider = await setupPubnub(this.uuid)
100
         this.provider = await setupPubnub(this.uuid)
101
-            
101
+
102
         //  step 1: build the this.groupings object from the backend
102
         //  step 1: build the this.groupings object from the backend
103
         // ? .then() to wait for the groupings to be fetched before subscribing to channels
103
         // ? .then() to wait for the groupings to be fetched before subscribing to channels
104
         this.getGroupingsByProfileId(this.uuid).then(() => {
104
         this.getGroupingsByProfileId(this.uuid).then(() => {
105
             this._listenFor({ listeners: this.listeners })
105
             this._listenFor({ listeners: this.listeners })
106
             this._subscribe(this.subscriptions)
106
             this._subscribe(this.subscriptions)
107
         })
107
         })
108
-        
108
+
109
         console.log('this.subscriptions', this.subscriptions)
109
         console.log('this.subscriptions', this.subscriptions)
110
-       
111
     }
110
     }
112
     /**
111
     /**
113
      * Send a message to a channel
112
      * Send a message to a channel
136
     _listenFor({ listeners }) {
135
     _listenFor({ listeners }) {
137
         providerMethods['listen'](listeners)
136
         providerMethods['listen'](listeners)
138
     }
137
     }
139
-    
140
     //  step 2: build the this.subscriptions array from the this.groupings object
138
     //  step 2: build the this.subscriptions array from the this.groupings object
141
     // fetch all groupings for this profile and then store them in the chatter groupings object for reference
139
     // fetch all groupings for this profile and then store them in the chatter groupings object for reference
142
     async getGroupingsByProfileId(profileId) {
140
     async getGroupingsByProfileId(profileId) {
149
     createChannelNamesByGroupings(groupings) {
147
     createChannelNamesByGroupings(groupings) {
150
         groupings.forEach(item => {
148
         groupings.forEach(item => {
151
             this.subscriptions.push(item.grouping_name)
149
             this.subscriptions.push(item.grouping_name)
152
-        });
153
-        
154
-        
150
+        })
151
+    }
152
+    stop() {
153
+        console.warn('chatter stop no implemented')
155
     }
154
     }
156
 }
155
 }
157
 
156
 

+ 8
- 10
frontend/src/services/login.service.js Просмотреть файл

1
 import { ref } from 'vue'
1
 import { ref } from 'vue'
2
-import {
3
-    fetchResponsesByProfileId,
4
-    Chatter,
5
-    StonkAlert,
6
-    MatchAlert,
7
-} from '../services'
2
+import { fetchResponsesByProfileId, Chatter, StonkAlert } from '../services'
8
 import { surveyFactory } from '../utils'
3
 import { surveyFactory } from '../utils'
9
 
4
 
10
 
5
 
23
         this.tags = []
18
         this.tags = []
24
 
19
 
25
         this.toaster = null
20
         this.toaster = null
26
-        this.matcher = null
27
         this.chatter = null
21
         this.chatter = null
28
     }
22
     }
29
     get isLoading() {
23
     get isLoading() {
63
      * @param {number} profileId
57
      * @param {number} profileId
64
      * @returns {number} stored reactive id
58
      * @returns {number} stored reactive id
65
      */
59
      */
66
-    async login(profileId) {
60
+    async login(profileId, cb) {
67
         console.warn('logging in:', profileId)
61
         console.warn('logging in:', profileId)
68
         this.id.value = parseInt(profileId)
62
         this.id.value = parseInt(profileId)
63
+
64
+        this.setupChatter()
65
+        this.setupToaster(cb)
66
+
69
         return this.id.value
67
         return this.id.value
70
     }
68
     }
71
     logout() {
69
     logout() {
70
+        console.warn('logging out:', this.id.value)
72
         this.id.value = null
71
         this.id.value = null
73
         if (this.toaster) {
72
         if (this.toaster) {
74
             this.toaster.stop()
73
             this.toaster.stop()
75
         }
74
         }
76
         if (this.chatter) {
75
         if (this.chatter) {
77
-            this.toaster.stop()
76
+            this.chatter.stop()
78
         }
77
         }
79
     }
78
     }
80
 
79
 
106
      */
105
      */
107
     setupToaster(waveCb) {
106
     setupToaster(waveCb) {
108
         this.toaster = new StonkAlert(this.id.value, waveCb)
107
         this.toaster = new StonkAlert(this.id.value, waveCb)
109
-        this.matcher = new MatchAlert(this.id.value, waveCb)
110
     }
108
     }
111
     setupChatter() {
109
     setupChatter() {
112
         this.chatter = new Chatter()
110
         this.chatter = new Chatter()

+ 1
- 16
frontend/src/services/notification.service.js Просмотреть файл

37
         return `${parsed.name}: ${parsed.profile_id} ${parsed.order} at ${parsed.price}`
37
         return `${parsed.name}: ${parsed.profile_id} ${parsed.order} at ${parsed.price}`
38
     }
38
     }
39
 }
39
 }
40
-class MatchAlert extends Toaster {
41
-    constructor(profileId, waveCb) {
42
-        super(profileId)
43
-        this.event = 'match'
44
-        this.matches = {}
45
-        this.listenFor(`${profileId}.${this.event}`, message => {
46
-            const parsed = JSON.parse(message.data)
47
-            this.matches[parsed.target] = parsed
48
-            waveCb(this._formatToast(parsed), parsed.type)
49
-        })
50
-    }
51
-    _formatToast(parsed) {
52
-        return `${parsed.name}: ${parsed.target}`
53
-    }
54
-}
55
 
40
 
56
-export { Toaster, StonkAlert, MatchAlert }
41
+export { Toaster, StonkAlert }

+ 13
- 12
frontend/src/services/queue.service.js Просмотреть файл

8
  */
8
  */
9
 const fetchQueueByProfileId = async profileId => {
9
 const fetchQueueByProfileId = async profileId => {
10
     let queue
10
     let queue
11
-    
11
+
12
     try {
12
     try {
13
-        queue = await db.get(
14
-            `/profile/${profileId}/queue?include_profile=true`,
15
-        )
16
-        if(!queue?.length) {
13
+        queue = await db.get(`/profile/${profileId}/queue?include_profile=true`)
14
+        if (!queue?.length) {
17
             throw 'Could not retrieve match queue. Please take the survey and rescore.'
15
             throw 'Could not retrieve match queue. Please take the survey and rescore.'
18
         }
16
         }
19
     } catch (err) {
17
     } catch (err) {
20
         console.error(err)
18
         console.error(err)
21
     }
19
     }
22
 
20
 
23
-    return queue ? queue.map(profileData => {
24
-        return new Profile({ email: 'fixme@gmail.com', ...profileData })
25
-    }) : []
21
+    return queue
22
+        ? queue.map(profileData => {
23
+              return new Profile({ email: 'fixme@gmail.com', ...profileData })
24
+          })
25
+        : []
26
 }
26
 }
27
 
27
 
28
 /**
28
 /**
35
 const updateQueueByProfileId = async (profileId, targetId, reinsert) => {
35
 const updateQueueByProfileId = async (profileId, targetId, reinsert) => {
36
     const updateQueue = await db.patch(
36
     const updateQueue = await db.patch(
37
         `/profile/${profileId}/queue/${targetId}/delete?include_profile=true&reinsert=${reinsert}`,
37
         `/profile/${profileId}/queue/${targetId}/delete?include_profile=true&reinsert=${reinsert}`,
38
-        [ targetId ],
39
     )
38
     )
40
-    return updateQueue ? updateQueue.map(profileData => {
41
-        return new Profile({ email: 'fixme@gmail.com', ...profileData })
42
-    }) : []
39
+    return updateQueue
40
+        ? updateQueue.map(profileData => {
41
+              return new Profile({ email: 'fixme@gmail.com', ...profileData })
42
+          })
43
+        : []
43
 }
44
 }
44
 
45
 
45
 export { fetchQueueByProfileId, updateQueueByProfileId }
46
 export { fetchQueueByProfileId, updateQueueByProfileId }

Загрузка…
Отмена
Сохранить