@lilaquadrat/studio 11.5.2 → 12.1.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/lib/src/Immutable.class.d.ts +5 -1
- package/lib/src/Immutable.class.js +16 -1
- package/lib/src/Immutable.class.js.map +1 -1
- package/lib/src/helpers/cacheHelper.js +4 -0
- package/lib/src/helpers/cacheHelper.js.map +1 -1
- package/lib/src/interfaces/Participant.d.ts +1 -1
- package/lib/src/interfaces/Participant.js +1 -1
- package/lib/src/interfaces/Participant.js.map +1 -1
- package/lib/src/models/customers.model.js +17 -0
- package/lib/src/models/customers.model.js.map +1 -1
- package/lib/src/models/history.model.js +25 -6
- package/lib/src/models/history.model.js.map +1 -1
- package/lib/src/models/lists.model.js +2 -0
- package/lib/src/models/lists.model.js.map +1 -1
- package/lib/src/models/listsParticipants.model.js +13 -3
- package/lib/src/models/listsParticipants.model.js.map +1 -1
- package/lib/src/services/customers.service.d.ts +2 -1
- package/lib/src/services/customers.service.js +33 -1
- package/lib/src/services/customers.service.js.map +1 -1
- package/lib/src/services/history.service.d.ts +11 -4
- package/lib/src/services/history.service.js +137 -146
- package/lib/src/services/history.service.js.map +1 -1
- package/lib/src/services/listParticipants.service.d.ts +16 -1
- package/lib/src/services/listParticipants.service.js +69 -10
- package/lib/src/services/listParticipants.service.js.map +1 -1
- package/lib/src/services/lists.service.js +4 -4
- package/lib/src/services/lists.service.js.map +1 -1
- package/lib/src/services/structures.service.d.ts +4 -0
- package/lib/src/services/structures.service.js +4 -1
- package/lib/src/services/structures.service.js.map +1 -1
- package/lib/tests/cacheHelper.spec.js +4 -0
- package/lib/tests/cacheHelper.spec.js.map +1 -1
- package/lib/tests/customersServiceUpdateMe.spec.d.ts +1 -0
- package/lib/tests/customersServiceUpdateMe.spec.js +276 -0
- package/lib/tests/customersServiceUpdateMe.spec.js.map +1 -0
- package/lib/tests/immutableClass.spec.d.ts +1 -0
- package/lib/tests/immutableClass.spec.js +552 -0
- package/lib/tests/immutableClass.spec.js.map +1 -0
- package/lib/tests/listParticipantsHistory.spec.d.ts +1 -0
- package/lib/tests/listParticipantsHistory.spec.js +136 -0
- package/lib/tests/listParticipantsHistory.spec.js.map +1 -0
- package/lib/tests/listParticipantsMembersSelfService.spec.d.ts +1 -0
- package/lib/tests/listParticipantsMembersSelfService.spec.js +241 -0
- package/lib/tests/listParticipantsMembersSelfService.spec.js.map +1 -0
- package/lib/tests/listParticipantsServiceGetMyLists.spec.d.ts +1 -0
- package/lib/tests/listParticipantsServiceGetMyLists.spec.js +55 -0
- package/lib/tests/listParticipantsServiceGetMyLists.spec.js.map +1 -0
- package/package.json +2 -2
|
@@ -2,10 +2,17 @@ import { Filter, ObjectId, OrderedBulkOperation, UnorderedBulkOperation, Documen
|
|
|
2
2
|
import { HistoryReason, History, BasicData, Options } from '@lilaquadrat/interfaces';
|
|
3
3
|
declare class HistoryService {
|
|
4
4
|
model: import("../classes/modelv2.class.js").default<History, string>;
|
|
5
|
+
/**
|
|
6
|
+
* resolve the author of a history entry to a display name in one lookup.
|
|
7
|
+
* studio accounts live in 'me', member accounts (origin 'member') are linked
|
|
8
|
+
* to their customer through the accounts array, so both are unioned and the
|
|
9
|
+
* entry falls back to the raw account when no profile can be resolved.
|
|
10
|
+
*/
|
|
11
|
+
private userLookup;
|
|
5
12
|
create<T>(data: BasicData<T>, user: string, reason: HistoryReason, app: string, modelName: string): Promise<any>;
|
|
6
13
|
create<T, S>(data: BasicData<T>, user: string, reason: HistoryReason, app: string, modelName: string, additionalHistoryData?: Record<string, string | number>, copySource?: BasicData<S>): Promise<any>;
|
|
7
|
-
create<T, S>(data: BasicData<T>, user: string, reason: HistoryReason, app: string, modelName: string, additionalHistoryData?: Record<string, string | number> | undefined, copySource?: BasicData<S>, bulk?: UnorderedBulkOperation | OrderedBulkOperation): UnorderedBulkOperation | OrderedBulkOperation;
|
|
8
|
-
list(company: string, project: string | undefined, id?: string | ObjectId, reason?: HistoryReason,
|
|
14
|
+
create<T, S>(data: BasicData<T>, user: string, reason: HistoryReason, app: string, modelName: string, additionalHistoryData?: Record<string, string | number> | undefined, copySource?: BasicData<S>, bulk?: UnorderedBulkOperation | OrderedBulkOperation, origin?: History['history']['origin']): UnorderedBulkOperation | OrderedBulkOperation;
|
|
15
|
+
list(company: string, project: string | undefined, model: string, id?: string | ObjectId, reason?: HistoryReason, app?: string, sort?: number, limit?: number, skip?: number): Promise<{
|
|
9
16
|
all: number;
|
|
10
17
|
data: Document[];
|
|
11
18
|
count: number;
|
|
@@ -18,14 +25,14 @@ declare class HistoryService {
|
|
|
18
25
|
data: T[];
|
|
19
26
|
count: number;
|
|
20
27
|
}>;
|
|
21
|
-
singleList(company: string, project: string | undefined, internalId: ObjectId,
|
|
28
|
+
singleList(company: string, project: string | undefined, internalId: ObjectId, model: string, reason?: HistoryReason, app?: string, sort?: number, limit?: number, skip?: number): Promise<{
|
|
22
29
|
all: number;
|
|
23
30
|
data: Document[];
|
|
24
31
|
count: number;
|
|
25
32
|
}>;
|
|
26
33
|
single(company: string, project: string | undefined, id: string, version: number): Promise<Document>;
|
|
27
34
|
internal(company: string, project: string | undefined, id: ObjectId): Promise<Document>;
|
|
28
|
-
createQuery(company: string, project: string | undefined, idorInernalId: string | ObjectId | undefined, reason?: HistoryReason,
|
|
35
|
+
createQuery(company: string, project: string | undefined, model: string, idorInernalId: string | ObjectId | undefined, reason?: HistoryReason, app?: string, projection?: boolean, sort?: number, limit?: number, skip?: number): {
|
|
29
36
|
countQuery: Filter<History>;
|
|
30
37
|
aggregation: any[];
|
|
31
38
|
};
|
|
@@ -8,7 +8,113 @@ class HistoryService {
|
|
|
8
8
|
constructor() {
|
|
9
9
|
this.model = HistoryModel;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* resolve the author of a history entry to a display name in one lookup.
|
|
13
|
+
* studio accounts live in 'me', member accounts (origin 'member') are linked
|
|
14
|
+
* to their customer through the accounts array, so both are unioned and the
|
|
15
|
+
* entry falls back to the raw account when no profile can be resolved.
|
|
16
|
+
*/
|
|
17
|
+
userLookup() {
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
$lookup: {
|
|
21
|
+
from: 'me',
|
|
22
|
+
as: 'userData',
|
|
23
|
+
let: {
|
|
24
|
+
userid: '$history.user',
|
|
25
|
+
app: '$history.app',
|
|
26
|
+
company: '$company',
|
|
27
|
+
origin: '$history.origin',
|
|
28
|
+
},
|
|
29
|
+
pipeline: [
|
|
30
|
+
{
|
|
31
|
+
$match: {
|
|
32
|
+
$expr: {
|
|
33
|
+
$and: [
|
|
34
|
+
{ $eq: ['$id', '$$userid'] },
|
|
35
|
+
{ $ne: ['$$origin', 'member'] },
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
$project: {
|
|
42
|
+
prename: 1,
|
|
43
|
+
lastname: 1,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
$unionWith: {
|
|
48
|
+
coll: 'customers',
|
|
49
|
+
pipeline: [
|
|
50
|
+
{
|
|
51
|
+
$match: {
|
|
52
|
+
$expr: {
|
|
53
|
+
$and: [
|
|
54
|
+
{ $eq: ['$$origin', 'member'] },
|
|
55
|
+
{ $eq: ['$company', '$$company'] },
|
|
56
|
+
{
|
|
57
|
+
$gt: [
|
|
58
|
+
{
|
|
59
|
+
$size: {
|
|
60
|
+
$filter: {
|
|
61
|
+
input: { $ifNull: ['$accounts', []] },
|
|
62
|
+
as: 'account',
|
|
63
|
+
cond: {
|
|
64
|
+
$and: [
|
|
65
|
+
{ $eq: ['$$account.account', '$$userid'] },
|
|
66
|
+
{ $eq: ['$$account.app', '$$app'] },
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
0,
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
$project: {
|
|
81
|
+
prename: 1,
|
|
82
|
+
lastname: '$name',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
$project: {
|
|
90
|
+
prename: 1,
|
|
91
|
+
lastname: 1,
|
|
92
|
+
_id: 0,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{ $limit: 1 },
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
$unwind: {
|
|
101
|
+
path: '$userData',
|
|
102
|
+
preserveNullAndEmptyArrays: true,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
$addFields: {
|
|
107
|
+
'history.user': {
|
|
108
|
+
$ifNull: [
|
|
109
|
+
{ $concat: ['$userData.lastname', ', ', '$userData.prename'] },
|
|
110
|
+
'$history.user',
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
create(data, user, reason, app, modelName, additionalHistoryData, copySource, bulk, origin) {
|
|
12
118
|
const immutable = {
|
|
13
119
|
...data,
|
|
14
120
|
_id: new ObjectId(),
|
|
@@ -23,6 +129,9 @@ class HistoryService {
|
|
|
23
129
|
model: modelName,
|
|
24
130
|
},
|
|
25
131
|
};
|
|
132
|
+
// Origin belongs to this action, not to the document's previous edit.
|
|
133
|
+
if (origin)
|
|
134
|
+
immutable.history.origin = origin;
|
|
26
135
|
if (additionalHistoryData) {
|
|
27
136
|
immutable.history.additional = data.history?.additional;
|
|
28
137
|
}
|
|
@@ -38,8 +147,8 @@ class HistoryService {
|
|
|
38
147
|
? bulk.insert(immutable)
|
|
39
148
|
: this.model.db.insertOne(immutable);
|
|
40
149
|
}
|
|
41
|
-
async list(company, project, id, reason,
|
|
42
|
-
const queries = this.createQuery(company, project, id, reason,
|
|
150
|
+
async list(company, project, model, id, reason, app, sort, limit, skip) {
|
|
151
|
+
const queries = this.createQuery(company, project, model, id, reason, app, true, sort, limit, skip);
|
|
43
152
|
const all = await this.model.db.countDocuments(queries.countQuery);
|
|
44
153
|
const data = await this.model.db.aggregate(queries.aggregation)
|
|
45
154
|
.toArray();
|
|
@@ -51,8 +160,8 @@ class HistoryService {
|
|
|
51
160
|
.toArray();
|
|
52
161
|
return { all, data, count: data.length };
|
|
53
162
|
}
|
|
54
|
-
async singleList(company, project, internalId,
|
|
55
|
-
const queries = this.createQuery(company, project, internalId, reason,
|
|
163
|
+
async singleList(company, project, internalId, model, reason, app, sort, limit, skip) {
|
|
164
|
+
const queries = this.createQuery(company, project, model, internalId, reason, app, true, sort, limit, skip);
|
|
56
165
|
const all = await this.model.db.countDocuments(queries.countQuery);
|
|
57
166
|
const data = await this.model.db.aggregate(queries.aggregation)
|
|
58
167
|
.toArray();
|
|
@@ -61,183 +170,65 @@ class HistoryService {
|
|
|
61
170
|
async single(company, project, id, version) {
|
|
62
171
|
const aggregation = [{
|
|
63
172
|
$match: {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
{ $expr: { $eq: ['$history.version', version] } },
|
|
69
|
-
],
|
|
173
|
+
company,
|
|
174
|
+
project,
|
|
175
|
+
id,
|
|
176
|
+
'history.version': version,
|
|
70
177
|
},
|
|
71
178
|
}];
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
$lookup: {
|
|
75
|
-
from: 'me',
|
|
76
|
-
as: 'userData',
|
|
77
|
-
let: { userid: '$history.user' },
|
|
78
|
-
pipeline: [
|
|
79
|
-
{
|
|
80
|
-
$match: {
|
|
81
|
-
$and: [
|
|
82
|
-
{ $expr: { $eq: ['$id', '$$userid'] } },
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
$unwind: {
|
|
91
|
-
path: '$userData',
|
|
92
|
-
preserveNullAndEmptyArrays: true,
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
$addFields: {
|
|
97
|
-
'history.user': {
|
|
98
|
-
$concat: ['$userData.lastname', ', ', '$userData.prename'],
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
];
|
|
103
|
-
aggregation.push(...lookup, ...partialAggregation, ...childDataAggregation);
|
|
179
|
+
aggregation.push(...this.userLookup(), ...partialAggregation, ...childDataAggregation);
|
|
104
180
|
return this.model.db.aggregate(aggregation).toArray()
|
|
105
181
|
.then((single) => single[0]);
|
|
106
182
|
}
|
|
107
183
|
async internal(company, project, id) {
|
|
108
184
|
const aggregation = [{
|
|
109
185
|
$match: {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{ $expr: { $eq: ['$_id', id] } },
|
|
114
|
-
],
|
|
186
|
+
company,
|
|
187
|
+
project,
|
|
188
|
+
_id: id,
|
|
115
189
|
},
|
|
116
190
|
}];
|
|
117
|
-
|
|
118
|
-
{
|
|
119
|
-
$lookup: {
|
|
120
|
-
from: 'me',
|
|
121
|
-
as: 'userData',
|
|
122
|
-
let: { userid: '$history.user' },
|
|
123
|
-
pipeline: [
|
|
124
|
-
{
|
|
125
|
-
$match: {
|
|
126
|
-
$and: [
|
|
127
|
-
{ $expr: { $eq: ['$id', '$$userid'] } },
|
|
128
|
-
],
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
$project: {
|
|
133
|
-
_id: 1,
|
|
134
|
-
id: 1,
|
|
135
|
-
prename: 1,
|
|
136
|
-
lastname: 1,
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
],
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
$unwind: {
|
|
144
|
-
path: '$userData',
|
|
145
|
-
preserveNullAndEmptyArrays: true,
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
$addFields: {
|
|
150
|
-
'history.user': {
|
|
151
|
-
$concat: ['$userData.lastname', ', ', '$userData.prename'],
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
aggregation.push(...lookup);
|
|
191
|
+
aggregation.push(...this.userLookup());
|
|
157
192
|
aggregation.push(...partialAggregation);
|
|
158
193
|
aggregation.push(...childDataAggregation);
|
|
159
194
|
aggregation.push(...genericDataAggregation);
|
|
160
195
|
return this.model.db.aggregate(aggregation).toArray()
|
|
161
196
|
.then((single) => single[0]);
|
|
162
197
|
}
|
|
163
|
-
createQuery(company, project, idorInernalId, reason,
|
|
164
|
-
let aggregation = [
|
|
165
|
-
{
|
|
166
|
-
$match: {
|
|
167
|
-
$and: [
|
|
168
|
-
{ $expr: { $eq: ['$company', company] } },
|
|
169
|
-
],
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
];
|
|
173
|
-
aggregation.push({
|
|
174
|
-
$sort: { _id: sort || -1 },
|
|
175
|
-
});
|
|
198
|
+
createQuery(company, project, model, idorInernalId, reason, app, projection, sort, limit, skip) {
|
|
176
199
|
const countQuery = {
|
|
177
200
|
company,
|
|
201
|
+
'history.model': model,
|
|
178
202
|
};
|
|
179
|
-
if (project)
|
|
203
|
+
if (project)
|
|
180
204
|
countQuery.project = project;
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
if (reason) {
|
|
205
|
+
if (reason)
|
|
184
206
|
countQuery['history.reason'] = reason;
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
if (app) {
|
|
207
|
+
if (app)
|
|
188
208
|
countQuery['history.app'] = app;
|
|
189
|
-
aggregation[0].$match.$and.push({ $expr: { $eq: ['$history.app', app] } });
|
|
190
|
-
}
|
|
191
|
-
if (model) {
|
|
192
|
-
countQuery['history.model'] = model;
|
|
193
|
-
aggregation[0].$match.$and.push({ $expr: { $eq: ['$history.model', model] } });
|
|
194
|
-
}
|
|
195
209
|
if (idorInernalId) {
|
|
196
210
|
if (typeof idorInernalId === 'object') {
|
|
197
211
|
countQuery['history.parent'] = idorInernalId;
|
|
198
|
-
aggregation[0].$match.$and.push({ $expr: { $eq: ['$history.parent', idorInernalId] } });
|
|
199
212
|
}
|
|
200
213
|
else {
|
|
201
214
|
countQuery.id = idorInernalId;
|
|
202
|
-
aggregation[0].$match.$and.push({ $expr: { $eq: ['$id', idorInernalId] } });
|
|
203
215
|
}
|
|
204
216
|
}
|
|
205
|
-
aggregation
|
|
206
|
-
$skip: skip,
|
|
207
|
-
}, {
|
|
208
|
-
$limit: limit,
|
|
209
|
-
});
|
|
210
|
-
const lookup = [
|
|
217
|
+
const aggregation = [
|
|
211
218
|
{
|
|
212
|
-
$
|
|
213
|
-
from: 'me',
|
|
214
|
-
as: 'userData',
|
|
215
|
-
let: { userid: '$history.user' },
|
|
216
|
-
pipeline: [
|
|
217
|
-
{
|
|
218
|
-
$match: {
|
|
219
|
-
$and: [
|
|
220
|
-
{ $expr: { $eq: ['$id', '$$userid'] } },
|
|
221
|
-
],
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
],
|
|
225
|
-
},
|
|
219
|
+
$match: { ...countQuery },
|
|
226
220
|
},
|
|
227
221
|
{
|
|
228
|
-
$
|
|
229
|
-
path: '$userData',
|
|
230
|
-
preserveNullAndEmptyArrays: true,
|
|
231
|
-
},
|
|
222
|
+
$sort: { _id: sort || -1 },
|
|
232
223
|
},
|
|
233
224
|
{
|
|
234
|
-
$
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
},
|
|
225
|
+
$skip: skip,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
$limit: limit,
|
|
239
229
|
},
|
|
240
230
|
];
|
|
231
|
+
const lookup = this.userLookup();
|
|
241
232
|
if (projection) {
|
|
242
233
|
lookup.push({
|
|
243
234
|
$project: {
|
|
@@ -248,7 +239,7 @@ class HistoryService {
|
|
|
248
239
|
},
|
|
249
240
|
});
|
|
250
241
|
}
|
|
251
|
-
aggregation
|
|
242
|
+
aggregation.push(...lookup);
|
|
252
243
|
return {
|
|
253
244
|
countQuery,
|
|
254
245
|
aggregation,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.service.js","sourceRoot":"","sources":["../../../src/services/history.service.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,oBAAoB,MAAM,yCAAyC,CAAC;AAC3E,OAAO,kBAAkB,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,YAAY,MAAM,oCAAoC,CAAC;AAE9D,OAAO,sBAAsB,MAAM,2CAA2C,CAAC;AAE/E,MAAM,cAAc;IAApB;QAEE,UAAK,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"history.service.js","sourceRoot":"","sources":["../../../src/services/history.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -195,6 +195,21 @@ export declare class ListParticipantsService extends Immutable<ListParticipants>
|
|
|
195
195
|
* Updates the state of a participant in a list
|
|
196
196
|
*/
|
|
197
197
|
state(list: ObjectId, participationId: ObjectId, state: ListParticipants['state'], options: Required<UserAppWithOptions>): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* resolve the authenticated member's own entry for a list.
|
|
200
|
+
* the client never sends a participant id, so one member can never write another's entry.
|
|
201
|
+
*/
|
|
202
|
+
private ownParticipant;
|
|
203
|
+
/**
|
|
204
|
+
* member self-service: change the state of the own list entry.
|
|
205
|
+
* only 'canceled' is allowed, admin states can never be set and no email is sent.
|
|
206
|
+
*/
|
|
207
|
+
membersState(list: ObjectId, account: string, state: ListParticipants['state'], options: Required<UserAppWithOptions>): Promise<WithId<ListParticipants> | null>;
|
|
208
|
+
/**
|
|
209
|
+
* member self-service: replace the structure (s-*) answers of the own list entry.
|
|
210
|
+
* values are validated against the project's listsParticipants structures, no email is sent.
|
|
211
|
+
*/
|
|
212
|
+
membersStructures(list: ObjectId, account: string, structureInput: Record<string, string | boolean | number | string[]>, options: Required<UserAppWithOptions>): Promise<WithId<ListParticipants> | null>;
|
|
198
213
|
note(list: ObjectId, participationId: ObjectId, note: ListParticipants['note'] | undefined, options: Required<UserAppWithOptions>): Promise<import("mongodb").UpdateResult<import("bson").Document>>;
|
|
199
214
|
participantInList(list: ObjectId, user: ObjectId, options: Required<UserAppWithOptions>): Promise<boolean>;
|
|
200
215
|
singleWithoutLookup(list: ObjectId, user: ObjectId, options: Required<UserAppWithOptions>): Promise<WithId<ListParticipants> | null>;
|
|
@@ -210,7 +225,7 @@ export declare class ListParticipantsService extends Immutable<ListParticipants>
|
|
|
210
225
|
validator?: ValidateFunction;
|
|
211
226
|
}): Promise<import("@lilaquadrat/interfaces").CreateResult<BasicData<ListParticipants>>>;
|
|
212
227
|
removeParticipant(list: ObjectId, user: string, options: Required<UserAppWithOptions>): void;
|
|
213
|
-
listHistory(list: ObjectId, reason: HistoryReason | undefined, options: Required<UserAppWithOptions
|
|
228
|
+
listHistory(list: ObjectId, reason: HistoryReason | undefined, options: Required<UserAppWithOptions>, limit?: number, skip?: number): Promise<{
|
|
214
229
|
all: number;
|
|
215
230
|
data: HistoryWithType<ListParticipants>[];
|
|
216
231
|
count: number;
|
|
@@ -600,7 +600,7 @@ export class ListParticipantsService extends Immutable {
|
|
|
600
600
|
category,
|
|
601
601
|
company: options.company,
|
|
602
602
|
project: options.project,
|
|
603
|
-
state: { $nin: ['blocked', 'notuseful'] },
|
|
603
|
+
state: { $nin: ['blocked', 'notuseful', 'canceled'] },
|
|
604
604
|
},
|
|
605
605
|
},
|
|
606
606
|
{ $count: 'count' },
|
|
@@ -644,6 +644,55 @@ export class ListParticipantsService extends Immutable {
|
|
|
644
644
|
await this.sendStateAndAudienceAwareEmail(list, customer._id, state, audience, options);
|
|
645
645
|
}
|
|
646
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* resolve the authenticated member's own entry for a list.
|
|
649
|
+
* the client never sends a participant id, so one member can never write another's entry.
|
|
650
|
+
*/
|
|
651
|
+
async ownParticipant(list, account, options) {
|
|
652
|
+
const customer = await CustomersService.getCustomerByAccount(account, options.app);
|
|
653
|
+
if (!customer)
|
|
654
|
+
throw new Error('CUSTOMER_NOT_FOUND');
|
|
655
|
+
const participant = await this.singleWithoutLookup(list, customer._id, options);
|
|
656
|
+
if (!participant)
|
|
657
|
+
throw new Error('PARTICIPANT_NOT_FOUND');
|
|
658
|
+
// member self-service is opt-in per list, disabled by default
|
|
659
|
+
const listData = await ListsModel.db.findOne({ _id: list, company: options.company, project: options.project }, { projection: { 'participants.selfService': 1 } });
|
|
660
|
+
if (listData?.participants?.selfService !== true)
|
|
661
|
+
throw new Error('LIST_SELF_SERVICE_DISABLED');
|
|
662
|
+
// a canceled or blocked entry is terminal: the member can neither edit nor cancel it again
|
|
663
|
+
if (participant.state === 'canceled' || participant.state === 'blocked')
|
|
664
|
+
throw new ImmutableError('VALIDATION_FAILED');
|
|
665
|
+
return participant;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* member self-service: change the state of the own list entry.
|
|
669
|
+
* only 'canceled' is allowed, admin states can never be set and no email is sent.
|
|
670
|
+
*/
|
|
671
|
+
async membersState(list, account, state, options) {
|
|
672
|
+
if (state !== 'canceled')
|
|
673
|
+
throw new ImmutableError('VALIDATION_FAILED');
|
|
674
|
+
const participant = await this.ownParticipant(list, account, options);
|
|
675
|
+
await this.immutable({ _id: participant._id, list, company: options.company, project: options.project }, { state }, options.user, 'change', options.app, undefined, undefined, 'updateState', { origin: 'member' });
|
|
676
|
+
return this.singleWithoutLookup(list, participant.user, options);
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* member self-service: replace the structure (s-*) answers of the own list entry.
|
|
680
|
+
* values are validated against the project's listsParticipants structures, no email is sent.
|
|
681
|
+
*/
|
|
682
|
+
async membersStructures(list, account, structureInput, options) {
|
|
683
|
+
const baseSchema = ListParticipantsModel.getSchema('changeMemberEntry');
|
|
684
|
+
if (!baseSchema)
|
|
685
|
+
throw new ImmutableError('VALIDATION_FAILED');
|
|
686
|
+
const structures = await StructureService.getByModel('listsParticipants', options);
|
|
687
|
+
const validator = StructureService.createValidator([], [], structures, hardCopy(baseSchema.schema));
|
|
688
|
+
const participant = await this.ownParticipant(list, account, options);
|
|
689
|
+
const payload = (structureInput ?? {});
|
|
690
|
+
const structureIds = structures.map((structure) => structure.id).filter((id) => Boolean(id));
|
|
691
|
+
// every structure answer that was not submitted (or is falsy) must be removed
|
|
692
|
+
const unset = structureIds.filter((key) => !payload[key]);
|
|
693
|
+
await this.immutable({ _id: participant._id, list, company: options.company, project: options.project }, structureInput, options.user, 'change', options.app, undefined, undefined, 'changeMemberEntry', { origin: 'member', validator, unset });
|
|
694
|
+
return this.singleWithoutLookup(list, participant.user, options);
|
|
695
|
+
}
|
|
647
696
|
async note(list, participationId, note, options) {
|
|
648
697
|
return this.immutable({ _id: participationId, list, company: options.company, project: options.project }, note ? { note } : {}, options.user, 'change', options.app, undefined, undefined, 'updateNote');
|
|
649
698
|
}
|
|
@@ -745,15 +794,11 @@ export class ListParticipantsService extends Immutable {
|
|
|
745
794
|
}
|
|
746
795
|
removeParticipant(list, user, options) {
|
|
747
796
|
}
|
|
748
|
-
listHistory(list, reason, options) {
|
|
749
|
-
const query = HistoryService.createQuery(options.company, options.project, undefined, reason,
|
|
797
|
+
listHistory(list, reason, options, limit = 20, skip = 0) {
|
|
798
|
+
const query = HistoryService.createQuery(options.company, options.project, 'listParticipants', undefined, reason, undefined, false, -1, limit, skip);
|
|
750
799
|
query.countQuery.list = list;
|
|
751
|
-
query.aggregation[0].$match
|
|
752
|
-
query.aggregation
|
|
753
|
-
query.aggregation[0],
|
|
754
|
-
query.aggregation[1],
|
|
755
|
-
...this.customerLookup,
|
|
756
|
-
];
|
|
800
|
+
query.aggregation[0].$match.list = list;
|
|
801
|
+
query.aggregation.push(...this.customerLookup);
|
|
757
802
|
return HistoryService.listCustomQuery(query);
|
|
758
803
|
}
|
|
759
804
|
agreementsMissing(listAgreements, providedAgreements) {
|
|
@@ -788,7 +833,7 @@ export class ListParticipantsService extends Immutable {
|
|
|
788
833
|
aggregation[0].$match.$and.push({ $expr: { $in: ['$state', state] } });
|
|
789
834
|
}
|
|
790
835
|
else {
|
|
791
|
-
aggregation[0].$match.$and.push({ $expr: { $not: { $in: ['$state', ['blocked', 'unchecked', 'notuseful']] } } });
|
|
836
|
+
aggregation[0].$match.$and.push({ $expr: { $not: { $in: ['$state', ['blocked', 'unchecked', 'notuseful', 'canceled']] } } });
|
|
792
837
|
}
|
|
793
838
|
if (category) {
|
|
794
839
|
aggregation[0].$match.$and.push({ $expr: { $in: ['$category', category] } });
|
|
@@ -829,6 +874,19 @@ export class ListParticipantsService extends Immutable {
|
|
|
829
874
|
return data[0] ? { all: data[0].all.all, data: data[0].data, count: data[0].data?.length } : { all: 0, data: [], count: 0 };
|
|
830
875
|
}
|
|
831
876
|
async getMyListsQuery(customerInternalId, filter, options) {
|
|
877
|
+
const listMatch = {};
|
|
878
|
+
if (filter.state) {
|
|
879
|
+
listMatch['listData.state'] = filter.state;
|
|
880
|
+
}
|
|
881
|
+
if (filter.mode) {
|
|
882
|
+
listMatch['listData.mode'] = filter.mode;
|
|
883
|
+
}
|
|
884
|
+
if (filter.name) {
|
|
885
|
+
listMatch.$or = [
|
|
886
|
+
{ 'listData.name': { $regex: filter.name, $options: 'i' } },
|
|
887
|
+
{ 'listData.location': { $regex: filter.name, $options: 'i' } },
|
|
888
|
+
];
|
|
889
|
+
}
|
|
832
890
|
const aggregation = [
|
|
833
891
|
{
|
|
834
892
|
$match: {
|
|
@@ -846,6 +904,7 @@ export class ListParticipantsService extends Immutable {
|
|
|
846
904
|
{
|
|
847
905
|
$unwind: '$listData',
|
|
848
906
|
},
|
|
907
|
+
...(Object.keys(listMatch).length ? [{ $match: listMatch }] : []),
|
|
849
908
|
{
|
|
850
909
|
$addFields: {
|
|
851
910
|
'listData.user': {
|