@stamhoofd/backend 2.58.0 → 2.60.0
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/index.ts +10 -1
- package/package.json +12 -12
- package/src/audit-logs/DocumentTemplateLogger.ts +22 -0
- package/src/audit-logs/EventLogger.ts +30 -0
- package/src/audit-logs/GroupLogger.ts +95 -0
- package/src/audit-logs/MemberLogger.ts +24 -0
- package/src/audit-logs/MemberPlatformMembershipLogger.ts +60 -0
- package/src/audit-logs/MemberResponsibilityRecordLogger.ts +69 -0
- package/src/audit-logs/ModelLogger.ts +219 -0
- package/src/audit-logs/OrderLogger.ts +57 -0
- package/src/audit-logs/OrganizationLogger.ts +16 -0
- package/src/audit-logs/OrganizationRegistrationPeriodLogger.ts +77 -0
- package/src/audit-logs/PaymentLogger.ts +43 -0
- package/src/audit-logs/PlatformLogger.ts +13 -0
- package/src/audit-logs/RegistrationLogger.ts +53 -0
- package/src/audit-logs/RegistrationPeriodLogger.ts +21 -0
- package/src/audit-logs/StripeAccountLogger.ts +47 -0
- package/src/audit-logs/WebshopLogger.ts +35 -0
- package/src/crons/updateSetupSteps.ts +1 -1
- package/src/crons.ts +2 -1
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +12 -24
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +7 -21
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +5 -13
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +5 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +0 -15
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +43 -27
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +0 -19
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +3 -13
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +20 -43
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +0 -6
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +0 -6
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +5 -14
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +7 -4
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +8 -2
- package/src/helpers/AuthenticatedStructures.ts +16 -1
- package/src/helpers/Context.ts +8 -2
- package/src/helpers/MemberUserSyncer.ts +45 -40
- package/src/helpers/PeriodHelper.ts +5 -5
- package/src/helpers/SetupStepUpdater.ts +503 -0
- package/src/helpers/TagHelper.ts +23 -20
- package/src/seeds/1722344162-update-membership.ts +2 -2
- package/src/seeds/1726572303-schedule-stock-updates.ts +2 -1
- package/src/seeds/1726847064-setup-steps.ts +1 -1
- package/src/seeds/1733319079-fill-paying-organization-ids.ts +68 -0
- package/src/services/AuditLogService.ts +81 -296
- package/src/services/BalanceItemPaymentService.ts +1 -1
- package/src/services/BalanceItemService.ts +14 -5
- package/src/services/DocumentService.ts +43 -0
- package/src/services/MemberNumberService.ts +120 -0
- package/src/services/PaymentService.ts +199 -193
- package/src/services/PlatformMembershipService.ts +284 -0
- package/src/services/RegistrationService.ts +78 -27
- package/src/services/diff.ts +512 -0
- package/src/sql-filters/events.ts +13 -1
- package/src/helpers/MembershipHelper.ts +0 -54
- package/src/services/explainPatch.ts +0 -782
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Organization, OrganizationRegistrationPeriod, RegistrationPeriod } from '@stamhoofd/models';
|
|
2
|
+
import { getDefaultGenerator, ModelLogger } from './ModelLogger';
|
|
3
|
+
import { AuditLogPatchItem, AuditLogPatchItemType, AuditLogReplacement, AuditLogReplacementType, AuditLogType } from '@stamhoofd/structures';
|
|
4
|
+
|
|
5
|
+
const defaultGenerator = getDefaultGenerator({
|
|
6
|
+
created: AuditLogType.OrganizationEdited,
|
|
7
|
+
updated: AuditLogType.OrganizationEdited,
|
|
8
|
+
deleted: AuditLogType.OrganizationEdited,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const OrganizationRegistrationPeriodLogger = new ModelLogger(OrganizationRegistrationPeriod, {
|
|
12
|
+
async optionsGenerator(event) {
|
|
13
|
+
const result = await defaultGenerator(event);
|
|
14
|
+
|
|
15
|
+
if (!result) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Load data
|
|
20
|
+
const organization = await Organization.getByID(event.model.organizationId);
|
|
21
|
+
if (!organization) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const period = await RegistrationPeriod.getByID(event.model.periodId);
|
|
26
|
+
if (!period) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
...result,
|
|
32
|
+
data: {
|
|
33
|
+
organization,
|
|
34
|
+
period,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
createReplacements(_, { data }) {
|
|
40
|
+
return new Map([
|
|
41
|
+
['o', AuditLogReplacement.create({
|
|
42
|
+
id: data.organization.id,
|
|
43
|
+
value: data.organization.name,
|
|
44
|
+
type: AuditLogReplacementType.Organization,
|
|
45
|
+
})],
|
|
46
|
+
]);
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
postProcess(event, options, log) {
|
|
50
|
+
const prependKey = AuditLogReplacement.create({
|
|
51
|
+
id: event.model.periodId,
|
|
52
|
+
value: options.data.period.getStructure().name,
|
|
53
|
+
type: AuditLogReplacementType.RegistrationPeriod,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Prefix changes
|
|
57
|
+
for (const item of log.patchList) {
|
|
58
|
+
item.key = item.key.prepend(prependKey);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (event.type === 'created') {
|
|
62
|
+
// Add create patch
|
|
63
|
+
log.patchList.push(AuditLogPatchItem.create({
|
|
64
|
+
key: prependKey,
|
|
65
|
+
type: AuditLogPatchItemType.Added,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (event.type === 'deleted') {
|
|
70
|
+
// Add delete patch
|
|
71
|
+
log.patchList.push(AuditLogPatchItem.create({
|
|
72
|
+
key: prependKey,
|
|
73
|
+
type: AuditLogPatchItemType.Removed,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Payment } from '@stamhoofd/models';
|
|
2
|
+
import { AuditLogReplacement, AuditLogReplacementType, AuditLogType, PaymentMethod, PaymentMethodHelper, PaymentStatusHelper } from '@stamhoofd/structures';
|
|
3
|
+
import { Formatter } from '@stamhoofd/utility';
|
|
4
|
+
import { getDefaultGenerator, ModelLogger } from './ModelLogger';
|
|
5
|
+
|
|
6
|
+
export const PaymentLogger = new ModelLogger(Payment, {
|
|
7
|
+
skipKeys: ['transferFee'],
|
|
8
|
+
|
|
9
|
+
optionsGenerator: getDefaultGenerator({
|
|
10
|
+
created: AuditLogType.PaymentAdded,
|
|
11
|
+
updated: AuditLogType.PaymentEdited,
|
|
12
|
+
deleted: AuditLogType.PaymentDeleted,
|
|
13
|
+
}),
|
|
14
|
+
|
|
15
|
+
generateDescription(event, options) {
|
|
16
|
+
if (event.type === 'created') {
|
|
17
|
+
let description = `Status: ${PaymentStatusHelper.getNameCapitalized(event.model.status)}\n`
|
|
18
|
+
+ `Bedrag: ${Formatter.price(event.model.price)}`;
|
|
19
|
+
|
|
20
|
+
if (event.model.method === PaymentMethod.Transfer && event.model.transferDescription) {
|
|
21
|
+
description += `\nMededeling: ${event.model.transferDescription}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return description;
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
createReplacements(model, options) {
|
|
29
|
+
let name = `${PaymentMethodHelper.getPaymentName(model.method)}`;
|
|
30
|
+
|
|
31
|
+
if (model.customer?.dynamicName) {
|
|
32
|
+
name += ` van ${model.customer.dynamicName}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return new Map([
|
|
36
|
+
['p', AuditLogReplacement.create({
|
|
37
|
+
id: model.id,
|
|
38
|
+
value: name,
|
|
39
|
+
type: AuditLogReplacementType.Payment,
|
|
40
|
+
})],
|
|
41
|
+
]);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Platform } from '@stamhoofd/models';
|
|
2
|
+
import { getDefaultGenerator, ModelLogger } from './ModelLogger';
|
|
3
|
+
import { AuditLogType } from '@stamhoofd/structures';
|
|
4
|
+
|
|
5
|
+
export const PlatformLogger = new ModelLogger(Platform, {
|
|
6
|
+
optionsGenerator: getDefaultGenerator({
|
|
7
|
+
updated: AuditLogType.PlatformSettingsChanged,
|
|
8
|
+
}),
|
|
9
|
+
|
|
10
|
+
postProcess(event, options, log) {
|
|
11
|
+
log.organizationId = null;
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Group, Member, Registration } from '@stamhoofd/models';
|
|
2
|
+
import { ModelLogger } from './ModelLogger';
|
|
3
|
+
import { AuditLogReplacement, AuditLogReplacementType, AuditLogType } from '@stamhoofd/structures';
|
|
4
|
+
|
|
5
|
+
export const RegistrationLogger = new ModelLogger(Registration, {
|
|
6
|
+
async optionsGenerator(event) {
|
|
7
|
+
if (event.type === 'created' && event.model.registeredAt === null) {
|
|
8
|
+
// Ignored for now
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const wasActive = event.type === 'updated' ? (!event.originalFields.deactivatedAt && !!event.originalFields.registeredAt) : true;
|
|
12
|
+
const isActive = event.type === 'deleted' ? false : (!event.model.deactivatedAt && !!event.model.registeredAt);
|
|
13
|
+
|
|
14
|
+
if (wasActive === isActive) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const member = await Member.getByID(event.model.memberId);
|
|
19
|
+
const group = await Group.getByID(event.model.groupId);
|
|
20
|
+
|
|
21
|
+
if (!member || !group) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
type: wasActive ? AuditLogType.MemberUnregistered : AuditLogType.MemberRegistered,
|
|
27
|
+
generatePatchList: false,
|
|
28
|
+
data: { member, group },
|
|
29
|
+
objectId: member.id,
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
createReplacements(_, { data }) {
|
|
34
|
+
return new Map([
|
|
35
|
+
['m', AuditLogReplacement.create({
|
|
36
|
+
id: data.member.id,
|
|
37
|
+
value: data.member.details.name,
|
|
38
|
+
type: AuditLogReplacementType.Member,
|
|
39
|
+
})],
|
|
40
|
+
['g', AuditLogReplacement.create({
|
|
41
|
+
id: data.group.id,
|
|
42
|
+
value: data.group.settings.name,
|
|
43
|
+
type: AuditLogReplacementType.Group,
|
|
44
|
+
})],
|
|
45
|
+
]);
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
generateDescription(event, options) {
|
|
49
|
+
const d = event.model.setRelation(Registration.group, options.data.group).getStructure();
|
|
50
|
+
return d.description;
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RegistrationPeriod } from '@stamhoofd/models';
|
|
2
|
+
import { getDefaultGenerator, ModelLogger } from './ModelLogger';
|
|
3
|
+
import { AuditLogReplacement, AuditLogReplacementType, AuditLogType } from '@stamhoofd/structures';
|
|
4
|
+
|
|
5
|
+
export const RegistrationPeriodLogger = new ModelLogger(RegistrationPeriod, {
|
|
6
|
+
optionsGenerator: getDefaultGenerator({
|
|
7
|
+
created: AuditLogType.RegistrationPeriodAdded,
|
|
8
|
+
updated: AuditLogType.RegistrationPeriodEdited,
|
|
9
|
+
deleted: AuditLogType.RegistrationPeriodDeleted,
|
|
10
|
+
}),
|
|
11
|
+
|
|
12
|
+
createReplacements(model) {
|
|
13
|
+
return new Map([
|
|
14
|
+
['p', AuditLogReplacement.create({
|
|
15
|
+
id: model.id,
|
|
16
|
+
value: model.getStructure().nameShort,
|
|
17
|
+
type: AuditLogReplacementType.RegistrationPeriod,
|
|
18
|
+
})],
|
|
19
|
+
]);
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { StripeAccount } from '@stamhoofd/models';
|
|
2
|
+
import { AuditLogReplacement, AuditLogReplacementType, AuditLogSource, AuditLogType } from '@stamhoofd/structures';
|
|
3
|
+
import { getDefaultGenerator, ModelLogger } from './ModelLogger';
|
|
4
|
+
|
|
5
|
+
const defaultGenerator = getDefaultGenerator({
|
|
6
|
+
created: AuditLogType.StripeAccountAdded,
|
|
7
|
+
updated: AuditLogType.StripeAccountEdited,
|
|
8
|
+
deleted: AuditLogType.StripeAccountDeleted,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const StripeAccountLogger = new ModelLogger(StripeAccount, {
|
|
12
|
+
async optionsGenerator(event) {
|
|
13
|
+
const result = await defaultGenerator(event);
|
|
14
|
+
|
|
15
|
+
if (!result) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (event.type === 'updated' && 'status' in event.changedFields && event.changedFields.status === 'deleted') {
|
|
20
|
+
result.type = AuditLogType.StripeAccountDeleted;
|
|
21
|
+
result.generatePatchList = false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return result;
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
createReplacements(model) {
|
|
28
|
+
return new Map([
|
|
29
|
+
['a', AuditLogReplacement.create({
|
|
30
|
+
id: model.id,
|
|
31
|
+
value: model.accountId,
|
|
32
|
+
type: AuditLogReplacementType.StripeAccount,
|
|
33
|
+
})],
|
|
34
|
+
]);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
postProcess: (event, _options, log) => {
|
|
38
|
+
if (log.type === AuditLogType.StripeAccountEdited) {
|
|
39
|
+
// Never caused by a user
|
|
40
|
+
log.userId = null;
|
|
41
|
+
|
|
42
|
+
if (log.source === AuditLogSource.User) {
|
|
43
|
+
log.source = AuditLogSource.System;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Webshop } from '@stamhoofd/models';
|
|
2
|
+
import { getDefaultGenerator, ModelLogger } from './ModelLogger';
|
|
3
|
+
import { AuditLogReplacement, AuditLogReplacementType, AuditLogType } from '@stamhoofd/structures';
|
|
4
|
+
|
|
5
|
+
const defaultGenerator = getDefaultGenerator({
|
|
6
|
+
created: AuditLogType.WebshopAdded,
|
|
7
|
+
updated: AuditLogType.WebshopEdited,
|
|
8
|
+
deleted: AuditLogType.WebshopDeleted,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const WebshopLogger = new ModelLogger(Webshop, {
|
|
12
|
+
skipKeys: [],
|
|
13
|
+
async optionsGenerator(event) {
|
|
14
|
+
const result = await defaultGenerator(event);
|
|
15
|
+
|
|
16
|
+
if (!result) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// todo: when placing an order / marking an order as paid
|
|
21
|
+
// we should not log any stock changes
|
|
22
|
+
|
|
23
|
+
return result;
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
createReplacements: (model) => {
|
|
27
|
+
return new Map([
|
|
28
|
+
['w', AuditLogReplacement.create({
|
|
29
|
+
id: model.id,
|
|
30
|
+
value: model.meta.name,
|
|
31
|
+
type: AuditLogReplacementType.Webshop,
|
|
32
|
+
})],
|
|
33
|
+
]);
|
|
34
|
+
},
|
|
35
|
+
});
|
package/src/crons.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { ExchangePaymentEndpoint } from './endpoints/organization/shared/Exchang
|
|
|
14
14
|
import { checkSettlements } from './helpers/CheckSettlements';
|
|
15
15
|
import { ForwardHandler } from './helpers/ForwardHandler';
|
|
16
16
|
import { PaymentService } from './services/PaymentService';
|
|
17
|
+
import { RegistrationService } from './services/RegistrationService';
|
|
17
18
|
|
|
18
19
|
// Importing postmark returns undefined (this is a bug, so we need to use require)
|
|
19
20
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -595,7 +596,7 @@ async function checkReservedUntil() {
|
|
|
595
596
|
});
|
|
596
597
|
|
|
597
598
|
for (const registration of registrations) {
|
|
598
|
-
|
|
599
|
+
RegistrationService.scheduleStockUpdate(registration.id);
|
|
599
600
|
}
|
|
600
601
|
|
|
601
602
|
// Update occupancy
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, patchObject, StringDecoder } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { Event, Group, Platform, RegistrationPeriod } from '@stamhoofd/models';
|
|
4
|
-
import { Event as EventStruct, GroupType, NamedObject, Group as GroupStruct, AuditLogType } from '@stamhoofd/structures';
|
|
4
|
+
import { Event as EventStruct, GroupType, NamedObject, Group as GroupStruct, AuditLogType, AuditLogSource } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
6
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
7
7
|
import { SQL, SQLWhereSign } from '@stamhoofd/sql';
|
|
@@ -96,7 +96,9 @@ export class PatchEventsEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
96
96
|
put.group.organizationId,
|
|
97
97
|
period,
|
|
98
98
|
);
|
|
99
|
-
await
|
|
99
|
+
await AuditLogService.setContext({ source: AuditLogSource.System }, async () => {
|
|
100
|
+
await event.syncGroupRequirements(group);
|
|
101
|
+
});
|
|
100
102
|
event.groupId = group.id;
|
|
101
103
|
}
|
|
102
104
|
|
|
@@ -107,15 +109,9 @@ export class PatchEventsEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
107
109
|
await event.save();
|
|
108
110
|
|
|
109
111
|
events.push(event);
|
|
110
|
-
|
|
111
|
-
await AuditLogService.log({
|
|
112
|
-
type: AuditLogType.EventAdded,
|
|
113
|
-
event,
|
|
114
|
-
});
|
|
115
112
|
}
|
|
116
113
|
|
|
117
114
|
const patchingEvents = await Event.getByIDs(...request.body.getPatches().map(p => p.id));
|
|
118
|
-
const initialStructs = (await AuthenticatedStructures.events(patchingEvents)).map(e => e.clone()); // Clone is required for audit log (otherwise references might change)
|
|
119
115
|
|
|
120
116
|
for (const patch of request.body.getPatches()) {
|
|
121
117
|
const event = patchingEvents.find(e => e.id === patch.id);
|
|
@@ -232,7 +228,11 @@ export class PatchEventsEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
232
228
|
// Correct period id if needed
|
|
233
229
|
const period = await RegistrationPeriod.getByDate(event.startDate);
|
|
234
230
|
if (event.groupId) {
|
|
235
|
-
await
|
|
231
|
+
await AuditLogService.setContext({ source: AuditLogSource.System }, async () => {
|
|
232
|
+
if (event.groupId) {
|
|
233
|
+
await PatchOrganizationRegistrationPeriodsEndpoint.patchGroup(GroupStruct.patch({ id: event.groupId }), period);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
}
|
|
@@ -246,20 +246,13 @@ export class PatchEventsEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
246
246
|
if (event.groupId) {
|
|
247
247
|
const group = await Group.getByID(event.groupId);
|
|
248
248
|
if (group) {
|
|
249
|
-
await
|
|
249
|
+
await AuditLogService.setContext({ source: AuditLogSource.System }, async () => {
|
|
250
|
+
await event.syncGroupRequirements(group);
|
|
251
|
+
});
|
|
250
252
|
}
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
events.push(event);
|
|
254
|
-
|
|
255
|
-
const struct = initialStructs.find(e => e.id === patch.id);
|
|
256
|
-
|
|
257
|
-
await AuditLogService.log({
|
|
258
|
-
type: AuditLogType.EventEdited,
|
|
259
|
-
event,
|
|
260
|
-
oldData: struct,
|
|
261
|
-
patch,
|
|
262
|
-
});
|
|
263
256
|
}
|
|
264
257
|
|
|
265
258
|
for (const id of request.body.getDeletes()) {
|
|
@@ -276,11 +269,6 @@ export class PatchEventsEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
276
269
|
}
|
|
277
270
|
|
|
278
271
|
await event.delete();
|
|
279
|
-
|
|
280
|
-
await AuditLogService.log({
|
|
281
|
-
type: AuditLogType.EventDeleted,
|
|
282
|
-
event,
|
|
283
|
-
});
|
|
284
272
|
}
|
|
285
273
|
|
|
286
274
|
const structures = await AuthenticatedStructures.events(events);
|
|
@@ -2,8 +2,8 @@ import { OneToManyRelation } from '@simonbackx/simple-database';
|
|
|
2
2
|
import { ConvertArrayToPatchableArray, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
3
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
5
|
-
import { BalanceItem, Document, Group, Member, MemberFactory, MemberPlatformMembership, MemberResponsibilityRecord, MemberWithRegistrations, mergeTwoMembers, Organization, Platform, RateLimiter, Registration,
|
|
6
|
-
import {
|
|
5
|
+
import { BalanceItem, Document, Group, Member, MemberFactory, MemberPlatformMembership, MemberResponsibilityRecord, MemberWithRegistrations, mergeTwoMembers, Organization, Platform, RateLimiter, Registration, User } from '@stamhoofd/models';
|
|
6
|
+
import { GroupType, MembersBlob, MemberWithRegistrationsBlob, PermissionLevel } from '@stamhoofd/structures';
|
|
7
7
|
import { Formatter } from '@stamhoofd/utility';
|
|
8
8
|
|
|
9
9
|
import { Email } from '@stamhoofd/email';
|
|
@@ -13,7 +13,9 @@ import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructure
|
|
|
13
13
|
import { Context } from '../../../helpers/Context';
|
|
14
14
|
import { MembershipCharger } from '../../../helpers/MembershipCharger';
|
|
15
15
|
import { MemberUserSyncer } from '../../../helpers/MemberUserSyncer';
|
|
16
|
-
import {
|
|
16
|
+
import { PlatformMembershipService } from '../../../services/PlatformMembershipService';
|
|
17
|
+
import { RegistrationService } from '../../../services/RegistrationService';
|
|
18
|
+
import { SetupStepUpdater } from '../../../helpers/SetupStepUpdater';
|
|
17
19
|
|
|
18
20
|
type Params = Record<string, never>;
|
|
19
21
|
type Query = undefined;
|
|
@@ -143,13 +145,6 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
|
|
|
143
145
|
|
|
144
146
|
// Auto link users based on data
|
|
145
147
|
await MemberUserSyncer.onChangeMember(member);
|
|
146
|
-
|
|
147
|
-
if (!duplicate) {
|
|
148
|
-
await AuditLogService.log({
|
|
149
|
-
type: AuditLogType.MemberAdded,
|
|
150
|
-
member: member,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
148
|
}
|
|
154
149
|
|
|
155
150
|
let shouldUpdateSetupSteps = false;
|
|
@@ -205,15 +200,6 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
|
|
|
205
200
|
|
|
206
201
|
await member.save();
|
|
207
202
|
|
|
208
|
-
if (patch.details) {
|
|
209
|
-
await AuditLogService.log({
|
|
210
|
-
type: AuditLogType.MemberEdited,
|
|
211
|
-
member: member,
|
|
212
|
-
oldMemberDetails: originalDetails,
|
|
213
|
-
memberDetailsPatch: patch.details,
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
203
|
// Update documents
|
|
218
204
|
await Document.updateForMember(member.id);
|
|
219
205
|
|
|
@@ -553,7 +539,7 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
|
|
|
553
539
|
|
|
554
540
|
for (const member of members) {
|
|
555
541
|
if (updateMembershipMemberIds.has(member.id)) {
|
|
556
|
-
await member.
|
|
542
|
+
await PlatformMembershipService.updateMembershipsForId(member.id);
|
|
557
543
|
}
|
|
558
544
|
}
|
|
559
545
|
|
|
@@ -600,7 +586,7 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
|
|
|
600
586
|
}
|
|
601
587
|
|
|
602
588
|
for (const registration of updateRegistrations.values()) {
|
|
603
|
-
|
|
589
|
+
RegistrationService.scheduleStockUpdate(registration.id);
|
|
604
590
|
}
|
|
605
591
|
|
|
606
592
|
const groups = await Group.getByIDs(...Array.from(updateGroups));
|
|
@@ -5,10 +5,9 @@ import { Organization, StripeAccount, StripeCheckoutSession, StripePaymentIntent
|
|
|
5
5
|
import { isDebouncedError, QueueHandler } from '@stamhoofd/queues';
|
|
6
6
|
|
|
7
7
|
import { StripeHelper } from '../../../helpers/StripeHelper';
|
|
8
|
-
import { ExchangePaymentEndpoint } from '../../organization/shared/ExchangePaymentEndpoint';
|
|
9
8
|
import { PaymentService } from '../../../services/PaymentService';
|
|
9
|
+
import { AuditLog, AuditLogSource } from '@stamhoofd/structures';
|
|
10
10
|
import { AuditLogService } from '../../../services/AuditLogService';
|
|
11
|
-
import { AuditLogType } from '@stamhoofd/structures';
|
|
12
11
|
|
|
13
12
|
type Params = Record<string, never>;
|
|
14
13
|
class Body extends AutoEncoder {
|
|
@@ -87,17 +86,10 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
87
86
|
const id = account.id as string;
|
|
88
87
|
const [model] = await StripeAccount.where({ accountId: id }, { limit: 1 });
|
|
89
88
|
if (model) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
await AuditLogService.log({
|
|
95
|
-
type: AuditLogType.StripeAccountEdited,
|
|
96
|
-
stripeAccount: model,
|
|
97
|
-
oldData: beforeMeta,
|
|
98
|
-
patch: model.meta,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
89
|
+
await AuditLogService.setContext({ userId: null, source: AuditLogSource.System }, async () => {
|
|
90
|
+
model.setMetaFromStripeAccount(account);
|
|
91
|
+
await model.save();
|
|
92
|
+
});
|
|
101
93
|
}
|
|
102
94
|
else {
|
|
103
95
|
console.warn('Could not find stripe account with id', id);
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { AutoEncoderPatchType, Decoder, isPatchableArray, patchObject } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
|
-
import { Organization, Platform, RegistrationPeriod
|
|
4
|
-
import {
|
|
3
|
+
import { Organization, Platform, RegistrationPeriod } from '@stamhoofd/models';
|
|
4
|
+
import { MemberResponsibility, PlatformConfig, PlatformPremiseType, Platform as PlatformStruct } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
6
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
7
7
|
import { QueueHandler } from '@stamhoofd/queues';
|
|
8
8
|
import { Context } from '../../../helpers/Context';
|
|
9
9
|
import { MembershipCharger } from '../../../helpers/MembershipCharger';
|
|
10
|
-
import { MembershipHelper } from '../../../helpers/MembershipHelper';
|
|
11
10
|
import { PeriodHelper } from '../../../helpers/PeriodHelper';
|
|
12
11
|
import { TagHelper } from '../../../helpers/TagHelper';
|
|
13
|
-
import {
|
|
12
|
+
import { PlatformMembershipService } from '../../../services/PlatformMembershipService';
|
|
13
|
+
import { SetupStepUpdater } from '../../../helpers/SetupStepUpdater';
|
|
14
14
|
|
|
15
15
|
type Params = Record<string, never>;
|
|
16
16
|
type Query = undefined;
|
|
@@ -49,7 +49,6 @@ export class PatchPlatformEndpoint extends Endpoint<
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const platform = await Platform.getShared();
|
|
52
|
-
const initialStruct = (await Platform.getSharedPrivateStruct()).clone();
|
|
53
52
|
|
|
54
53
|
if (request.body.privateConfig) {
|
|
55
54
|
// Did we patch roles?
|
|
@@ -206,7 +205,7 @@ export class PatchPlatformEndpoint extends Endpoint<
|
|
|
206
205
|
if (!QueueHandler.isRunning('update-membership-prices')) {
|
|
207
206
|
QueueHandler.schedule('update-membership-prices', async () => {
|
|
208
207
|
await MembershipCharger.updatePrices();
|
|
209
|
-
await
|
|
208
|
+
await PlatformMembershipService.updateAll();
|
|
210
209
|
}).catch(console.error);
|
|
211
210
|
}
|
|
212
211
|
}
|
|
@@ -223,12 +222,6 @@ export class PatchPlatformEndpoint extends Endpoint<
|
|
|
223
222
|
SetupStepUpdater.updateSetupStepsForAllOrganizationsInCurrentPeriod().catch(console.error);
|
|
224
223
|
}
|
|
225
224
|
|
|
226
|
-
await AuditLogService.log({
|
|
227
|
-
type: AuditLogType.PlatformSettingsChanged,
|
|
228
|
-
oldData: initialStruct,
|
|
229
|
-
patch: request.body,
|
|
230
|
-
});
|
|
231
|
-
|
|
232
225
|
return new Response(await Platform.getSharedPrivateStruct());
|
|
233
226
|
}
|
|
234
227
|
|
|
@@ -69,11 +69,6 @@ export class PatchUserMembersEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
69
69
|
|
|
70
70
|
await member.save();
|
|
71
71
|
addedMembers.push(member);
|
|
72
|
-
|
|
73
|
-
await AuditLogService.log({
|
|
74
|
-
type: AuditLogType.MemberAdded,
|
|
75
|
-
member: member,
|
|
76
|
-
});
|
|
77
72
|
}
|
|
78
73
|
|
|
79
74
|
// Modify members
|
|
@@ -90,7 +85,6 @@ export class PatchUserMembersEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
90
85
|
}
|
|
91
86
|
const securityCode = struct.details?.securityCode; // will get cleared after the filter
|
|
92
87
|
struct = await Context.auth.filterMemberPatch(member, struct);
|
|
93
|
-
const originalDetails = member.details.clone();
|
|
94
88
|
|
|
95
89
|
if (struct.details) {
|
|
96
90
|
if (struct.details.isPut()) {
|
|
@@ -129,15 +123,6 @@ export class PatchUserMembersEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
129
123
|
await member.save();
|
|
130
124
|
await MemberUserSyncer.onChangeMember(member);
|
|
131
125
|
|
|
132
|
-
if (struct.details) {
|
|
133
|
-
await AuditLogService.log({
|
|
134
|
-
type: AuditLogType.MemberEdited,
|
|
135
|
-
member: member,
|
|
136
|
-
oldMemberDetails: originalDetails,
|
|
137
|
-
memberDetailsPatch: struct.details,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
126
|
// Update documents
|
|
142
127
|
await Document.updateForMember(member.id);
|
|
143
128
|
}
|