@nest-util/nest-crud 2.0.0 → 2.0.2
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/dist/lib/controllers/nest-crud.controller.d.ts.map +1 -1
- package/dist/lib/controllers/nest-crud.controller.js +18 -0
- package/dist/lib/dtos/request-modification.dto.d.ts.map +1 -1
- package/dist/lib/dtos/request-modification.dto.js +1 -1
- package/dist/lib/entities/approval-status.entity.d.ts +4 -4
- package/dist/lib/entities/approval-status.entity.d.ts.map +1 -1
- package/dist/lib/entities/approval-status.entity.js +4 -4
- package/dist/lib/interfaces/approval-pipeline.interface.d.ts +34 -10
- package/dist/lib/interfaces/approval-pipeline.interface.d.ts.map +1 -1
- package/dist/lib/interfaces/approval-pipeline.interface.js +5 -4
- package/dist/lib/interfaces/crud.interface.d.ts +2 -1
- package/dist/lib/interfaces/crud.interface.d.ts.map +1 -1
- package/dist/lib/interfaces/hooks.interface.d.ts +29 -0
- package/dist/lib/interfaces/hooks.interface.d.ts.map +1 -1
- package/dist/lib/services/nest-crud.service.d.ts +18 -1
- package/dist/lib/services/nest-crud.service.d.ts.map +1 -1
- package/dist/lib/services/nest-crud.service.js +147 -11
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nest-crud.controller.d.ts","sourceRoot":"","sources":["../../../src/lib/controllers/nest-crud.controller.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"nest-crud.controller.d.ts","sourceRoot":"","sources":["../../../src/lib/controllers/nest-crud.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,IAAI,EAEL,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,2CAA2C,CAAC;AAEnD,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAC9C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;IACzC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,CACL,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,YAAY,CAAC,CACX,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,eAAe,EACpB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,EAAE,CAAC,CAAC;IACf,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1D,WAAW,CAAC,CACV,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC;QAAE,QAAQ,EAAE,kBAAkB,CAAC;QAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;KAAE,CAAC,CAAC;IAC7E,eAAe,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChF,cAAc,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/E,mBAAmB,CAAC,CAClB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,0BAA0B,EAC/B,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/B,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClF;AAyDD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EACnD,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAkQnC"}
|
|
@@ -121,6 +121,13 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
|
|
|
121
121
|
}
|
|
122
122
|
return this.service.resubmitApproval(id, user);
|
|
123
123
|
}
|
|
124
|
+
submitApproval(id, user) {
|
|
125
|
+
this.ensureEndpointEnabled('submitApproval');
|
|
126
|
+
if (!this.service.submitApproval) {
|
|
127
|
+
throw (0, nest_error_1.keyed)(common_1.HttpStatus.NOT_FOUND, nest_error_1.ErrorKey.CRUD_RESOURCE_NOT_FOUND);
|
|
128
|
+
}
|
|
129
|
+
return this.service.submitApproval(id, user);
|
|
130
|
+
}
|
|
124
131
|
remove(id, user) {
|
|
125
132
|
this.ensureEndpointEnabled('remove');
|
|
126
133
|
return this.service.remove(id, user);
|
|
@@ -280,6 +287,17 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
|
|
|
280
287
|
tslib_1.__metadata("design:paramtypes", [Number, Object]),
|
|
281
288
|
tslib_1.__metadata("design:returntype", void 0)
|
|
282
289
|
], BaseController.prototype, "resubmitApproval", null);
|
|
290
|
+
tslib_1.__decorate([
|
|
291
|
+
(0, common_1.Post)(':id/approval/submit'),
|
|
292
|
+
(0, response_message_decorator_1.Message)('submitted'),
|
|
293
|
+
(0, audit_log_decorator_1.Audit)({ action: 'SUBMIT' }),
|
|
294
|
+
(0, swagger_1.ApiResponse)({ description: 'The updated approval status' }),
|
|
295
|
+
tslib_1.__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
|
|
296
|
+
tslib_1.__param(1, (0, nest_auth_1.CurrentUser)()),
|
|
297
|
+
tslib_1.__metadata("design:type", Function),
|
|
298
|
+
tslib_1.__metadata("design:paramtypes", [Number, Object]),
|
|
299
|
+
tslib_1.__metadata("design:returntype", void 0)
|
|
300
|
+
], BaseController.prototype, "submitApproval", null);
|
|
283
301
|
tslib_1.__decorate([
|
|
284
302
|
(0, common_1.Delete)(':id'),
|
|
285
303
|
(0, response_message_decorator_1.Message)('deleted'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-modification.dto.d.ts","sourceRoot":"","sources":["../../../src/lib/dtos/request-modification.dto.ts"],"names":[],"mappings":"AAWA,qBAAa,mBAAmB;IAG9B,KAAK,EAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"request-modification.dto.d.ts","sourceRoot":"","sources":["../../../src/lib/dtos/request-modification.dto.ts"],"names":[],"mappings":"AAWA,qBAAa,mBAAmB;IAG9B,KAAK,EAAG,MAAM,CAAC;IAQf,YAAY,CAAC,EAAE,OAAO,CAAC;IAIvB,WAAW,EAAG,OAAO,CAAC;IAKtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,sBAAsB;IASjC,aAAa,EAAG,mBAAmB,EAAE,CAAC;IAQtC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -15,7 +15,7 @@ tslib_1.__decorate([
|
|
|
15
15
|
], ModificationItemDto.prototype, "field", void 0);
|
|
16
16
|
tslib_1.__decorate([
|
|
17
17
|
(0, swagger_1.ApiProperty)({
|
|
18
|
-
description: 'Value currently stored on the record (
|
|
18
|
+
description: 'Value currently stored on the record. Auto-filled from the live entity when omitted (supports relation objects).',
|
|
19
19
|
required: false,
|
|
20
20
|
}),
|
|
21
21
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ModificationItem } from '../interfaces/approval-pipeline.interface';
|
|
2
2
|
/**
|
|
3
|
-
* Tracks the approval lifecycle of a created record. One row per
|
|
4
|
-
*
|
|
5
|
-
* name (`entity`) and its primary key (`entityId`).
|
|
3
|
+
* Tracks the approval lifecycle of a created record. One row per
|
|
4
|
+
* draft/submitted/approved entity, polymorphically referencing the target row
|
|
5
|
+
* via the table name (`entity`) and its primary key (`entityId`).
|
|
6
6
|
*/
|
|
7
7
|
export declare class ApprovalStatusEntity {
|
|
8
8
|
id: number;
|
|
@@ -10,7 +10,7 @@ export declare class ApprovalStatusEntity {
|
|
|
10
10
|
entity: string;
|
|
11
11
|
/** Stringified primary key of the target row (works for int and uuid). */
|
|
12
12
|
entityId: string;
|
|
13
|
-
/**
|
|
13
|
+
/** draft | submitted | approved | rejected | modification_requested | resubmitted */
|
|
14
14
|
status: string;
|
|
15
15
|
/** User who submitted the record for approval. */
|
|
16
16
|
requestedBy?: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-status.entity.d.ts","sourceRoot":"","sources":["../../../src/lib/entities/approval-status.entity.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAElF;;;;GAIG;AACH,qBACa,oBAAoB;IAE/B,EAAE,EAAG,MAAM,CAAC;IAEZ,uCAAuC;IAGvC,MAAM,EAAG,MAAM,CAAC;IAEhB,0EAA0E;IAG1E,QAAQ,EAAG,MAAM,CAAC;IAElB,
|
|
1
|
+
{"version":3,"file":"approval-status.entity.d.ts","sourceRoot":"","sources":["../../../src/lib/entities/approval-status.entity.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAElF;;;;GAIG;AACH,qBACa,oBAAoB;IAE/B,EAAE,EAAG,MAAM,CAAC;IAEZ,uCAAuC;IAGvC,MAAM,EAAG,MAAM,CAAC;IAEhB,0EAA0E;IAG1E,QAAQ,EAAG,MAAM,CAAC;IAElB,qFAAqF;IAGrF,MAAM,EAAG,MAAM,CAAC;IAEhB,kDAAkD;IAGlD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5B,WAAW,EAAG,IAAI,CAAC;IAEnB,2EAA2E;IAE3E,oBAAoB,CAAC,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAEjD,gDAAgD;IAEhD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1B,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAExB,2DAA2D;IAE3D,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAG5B,SAAS,EAAG,IAAI,CAAC;IAGjB,SAAS,EAAG,IAAI,CAAC;CAClB"}
|
|
@@ -4,9 +4,9 @@ exports.ApprovalStatusEntity = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const typeorm_1 = require("typeorm");
|
|
6
6
|
/**
|
|
7
|
-
* Tracks the approval lifecycle of a created record. One row per
|
|
8
|
-
*
|
|
9
|
-
* name (`entity`) and its primary key (`entityId`).
|
|
7
|
+
* Tracks the approval lifecycle of a created record. One row per
|
|
8
|
+
* draft/submitted/approved entity, polymorphically referencing the target row
|
|
9
|
+
* via the table name (`entity`) and its primary key (`entityId`).
|
|
10
10
|
*/
|
|
11
11
|
let ApprovalStatusEntity = class ApprovalStatusEntity {
|
|
12
12
|
};
|
|
@@ -27,7 +27,7 @@ tslib_1.__decorate([
|
|
|
27
27
|
], ApprovalStatusEntity.prototype, "entityId", void 0);
|
|
28
28
|
tslib_1.__decorate([
|
|
29
29
|
(0, typeorm_1.Index)(),
|
|
30
|
-
(0, typeorm_1.Column)({ default: '
|
|
30
|
+
(0, typeorm_1.Column)({ default: 'draft' }),
|
|
31
31
|
tslib_1.__metadata("design:type", String)
|
|
32
32
|
], ApprovalStatusEntity.prototype, "status", void 0);
|
|
33
33
|
tslib_1.__decorate([
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import type { ApprovalHooks } from './hooks.interface';
|
|
1
2
|
/**
|
|
2
3
|
* Lifecycle of an approval status row.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
* │
|
|
6
|
-
* └─> modification_requested ──> resubmitted ──> approved / rejected
|
|
5
|
+
* draft ──> submitted ────────> approved
|
|
6
|
+
* │ │ └────────────> rejected
|
|
7
|
+
* │ └─> modification_requested ──> resubmitted ──> approved / rejected
|
|
7
8
|
* │ │
|
|
8
9
|
* └────────────────────────────────────┘
|
|
9
10
|
* (modifications may be requested again)
|
|
10
11
|
*/
|
|
11
12
|
export declare const APPROVAL_STATUS: {
|
|
12
|
-
readonly
|
|
13
|
+
readonly draft: "draft";
|
|
14
|
+
readonly submitted: "submitted";
|
|
13
15
|
readonly approved: "approved";
|
|
14
16
|
readonly rejected: "rejected";
|
|
15
17
|
readonly modificationRequested: "modification_requested";
|
|
@@ -17,13 +19,17 @@ export declare const APPROVAL_STATUS: {
|
|
|
17
19
|
};
|
|
18
20
|
export type ApprovalStatus = (typeof APPROVAL_STATUS)[keyof typeof APPROVAL_STATUS];
|
|
19
21
|
/**
|
|
20
|
-
* A single requested modification on a
|
|
22
|
+
* A single requested modification on a record under review. Each item names the
|
|
21
23
|
* field to change and the value the reviewer wants instead.
|
|
22
24
|
*/
|
|
23
25
|
export interface ModificationItem {
|
|
24
|
-
/** Entity field to modify, e.g. 'title'. */
|
|
26
|
+
/** Entity field to modify, e.g. 'title' or 'category' (a relation). */
|
|
25
27
|
field: string;
|
|
26
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Value currently stored on the record. Auto-captured from the live entity
|
|
30
|
+
* when omitted (supports relation objects; circular refs are sanitized to
|
|
31
|
+
* '[Circular]').
|
|
32
|
+
*/
|
|
27
33
|
currentValue?: unknown;
|
|
28
34
|
/** Value the reviewer wants instead. */
|
|
29
35
|
wantedValue: unknown;
|
|
@@ -54,22 +60,34 @@ export interface ApprovalHistoryView {
|
|
|
54
60
|
note?: string | null;
|
|
55
61
|
}
|
|
56
62
|
export interface ApprovalPipelinePermissions {
|
|
57
|
-
/** Required permission to approve (
|
|
63
|
+
/** Required permission to approve (submitted/resubmitted -> approved). */
|
|
58
64
|
approve?: string;
|
|
59
|
-
/** Required permission to reject (
|
|
65
|
+
/** Required permission to reject (submitted/resubmitted -> rejected). */
|
|
60
66
|
reject?: string;
|
|
61
67
|
/** Required permission to request modifications. */
|
|
62
68
|
requestModification?: string;
|
|
63
69
|
/** Required permission to resubmit after modifications. */
|
|
64
70
|
resubmit?: string;
|
|
71
|
+
/** Required permission to submit a draft for approval. */
|
|
72
|
+
submit?: string;
|
|
65
73
|
}
|
|
66
74
|
export interface ApprovalPipelineConfig {
|
|
67
75
|
/**
|
|
68
|
-
* When true, every created record also gets a
|
|
76
|
+
* When true, every created record also gets a draft approval status row
|
|
69
77
|
* (created in the same transaction). Defaults to true when the option is
|
|
70
78
|
* provided.
|
|
71
79
|
*/
|
|
72
80
|
enabled?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Initial status assigned to a record's approval row on create.
|
|
83
|
+
* - 'draft' (default): the record waits in draft until `submitApproval`
|
|
84
|
+
* is called; the `submit` permission applies and `requestedBy` is filled
|
|
85
|
+
* on submit.
|
|
86
|
+
* - 'submitted': the record is created already in the reviewable state
|
|
87
|
+
* (the creating user becomes the requester), so no explicit submit step
|
|
88
|
+
* is needed.
|
|
89
|
+
*/
|
|
90
|
+
initialStatus?: 'draft' | 'submitted';
|
|
73
91
|
/**
|
|
74
92
|
* Optional permission strings required to perform each action. When unset,
|
|
75
93
|
* the action is allowed for any authenticated (or anonymous) caller.
|
|
@@ -82,6 +100,12 @@ export interface ApprovalPipelineConfig {
|
|
|
82
100
|
* of approval state.
|
|
83
101
|
*/
|
|
84
102
|
visibleStatuses?: readonly ApprovalStatus[];
|
|
103
|
+
/**
|
|
104
|
+
* Before/after hooks for each approval transition, mirroring the generic
|
|
105
|
+
* `CrudHooks` API. Each hook receives the approval row view and (for
|
|
106
|
+
* `after*`) the previous status.
|
|
107
|
+
*/
|
|
108
|
+
hooks?: ApprovalHooks;
|
|
85
109
|
}
|
|
86
110
|
export interface RequestModificationPayload {
|
|
87
111
|
modifications: ModificationItem[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-pipeline.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/approval-pipeline.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"approval-pipeline.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/approval-pipeline.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,IAAI,CAAC;IAClB,oBAAoB,CAAC,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAEtC;;;OAGG;IACH,WAAW,CAAC,EAAE,2BAA2B,CAAC;IAE1C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAE5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -4,15 +4,16 @@ exports.APPROVAL_STATUS = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* Lifecycle of an approval status row.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* │
|
|
9
|
-
* └─> modification_requested ──> resubmitted ──> approved / rejected
|
|
7
|
+
* draft ──> submitted ────────> approved
|
|
8
|
+
* │ │ └────────────> rejected
|
|
9
|
+
* │ └─> modification_requested ──> resubmitted ──> approved / rejected
|
|
10
10
|
* │ │
|
|
11
11
|
* └────────────────────────────────────┘
|
|
12
12
|
* (modifications may be requested again)
|
|
13
13
|
*/
|
|
14
14
|
exports.APPROVAL_STATUS = {
|
|
15
|
-
|
|
15
|
+
draft: 'draft',
|
|
16
|
+
submitted: 'submitted',
|
|
16
17
|
approved: 'approved',
|
|
17
18
|
rejected: 'rejected',
|
|
18
19
|
modificationRequested: 'modification_requested',
|
|
@@ -4,7 +4,7 @@ import { CursorPaginationDto } from '../dtos/cursor-pagination.dto';
|
|
|
4
4
|
import { OwnershipUser } from './find-mine.interface';
|
|
5
5
|
import { StatusValue } from './status-pipeline.interface';
|
|
6
6
|
import { ApprovalHistoryView, ApprovalStatusView, RequestModificationPayload } from './approval-pipeline.interface';
|
|
7
|
-
export type CrudEndpoint = 'findAll' | 'findOne' | 'create' | 'update' | 'changeStatus' | 'remove' | 'findAuditLogs' | 'findMine' | 'getApproval' | 'approveApproval' | 'rejectApproval' | 'requestModification' | 'resubmitApproval';
|
|
7
|
+
export type CrudEndpoint = 'findAll' | 'findOne' | 'create' | 'update' | 'changeStatus' | 'remove' | 'findAuditLogs' | 'findMine' | 'getApproval' | 'approveApproval' | 'rejectApproval' | 'requestModification' | 'resubmitApproval' | 'submitApproval';
|
|
8
8
|
export interface AuditLogQuery {
|
|
9
9
|
user_id?: string;
|
|
10
10
|
start_date?: string;
|
|
@@ -46,5 +46,6 @@ export interface CrudInterface<CreateDto, UpdateDto, ResponseDto> {
|
|
|
46
46
|
rejectApproval?(id: number, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
47
47
|
requestModification?(id: number, dto: RequestModificationPayload, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
48
48
|
resubmitApproval?(id: number, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
49
|
+
submitApproval?(id: number, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
49
50
|
}
|
|
50
51
|
//# sourceMappingURL=crud.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crud.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/crud.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,cAAc,GACd,QAAQ,GACR,eAAe,GACf,UAAU,GACV,aAAa,GACb,iBAAiB,GACjB,gBAAgB,GAChB,qBAAqB,GACrB,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"crud.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/crud.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ApprovalStatus, ApprovalStatusView, ModificationItem } from './approval-pipeline.interface';
|
|
2
|
+
import { OwnershipUser } from './find-mine.interface';
|
|
1
3
|
export type CrudHook<TContext = any> = (context: TContext) => Promise<any> | any;
|
|
2
4
|
export interface CrudHookConfig<TContext = any> {
|
|
3
5
|
handler: CrudHook<TContext>;
|
|
@@ -49,4 +51,31 @@ export interface TransactionConfig {
|
|
|
49
51
|
isolationLevel?: 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SERIALIZABLE';
|
|
50
52
|
timeout?: number;
|
|
51
53
|
}
|
|
54
|
+
export interface ApprovalHookContext {
|
|
55
|
+
id: number;
|
|
56
|
+
user?: OwnershipUser;
|
|
57
|
+
approval: ApprovalStatusView;
|
|
58
|
+
}
|
|
59
|
+
export interface AfterApprovalHookContext extends ApprovalHookContext {
|
|
60
|
+
previousStatus: ApprovalStatus;
|
|
61
|
+
}
|
|
62
|
+
export interface RequestModificationApprovalHookContext extends ApprovalHookContext {
|
|
63
|
+
modifications: ModificationItem[];
|
|
64
|
+
note?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface AfterRequestModificationApprovalHookContext extends RequestModificationApprovalHookContext {
|
|
67
|
+
previousStatus: ApprovalStatus;
|
|
68
|
+
}
|
|
69
|
+
export interface ApprovalHooks {
|
|
70
|
+
beforeSubmit?: CrudHookConfig<ApprovalHookContext>;
|
|
71
|
+
afterSubmit?: CrudHookConfig<AfterApprovalHookContext>;
|
|
72
|
+
beforeApprove?: CrudHookConfig<ApprovalHookContext>;
|
|
73
|
+
afterApprove?: CrudHookConfig<AfterApprovalHookContext>;
|
|
74
|
+
beforeReject?: CrudHookConfig<ApprovalHookContext>;
|
|
75
|
+
afterReject?: CrudHookConfig<AfterApprovalHookContext>;
|
|
76
|
+
beforeRequestModification?: CrudHookConfig<RequestModificationApprovalHookContext>;
|
|
77
|
+
afterRequestModification?: CrudHookConfig<AfterRequestModificationApprovalHookContext>;
|
|
78
|
+
beforeResubmit?: CrudHookConfig<ApprovalHookContext>;
|
|
79
|
+
afterResubmit?: CrudHookConfig<AfterApprovalHookContext>;
|
|
80
|
+
}
|
|
52
81
|
//# sourceMappingURL=hooks.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/hooks.interface.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,CAAC,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAEjF,MAAM,WAAW,cAAc,CAAC,QAAQ,GAAG,GAAG;IAC5C,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO,EAAE,UAAU;IACtD,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB,CAAC,OAAO,EAAE,UAAU;IACrD,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO,EAAE,UAAU;IACtD,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,kBAAkB,CAAC,OAAO,EAAE,UAAU;IACrD,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU;IACxD,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,EAAE,cAAc,CAAC,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,EAAE,cAAc,CAAC,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5D,WAAW,CAAC,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,cAAc,CAAC,oBAAoB,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EACX,kBAAkB,GAClB,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
|
1
|
+
{"version":3,"file":"hooks.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/hooks.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { CursorPaginationDto } from '../dtos/cursor-pagination.dto';
|
|
|
6
6
|
import { FilterDto } from '../dtos/filter.dto';
|
|
7
7
|
import { CrudEndpoint, CrudInterface, CursorPaginationResult } from '../interfaces/crud.interface';
|
|
8
8
|
import { CursorStrategy } from '../interfaces/cursor-strategy.interface';
|
|
9
|
-
import { CrudHooks, TransactionConfig } from '../interfaces/hooks.interface';
|
|
9
|
+
import { ApprovalHooks, CrudHooks, TransactionConfig } from '../interfaces/hooks.interface';
|
|
10
10
|
import { FindMineConfig, OwnershipUser } from '../interfaces/find-mine.interface';
|
|
11
11
|
import { StatusPipelineConfig, StatusTransitionAction, StatusValue } from '../interfaces/status-pipeline.interface';
|
|
12
12
|
import { ApprovalPipelineConfig, ApprovalStatusView, ApprovalHistoryView, RequestModificationPayload } from '../interfaces/approval-pipeline.interface';
|
|
@@ -63,6 +63,7 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
|
|
|
63
63
|
action?: StatusTransitionAction<Entity>;
|
|
64
64
|
}>;
|
|
65
65
|
protected readonly approvalPipeline?: ApprovalPipelineConfig;
|
|
66
|
+
protected readonly approvalHooks: ApprovalHooks;
|
|
66
67
|
constructor(options: CrudServiceOptions<Entity, ResponseDto>);
|
|
67
68
|
private normalizeStatusTransitions;
|
|
68
69
|
private resolveRelations;
|
|
@@ -110,14 +111,30 @@ export declare class NestCrudService<Entity extends ObjectLiteral, CreateDto = P
|
|
|
110
111
|
rejectApproval(id: number, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
111
112
|
requestModification(id: number, payload: RequestModificationPayload, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
112
113
|
resubmitApproval(id: number, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
114
|
+
submitApproval(id: number, user?: OwnershipUser): Promise<ApprovalStatusView>;
|
|
113
115
|
private isApprovalPipelineConfigured;
|
|
114
116
|
private hasApprovalVisibilityFilter;
|
|
115
117
|
private getApprovalRepository;
|
|
116
118
|
private getHistoryRepository;
|
|
117
119
|
private createWithApproval;
|
|
118
120
|
private resolveEntityForApproval;
|
|
121
|
+
/**
|
|
122
|
+
* Loads the target entity with its configured `include` relations so that
|
|
123
|
+
* relation fields can be read as objects when capturing modification values.
|
|
124
|
+
*/
|
|
125
|
+
private getEntityWithRelations;
|
|
126
|
+
/** Reads a (possibly nested, dot-path) field from an entity. */
|
|
127
|
+
private readCurrentValue;
|
|
128
|
+
/**
|
|
129
|
+
* Deep-clones a value so it can be safely stored in a jsonb column. Object
|
|
130
|
+
* graphs with circular references (common for loaded relations) are
|
|
131
|
+
* sanitized: a circular branch is replaced with the string '[Circular]'.
|
|
132
|
+
*/
|
|
133
|
+
private sanitizeForJsonb;
|
|
119
134
|
private loadApprovalStatus;
|
|
120
135
|
private transitionApproval;
|
|
136
|
+
private fireApprovalBeforeHook;
|
|
137
|
+
private fireApprovalAfterHook;
|
|
121
138
|
private assertTransitionAllowed;
|
|
122
139
|
private userHasPermission;
|
|
123
140
|
private applyApprovalVisibility;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nest-crud.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/nest-crud.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE9D,OAAO,EAAe,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"nest-crud.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/nest-crud.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,6 +46,7 @@ let NestCrudService = class NestCrudService {
|
|
|
46
46
|
this.statusTransitions = this.normalizeStatusTransitions(options.statusPipeline.transitions);
|
|
47
47
|
}
|
|
48
48
|
this.approvalPipeline = options.approvalPipeline;
|
|
49
|
+
this.approvalHooks = options.approvalPipeline?.hooks ?? {};
|
|
49
50
|
}
|
|
50
51
|
normalizeStatusTransitions(transitions) {
|
|
51
52
|
const result = new Map();
|
|
@@ -510,6 +511,9 @@ let NestCrudService = class NestCrudService {
|
|
|
510
511
|
async resubmitApproval(id, user) {
|
|
511
512
|
return this.transitionApproval(id, 'resubmit', user);
|
|
512
513
|
}
|
|
514
|
+
async submitApproval(id, user) {
|
|
515
|
+
return this.transitionApproval(id, 'submit', user);
|
|
516
|
+
}
|
|
513
517
|
isApprovalPipelineConfigured() {
|
|
514
518
|
return Boolean(this.approvalPipeline && this.approvalPipeline.enabled !== false);
|
|
515
519
|
}
|
|
@@ -531,11 +535,14 @@ let NestCrudService = class NestCrudService {
|
|
|
531
535
|
const entityRepo = manager.getRepository(this.repo.target);
|
|
532
536
|
const saved = await entityRepo.save(resolved);
|
|
533
537
|
const approvalRepo = manager.getRepository(approval_status_entity_1.ApprovalStatusEntity);
|
|
538
|
+
const initialStatus = this.approvalPipeline?.initialStatus ?? approval_pipeline_interface_1.APPROVAL_STATUS.draft;
|
|
534
539
|
const approval = approvalRepo.create({
|
|
535
540
|
entity: this.repo.metadata.tableName,
|
|
536
541
|
entityId: String(saved.id),
|
|
537
|
-
status:
|
|
538
|
-
|
|
542
|
+
status: initialStatus,
|
|
543
|
+
...(initialStatus === approval_pipeline_interface_1.APPROVAL_STATUS.submitted
|
|
544
|
+
? { requestedBy: user?.id != null ? String(user.id) : null }
|
|
545
|
+
: {}),
|
|
539
546
|
});
|
|
540
547
|
await approvalRepo.save(approval);
|
|
541
548
|
return saved;
|
|
@@ -548,6 +555,63 @@ let NestCrudService = class NestCrudService {
|
|
|
548
555
|
}
|
|
549
556
|
return this.repo.findOneBy({ id });
|
|
550
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Loads the target entity with its configured `include` relations so that
|
|
560
|
+
* relation fields can be read as objects when capturing modification values.
|
|
561
|
+
*/
|
|
562
|
+
async getEntityWithRelations(id, user) {
|
|
563
|
+
if (this.enforceOwnershipFor(user)) {
|
|
564
|
+
return this.findOwnedEntity(id, user);
|
|
565
|
+
}
|
|
566
|
+
const relations = this.include.length
|
|
567
|
+
? this.buildRelationsObject(this.include)
|
|
568
|
+
: undefined;
|
|
569
|
+
return this.repo.findOne({
|
|
570
|
+
where: { id },
|
|
571
|
+
relations: relations,
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
/** Reads a (possibly nested, dot-path) field from an entity. */
|
|
575
|
+
readCurrentValue(entity, field) {
|
|
576
|
+
if (!entity || !field) {
|
|
577
|
+
return undefined;
|
|
578
|
+
}
|
|
579
|
+
const parts = field.split('.');
|
|
580
|
+
let current = entity;
|
|
581
|
+
for (const part of parts) {
|
|
582
|
+
if (current == null) {
|
|
583
|
+
return undefined;
|
|
584
|
+
}
|
|
585
|
+
current = current[part];
|
|
586
|
+
}
|
|
587
|
+
return current;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Deep-clones a value so it can be safely stored in a jsonb column. Object
|
|
591
|
+
* graphs with circular references (common for loaded relations) are
|
|
592
|
+
* sanitized: a circular branch is replaced with the string '[Circular]'.
|
|
593
|
+
*/
|
|
594
|
+
sanitizeForJsonb(value) {
|
|
595
|
+
const seen = new WeakSet();
|
|
596
|
+
const walk = (node) => {
|
|
597
|
+
if (node === null || typeof node !== 'object') {
|
|
598
|
+
return node;
|
|
599
|
+
}
|
|
600
|
+
if (seen.has(node)) {
|
|
601
|
+
return '[Circular]';
|
|
602
|
+
}
|
|
603
|
+
seen.add(node);
|
|
604
|
+
if (Array.isArray(node)) {
|
|
605
|
+
return node.map((item) => walk(item));
|
|
606
|
+
}
|
|
607
|
+
const out = {};
|
|
608
|
+
for (const key of Object.keys(node)) {
|
|
609
|
+
out[key] = walk(node[key]);
|
|
610
|
+
}
|
|
611
|
+
return out;
|
|
612
|
+
};
|
|
613
|
+
return walk(value);
|
|
614
|
+
}
|
|
551
615
|
async loadApprovalStatus(id, user) {
|
|
552
616
|
const entity = await this.resolveEntityForApproval(id, user);
|
|
553
617
|
if (!entity) {
|
|
@@ -572,38 +636,65 @@ let NestCrudService = class NestCrudService {
|
|
|
572
636
|
throw (0, nest_error_1.keyed)(common_1.HttpStatus.NOT_FOUND, nest_error_1.ErrorKey.CRUD_RESOURCE_NOT_FOUND);
|
|
573
637
|
}
|
|
574
638
|
const current = approval.status;
|
|
639
|
+
const previousStatus = current;
|
|
575
640
|
const now = new Date();
|
|
576
641
|
const userId = user?.id != null ? String(user.id) : null;
|
|
577
|
-
const
|
|
578
|
-
approval_pipeline_interface_1.APPROVAL_STATUS.
|
|
642
|
+
const reviewable = [
|
|
643
|
+
approval_pipeline_interface_1.APPROVAL_STATUS.submitted,
|
|
579
644
|
approval_pipeline_interface_1.APPROVAL_STATUS.resubmitted,
|
|
580
645
|
];
|
|
646
|
+
// Already in a reviewable/terminal state (e.g. the pipeline was
|
|
647
|
+
// configured with initialStatus: 'submitted'): no submit transition is
|
|
648
|
+
// needed, so this is a harmless no-op returning the current status. Hooks
|
|
649
|
+
// are skipped because no transition actually occurs.
|
|
650
|
+
if (action === 'submit' && current !== approval_pipeline_interface_1.APPROVAL_STATUS.draft) {
|
|
651
|
+
return this.toApprovalStatusView(approval);
|
|
652
|
+
}
|
|
653
|
+
const beforeContext = {
|
|
654
|
+
id,
|
|
655
|
+
user,
|
|
656
|
+
approval: this.toApprovalStatusView(approval),
|
|
657
|
+
};
|
|
658
|
+
await this.fireApprovalBeforeHook(action, beforeContext, modifications ?? [], note);
|
|
581
659
|
switch (action) {
|
|
660
|
+
case 'submit':
|
|
661
|
+
approval.status = approval_pipeline_interface_1.APPROVAL_STATUS.submitted;
|
|
662
|
+
approval.requestedBy = userId;
|
|
663
|
+
break;
|
|
582
664
|
case 'approve':
|
|
583
|
-
this.assertTransitionAllowed(action, current,
|
|
665
|
+
this.assertTransitionAllowed(action, current, reviewable);
|
|
584
666
|
approval.status = approval_pipeline_interface_1.APPROVAL_STATUS.approved;
|
|
585
667
|
approval.decidedBy = userId;
|
|
586
668
|
approval.decidedAt = now;
|
|
587
669
|
approval.currentModifications = null;
|
|
588
670
|
break;
|
|
589
671
|
case 'reject':
|
|
590
|
-
this.assertTransitionAllowed(action, current,
|
|
672
|
+
this.assertTransitionAllowed(action, current, reviewable);
|
|
591
673
|
approval.status = approval_pipeline_interface_1.APPROVAL_STATUS.rejected;
|
|
592
674
|
approval.decidedBy = userId;
|
|
593
675
|
approval.decidedAt = now;
|
|
594
676
|
approval.currentModifications = null;
|
|
595
677
|
break;
|
|
596
|
-
case 'requestModification':
|
|
597
|
-
this.assertTransitionAllowed(action, current,
|
|
678
|
+
case 'requestModification': {
|
|
679
|
+
this.assertTransitionAllowed(action, current, reviewable);
|
|
598
680
|
approval.status = approval_pipeline_interface_1.APPROVAL_STATUS.modificationRequested;
|
|
599
|
-
|
|
681
|
+
const entity = await this.getEntityWithRelations(id, user);
|
|
682
|
+
const capturedModifications = (modifications ?? []).map((m) => ({
|
|
683
|
+
...m,
|
|
684
|
+
currentValue: this.sanitizeForJsonb(m.currentValue !== undefined
|
|
685
|
+
? m.currentValue
|
|
686
|
+
: this.readCurrentValue(entity, m.field)),
|
|
687
|
+
wantedValue: this.sanitizeForJsonb(m.wantedValue),
|
|
688
|
+
}));
|
|
689
|
+
approval.currentModifications = capturedModifications;
|
|
600
690
|
await this.getHistoryRepository().save(this.getHistoryRepository().create({
|
|
601
691
|
approvalStatusId: approval.id,
|
|
602
|
-
modifications:
|
|
692
|
+
modifications: capturedModifications,
|
|
603
693
|
requestedBy: userId,
|
|
604
694
|
note: note ?? null,
|
|
605
695
|
}));
|
|
606
696
|
break;
|
|
697
|
+
}
|
|
607
698
|
case 'resubmit':
|
|
608
699
|
if (current !== approval_pipeline_interface_1.APPROVAL_STATUS.modificationRequested) {
|
|
609
700
|
throw (0, nest_error_1.keyed)(common_1.HttpStatus.BAD_REQUEST, nest_error_1.ErrorKey.CRUD_APPROVAL_INVALID_TRANSITION, { action: 'resubmit', current: String(current) });
|
|
@@ -615,7 +706,52 @@ let NestCrudService = class NestCrudService {
|
|
|
615
706
|
break;
|
|
616
707
|
}
|
|
617
708
|
const saved = await this.getApprovalRepository().save(approval);
|
|
618
|
-
|
|
709
|
+
const afterContext = {
|
|
710
|
+
id,
|
|
711
|
+
user,
|
|
712
|
+
approval: this.toApprovalStatusView(saved),
|
|
713
|
+
previousStatus,
|
|
714
|
+
};
|
|
715
|
+
await this.fireApprovalAfterHook(action, afterContext, modifications ?? [], note);
|
|
716
|
+
return afterContext.approval;
|
|
717
|
+
}
|
|
718
|
+
async fireApprovalBeforeHook(action, context, modifications, note) {
|
|
719
|
+
switch (action) {
|
|
720
|
+
case 'submit':
|
|
721
|
+
await this.executeHook(this.approvalHooks.beforeSubmit, context);
|
|
722
|
+
break;
|
|
723
|
+
case 'approve':
|
|
724
|
+
await this.executeHook(this.approvalHooks.beforeApprove, context);
|
|
725
|
+
break;
|
|
726
|
+
case 'reject':
|
|
727
|
+
await this.executeHook(this.approvalHooks.beforeReject, context);
|
|
728
|
+
break;
|
|
729
|
+
case 'resubmit':
|
|
730
|
+
await this.executeHook(this.approvalHooks.beforeResubmit, context);
|
|
731
|
+
break;
|
|
732
|
+
case 'requestModification':
|
|
733
|
+
await this.executeHook(this.approvalHooks.beforeRequestModification, { ...context, modifications, note });
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
async fireApprovalAfterHook(action, context, modifications, note) {
|
|
738
|
+
switch (action) {
|
|
739
|
+
case 'submit':
|
|
740
|
+
await this.executeHook(this.approvalHooks.afterSubmit, context);
|
|
741
|
+
break;
|
|
742
|
+
case 'approve':
|
|
743
|
+
await this.executeHook(this.approvalHooks.afterApprove, context);
|
|
744
|
+
break;
|
|
745
|
+
case 'reject':
|
|
746
|
+
await this.executeHook(this.approvalHooks.afterReject, context);
|
|
747
|
+
break;
|
|
748
|
+
case 'resubmit':
|
|
749
|
+
await this.executeHook(this.approvalHooks.afterResubmit, context);
|
|
750
|
+
break;
|
|
751
|
+
case 'requestModification':
|
|
752
|
+
await this.executeHook(this.approvalHooks.afterRequestModification, { ...context, modifications, note });
|
|
753
|
+
break;
|
|
754
|
+
}
|
|
619
755
|
}
|
|
620
756
|
assertTransitionAllowed(action, current, allowedFrom) {
|
|
621
757
|
if (!allowedFrom.includes(current)) {
|