@open-mercato/core 0.6.6-develop.6460.1.f94c74174c → 0.6.6-develop.6465.1.019f0fb26f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/helpers/integration/auth.js +148 -82
- package/dist/helpers/integration/auth.js.map +2 -2
- package/dist/modules/sales/api/document-addresses/route.js +96 -6
- package/dist/modules/sales/api/document-addresses/route.js.map +2 -2
- package/dist/modules/sales/commands/documentAddresses.js +7 -0
- package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
- package/dist/modules/staff/commands/activities.js +23 -12
- package/dist/modules/staff/commands/activities.js.map +2 -2
- package/dist/modules/staff/commands/addresses.js +20 -12
- package/dist/modules/staff/commands/addresses.js.map +2 -2
- package/dist/modules/staff/commands/comments.js +18 -11
- package/dist/modules/staff/commands/comments.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +23 -12
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +37 -19
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/commands/shared.js +28 -1
- package/dist/modules/staff/commands/shared.js.map +2 -2
- package/dist/modules/staff/commands/tag-assignments.js +20 -3
- package/dist/modules/staff/commands/tag-assignments.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +21 -11
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/commands/team-roles.js +21 -11
- package/dist/modules/staff/commands/team-roles.js.map +2 -2
- package/dist/modules/staff/commands/teams.js +21 -11
- package/dist/modules/staff/commands/teams.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +24 -14
- package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-projects.js +34 -18
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/workflows/api/instances/route.js +1 -1
- package/dist/modules/workflows/api/instances/route.js.map +2 -2
- package/package.json +7 -7
- package/src/helpers/integration/auth.ts +178 -86
- package/src/modules/sales/api/document-addresses/route.ts +140 -7
- package/src/modules/sales/commands/documentAddresses.ts +8 -0
- package/src/modules/staff/commands/activities.ts +23 -11
- package/src/modules/staff/commands/addresses.ts +20 -11
- package/src/modules/staff/commands/comments.ts +18 -10
- package/src/modules/staff/commands/job-histories.ts +27 -11
- package/src/modules/staff/commands/leave-requests.ts +38 -19
- package/src/modules/staff/commands/shared.ts +38 -0
- package/src/modules/staff/commands/tag-assignments.ts +19 -2
- package/src/modules/staff/commands/team-members.ts +21 -10
- package/src/modules/staff/commands/team-roles.ts +21 -10
- package/src/modules/staff/commands/teams.ts +21 -10
- package/src/modules/staff/commands/timesheets-entries.ts +24 -13
- package/src/modules/staff/commands/timesheets-projects.ts +34 -17
- package/src/modules/workflows/api/instances/route.ts +2 -2
|
@@ -74,6 +74,44 @@ export function scopeForDecryption(scope: StaffCommandScope): { tenantId: string
|
|
|
74
74
|
return { tenantId: scope.tenantId, organizationId: scope.organizationId }
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
export type StaffSnapshotScope = {
|
|
78
|
+
tenantId?: string | null
|
|
79
|
+
organizationId?: string | null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type StaffSnapshotScopeSource = {
|
|
83
|
+
tenantId?: string | null
|
|
84
|
+
organizationId?: string | null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const NULL_DECRYPTION_SCOPE = { tenantId: null, organizationId: null } as const
|
|
88
|
+
|
|
89
|
+
export function staffSnapshotScopeFromContext(ctx: CommandRuntimeContext): StaffSnapshotScope | null {
|
|
90
|
+
const tenantId = ctx.auth?.tenantId ?? null
|
|
91
|
+
if (!tenantId) return null
|
|
92
|
+
return { tenantId }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function staffSnapshotScopeFromSnapshot(source: StaffSnapshotScopeSource | null | undefined): StaffSnapshotScope | null {
|
|
96
|
+
if (!source?.tenantId || !source.organizationId) return null
|
|
97
|
+
return { tenantId: source.tenantId, organizationId: source.organizationId }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function scopedStaffSnapshotWhere(id: string, scope?: StaffSnapshotScope | null) {
|
|
101
|
+
const where: { id: string; tenantId?: string; organizationId?: string } = { id }
|
|
102
|
+
if (scope?.tenantId) where.tenantId = scope.tenantId
|
|
103
|
+
if (scope?.organizationId) where.organizationId = scope.organizationId
|
|
104
|
+
return where
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function staffSnapshotDecryptionScope(scope?: StaffSnapshotScope | null) {
|
|
108
|
+
if (!scope) return NULL_DECRYPTION_SCOPE
|
|
109
|
+
return {
|
|
110
|
+
tenantId: scope.tenantId ?? null,
|
|
111
|
+
organizationId: scope.organizationId ?? null,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
77
115
|
export async function requireTeamMember(
|
|
78
116
|
em: EntityManager,
|
|
79
117
|
memberId: string,
|
|
@@ -20,6 +20,9 @@ import {
|
|
|
20
20
|
explicitStaffCommandScope,
|
|
21
21
|
extractUndoPayload,
|
|
22
22
|
scopeForDecryption,
|
|
23
|
+
scopedStaffSnapshotWhere,
|
|
24
|
+
staffSnapshotDecryptionScope,
|
|
25
|
+
staffSnapshotScopeFromSnapshot,
|
|
23
26
|
} from './shared'
|
|
24
27
|
|
|
25
28
|
type TeamMemberTagAssignmentSnapshot = {
|
|
@@ -113,7 +116,14 @@ const assignTeamMemberTagCommand: CommandHandler<StaffTeamMemberTagAssignmentInp
|
|
|
113
116
|
const before = payload?.before
|
|
114
117
|
if (!before) return
|
|
115
118
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
116
|
-
const
|
|
119
|
+
const snapshotScope = staffSnapshotScopeFromSnapshot(before)
|
|
120
|
+
const member = await findOneWithDecryption(
|
|
121
|
+
em,
|
|
122
|
+
StaffTeamMember,
|
|
123
|
+
scopedStaffSnapshotWhere(before.memberId, snapshotScope),
|
|
124
|
+
undefined,
|
|
125
|
+
staffSnapshotDecryptionScope(snapshotScope),
|
|
126
|
+
)
|
|
117
127
|
if (!member) return
|
|
118
128
|
const nextTags = normalizeTagList(
|
|
119
129
|
Array.isArray(member.tags) ? member.tags.filter((tag) => tag !== before.tag) : [],
|
|
@@ -243,7 +253,14 @@ const unassignTeamMemberTagCommand: CommandHandler<StaffTeamMemberTagAssignmentI
|
|
|
243
253
|
const before = payload?.before
|
|
244
254
|
if (!before) return
|
|
245
255
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
246
|
-
const
|
|
256
|
+
const snapshotScope = staffSnapshotScopeFromSnapshot(before)
|
|
257
|
+
const member = await findOneWithDecryption(
|
|
258
|
+
em,
|
|
259
|
+
StaffTeamMember,
|
|
260
|
+
scopedStaffSnapshotWhere(before.memberId, snapshotScope),
|
|
261
|
+
undefined,
|
|
262
|
+
staffSnapshotDecryptionScope(snapshotScope),
|
|
263
|
+
)
|
|
247
264
|
if (!member) return
|
|
248
265
|
const currentTags = Array.isArray(member.tags) ? member.tags : []
|
|
249
266
|
if (!currentTags.includes(before.tag)) {
|
|
@@ -27,6 +27,11 @@ import {
|
|
|
27
27
|
ensureTenantScope,
|
|
28
28
|
extractUndoPayload,
|
|
29
29
|
scopeForDecryption,
|
|
30
|
+
scopedStaffSnapshotWhere,
|
|
31
|
+
staffSnapshotDecryptionScope,
|
|
32
|
+
staffSnapshotScopeFromContext,
|
|
33
|
+
staffSnapshotScopeFromSnapshot,
|
|
34
|
+
type StaffSnapshotScope,
|
|
30
35
|
} from './shared'
|
|
31
36
|
import { E } from '#generated/entities.ids.generated'
|
|
32
37
|
|
|
@@ -67,8 +72,14 @@ function normalizeStringList(value: unknown): string[] {
|
|
|
67
72
|
return Array.from(set)
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
async function loadTeamMemberSnapshot(em: EntityManager, id: string): Promise<TeamMemberSnapshot | null> {
|
|
71
|
-
const member = await findOneWithDecryption(
|
|
75
|
+
async function loadTeamMemberSnapshot(em: EntityManager, id: string, scope?: StaffSnapshotScope | null): Promise<TeamMemberSnapshot | null> {
|
|
76
|
+
const member = await findOneWithDecryption(
|
|
77
|
+
em,
|
|
78
|
+
StaffTeamMember,
|
|
79
|
+
scopedStaffSnapshotWhere(id, scope),
|
|
80
|
+
undefined,
|
|
81
|
+
staffSnapshotDecryptionScope(scope),
|
|
82
|
+
)
|
|
72
83
|
if (!member) return null
|
|
73
84
|
return {
|
|
74
85
|
id: member.id,
|
|
@@ -232,14 +243,14 @@ const createTeamMemberCommand: CommandHandler<StaffTeamMemberCreateInput, { memb
|
|
|
232
243
|
},
|
|
233
244
|
captureAfter: async (_input, result, ctx) => {
|
|
234
245
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
235
|
-
const snapshot = await loadTeamMemberSnapshot(em, result.memberId)
|
|
246
|
+
const snapshot = await loadTeamMemberSnapshot(em, result.memberId, staffSnapshotScopeFromContext(ctx))
|
|
236
247
|
if (!snapshot) return null
|
|
237
248
|
const custom = await loadTeamMemberCustomSnapshot(em, snapshot)
|
|
238
249
|
return { snapshot, custom }
|
|
239
250
|
},
|
|
240
251
|
buildLog: async ({ result, ctx }) => {
|
|
241
252
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
242
|
-
const snapshot = await loadTeamMemberSnapshot(em, result.memberId)
|
|
253
|
+
const snapshot = await loadTeamMemberSnapshot(em, result.memberId, staffSnapshotScopeFromContext(ctx))
|
|
243
254
|
if (!snapshot) return null
|
|
244
255
|
const custom = await loadTeamMemberCustomSnapshot(em, snapshot)
|
|
245
256
|
const { translate } = await resolveTranslations()
|
|
@@ -263,7 +274,7 @@ const createTeamMemberCommand: CommandHandler<StaffTeamMemberCreateInput, { memb
|
|
|
263
274
|
const after = payload?.after
|
|
264
275
|
if (!after) return
|
|
265
276
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
266
|
-
const member = await em.findOne(StaffTeamMember,
|
|
277
|
+
const member = await em.findOne(StaffTeamMember, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
267
278
|
if (member) {
|
|
268
279
|
member.deletedAt = new Date()
|
|
269
280
|
await em.flush()
|
|
@@ -306,7 +317,7 @@ const updateTeamMemberCommand: CommandHandler<StaffTeamMemberUpdateInput, { memb
|
|
|
306
317
|
async prepare(rawInput, ctx) {
|
|
307
318
|
const { parsed } = parseWithCustomFields(staffTeamMemberUpdateSchema, rawInput)
|
|
308
319
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
309
|
-
const snapshot = await loadTeamMemberSnapshot(em, parsed.id)
|
|
320
|
+
const snapshot = await loadTeamMemberSnapshot(em, parsed.id, staffSnapshotScopeFromContext(ctx))
|
|
310
321
|
if (!snapshot) return {}
|
|
311
322
|
const custom = await loadTeamMemberCustomSnapshot(em, snapshot)
|
|
312
323
|
return { before: snapshot, customBefore: custom }
|
|
@@ -387,7 +398,7 @@ const updateTeamMemberCommand: CommandHandler<StaffTeamMemberUpdateInput, { memb
|
|
|
387
398
|
const before = snapshots.before as TeamMemberSnapshot | undefined
|
|
388
399
|
if (!before) return null
|
|
389
400
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
390
|
-
const after = await loadTeamMemberSnapshot(em, before.id)
|
|
401
|
+
const after = await loadTeamMemberSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))
|
|
391
402
|
if (!after) return null
|
|
392
403
|
const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined
|
|
393
404
|
const customAfter = await loadTeamMemberCustomSnapshot(em, after)
|
|
@@ -430,7 +441,7 @@ const updateTeamMemberCommand: CommandHandler<StaffTeamMemberUpdateInput, { memb
|
|
|
430
441
|
const before = payload?.before
|
|
431
442
|
if (!before) return
|
|
432
443
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
433
|
-
const member = await em.findOne(StaffTeamMember,
|
|
444
|
+
const member = await em.findOne(StaffTeamMember, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
434
445
|
if (!member) return
|
|
435
446
|
member.teamId = before.teamId ?? null
|
|
436
447
|
member.displayName = before.displayName
|
|
@@ -477,7 +488,7 @@ const deleteTeamMemberCommand: CommandHandler<{ id?: string }, { memberId: strin
|
|
|
477
488
|
const id = input?.id
|
|
478
489
|
if (!id) throw new CrudHttpError(400, { error: 'Member id is required.' })
|
|
479
490
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
480
|
-
const snapshot = await loadTeamMemberSnapshot(em, id)
|
|
491
|
+
const snapshot = await loadTeamMemberSnapshot(em, id, staffSnapshotScopeFromContext(ctx))
|
|
481
492
|
if (!snapshot) return {}
|
|
482
493
|
const custom = await loadTeamMemberCustomSnapshot(em, snapshot)
|
|
483
494
|
return { before: snapshot, customBefore: custom }
|
|
@@ -542,7 +553,7 @@ const deleteTeamMemberCommand: CommandHandler<{ id?: string }, { memberId: strin
|
|
|
542
553
|
const before = payload?.before
|
|
543
554
|
if (!before) return
|
|
544
555
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
545
|
-
let member = await em.findOne(StaffTeamMember,
|
|
556
|
+
let member = await em.findOne(StaffTeamMember, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
546
557
|
if (!member) {
|
|
547
558
|
member = em.create(StaffTeamMember, {
|
|
548
559
|
id: before.id,
|
|
@@ -25,6 +25,11 @@ import {
|
|
|
25
25
|
ensureTenantScope,
|
|
26
26
|
extractUndoPayload,
|
|
27
27
|
scopeForDecryption,
|
|
28
|
+
scopedStaffSnapshotWhere,
|
|
29
|
+
staffSnapshotDecryptionScope,
|
|
30
|
+
staffSnapshotScopeFromContext,
|
|
31
|
+
staffSnapshotScopeFromSnapshot,
|
|
32
|
+
type StaffSnapshotScope,
|
|
28
33
|
} from './shared'
|
|
29
34
|
import { E } from '#generated/entities.ids.generated'
|
|
30
35
|
|
|
@@ -51,8 +56,14 @@ type TeamRoleUndoPayload = {
|
|
|
51
56
|
customAfter?: CustomFieldSnapshot | null
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
async function loadTeamRoleSnapshot(em: EntityManager, id: string): Promise<TeamRoleSnapshot | null> {
|
|
55
|
-
const role = await findOneWithDecryption(
|
|
59
|
+
async function loadTeamRoleSnapshot(em: EntityManager, id: string, scope?: StaffSnapshotScope | null): Promise<TeamRoleSnapshot | null> {
|
|
60
|
+
const role = await findOneWithDecryption(
|
|
61
|
+
em,
|
|
62
|
+
StaffTeamRole,
|
|
63
|
+
scopedStaffSnapshotWhere(id, scope),
|
|
64
|
+
undefined,
|
|
65
|
+
staffSnapshotDecryptionScope(scope),
|
|
66
|
+
)
|
|
56
67
|
if (!role) return null
|
|
57
68
|
return {
|
|
58
69
|
id: role.id,
|
|
@@ -157,14 +168,14 @@ const createTeamRoleCommand: CommandHandler<StaffTeamRoleCreateInput, { roleId:
|
|
|
157
168
|
},
|
|
158
169
|
captureAfter: async (_input, result, ctx) => {
|
|
159
170
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
160
|
-
const snapshot = await loadTeamRoleSnapshot(em, result.roleId)
|
|
171
|
+
const snapshot = await loadTeamRoleSnapshot(em, result.roleId, staffSnapshotScopeFromContext(ctx))
|
|
161
172
|
if (!snapshot) return null
|
|
162
173
|
const custom = await loadTeamRoleCustomSnapshot(em, snapshot)
|
|
163
174
|
return { snapshot, custom }
|
|
164
175
|
},
|
|
165
176
|
buildLog: async ({ result, ctx }) => {
|
|
166
177
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
167
|
-
const snapshot = await loadTeamRoleSnapshot(em, result.roleId)
|
|
178
|
+
const snapshot = await loadTeamRoleSnapshot(em, result.roleId, staffSnapshotScopeFromContext(ctx))
|
|
168
179
|
if (!snapshot) return null
|
|
169
180
|
const custom = await loadTeamRoleCustomSnapshot(em, snapshot)
|
|
170
181
|
const { translate } = await resolveTranslations()
|
|
@@ -188,7 +199,7 @@ const createTeamRoleCommand: CommandHandler<StaffTeamRoleCreateInput, { roleId:
|
|
|
188
199
|
const after = payload?.after
|
|
189
200
|
if (!after) return
|
|
190
201
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
191
|
-
const role = await em.findOne(StaffTeamRole,
|
|
202
|
+
const role = await em.findOne(StaffTeamRole, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
192
203
|
if (role) {
|
|
193
204
|
role.deletedAt = new Date()
|
|
194
205
|
await em.flush()
|
|
@@ -231,7 +242,7 @@ const updateTeamRoleCommand: CommandHandler<StaffTeamRoleUpdateInput, { roleId:
|
|
|
231
242
|
async prepare(rawInput, ctx) {
|
|
232
243
|
const { parsed } = parseWithCustomFields(staffTeamRoleUpdateSchema, rawInput)
|
|
233
244
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
234
|
-
const snapshot = await loadTeamRoleSnapshot(em, parsed.id)
|
|
245
|
+
const snapshot = await loadTeamRoleSnapshot(em, parsed.id, staffSnapshotScopeFromContext(ctx))
|
|
235
246
|
if (!snapshot) return {}
|
|
236
247
|
const custom = await loadTeamRoleCustomSnapshot(em, snapshot)
|
|
237
248
|
return { before: snapshot, customBefore: custom }
|
|
@@ -293,7 +304,7 @@ const updateTeamRoleCommand: CommandHandler<StaffTeamRoleUpdateInput, { roleId:
|
|
|
293
304
|
const before = snapshots.before as TeamRoleSnapshot | undefined
|
|
294
305
|
if (!before) return null
|
|
295
306
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
296
|
-
const after = await loadTeamRoleSnapshot(em, before.id)
|
|
307
|
+
const after = await loadTeamRoleSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))
|
|
297
308
|
if (!after) return null
|
|
298
309
|
const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined
|
|
299
310
|
const customAfter = await loadTeamRoleCustomSnapshot(em, after)
|
|
@@ -334,7 +345,7 @@ const updateTeamRoleCommand: CommandHandler<StaffTeamRoleUpdateInput, { roleId:
|
|
|
334
345
|
const before = payload?.before
|
|
335
346
|
if (!before) return
|
|
336
347
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
337
|
-
const role = await em.findOne(StaffTeamRole,
|
|
348
|
+
const role = await em.findOne(StaffTeamRole, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
338
349
|
if (!role) return
|
|
339
350
|
role.teamId = before.teamId ?? null
|
|
340
351
|
role.name = before.name
|
|
@@ -379,7 +390,7 @@ const deleteTeamRoleCommand: CommandHandler<{ id?: string }, { roleId: string }>
|
|
|
379
390
|
const id = input?.id
|
|
380
391
|
if (!id) throw new CrudHttpError(400, { error: 'Role id is required.' })
|
|
381
392
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
382
|
-
const snapshot = await loadTeamRoleSnapshot(em, id)
|
|
393
|
+
const snapshot = await loadTeamRoleSnapshot(em, id, staffSnapshotScopeFromContext(ctx))
|
|
383
394
|
if (!snapshot) return {}
|
|
384
395
|
const custom = await loadTeamRoleCustomSnapshot(em, snapshot)
|
|
385
396
|
return { before: snapshot, customBefore: custom }
|
|
@@ -464,7 +475,7 @@ const deleteTeamRoleCommand: CommandHandler<{ id?: string }, { roleId: string }>
|
|
|
464
475
|
const before = payload?.before
|
|
465
476
|
if (!before) return
|
|
466
477
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
467
|
-
let role = await em.findOne(StaffTeamRole,
|
|
478
|
+
let role = await em.findOne(StaffTeamRole, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
468
479
|
if (!role) {
|
|
469
480
|
role = em.create(StaffTeamRole, {
|
|
470
481
|
id: before.id,
|
|
@@ -25,6 +25,11 @@ import {
|
|
|
25
25
|
ensureTenantScope,
|
|
26
26
|
extractUndoPayload,
|
|
27
27
|
scopeForDecryption,
|
|
28
|
+
scopedStaffSnapshotWhere,
|
|
29
|
+
staffSnapshotDecryptionScope,
|
|
30
|
+
staffSnapshotScopeFromContext,
|
|
31
|
+
staffSnapshotScopeFromSnapshot,
|
|
32
|
+
type StaffSnapshotScope,
|
|
28
33
|
} from './shared'
|
|
29
34
|
import { E } from '#generated/entities.ids.generated'
|
|
30
35
|
|
|
@@ -49,8 +54,14 @@ type TeamUndoPayload = {
|
|
|
49
54
|
customAfter?: CustomFieldSnapshot | null
|
|
50
55
|
}
|
|
51
56
|
|
|
52
|
-
async function loadTeamSnapshot(em: EntityManager, id: string): Promise<TeamSnapshot | null> {
|
|
53
|
-
const team = await findOneWithDecryption(
|
|
57
|
+
async function loadTeamSnapshot(em: EntityManager, id: string, scope?: StaffSnapshotScope | null): Promise<TeamSnapshot | null> {
|
|
58
|
+
const team = await findOneWithDecryption(
|
|
59
|
+
em,
|
|
60
|
+
StaffTeam,
|
|
61
|
+
scopedStaffSnapshotWhere(id, scope),
|
|
62
|
+
undefined,
|
|
63
|
+
staffSnapshotDecryptionScope(scope),
|
|
64
|
+
)
|
|
54
65
|
if (!team) return null
|
|
55
66
|
return {
|
|
56
67
|
id: team.id,
|
|
@@ -129,14 +140,14 @@ const createTeamCommand: CommandHandler<StaffTeamCreateInput, { teamId: string }
|
|
|
129
140
|
},
|
|
130
141
|
captureAfter: async (_input, result, ctx) => {
|
|
131
142
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
132
|
-
const snapshot = await loadTeamSnapshot(em, result.teamId)
|
|
143
|
+
const snapshot = await loadTeamSnapshot(em, result.teamId, staffSnapshotScopeFromContext(ctx))
|
|
133
144
|
if (!snapshot) return null
|
|
134
145
|
const custom = await loadTeamCustomSnapshot(em, snapshot)
|
|
135
146
|
return { snapshot, custom }
|
|
136
147
|
},
|
|
137
148
|
buildLog: async ({ result, ctx }) => {
|
|
138
149
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
139
|
-
const snapshot = await loadTeamSnapshot(em, result.teamId)
|
|
150
|
+
const snapshot = await loadTeamSnapshot(em, result.teamId, staffSnapshotScopeFromContext(ctx))
|
|
140
151
|
if (!snapshot) return null
|
|
141
152
|
const custom = await loadTeamCustomSnapshot(em, snapshot)
|
|
142
153
|
const { translate } = await resolveTranslations()
|
|
@@ -160,7 +171,7 @@ const createTeamCommand: CommandHandler<StaffTeamCreateInput, { teamId: string }
|
|
|
160
171
|
const after = payload?.after
|
|
161
172
|
if (!after) return
|
|
162
173
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
163
|
-
const team = await em.findOne(StaffTeam,
|
|
174
|
+
const team = await em.findOne(StaffTeam, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
164
175
|
if (team) {
|
|
165
176
|
team.deletedAt = new Date()
|
|
166
177
|
await em.flush()
|
|
@@ -203,7 +214,7 @@ const updateTeamCommand: CommandHandler<StaffTeamUpdateInput, { teamId: string }
|
|
|
203
214
|
async prepare(rawInput, ctx) {
|
|
204
215
|
const { parsed } = parseWithCustomFields(staffTeamUpdateSchema, rawInput)
|
|
205
216
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
206
|
-
const snapshot = await loadTeamSnapshot(em, parsed.id)
|
|
217
|
+
const snapshot = await loadTeamSnapshot(em, parsed.id, staffSnapshotScopeFromContext(ctx))
|
|
207
218
|
if (!snapshot) return {}
|
|
208
219
|
const custom = await loadTeamCustomSnapshot(em, snapshot)
|
|
209
220
|
return { before: snapshot, customBefore: custom }
|
|
@@ -258,7 +269,7 @@ const updateTeamCommand: CommandHandler<StaffTeamUpdateInput, { teamId: string }
|
|
|
258
269
|
const before = snapshots.before as TeamSnapshot | undefined
|
|
259
270
|
if (!before) return null
|
|
260
271
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
261
|
-
const after = await loadTeamSnapshot(em, before.id)
|
|
272
|
+
const after = await loadTeamSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))
|
|
262
273
|
if (!after) return null
|
|
263
274
|
const customBefore = (snapshots as { customBefore?: CustomFieldSnapshot | null }).customBefore ?? undefined
|
|
264
275
|
const customAfter = await loadTeamCustomSnapshot(em, after)
|
|
@@ -297,7 +308,7 @@ const updateTeamCommand: CommandHandler<StaffTeamUpdateInput, { teamId: string }
|
|
|
297
308
|
const before = payload?.before
|
|
298
309
|
if (!before) return
|
|
299
310
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
300
|
-
const team = await em.findOne(StaffTeam,
|
|
311
|
+
const team = await em.findOne(StaffTeam, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
301
312
|
if (!team) return
|
|
302
313
|
team.name = before.name
|
|
303
314
|
team.description = before.description ?? null
|
|
@@ -340,7 +351,7 @@ const deleteTeamCommand: CommandHandler<{ id?: string }, { teamId: string }> = {
|
|
|
340
351
|
const id = input?.id
|
|
341
352
|
if (!id) throw new CrudHttpError(400, { error: 'Team id is required.' })
|
|
342
353
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
343
|
-
const snapshot = await loadTeamSnapshot(em, id)
|
|
354
|
+
const snapshot = await loadTeamSnapshot(em, id, staffSnapshotScopeFromContext(ctx))
|
|
344
355
|
if (!snapshot) return {}
|
|
345
356
|
const custom = await loadTeamCustomSnapshot(em, snapshot)
|
|
346
357
|
return { before: snapshot, customBefore: custom }
|
|
@@ -418,7 +429,7 @@ const deleteTeamCommand: CommandHandler<{ id?: string }, { teamId: string }> = {
|
|
|
418
429
|
const before = payload?.before
|
|
419
430
|
if (!before) return
|
|
420
431
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
421
|
-
let team = await em.findOne(StaffTeam,
|
|
432
|
+
let team = await em.findOne(StaffTeam, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
422
433
|
if (!team) {
|
|
423
434
|
team = em.create(StaffTeam, {
|
|
424
435
|
id: before.id,
|
|
@@ -30,6 +30,11 @@ import {
|
|
|
30
30
|
ensureTenantScope,
|
|
31
31
|
extractUndoPayload,
|
|
32
32
|
scopeForDecryption,
|
|
33
|
+
scopedStaffSnapshotWhere,
|
|
34
|
+
staffSnapshotDecryptionScope,
|
|
35
|
+
staffSnapshotScopeFromContext,
|
|
36
|
+
staffSnapshotScopeFromSnapshot,
|
|
37
|
+
type StaffSnapshotScope,
|
|
33
38
|
} from './shared'
|
|
34
39
|
import { getStaffMemberByUserId } from '../lib/staffMemberResolver'
|
|
35
40
|
|
|
@@ -132,8 +137,14 @@ type TimeEntryUndoPayload = {
|
|
|
132
137
|
after?: TimeEntrySnapshot | null
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
async function loadTimeEntrySnapshot(em: EntityManager, id: string): Promise<TimeEntrySnapshot | null> {
|
|
136
|
-
const entry = await findOneWithDecryption(
|
|
140
|
+
async function loadTimeEntrySnapshot(em: EntityManager, id: string, scope?: StaffSnapshotScope | null): Promise<TimeEntrySnapshot | null> {
|
|
141
|
+
const entry = await findOneWithDecryption(
|
|
142
|
+
em,
|
|
143
|
+
StaffTimeEntry,
|
|
144
|
+
scopedStaffSnapshotWhere(id, scope),
|
|
145
|
+
undefined,
|
|
146
|
+
staffSnapshotDecryptionScope(scope),
|
|
147
|
+
)
|
|
137
148
|
if (!entry) return null
|
|
138
149
|
return {
|
|
139
150
|
id: entry.id,
|
|
@@ -241,13 +252,13 @@ const createTimeEntryCommand: CommandHandler<StaffTimeEntryCreateInput, { timeEn
|
|
|
241
252
|
},
|
|
242
253
|
captureAfter: async (_input, result, ctx) => {
|
|
243
254
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
244
|
-
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId)
|
|
255
|
+
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId, staffSnapshotScopeFromContext(ctx))
|
|
245
256
|
if (!snapshot) return null
|
|
246
257
|
return { snapshot }
|
|
247
258
|
},
|
|
248
259
|
buildLog: async ({ result, ctx }) => {
|
|
249
260
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
250
|
-
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId)
|
|
261
|
+
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId, staffSnapshotScopeFromContext(ctx))
|
|
251
262
|
if (!snapshot) return null
|
|
252
263
|
const { translate } = await resolveTranslations()
|
|
253
264
|
return {
|
|
@@ -269,7 +280,7 @@ const createTimeEntryCommand: CommandHandler<StaffTimeEntryCreateInput, { timeEn
|
|
|
269
280
|
const after = payload?.after
|
|
270
281
|
if (!after) return
|
|
271
282
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
272
|
-
const entry = await em.findOne(StaffTimeEntry,
|
|
283
|
+
const entry = await em.findOne(StaffTimeEntry, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
273
284
|
if (entry) {
|
|
274
285
|
entry.deletedAt = new Date()
|
|
275
286
|
await em.flush()
|
|
@@ -411,13 +422,13 @@ const startTimerCommand: CommandHandler<StaffTimeEntryStartTimerInput, { timeEnt
|
|
|
411
422
|
},
|
|
412
423
|
captureAfter: async (_input, result, ctx) => {
|
|
413
424
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
414
|
-
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId)
|
|
425
|
+
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId, staffSnapshotScopeFromContext(ctx))
|
|
415
426
|
if (!snapshot) return null
|
|
416
427
|
return { snapshot }
|
|
417
428
|
},
|
|
418
429
|
buildLog: async ({ result, ctx }) => {
|
|
419
430
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
420
|
-
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId)
|
|
431
|
+
const snapshot = await loadTimeEntrySnapshot(em, result.timeEntryId, staffSnapshotScopeFromContext(ctx))
|
|
421
432
|
if (!snapshot) return null
|
|
422
433
|
const { translate } = await resolveTranslations()
|
|
423
434
|
return {
|
|
@@ -439,7 +450,7 @@ const startTimerCommand: CommandHandler<StaffTimeEntryStartTimerInput, { timeEnt
|
|
|
439
450
|
const after = payload?.after
|
|
440
451
|
if (!after) return
|
|
441
452
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
442
|
-
const entry = await em.findOne(StaffTimeEntry,
|
|
453
|
+
const entry = await em.findOne(StaffTimeEntry, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
443
454
|
if (entry) {
|
|
444
455
|
entry.deletedAt = new Date()
|
|
445
456
|
await em.flush()
|
|
@@ -460,7 +471,7 @@ const updateTimeEntryCommand: CommandHandler<StaffTimeEntryUpdateInput, { timeEn
|
|
|
460
471
|
async prepare(rawInput, ctx) {
|
|
461
472
|
const parsed = staffTimeEntryUpdateSchema.parse(rawInput)
|
|
462
473
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
463
|
-
const snapshot = await loadTimeEntrySnapshot(em, parsed.id)
|
|
474
|
+
const snapshot = await loadTimeEntrySnapshot(em, parsed.id, staffSnapshotScopeFromContext(ctx))
|
|
464
475
|
if (!snapshot) return {}
|
|
465
476
|
return { before: snapshot }
|
|
466
477
|
},
|
|
@@ -521,7 +532,7 @@ const updateTimeEntryCommand: CommandHandler<StaffTimeEntryUpdateInput, { timeEn
|
|
|
521
532
|
const before = snapshots.before as TimeEntrySnapshot | undefined
|
|
522
533
|
if (!before) return null
|
|
523
534
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
524
|
-
const after = await loadTimeEntrySnapshot(em, before.id)
|
|
535
|
+
const after = await loadTimeEntrySnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))
|
|
525
536
|
if (!after) return null
|
|
526
537
|
const changes = buildChanges(before as unknown as Record<string, unknown>, after as unknown as Record<string, unknown>, [
|
|
527
538
|
'date',
|
|
@@ -556,7 +567,7 @@ const updateTimeEntryCommand: CommandHandler<StaffTimeEntryUpdateInput, { timeEn
|
|
|
556
567
|
const before = payload?.before
|
|
557
568
|
if (!before) return
|
|
558
569
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
559
|
-
const entry = await em.findOne(StaffTimeEntry,
|
|
570
|
+
const entry = await em.findOne(StaffTimeEntry, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
560
571
|
if (!entry) return
|
|
561
572
|
entry.date = before.date as unknown as Date
|
|
562
573
|
entry.durationMinutes = before.durationMinutes
|
|
@@ -586,7 +597,7 @@ const deleteTimeEntryCommand: CommandHandler<{ id?: string }, { timeEntryId: str
|
|
|
586
597
|
const id = input?.id
|
|
587
598
|
if (!id) throw new CrudHttpError(400, { error: 'Time entry id is required.' })
|
|
588
599
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
589
|
-
const snapshot = await loadTimeEntrySnapshot(em, id)
|
|
600
|
+
const snapshot = await loadTimeEntrySnapshot(em, id, staffSnapshotScopeFromContext(ctx))
|
|
590
601
|
if (!snapshot) return {}
|
|
591
602
|
return { before: snapshot }
|
|
592
603
|
},
|
|
@@ -656,7 +667,7 @@ const deleteTimeEntryCommand: CommandHandler<{ id?: string }, { timeEntryId: str
|
|
|
656
667
|
const before = payload?.before
|
|
657
668
|
if (!before) return
|
|
658
669
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
659
|
-
let entry = await em.findOne(StaffTimeEntry,
|
|
670
|
+
let entry = await em.findOne(StaffTimeEntry, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
660
671
|
if (!entry) {
|
|
661
672
|
entry = em.create(StaffTimeEntry, {
|
|
662
673
|
id: before.id,
|
|
@@ -35,6 +35,11 @@ import {
|
|
|
35
35
|
ensureTenantScope,
|
|
36
36
|
extractUndoPayload,
|
|
37
37
|
scopeForDecryption,
|
|
38
|
+
scopedStaffSnapshotWhere,
|
|
39
|
+
staffSnapshotDecryptionScope,
|
|
40
|
+
staffSnapshotScopeFromContext,
|
|
41
|
+
staffSnapshotScopeFromSnapshot,
|
|
42
|
+
type StaffSnapshotScope,
|
|
38
43
|
} from './shared'
|
|
39
44
|
|
|
40
45
|
function isUniqueViolation(error: unknown): boolean {
|
|
@@ -87,8 +92,14 @@ type TimeProjectMemberUndoPayload = {
|
|
|
87
92
|
after?: TimeProjectMemberSnapshot | null
|
|
88
93
|
}
|
|
89
94
|
|
|
90
|
-
async function loadTimeProjectSnapshot(em: EntityManager, id: string): Promise<TimeProjectSnapshot | null> {
|
|
91
|
-
const project = await findOneWithDecryption(
|
|
95
|
+
async function loadTimeProjectSnapshot(em: EntityManager, id: string, scope?: StaffSnapshotScope | null): Promise<TimeProjectSnapshot | null> {
|
|
96
|
+
const project = await findOneWithDecryption(
|
|
97
|
+
em,
|
|
98
|
+
StaffTimeProject,
|
|
99
|
+
scopedStaffSnapshotWhere(id, scope),
|
|
100
|
+
undefined,
|
|
101
|
+
staffSnapshotDecryptionScope(scope),
|
|
102
|
+
)
|
|
92
103
|
if (!project) return null
|
|
93
104
|
return {
|
|
94
105
|
id: project.id,
|
|
@@ -108,8 +119,14 @@ async function loadTimeProjectSnapshot(em: EntityManager, id: string): Promise<T
|
|
|
108
119
|
}
|
|
109
120
|
}
|
|
110
121
|
|
|
111
|
-
async function loadTimeProjectMemberSnapshot(em: EntityManager, id: string): Promise<TimeProjectMemberSnapshot | null> {
|
|
112
|
-
const member = await findOneWithDecryption(
|
|
122
|
+
async function loadTimeProjectMemberSnapshot(em: EntityManager, id: string, scope?: StaffSnapshotScope | null): Promise<TimeProjectMemberSnapshot | null> {
|
|
123
|
+
const member = await findOneWithDecryption(
|
|
124
|
+
em,
|
|
125
|
+
StaffTimeProjectMember,
|
|
126
|
+
scopedStaffSnapshotWhere(id, scope),
|
|
127
|
+
undefined,
|
|
128
|
+
staffSnapshotDecryptionScope(scope),
|
|
129
|
+
)
|
|
113
130
|
if (!member) return null
|
|
114
131
|
return {
|
|
115
132
|
id: member.id,
|
|
@@ -223,13 +240,13 @@ const createTimeProjectCommand: CommandHandler<StaffTimeProjectCreateInput, { ti
|
|
|
223
240
|
},
|
|
224
241
|
captureAfter: async (_input, result, ctx) => {
|
|
225
242
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
226
|
-
const snapshot = await loadTimeProjectSnapshot(em, result.timeProjectId)
|
|
243
|
+
const snapshot = await loadTimeProjectSnapshot(em, result.timeProjectId, staffSnapshotScopeFromContext(ctx))
|
|
227
244
|
if (!snapshot) return null
|
|
228
245
|
return { snapshot }
|
|
229
246
|
},
|
|
230
247
|
buildLog: async ({ result, ctx }) => {
|
|
231
248
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
232
|
-
const snapshot = await loadTimeProjectSnapshot(em, result.timeProjectId)
|
|
249
|
+
const snapshot = await loadTimeProjectSnapshot(em, result.timeProjectId, staffSnapshotScopeFromContext(ctx))
|
|
233
250
|
if (!snapshot) return null
|
|
234
251
|
const { translate } = await resolveTranslations()
|
|
235
252
|
return {
|
|
@@ -251,7 +268,7 @@ const createTimeProjectCommand: CommandHandler<StaffTimeProjectCreateInput, { ti
|
|
|
251
268
|
const after = payload?.after
|
|
252
269
|
if (!after) return
|
|
253
270
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
254
|
-
const project = await em.findOne(StaffTimeProject,
|
|
271
|
+
const project = await em.findOne(StaffTimeProject, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
255
272
|
if (project) {
|
|
256
273
|
project.deletedAt = new Date()
|
|
257
274
|
await em.flush()
|
|
@@ -284,7 +301,7 @@ const updateTimeProjectCommand: CommandHandler<StaffTimeProjectUpdateInput, { ti
|
|
|
284
301
|
async prepare(rawInput, ctx) {
|
|
285
302
|
const parsed = staffTimeProjectUpdateSchema.parse(rawInput)
|
|
286
303
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
287
|
-
const snapshot = await loadTimeProjectSnapshot(em, parsed.id)
|
|
304
|
+
const snapshot = await loadTimeProjectSnapshot(em, parsed.id, staffSnapshotScopeFromContext(ctx))
|
|
288
305
|
if (!snapshot) return {}
|
|
289
306
|
return { before: snapshot }
|
|
290
307
|
},
|
|
@@ -346,7 +363,7 @@ const updateTimeProjectCommand: CommandHandler<StaffTimeProjectUpdateInput, { ti
|
|
|
346
363
|
const before = snapshots.before as TimeProjectSnapshot | undefined
|
|
347
364
|
if (!before) return null
|
|
348
365
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
349
|
-
const after = await loadTimeProjectSnapshot(em, before.id)
|
|
366
|
+
const after = await loadTimeProjectSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))
|
|
350
367
|
if (!after) return null
|
|
351
368
|
const changes = buildChanges(before as unknown as Record<string, unknown>, after as unknown as Record<string, unknown>, [
|
|
352
369
|
'name',
|
|
@@ -384,7 +401,7 @@ const updateTimeProjectCommand: CommandHandler<StaffTimeProjectUpdateInput, { ti
|
|
|
384
401
|
const before = payload?.before
|
|
385
402
|
if (!before) return
|
|
386
403
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
387
|
-
const project = await em.findOne(StaffTimeProject,
|
|
404
|
+
const project = await em.findOne(StaffTimeProject, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
388
405
|
if (!project) return
|
|
389
406
|
project.name = before.name
|
|
390
407
|
project.customerId = before.customerId ?? null
|
|
@@ -421,7 +438,7 @@ const deleteTimeProjectCommand: CommandHandler<{ id?: string }, { timeProjectId:
|
|
|
421
438
|
const id = input?.id
|
|
422
439
|
if (!id) throw new CrudHttpError(400, { error: 'Time project id is required.' })
|
|
423
440
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
424
|
-
const snapshot = await loadTimeProjectSnapshot(em, id)
|
|
441
|
+
const snapshot = await loadTimeProjectSnapshot(em, id, staffSnapshotScopeFromContext(ctx))
|
|
425
442
|
if (!snapshot) return {}
|
|
426
443
|
return { before: snapshot }
|
|
427
444
|
},
|
|
@@ -482,7 +499,7 @@ const deleteTimeProjectCommand: CommandHandler<{ id?: string }, { timeProjectId:
|
|
|
482
499
|
const before = payload?.before
|
|
483
500
|
if (!before) return
|
|
484
501
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
485
|
-
let project = await em.findOne(StaffTimeProject,
|
|
502
|
+
let project = await em.findOne(StaffTimeProject, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
486
503
|
if (!project) {
|
|
487
504
|
project = em.create(StaffTimeProject, {
|
|
488
505
|
id: before.id,
|
|
@@ -604,13 +621,13 @@ const assignTimeProjectMemberCommand: CommandHandler<StaffTimeProjectMemberAssig
|
|
|
604
621
|
},
|
|
605
622
|
captureAfter: async (_input, result, ctx) => {
|
|
606
623
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
607
|
-
const snapshot = await loadTimeProjectMemberSnapshot(em, result.timeProjectMemberId)
|
|
624
|
+
const snapshot = await loadTimeProjectMemberSnapshot(em, result.timeProjectMemberId, staffSnapshotScopeFromContext(ctx))
|
|
608
625
|
if (!snapshot) return null
|
|
609
626
|
return { snapshot }
|
|
610
627
|
},
|
|
611
628
|
buildLog: async ({ result, ctx }) => {
|
|
612
629
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
613
|
-
const snapshot = await loadTimeProjectMemberSnapshot(em, result.timeProjectMemberId)
|
|
630
|
+
const snapshot = await loadTimeProjectMemberSnapshot(em, result.timeProjectMemberId, staffSnapshotScopeFromContext(ctx))
|
|
614
631
|
if (!snapshot) return null
|
|
615
632
|
const { translate } = await resolveTranslations()
|
|
616
633
|
return {
|
|
@@ -632,7 +649,7 @@ const assignTimeProjectMemberCommand: CommandHandler<StaffTimeProjectMemberAssig
|
|
|
632
649
|
const after = payload?.after
|
|
633
650
|
if (!after) return
|
|
634
651
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
635
|
-
const member = await em.findOne(StaffTimeProjectMember,
|
|
652
|
+
const member = await em.findOne(StaffTimeProjectMember, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)))
|
|
636
653
|
if (member) {
|
|
637
654
|
member.deletedAt = new Date()
|
|
638
655
|
await em.flush()
|
|
@@ -662,7 +679,7 @@ const unassignTimeProjectMemberCommand: CommandHandler<{ id?: string }, { timePr
|
|
|
662
679
|
const id = input?.id
|
|
663
680
|
if (!id) throw new CrudHttpError(400, { error: 'Time project member id is required.' })
|
|
664
681
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
665
|
-
const snapshot = await loadTimeProjectMemberSnapshot(em, id)
|
|
682
|
+
const snapshot = await loadTimeProjectMemberSnapshot(em, id, staffSnapshotScopeFromContext(ctx))
|
|
666
683
|
if (!snapshot) return {}
|
|
667
684
|
return { before: snapshot }
|
|
668
685
|
},
|
|
@@ -720,7 +737,7 @@ const unassignTimeProjectMemberCommand: CommandHandler<{ id?: string }, { timePr
|
|
|
720
737
|
const before = payload?.before
|
|
721
738
|
if (!before) return
|
|
722
739
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
723
|
-
let member = await em.findOne(StaffTimeProjectMember,
|
|
740
|
+
let member = await em.findOne(StaffTimeProjectMember, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)))
|
|
724
741
|
if (!member) {
|
|
725
742
|
member = em.create(StaffTimeProjectMember, {
|
|
726
743
|
id: before.id,
|