Skip to content

Commit 7e0d269

Browse files
committed
fix: set manuallyChangedFields on member attributes update
1 parent 32352b1 commit 7e0d269

6 files changed

Lines changed: 101 additions & 44 deletions

File tree

backend/src/database/repositories/member/memberAttributesRepository.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

backend/src/services/member/memberAttributesService.ts

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
/* eslint-disable no-continue */
22
import { LoggerBase } from '@crowd/logging'
33
import { IAttributes } from '@crowd/types'
4+
import * as lodash from 'lodash'
45

5-
import MemberAttributesRepository from '@/database/repositories/member/memberAttributesRepository'
6+
import { captureApiChange, memberEditProfileAction } from '@crowd/audit-logs'
7+
import { Error404 } from '@crowd/common'
8+
import { fetchMemberAttributes, getMemberManuallyChangedFields, setMemberManuallyChangedFields, updateMemberAttributes } from '@crowd/data-access-layer/src/members'
9+
import SequelizeRepository from '@/database/repositories/sequelizeRepository'
610

711
import { IServiceOptions } from '../IServiceOptions'
812

@@ -16,11 +20,58 @@ export default class MemberAttributesService extends LoggerBase {
1620

1721
// Member attributes
1822
async list(memberId: string): Promise<IAttributes> {
19-
return MemberAttributesRepository.list(memberId, this.options)
23+
const qx = SequelizeRepository.getQueryExecutor(this.options)
24+
25+
// Get member attributes
26+
const result = await fetchMemberAttributes(qx, memberId)
27+
if (!result.length) {
28+
throw new Error404('Attributes not found for the given member!')
29+
}
30+
31+
return result
2032
}
2133

2234
// Update member attributes
2335
async update(memberId: string, data: IAttributes): Promise<IAttributes> {
24-
return MemberAttributesRepository.update(memberId, data, this.options)
36+
const qx = SequelizeRepository.getQueryExecutor(this.options)
37+
38+
const currentMemberAttributes = await fetchMemberAttributes(qx, memberId)
39+
if (!currentMemberAttributes) {
40+
throw new Error404('Attributes not found for the given member!')
41+
}
42+
43+
const existingManuallyChangedFields = (await getMemberManuallyChangedFields(qx, memberId)) || []
44+
45+
const updatedManuallyChangedFields = [...existingManuallyChangedFields]
46+
47+
const result = await captureApiChange(
48+
this.options,
49+
memberEditProfileAction(memberId, async (captureOldState, captureNewState) => {
50+
captureOldState({ attributes: currentMemberAttributes })
51+
52+
for (const key of Object.keys(data)) {
53+
if (
54+
!currentMemberAttributes[key] ||
55+
!lodash.isEqual(currentMemberAttributes[key].default, data[key].default)
56+
) {
57+
const fieldName = `attributes.${key}`
58+
if (!updatedManuallyChangedFields.includes(fieldName)) {
59+
updatedManuallyChangedFields.push(fieldName)
60+
}
61+
}
62+
}
63+
64+
await updateMemberAttributes(qx, memberId, data)
65+
66+
await setMemberManuallyChangedFields(qx, memberId, updatedManuallyChangedFields)
67+
68+
captureNewState({ attributes: data })
69+
70+
// Get updated member attributes
71+
return fetchMemberAttributes(qx, memberId)
72+
}),
73+
)
74+
75+
return result
2576
}
2677
}

frontend/src/modules/auth/auth.socket.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ export const connectSocket = (token) => {
5959
});
6060

6161
socketIoClient.on(SocketEvents.memberMerge, (data) => {
62-
console.info('Member merge done', data);
6362
const parsedData = JSON.parse(data);
6463
if (!parsedData.success) {
6564
return;

services/apps/data_sink_worker/src/service/member.service.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -604,17 +604,18 @@ export default class MemberService extends LoggerBase {
604604
let attributes: Record<string, unknown> | undefined
605605
if (member.attributes) {
606606
const temp = mergeWith({}, dbMember.attributes, member.attributes)
607-
608607
const manuallyChangedFields: string[] = dbMember.manuallyChangedFields || []
608+
609609
if (manuallyChangedFields.length > 0) {
610-
const attrColumn = 'attributes'
611-
const manuallyChangedAttributes = (dbMember.manuallyChangedFields || [])
612-
.filter((f) => f.startsWith(attrColumn))
613-
.map((f) => f.substring(attrColumn.length))
610+
const prefix = 'attributes.'
611+
612+
const manuallyChangedAttributes = manuallyChangedFields
613+
.filter((f) => f.startsWith(prefix))
614+
.map((f) => f.slice(prefix.length))
614615

615616
// Preserve manually changed attributes
616617
for (const key of manuallyChangedAttributes) {
617-
if (dbMember.attributes[key] !== undefined) {
618+
if (dbMember.attributes?.[key] !== undefined) {
618619
temp[key] = dbMember.attributes[key]
619620
}
620621
}

services/libs/data-access-layer/src/members/attributes.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { IAttributes, IMember } from '@crowd/types'
1+
import { IAttributes } from '@crowd/types'
22

33
import { QueryExecutor } from '../queryExecutor'
44

55
export async function fetchMemberAttributes(
66
qx: QueryExecutor,
77
memberId: string,
8-
): Promise<Partial<IMember>[]> {
9-
return qx.select(
8+
): Promise<IAttributes> {
9+
const result = await qx.select(
1010
`
1111
SELECT attributes
1212
FROM "members"
@@ -17,6 +17,8 @@ export async function fetchMemberAttributes(
1717
memberId,
1818
},
1919
)
20+
21+
return result[0]?.attributes
2022
}
2123

2224
export async function updateMemberAttributes(

services/libs/data-access-layer/src/members/others.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,38 @@ export async function updateMemberReach(
8282
export async function touchMemberUpdatedAt(qx: QueryExecutor, memberId: string): Promise<void> {
8383
return qx.result(`UPDATE members SET "updatedAt" = NOW() WHERE id = $(memberId)`, { memberId })
8484
}
85+
86+
export async function getMemberManuallyChangedFields(
87+
qx: QueryExecutor,
88+
memberId: string,
89+
): Promise<string[]> {
90+
return qx.select(
91+
`
92+
SELECT "manuallyChangedFields"
93+
FROM "members"
94+
WHERE "id" = $(memberId)
95+
LIMIT 1;
96+
`,
97+
{
98+
memberId,
99+
},
100+
)
101+
}
102+
103+
export async function setMemberManuallyChangedFields(
104+
qx: QueryExecutor,
105+
memberId: string,
106+
fields: string[],
107+
): Promise<void> {
108+
return qx.result(
109+
`
110+
UPDATE "members"
111+
SET "manuallyChangedFields" = $(fields)
112+
WHERE "id" = $(memberId)
113+
`,
114+
{
115+
memberId,
116+
fields,
117+
},
118+
)
119+
}

0 commit comments

Comments
 (0)