@tstdl/base 0.92.123 → 0.92.125
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/ai/ai-file.service.js +23 -18
- package/ai/ai.service.d.ts +4 -12
- package/ai/ai.service.js +79 -147
- package/ai/functions.d.ts +1 -1
- package/ai/types.d.ts +3 -1
- package/api/server/gateway.js +6 -6
- package/authentication/authentication.api.js +24 -24
- package/authentication/server/authentication.service.js +20 -20
- package/browser/page-controller.js +1 -1
- package/context/context.js +5 -5
- package/document-management/api/document-management.api.d.ts +60 -215
- package/document-management/api/document-management.api.js +32 -68
- package/document-management/models/document-assignment-scope.model.d.ts +11 -0
- package/document-management/models/{document-request-assignment-task-collection.model.js → document-assignment-scope.model.js} +14 -10
- package/document-management/models/document-assignment-task.model.d.ts +13 -0
- package/document-management/models/document-assignment-task.model.js +38 -0
- package/document-management/models/document-category.model.d.ts +2 -0
- package/document-management/models/document-category.model.js +7 -1
- package/document-management/models/{document-collection-document.model.d.ts → document-collection-assignment.model.d.ts} +1 -1
- package/document-management/models/{document-collection-document.model.js → document-collection-assignment.model.js} +7 -7
- package/document-management/models/document-collection.model.d.ts +2 -0
- package/document-management/models/document-collection.model.js +10 -0
- package/document-management/models/document-property-value.model.d.ts +3 -11
- package/document-management/models/document-property-value.model.js +15 -46
- package/document-management/models/document-property.model.d.ts +2 -1
- package/document-management/models/document-property.model.js +2 -2
- package/document-management/models/document-request-submission.model.d.ts +7 -0
- package/document-management/models/document-request-submission.model.js +34 -0
- package/document-management/models/document-request-template.d.ts +2 -4
- package/document-management/models/document-request-template.js +3 -8
- package/document-management/models/document-request.model.d.ts +14 -6
- package/document-management/models/document-request.model.js +22 -12
- package/document-management/models/document-type-validation.model.d.ts +6 -0
- package/document-management/models/document-type-validation.model.js +34 -0
- package/document-management/models/document-type.model.d.ts +0 -1
- package/document-management/models/document-type.model.js +0 -5
- package/document-management/models/document-validation-definition.model.d.ts +10 -0
- package/document-management/models/document-validation-definition.model.js +39 -0
- package/document-management/models/document-validation-execution-related-document.model.d.ts +7 -0
- package/document-management/models/document-validation-execution-related-document.model.js +34 -0
- package/document-management/models/document-validation-execution.model.d.ts +26 -0
- package/document-management/models/document-validation-execution.model.js +72 -0
- package/document-management/models/document-workflow.model.d.ts +35 -0
- package/document-management/models/document-workflow.model.js +70 -0
- package/document-management/models/document.model.d.ts +12 -1
- package/document-management/models/document.model.js +21 -5
- package/document-management/models/index.d.ts +10 -5
- package/document-management/models/index.js +10 -5
- package/document-management/models/service-models/categories-and-types.view-model.d.ts +3 -3
- package/document-management/models/service-models/categories-and-types.view-model.js +2 -21
- package/document-management/models/service-models/document-folders.view-model.d.ts +7 -14
- package/document-management/models/service-models/document-folders.view-model.js +20 -44
- package/document-management/models/service-models/document-management.view-model.d.ts +41 -0
- package/document-management/models/service-models/{document.view-model.js → document-management.view-model.js} +43 -26
- package/document-management/models/service-models/document.service-model.d.ts +51 -81
- package/document-management/models/service-models/document.service-model.js +30 -28
- package/document-management/models/service-models/enriched/enriched-document-assignment.view.d.ts +11 -0
- package/document-management/models/service-models/enriched/enriched-document-assignment.view.js +12 -0
- package/document-management/models/service-models/enriched/enriched-document-category.view.d.ts +13 -0
- package/document-management/models/service-models/enriched/enriched-document-category.view.js +47 -0
- package/document-management/models/service-models/enriched/enriched-document-collection.view.d.ts +22 -0
- package/document-management/models/service-models/enriched/enriched-document-collection.view.js +89 -0
- package/document-management/models/service-models/enriched/enriched-document-file.view.d.ts +12 -0
- package/document-management/models/service-models/enriched/enriched-document-file.view.js +16 -0
- package/document-management/models/service-models/enriched/enriched-document-management-data.view.d.ts +41 -0
- package/document-management/models/service-models/enriched/enriched-document-management-data.view.js +130 -0
- package/document-management/models/service-models/enriched/enriched-document-request.view.d.ts +17 -0
- package/document-management/models/service-models/enriched/enriched-document-request.view.js +52 -0
- package/document-management/models/service-models/enriched/enriched-document-type.view.d.ts +9 -0
- package/document-management/models/service-models/enriched/enriched-document-type.view.js +10 -0
- package/document-management/models/service-models/enriched/enriched-document.view.d.ts +28 -0
- package/document-management/models/service-models/enriched/enriched-document.view.js +77 -0
- package/document-management/models/service-models/enriched/enriched.d.ts +18 -0
- package/document-management/models/service-models/enriched/enriched.js +39 -0
- package/document-management/models/service-models/enriched/index.d.ts +9 -0
- package/document-management/models/service-models/enriched/index.js +9 -0
- package/document-management/models/service-models/index.d.ts +2 -2
- package/document-management/models/service-models/index.js +2 -2
- package/document-management/models/service-models/normalized-requests-template-data.model.d.ts +12 -10
- package/document-management/models/service-models/normalized-requests-template-data.model.js +5 -4
- package/document-management/models/service-models/stats.view-model.d.ts +7 -5
- package/document-management/models/service-models/stats.view-model.js +19 -9
- package/document-management/server/module.d.ts +2 -2
- package/document-management/server/module.js +3 -7
- package/document-management/server/schemas.d.ts +18 -23
- package/document-management/server/schemas.js +18 -23
- package/document-management/server/services/document-category-type.service.d.ts +25 -0
- package/document-management/server/services/document-category-type.service.js +66 -0
- package/document-management/server/services/document-collection.service.d.ts +13 -0
- package/document-management/server/services/document-collection.service.js +41 -0
- package/document-management/server/services/document-file.service.d.ts +17 -0
- package/document-management/server/services/document-file.service.js +204 -0
- package/document-management/server/services/document-management-ai.service.d.ts +22 -0
- package/document-management/server/services/document-management-ai.service.js +340 -0
- package/document-management/server/services/document-management-ancillary.service.d.ts +127 -3
- package/document-management/server/services/document-management-ancillary.service.js +24 -0
- package/document-management/server/services/document-management.service.d.ts +10 -122
- package/document-management/server/services/document-management.service.js +106 -888
- package/document-management/server/services/document-property.service.d.ts +84 -0
- package/document-management/server/services/document-property.service.js +87 -0
- package/document-management/server/services/document-request.service.d.ts +30 -0
- package/document-management/server/services/document-request.service.js +138 -0
- package/document-management/server/services/document-validation.service.d.ts +20 -0
- package/document-management/server/services/document-validation.service.js +145 -0
- package/document-management/server/services/document-workflow.service.d.ts +20 -0
- package/document-management/server/services/document-workflow.service.js +132 -0
- package/document-management/server/services/document.service.d.ts +16 -0
- package/document-management/server/services/document.service.js +81 -0
- package/document-management/server/services/index.d.ts +9 -0
- package/document-management/server/services/index.js +9 -0
- package/document-management/server/validators/ai-validation-executor.d.ts +19 -0
- package/document-management/server/validators/ai-validation-executor.js +51 -0
- package/document-management/server/validators/index.d.ts +2 -0
- package/document-management/server/validators/index.js +2 -0
- package/document-management/server/validators/single-document-validation-executor.d.ts +16 -0
- package/document-management/server/validators/single-document-validation-executor.js +20 -0
- package/document-management/server/validators/validator.d.ts +21 -0
- package/document-management/server/validators/validator.js +2 -0
- package/eslint.config.js +31 -17
- package/examples/document-management/main.d.ts +18 -3
- package/examples/document-management/main.js +28 -12
- package/file/mime-type.js +2 -9
- package/formats.d.ts +5 -2
- package/formats.js +32 -23
- package/http/client/http-client.js +1 -1
- package/injector/injector.js +2 -2
- package/object-storage/s3/s3.object-storage.js +1 -1
- package/orm/data-types/bytea.d.ts +8 -0
- package/orm/data-types/bytea.js +8 -0
- package/orm/data-types/index.d.ts +4 -0
- package/orm/data-types/index.js +4 -0
- package/orm/data-types/numeric-date.d.ts +9 -0
- package/orm/data-types/numeric-date.js +9 -0
- package/orm/data-types/timestamp.d.ts +9 -0
- package/orm/data-types/timestamp.js +9 -0
- package/orm/decorators.d.ts +139 -5
- package/orm/decorators.js +50 -0
- package/orm/entity.d.ts +19 -0
- package/orm/entity.js +19 -0
- package/orm/index.d.ts +5 -0
- package/orm/index.js +5 -0
- package/orm/query.d.ts +51 -0
- package/orm/query.js +6 -0
- package/orm/repository.types.d.ts +54 -2
- package/orm/server/database-schema.d.ts +34 -0
- package/orm/server/database-schema.js +29 -0
- package/orm/server/database.d.ts +19 -1
- package/orm/server/database.js +17 -3
- package/orm/server/drizzle/schema-converter.d.ts +2 -1
- package/orm/server/drizzle/schema-converter.js +12 -1
- package/orm/server/encryption.d.ts +16 -0
- package/orm/server/encryption.js +29 -4
- package/orm/server/index.d.ts +7 -0
- package/orm/server/index.js +7 -0
- package/orm/server/module.d.ts +20 -0
- package/orm/server/module.js +9 -0
- package/orm/server/query-converter.d.ts +17 -0
- package/orm/server/query-converter.js +66 -11
- package/orm/server/repository.d.ts +324 -18
- package/orm/server/repository.js +344 -73
- package/orm/server/transaction.d.ts +5 -5
- package/orm/server/transaction.js +5 -5
- package/orm/server/transactional.d.ts +75 -0
- package/orm/server/transactional.js +134 -0
- package/orm/server/types.d.ts +1 -0
- package/orm/sqls.d.ts +55 -0
- package/orm/sqls.js +60 -0
- package/orm/types.d.ts +67 -4
- package/orm/utils.d.ts +19 -3
- package/orm/utils.js +12 -0
- package/package.json +32 -31
- package/password/password-check-result.model.d.ts +9 -7
- package/password/password-check-result.model.js +8 -8
- package/password/password-check.js +5 -7
- package/password/password-check.localization.js +12 -12
- package/pdf/pdf.service.js +1 -1
- package/pdf/utils.d.ts +9 -0
- package/pdf/utils.js +19 -2
- package/process/spawn.d.ts +11 -4
- package/process/spawn.js +42 -5
- package/queue/postgres/queue.js +5 -5
- package/queue/queue.d.ts +6 -4
- package/queue/queue.js +6 -6
- package/schema/schemas/one-or-many.d.ts +2 -1
- package/schema/schemas/one-or-many.js +1 -1
- package/search-index/elastic/model/index-mapping.d.ts +1 -1
- package/search-index/elastic/model/index-mapping.js +0 -1
- package/search-index/elastic/search-index.d.ts +1 -2
- package/search-index/elastic/search-index.js +3 -3
- package/types.d.ts +1 -0
- package/utils/async-hook/async-hook.d.ts +9 -0
- package/utils/async-hook/async-hook.js +21 -0
- package/utils/async-hook/index.d.ts +1 -0
- package/utils/async-hook/index.js +1 -0
- package/utils/compression.js +1 -1
- package/utils/function/class.d.ts +6 -0
- package/utils/function/class.js +9 -0
- package/utils/function/index.d.ts +1 -0
- package/utils/function/index.js +1 -0
- package/utils/function/memoize.d.ts +18 -0
- package/utils/function/memoize.js +41 -2
- package/utils/jwt.d.ts +1 -1
- package/utils/jwt.js +5 -5
- package/utils/object/forward-ref.d.ts +3 -2
- package/utils/object/forward-ref.js +12 -12
- package/utils/object/lazy-property.js +2 -2
- package/utils/proxy.js +1 -1
- package/utils/stream/{readable-stream-from-promise.d.ts → from-promise.d.ts} +1 -0
- package/utils/stream/from-promise.js +27 -0
- package/utils/stream/index.d.ts +1 -1
- package/utils/stream/index.js +1 -1
- package/utils/stream/stream-reader.js +71 -31
- package/document-management/models/document-request-assignment-task-collection.model.d.ts +0 -7
- package/document-management/models/document-request-assignment-task.model.d.ts +0 -14
- package/document-management/models/document-request-assignment-task.model.js +0 -77
- package/document-management/models/document-request-file.model.d.ts +0 -16
- package/document-management/models/document-request-file.model.js +0 -86
- package/document-management/models/service-models/document.view-model.d.ts +0 -41
- package/document-management/models/service-models/normalized-document-collection-view.model.d.ts +0 -73
- package/document-management/models/service-models/normalized-document-collection-view.model.js +0 -110
- package/utils/stream/readable-stream-from-promise.js +0 -8
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { DocumentPropertyDataType } from '../../../document-management/models/index.js';
|
|
2
|
+
import type { DocumentPropertyValueView, SetDocumentPropertyParameters } from '../../../document-management/models/service-models/index.js';
|
|
3
|
+
import { Transactional } from '../../../orm/server/index.js';
|
|
4
|
+
import type { OneOrMany } from '../../../types.js';
|
|
5
|
+
import { Document, DocumentProperty } from '../../models/index.js';
|
|
6
|
+
export declare class DocumentPropertyService extends Transactional {
|
|
7
|
+
#private;
|
|
8
|
+
readonly repository: import("../../../orm/server/repository.js").EntityRepository<Document>;
|
|
9
|
+
readonly documentProperties: import("drizzle-orm/pg-core").WithSubqueryWithSelection<{
|
|
10
|
+
documentId: import("drizzle-orm/pg-core").PgColumn<{
|
|
11
|
+
name: string;
|
|
12
|
+
tableName: "document";
|
|
13
|
+
dataType: "string";
|
|
14
|
+
columnType: "PgUUID";
|
|
15
|
+
data: string;
|
|
16
|
+
driverParam: string;
|
|
17
|
+
notNull: true;
|
|
18
|
+
hasDefault: true;
|
|
19
|
+
isPrimaryKey: true;
|
|
20
|
+
isAutoincrement: false;
|
|
21
|
+
hasRuntimeDefault: false;
|
|
22
|
+
enumValues: undefined;
|
|
23
|
+
baseColumn: never;
|
|
24
|
+
identity: undefined;
|
|
25
|
+
generated: undefined;
|
|
26
|
+
}, {}, {}>;
|
|
27
|
+
propertyId: import("drizzle-orm/pg-core").PgColumn<{
|
|
28
|
+
name: string;
|
|
29
|
+
tableName: "document_property";
|
|
30
|
+
dataType: "string";
|
|
31
|
+
columnType: "PgUUID";
|
|
32
|
+
data: string;
|
|
33
|
+
driverParam: string;
|
|
34
|
+
notNull: true;
|
|
35
|
+
hasDefault: true;
|
|
36
|
+
isPrimaryKey: true;
|
|
37
|
+
isAutoincrement: false;
|
|
38
|
+
hasRuntimeDefault: false;
|
|
39
|
+
enumValues: undefined;
|
|
40
|
+
baseColumn: never;
|
|
41
|
+
identity: undefined;
|
|
42
|
+
generated: undefined;
|
|
43
|
+
}, {}, {}>;
|
|
44
|
+
label: import("drizzle-orm/pg-core").PgColumn<{
|
|
45
|
+
name: "label";
|
|
46
|
+
tableName: "document_property";
|
|
47
|
+
dataType: "string";
|
|
48
|
+
columnType: "PgText";
|
|
49
|
+
data: string;
|
|
50
|
+
driverParam: string;
|
|
51
|
+
notNull: true;
|
|
52
|
+
hasDefault: false;
|
|
53
|
+
isPrimaryKey: false;
|
|
54
|
+
isAutoincrement: false;
|
|
55
|
+
hasRuntimeDefault: false;
|
|
56
|
+
enumValues: [string];
|
|
57
|
+
baseColumn: never;
|
|
58
|
+
identity: undefined;
|
|
59
|
+
generated: undefined;
|
|
60
|
+
}, {}, {}>;
|
|
61
|
+
dataType: import("drizzle-orm/pg-core").PgColumn<{
|
|
62
|
+
name: "dataType";
|
|
63
|
+
tableName: "document_property";
|
|
64
|
+
dataType: "string";
|
|
65
|
+
columnType: "PgEnumColumn";
|
|
66
|
+
data: "boolean" | "date" | "decimal" | "text" | "integer";
|
|
67
|
+
driverParam: string;
|
|
68
|
+
notNull: true;
|
|
69
|
+
hasDefault: false;
|
|
70
|
+
isPrimaryKey: false;
|
|
71
|
+
isAutoincrement: false;
|
|
72
|
+
hasRuntimeDefault: false;
|
|
73
|
+
enumValues: ["boolean", "date", "decimal", "text", "integer"];
|
|
74
|
+
baseColumn: never;
|
|
75
|
+
identity: undefined;
|
|
76
|
+
generated: undefined;
|
|
77
|
+
}, {}, {}>;
|
|
78
|
+
value: import("drizzle-orm").SQL.Aliased<string | number | boolean | null>;
|
|
79
|
+
}, "documentProperties">;
|
|
80
|
+
createProperty(label: string, dataType: DocumentPropertyDataType): Promise<DocumentProperty>;
|
|
81
|
+
assignPropertyToType(typeId: string, propertyId: string): Promise<void>;
|
|
82
|
+
loadDocumentProperties(documentId: OneOrMany<string>, includeNulls?: boolean): Promise<DocumentPropertyValueView[]>;
|
|
83
|
+
setPropertyValues(documentId: string, propertyValues: SetDocumentPropertyParameters[]): Promise<void>;
|
|
84
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { and, isNotNull as drizzleIsNotNull, eq, inArray } from 'drizzle-orm';
|
|
2
|
+
import { DocumentPropertyDataType, DocumentPropertyValue, DocumentTypeProperty } from '../../../document-management/models/index.js';
|
|
3
|
+
import { BadRequestError } from '../../../errors/bad-request.error.js';
|
|
4
|
+
import { coalesce, getEntityMap, toJsonb } from '../../../orm/index.js';
|
|
5
|
+
import { Transactional } from '../../../orm/server/index.js';
|
|
6
|
+
import { injectRepository } from '../../../orm/server/repository.js';
|
|
7
|
+
import { toArray } from '../../../utils/array/index.js';
|
|
8
|
+
import { assertBooleanPass, assertDefinedPass, assertNumberPass, assertStringPass, isBoolean, isNotNull, isNull, isNumber, isString } from '../../../utils/type-guards.js';
|
|
9
|
+
import { Document, DocumentProperty } from '../../models/index.js';
|
|
10
|
+
import { document, documentProperty, documentPropertyValue, documentType, documentTypeProperty } from '../schemas.js';
|
|
11
|
+
const documentPropertyValueValidators = {
|
|
12
|
+
[DocumentPropertyDataType.Text]: (value) => isString(value) || isNull(value),
|
|
13
|
+
[DocumentPropertyDataType.Integer]: (value) => isNumber(value) || isNull(value),
|
|
14
|
+
[DocumentPropertyDataType.Decimal]: (value) => isNumber(value) || isNull(value),
|
|
15
|
+
[DocumentPropertyDataType.Boolean]: (value) => isBoolean(value) || isNull(value),
|
|
16
|
+
[DocumentPropertyDataType.Date]: (value) => isNumber(value) || isNull(value),
|
|
17
|
+
};
|
|
18
|
+
export class DocumentPropertyService extends Transactional {
|
|
19
|
+
#documentPropertyRepository = injectRepository(DocumentProperty);
|
|
20
|
+
#documentPropertyValueRepository = injectRepository(DocumentPropertyValue);
|
|
21
|
+
#documentTypePropertyRepository = injectRepository(DocumentTypeProperty);
|
|
22
|
+
repository = injectRepository(Document).withSession(this.session);
|
|
23
|
+
documentProperties = this.session.$with('documentProperties').as(this.session
|
|
24
|
+
.select({
|
|
25
|
+
documentId: document.id,
|
|
26
|
+
propertyId: documentProperty.id,
|
|
27
|
+
label: documentProperty.label,
|
|
28
|
+
dataType: documentProperty.dataType,
|
|
29
|
+
value: coalesce(toJsonb(documentPropertyValue.text), toJsonb(documentPropertyValue.integer), toJsonb(documentPropertyValue.decimal), toJsonb(documentPropertyValue.boolean), toJsonb(documentPropertyValue.date)).as('value'),
|
|
30
|
+
})
|
|
31
|
+
.from(document)
|
|
32
|
+
.innerJoin(documentType, eq(documentType.id, document.typeId))
|
|
33
|
+
.innerJoin(documentTypeProperty, eq(documentTypeProperty.typeId, documentType.id))
|
|
34
|
+
.innerJoin(documentProperty, eq(documentProperty.id, documentTypeProperty.propertyId))
|
|
35
|
+
.leftJoin(documentPropertyValue, and(eq(documentPropertyValue.documentId, document.id), eq(documentPropertyValue.propertyId, documentProperty.id))));
|
|
36
|
+
async createProperty(label, dataType) {
|
|
37
|
+
return this.#documentPropertyRepository.insert({ label, dataType });
|
|
38
|
+
}
|
|
39
|
+
async assignPropertyToType(typeId, propertyId) {
|
|
40
|
+
await this.#documentTypePropertyRepository.insert({ typeId, propertyId });
|
|
41
|
+
}
|
|
42
|
+
async loadDocumentProperties(documentId, includeNulls = false) {
|
|
43
|
+
return this.session
|
|
44
|
+
.select({
|
|
45
|
+
documentId: this.documentProperties.documentId,
|
|
46
|
+
propertyId: this.documentProperties.propertyId,
|
|
47
|
+
label: this.documentProperties.label,
|
|
48
|
+
dataType: this.documentProperties.dataType,
|
|
49
|
+
value: this.documentProperties.value,
|
|
50
|
+
})
|
|
51
|
+
.from(this.documentProperties)
|
|
52
|
+
.where(and(inArray(this.documentProperties.documentId, toArray(documentId)), includeNulls ? undefined : drizzleIsNotNull(this.documentProperties.value)));
|
|
53
|
+
}
|
|
54
|
+
async setPropertyValues(documentId, propertyValues) {
|
|
55
|
+
if ((propertyValues.length == 0)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await this.transaction(async (tx) => {
|
|
59
|
+
const propertyIds = propertyValues.map((property) => property.propertyId);
|
|
60
|
+
const properties = await this.#documentPropertyRepository.withTransaction(tx).loadManyByQuery({ id: { $in: propertyIds } });
|
|
61
|
+
const propertiesMap = getEntityMap(properties);
|
|
62
|
+
const upserts = propertyValues.filter((value) => isNotNull(value.value)).map(({ propertyId, value, metadata }) => {
|
|
63
|
+
const property = assertDefinedPass(propertiesMap.get(propertyId));
|
|
64
|
+
validatePropertyValue(propertyId, property.dataType, value);
|
|
65
|
+
return {
|
|
66
|
+
documentId,
|
|
67
|
+
propertyId,
|
|
68
|
+
text: (property.dataType == 'text') ? assertStringPass(value) : null,
|
|
69
|
+
integer: (property.dataType == 'integer') ? assertNumberPass(value) : null,
|
|
70
|
+
decimal: (property.dataType == 'decimal') ? assertNumberPass(value) : null,
|
|
71
|
+
boolean: (property.dataType == 'boolean') ? assertBooleanPass(value) : null,
|
|
72
|
+
date: (property.dataType == 'date') ? assertNumberPass(value) : null,
|
|
73
|
+
metadata,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
const deletePropertyIds = propertyValues.filter((value) => isNull(value.value)).map(({ propertyId }) => propertyId);
|
|
77
|
+
await this.#documentPropertyValueRepository.withTransaction(tx).hardDeleteManyByQuery({ documentId, propertyId: { $in: deletePropertyIds } });
|
|
78
|
+
await this.#documentPropertyValueRepository.withTransaction(tx).upsertMany(['documentId', 'propertyId'], upserts);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function validatePropertyValue(propertyId, dataType, value) {
|
|
83
|
+
const valid = documentPropertyValueValidators[dataType](value);
|
|
84
|
+
if (!valid) {
|
|
85
|
+
throw new BadRequestError(`Invalid value for data type ${dataType} for property ${propertyId}.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { RequestStats } from '../../../document-management/models/service-models/index.js';
|
|
2
|
+
import { Transactional } from '../../../orm/server/index.js';
|
|
3
|
+
import type { OneOrMany } from '../../../types.js';
|
|
4
|
+
import { DocumentRequest, DocumentRequestTemplate, DocumentRequestsTemplate } from '../../models/index.js';
|
|
5
|
+
export declare class DocumentRequestService extends Transactional {
|
|
6
|
+
#private;
|
|
7
|
+
getRequestStats(collectionIds: OneOrMany<string>): Promise<RequestStats>;
|
|
8
|
+
createRequestsTemplate(parameters: Pick<DocumentRequestsTemplate, 'label' | 'description'>): Promise<DocumentRequestsTemplate>;
|
|
9
|
+
updateRequestsTemplate(id: string, parameters: Pick<DocumentRequestsTemplate, 'label' | 'description' | 'metadata'>): Promise<DocumentRequestsTemplate>;
|
|
10
|
+
applyRequestsTemplate(id: string, collectionIds: string[]): Promise<void>;
|
|
11
|
+
deleteRequestsTemplate(id: string): Promise<DocumentRequestsTemplate>;
|
|
12
|
+
createRequestTemplate(requestsTemplateId: string, typeId: string, comment: string): Promise<DocumentRequestTemplate>;
|
|
13
|
+
updateRequestTemplate(id: string, parameters: Pick<DocumentRequestTemplate, 'typeId' | 'comment'>): Promise<DocumentRequestTemplate>;
|
|
14
|
+
deleteRequestTemplate(id: string): Promise<DocumentRequestTemplate>;
|
|
15
|
+
createRequest(typeId: string, collectionIds: string[], comment: string | null): Promise<DocumentRequest>;
|
|
16
|
+
updateRequest(id: string, update: Partial<Pick<DocumentRequest, 'typeId' | 'comment'>>): Promise<void>;
|
|
17
|
+
deleteRequest(id: string): Promise<void>;
|
|
18
|
+
assignDocument(requestId: string, documentId: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Fulfills a document request.
|
|
21
|
+
* Marks the request as fulfilled and creates associations between the document
|
|
22
|
+
* and the target collections defined in the request.
|
|
23
|
+
*
|
|
24
|
+
* @param requestId The ID of the DocumentRequest to fulfill.
|
|
25
|
+
* @param documentId The ID of the Document fulfilling the request.
|
|
26
|
+
* @param userId The ID of the user performing the action (for audit purposes).
|
|
27
|
+
* @throws NotFoundError if the DocumentRequest with the given ID does not exist.
|
|
28
|
+
*/
|
|
29
|
+
fulfillRequest(requestId: string, documentId: string): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { count, isNotNull as dbIsNotNull, isNull as dbIsNull, eq, inArray, sql } from 'drizzle-orm';
|
|
8
|
+
import { BadRequestError } from '../../../errors/index.js';
|
|
9
|
+
import { Injectable } from '../../../injector/index.js';
|
|
10
|
+
import { Transactional, injectRepository } from '../../../orm/server/index.js';
|
|
11
|
+
import { toArray } from '../../../utils/array/index.js';
|
|
12
|
+
import { assertDefinedPass, isNotNull } from '../../../utils/type-guards.js';
|
|
13
|
+
import { DocumentApproval, DocumentCollectionAssignment, DocumentRequest, DocumentRequestCollection, DocumentRequestState, DocumentRequestTemplate, DocumentRequestsTemplate } from '../../models/index.js';
|
|
14
|
+
import { document, documentRequest, documentRequestCollection } from '../schemas.js';
|
|
15
|
+
let DocumentRequestService = class DocumentRequestService extends Transactional {
|
|
16
|
+
#documentRequestCollectionRepository = injectRepository(DocumentRequestCollection);
|
|
17
|
+
#documentRequestRepository = injectRepository(DocumentRequest);
|
|
18
|
+
#documentRequestTemplateRepository = injectRepository(DocumentRequestTemplate);
|
|
19
|
+
#documentRequestsTemplateRepository = injectRepository(DocumentRequestsTemplate);
|
|
20
|
+
#documentCollectionAssignmentRepository = injectRepository(DocumentCollectionAssignment);
|
|
21
|
+
async getRequestStats(collectionIds) {
|
|
22
|
+
const relevantRequests = this.session.$with('relevant_requests').as(this.session.selectDistinct({ id: documentRequest.id })
|
|
23
|
+
.from(documentRequest)
|
|
24
|
+
.innerJoin(documentRequestCollection, eq(documentRequestCollection.requestId, documentRequest.id))
|
|
25
|
+
.where(inArray(documentRequestCollection.collectionId, toArray(collectionIds))));
|
|
26
|
+
const [result] = await this.session.with(relevantRequests)
|
|
27
|
+
.select({
|
|
28
|
+
total: count(sql `${documentRequest.id})`),
|
|
29
|
+
documentPending: count(sql `CASE WHEN ${eq(documentRequest.state, DocumentRequestState.Open)} AND ${dbIsNull(documentRequest.documentId)} THEN 1 END`),
|
|
30
|
+
approvalPending: count(sql `CASE WHEN ${eq(documentRequest.state, DocumentRequestState.Open)} AND ${dbIsNotNull(documentRequest.documentId)} AND ${eq(document.approval, DocumentApproval.Pending)} THEN 1 END`),
|
|
31
|
+
approvals: count(sql `CASE WHEN ${eq(documentRequest.state, DocumentRequestState.Closed)} AND ${dbIsNotNull(documentRequest.documentId)} AND ${eq(document.approval, DocumentApproval.Approved)} THEN 1 END`),
|
|
32
|
+
rejections: count(sql `CASE WHEN ${eq(documentRequest.state, DocumentRequestState.Closed)} AND ${dbIsNotNull(documentRequest.documentId)} AND ${eq(document.approval, DocumentApproval.Rejected)} THEN 1 END`),
|
|
33
|
+
closedWithoutDocument: count(sql `CASE WHEN ${eq(documentRequest.state, DocumentRequestState.Closed)} AND ${dbIsNull(documentRequest.documentId)} THEN 1 END`),
|
|
34
|
+
})
|
|
35
|
+
.from(documentRequest)
|
|
36
|
+
.leftJoin(document, eq(document.id, documentRequest.documentId))
|
|
37
|
+
.where(inArray(documentRequest.id, this.session.select({ id: relevantRequests.id }).from(relevantRequests)));
|
|
38
|
+
return assertDefinedPass(result);
|
|
39
|
+
}
|
|
40
|
+
async createRequestsTemplate(parameters) {
|
|
41
|
+
return this.#documentRequestsTemplateRepository.insert(parameters);
|
|
42
|
+
}
|
|
43
|
+
async updateRequestsTemplate(id, parameters) {
|
|
44
|
+
return this.#documentRequestsTemplateRepository.update(id, parameters);
|
|
45
|
+
}
|
|
46
|
+
async applyRequestsTemplate(id, collectionIds) {
|
|
47
|
+
const requestTemplates = await this.#documentRequestTemplateRepository.loadManyByQuery({ requestsTemplateId: id });
|
|
48
|
+
await this.transaction(async (tx) => {
|
|
49
|
+
for (const { typeId, comment } of requestTemplates) {
|
|
50
|
+
await this.withTransaction(tx).createRequest(typeId, collectionIds, comment);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async deleteRequestsTemplate(id) {
|
|
55
|
+
return this.#documentRequestsTemplateRepository.delete(id);
|
|
56
|
+
}
|
|
57
|
+
async createRequestTemplate(requestsTemplateId, typeId, comment) {
|
|
58
|
+
return this.#documentRequestTemplateRepository.insert({ requestsTemplateId, typeId, comment });
|
|
59
|
+
}
|
|
60
|
+
async updateRequestTemplate(id, parameters) {
|
|
61
|
+
return this.#documentRequestTemplateRepository.update(id, parameters);
|
|
62
|
+
}
|
|
63
|
+
async deleteRequestTemplate(id) {
|
|
64
|
+
return this.#documentRequestTemplateRepository.delete(id);
|
|
65
|
+
}
|
|
66
|
+
async createRequest(typeId, collectionIds, comment) {
|
|
67
|
+
if (collectionIds.length == 0) {
|
|
68
|
+
throw new BadRequestError('No target collectionId specified.');
|
|
69
|
+
}
|
|
70
|
+
return this.transaction(async (tx) => {
|
|
71
|
+
const request = await this.#documentRequestRepository.withTransaction(tx).insert({ typeId, documentId: null, comment, state: DocumentRequestState.Open });
|
|
72
|
+
const newDocumentRequestCollections = collectionIds.map((collectionId) => ({ requestId: request.id, collectionId }));
|
|
73
|
+
await this.#documentRequestCollectionRepository.withTransaction(tx).insertMany(newDocumentRequestCollections);
|
|
74
|
+
return request;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async updateRequest(id, update) {
|
|
78
|
+
await this.transaction(async (tx) => {
|
|
79
|
+
const request = await this.#documentRequestRepository.withTransaction(tx).load(id);
|
|
80
|
+
if (isNotNull(request.documentId)) {
|
|
81
|
+
throw new BadRequestError('Cannot update document requests which have an assigned document.');
|
|
82
|
+
}
|
|
83
|
+
await this.#documentRequestRepository.withTransaction(tx).update(id, update);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async deleteRequest(id) {
|
|
87
|
+
await this.transaction(async (tx) => {
|
|
88
|
+
const request = await this.#documentRequestRepository.withTransaction(tx).load(id);
|
|
89
|
+
if (isNotNull(request.documentId)) {
|
|
90
|
+
throw new BadRequestError('Cannot delete requests which have an assigned document.');
|
|
91
|
+
}
|
|
92
|
+
await this.#documentRequestCollectionRepository.withTransaction(tx).deleteManyByQuery({ requestId: id });
|
|
93
|
+
await this.#documentRequestRepository.withTransaction(tx).delete(id);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
async assignDocument(requestId, documentId) {
|
|
97
|
+
await this.transaction(async (tx) => {
|
|
98
|
+
const request = await this.#documentRequestRepository.withTransaction(tx).load(requestId);
|
|
99
|
+
if (isNotNull(request.documentId)) {
|
|
100
|
+
throw new BadRequestError('Document request already has a document assigned.');
|
|
101
|
+
}
|
|
102
|
+
await this.#documentRequestRepository.withTransaction(tx).update(requestId, { documentId });
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Fulfills a document request.
|
|
107
|
+
* Marks the request as fulfilled and creates associations between the document
|
|
108
|
+
* and the target collections defined in the request.
|
|
109
|
+
*
|
|
110
|
+
* @param requestId The ID of the DocumentRequest to fulfill.
|
|
111
|
+
* @param documentId The ID of the Document fulfilling the request.
|
|
112
|
+
* @param userId The ID of the user performing the action (for audit purposes).
|
|
113
|
+
* @throws NotFoundError if the DocumentRequest with the given ID does not exist.
|
|
114
|
+
*/
|
|
115
|
+
async fulfillRequest(requestId, documentId) {
|
|
116
|
+
await this.transaction(async (tx) => {
|
|
117
|
+
const request = await this.#documentRequestRepository.withTransaction(tx).load(requestId);
|
|
118
|
+
if (request.state == DocumentRequestState.Fulfilled) {
|
|
119
|
+
throw new BadRequestError('Document request is already fulfilled.');
|
|
120
|
+
}
|
|
121
|
+
const targetCollectionIds = await this.#documentRequestCollectionRepository.withTransaction(tx).loadManyByQuery({ requestId });
|
|
122
|
+
if (targetCollectionIds.length == 0) {
|
|
123
|
+
throw new Error('No document request collection for document request found.');
|
|
124
|
+
}
|
|
125
|
+
const links = targetCollectionIds.map((target) => ({
|
|
126
|
+
collectionId: target.collectionId,
|
|
127
|
+
documentId,
|
|
128
|
+
archiveTimestamp: null,
|
|
129
|
+
}));
|
|
130
|
+
await this.#documentCollectionAssignmentRepository.withTransaction(tx).insertMany(links);
|
|
131
|
+
await this.#documentRequestRepository.withTransaction(tx).update(requestId, { state: DocumentRequestState.Fulfilled });
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
DocumentRequestService = __decorate([
|
|
136
|
+
Injectable()
|
|
137
|
+
], DocumentRequestService);
|
|
138
|
+
export { DocumentRequestService };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CancellationSignal } from '../../../cancellation/token.js';
|
|
2
|
+
import { DocumentValidationResultStatus } from '../../../document-management/models/index.js';
|
|
3
|
+
import { afterResolve } from '../../../injector/interfaces.js';
|
|
4
|
+
import type { AfterResolveContext } from '../../../injector/types.js';
|
|
5
|
+
import type { Type } from '../../../types.js';
|
|
6
|
+
import type { DocumentValidationExecutor, DocumentValidationExecutorContext, DocumentValidationExecutorContextDocumentData } from '../validators/index.js';
|
|
7
|
+
export declare class DocumentValidationService {
|
|
8
|
+
#private;
|
|
9
|
+
[afterResolve](_: unknown, { cancellationSignal }: AfterResolveContext<any>): void;
|
|
10
|
+
processQueue(cancellationSignal: CancellationSignal): void;
|
|
11
|
+
startValidationWorkflow(documentId: string): Promise<void>;
|
|
12
|
+
setExecutionRunning(executionId: string): Promise<void>;
|
|
13
|
+
setExecutionCompleted(executionId: string, status: DocumentValidationResultStatus, message: string | null): Promise<void>;
|
|
14
|
+
setExecutionError(executionId: string, reason: string | null): Promise<void>;
|
|
15
|
+
loadRelatedDocument(executionId: string, documentId: string): Promise<DocumentValidationExecutorContextDocumentData>;
|
|
16
|
+
loadDocumentData(documentId: string): Promise<DocumentValidationExecutorContextDocumentData>;
|
|
17
|
+
protected loadDocumentValidationExecutorContext(executionId: string): Promise<DocumentValidationExecutorContext>;
|
|
18
|
+
processValidationExecution(executionId: string): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare function registerDocumentValidationExecutor(...executors: Type<DocumentValidationExecutor>[]): void;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { DocumentWorkflowStep } from '../../../document-management/models/document-workflow.model.js';
|
|
3
|
+
import { Document, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentProperty, DocumentPropertyValue, DocumentType, DocumentTypeProperty, DocumentTypeValidation, DocumentValidationDefinition, DocumentValidationExecution, DocumentValidationExecutionRelatedDocument, DocumentValidationExecutionState, DocumentValidationResultStatus } from '../../../document-management/models/index.js';
|
|
4
|
+
import { BadRequestError } from '../../../errors/bad-request.error.js';
|
|
5
|
+
import { inject, injectAll } from '../../../injector/inject.js';
|
|
6
|
+
import { Injector } from '../../../injector/injector.js';
|
|
7
|
+
import { afterResolve } from '../../../injector/interfaces.js';
|
|
8
|
+
import { injectionToken } from '../../../injector/token.js';
|
|
9
|
+
import { Logger } from '../../../logger/logger.js';
|
|
10
|
+
import { injectRepository } from '../../../orm/server/repository.js';
|
|
11
|
+
import { getEntityIds } from '../../../orm/utils.js';
|
|
12
|
+
import { Queue } from '../../../queue/queue.js';
|
|
13
|
+
import { currentTimestamp } from '../../../utils/date-time.js';
|
|
14
|
+
import { isNull, isUndefined } from '../../../utils/type-guards.js';
|
|
15
|
+
import { millisecondsPerMinute } from '../../../utils/units.js';
|
|
16
|
+
import { DocumentWorkflowService } from './document-workflow.service.js';
|
|
17
|
+
const DOCUMENT_VALIDATION_EXECUTORS = injectionToken('DocumentValidationExecutors');
|
|
18
|
+
export class DocumentValidationService {
|
|
19
|
+
#documentManagementService = injectRepository(DocumentCollection);
|
|
20
|
+
#documentCollectionAssignmentRepository = injectRepository(DocumentCollectionAssignment);
|
|
21
|
+
#documentService = injectRepository(Document);
|
|
22
|
+
#documentCategoryService = injectRepository(DocumentCategory);
|
|
23
|
+
#documentTypeService = injectRepository(DocumentType);
|
|
24
|
+
#documentTypePropertyService = injectRepository(DocumentTypeProperty);
|
|
25
|
+
#documentPropertyService = injectRepository(DocumentProperty);
|
|
26
|
+
#documentPropertyValueService = injectRepository(DocumentPropertyValue);
|
|
27
|
+
#documentWorkflowService = inject(DocumentWorkflowService);
|
|
28
|
+
#validationDefinitionService = injectRepository(DocumentValidationDefinition);
|
|
29
|
+
#validationExecutionService = injectRepository(DocumentValidationExecution);
|
|
30
|
+
#validationExecutionRelatedDocumentService = injectRepository(DocumentValidationExecutionRelatedDocument);
|
|
31
|
+
#documentTypeValidationService = injectRepository(DocumentTypeValidation);
|
|
32
|
+
#queue = inject((Queue), { name: 'DocumentManagement: validation', processTimeout: 5 * millisecondsPerMinute, maxTries: 3 });
|
|
33
|
+
#executors = injectAll(DOCUMENT_VALIDATION_EXECUTORS);
|
|
34
|
+
#logger = inject(Logger, _a.name);
|
|
35
|
+
#executorMap = new Map(this.#executors.map((executor) => [executor.identifier, executor]));
|
|
36
|
+
[afterResolve](_, { cancellationSignal }) {
|
|
37
|
+
this.processQueue(cancellationSignal);
|
|
38
|
+
}
|
|
39
|
+
processQueue(cancellationSignal) {
|
|
40
|
+
this.#queue.process({ concurrency: 5, cancellationSignal }, async (job) => {
|
|
41
|
+
this.#logger.verbose(`Processing validation execution "${job.data.executionId}"`);
|
|
42
|
+
await this.processValidationExecution(job.data.executionId);
|
|
43
|
+
}, this.#logger);
|
|
44
|
+
}
|
|
45
|
+
async startValidationWorkflow(documentId) {
|
|
46
|
+
const document = await this.#documentService.load(documentId);
|
|
47
|
+
if (isNull(document.typeId)) {
|
|
48
|
+
throw new BadRequestError('Document has no type');
|
|
49
|
+
}
|
|
50
|
+
const workflow = await this.#documentWorkflowService.initiateWorkflow(documentId, DocumentWorkflowStep.Validation);
|
|
51
|
+
const typeValidations = await this.#documentTypeValidationService.loadManyByQuery({ typeId: document.typeId });
|
|
52
|
+
for (const typeValidation of typeValidations) {
|
|
53
|
+
const validationDefinition = await this.#validationDefinitionService.load(typeValidation.validationId);
|
|
54
|
+
const execution = await this.#validationExecutionService.insert({
|
|
55
|
+
definitionId: validationDefinition.id,
|
|
56
|
+
workflowId: workflow.id,
|
|
57
|
+
state: DocumentValidationExecutionState.Pending,
|
|
58
|
+
resultStatus: null,
|
|
59
|
+
resultMessage: null,
|
|
60
|
+
startedAt: null,
|
|
61
|
+
completedAt: null,
|
|
62
|
+
});
|
|
63
|
+
await this.#queue.enqueue({ executionId: execution.id });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async setExecutionRunning(executionId) {
|
|
67
|
+
await this.#validationExecutionService.update(executionId, { state: DocumentValidationExecutionState.Running, resultStatus: null, resultMessage: null, startedAt: currentTimestamp(), completedAt: null });
|
|
68
|
+
}
|
|
69
|
+
async setExecutionCompleted(executionId, status, message) {
|
|
70
|
+
await this.#validationExecutionService.update(executionId, { state: DocumentValidationExecutionState.Completed, resultStatus: status, resultMessage: message, completedAt: currentTimestamp() });
|
|
71
|
+
}
|
|
72
|
+
async setExecutionError(executionId, reason) {
|
|
73
|
+
await this.#validationExecutionService.update(executionId, { state: DocumentValidationExecutionState.Error, resultStatus: DocumentValidationResultStatus.Failed, resultMessage: reason, completedAt: currentTimestamp() });
|
|
74
|
+
}
|
|
75
|
+
async loadRelatedDocument(executionId, documentId) {
|
|
76
|
+
const execution = await this.#validationExecutionService.load(executionId);
|
|
77
|
+
const workflow = await this.#documentWorkflowService.repository.load(execution.workflowId);
|
|
78
|
+
const documentData = await this.loadDocumentData(documentId);
|
|
79
|
+
await this.#validationExecutionRelatedDocumentService.upsert(['executionId', 'documentId'], { executionId, documentId: workflow.documentId });
|
|
80
|
+
return documentData;
|
|
81
|
+
}
|
|
82
|
+
async loadDocumentData(documentId) {
|
|
83
|
+
const document = await this.#documentService.load(documentId);
|
|
84
|
+
if (isNull(document.typeId)) {
|
|
85
|
+
throw new Error('Document has no type');
|
|
86
|
+
}
|
|
87
|
+
const [documentCollections, documentTypeProperties] = await Promise.all([
|
|
88
|
+
this.#documentCollectionAssignmentRepository.loadManyByQuery({ documentId: document.id }),
|
|
89
|
+
this.#documentTypePropertyService.loadManyByQuery({ typeId: document.typeId }),
|
|
90
|
+
]);
|
|
91
|
+
const documentCollectionIds = getEntityIds(documentCollections);
|
|
92
|
+
const documentPropertyIds = getEntityIds(documentTypeProperties);
|
|
93
|
+
const [collections, category, type, properties, propertyValues] = await Promise.all([
|
|
94
|
+
this.#documentManagementService.loadManyByQuery({ id: { $in: documentCollectionIds } }),
|
|
95
|
+
this.#documentCategoryService.load(document.typeId),
|
|
96
|
+
this.#documentTypeService.load(document.typeId),
|
|
97
|
+
this.#documentPropertyService.loadManyByQuery({ id: { $in: documentPropertyIds } }),
|
|
98
|
+
this.#documentPropertyValueService.loadManyByQuery({ documentId: document.id }),
|
|
99
|
+
]);
|
|
100
|
+
return {
|
|
101
|
+
document,
|
|
102
|
+
collections,
|
|
103
|
+
category,
|
|
104
|
+
type,
|
|
105
|
+
properties,
|
|
106
|
+
propertyValues,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async loadDocumentValidationExecutorContext(executionId) {
|
|
110
|
+
const execution = await this.#validationExecutionService.load(executionId);
|
|
111
|
+
const [definition, workflow] = await Promise.all([
|
|
112
|
+
this.#validationDefinitionService.load(execution.definitionId),
|
|
113
|
+
this.#documentWorkflowService.repository.load(execution.workflowId),
|
|
114
|
+
]);
|
|
115
|
+
const documentData = await this.loadDocumentData(workflow.documentId);
|
|
116
|
+
return {
|
|
117
|
+
execution,
|
|
118
|
+
definition,
|
|
119
|
+
...documentData,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async processValidationExecution(executionId) {
|
|
123
|
+
const context = await this.loadDocumentValidationExecutorContext(executionId);
|
|
124
|
+
const executor = this.#executorMap.get(context.definition.identifier);
|
|
125
|
+
if (isUndefined(executor)) {
|
|
126
|
+
await this.setExecutionError(executionId, `Invalid validation identifier`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
await this.setExecutionRunning(executionId);
|
|
131
|
+
const result = await executor.execute(context);
|
|
132
|
+
await this.setExecutionCompleted(executionId, result.status, result.message ?? null);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
this.#logger.error(error);
|
|
136
|
+
await this.setExecutionError(executionId, 'Internal error');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
_a = DocumentValidationService;
|
|
141
|
+
export function registerDocumentValidationExecutor(...executors) {
|
|
142
|
+
for (const executor of executors) {
|
|
143
|
+
Injector.register(DOCUMENT_VALIDATION_EXECUTORS, { useToken: executor }, { multi: true });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DocumentWorkflow, DocumentWorkflowStep } from '../../../document-management/models/document-workflow.model.js';
|
|
2
|
+
import type { AfterResolveContext } from '../../../injector/index.js';
|
|
3
|
+
import { afterResolve } from '../../../injector/interfaces.js';
|
|
4
|
+
import { Transactional } from '../../../orm/server/transactional.js';
|
|
5
|
+
export declare class DocumentWorkflowService extends Transactional {
|
|
6
|
+
#private;
|
|
7
|
+
readonly repository: import("../../../orm/server/repository.js").EntityRepository<DocumentWorkflow>;
|
|
8
|
+
[afterResolve](_: unknown, { cancellationSignal }: AfterResolveContext<any>): void;
|
|
9
|
+
loadLatestWorkflow(documentId: string): Promise<DocumentWorkflow>;
|
|
10
|
+
tryLoadLatestWorkflow(documentId: string): Promise<DocumentWorkflow | undefined>;
|
|
11
|
+
loadLatestWorkflows(documentIds: string[]): Promise<DocumentWorkflow[]>;
|
|
12
|
+
proceedWorkflow(documentId: string, userId: string): Promise<void>;
|
|
13
|
+
initiateWorkflow(documentId: string, step: DocumentWorkflowStep): Promise<DocumentWorkflow>;
|
|
14
|
+
private setWorkflowState;
|
|
15
|
+
private processWorkflowJob;
|
|
16
|
+
private processClassificationWorkflow;
|
|
17
|
+
private processExtractionWorkflow;
|
|
18
|
+
private processAssignmentWorkflow;
|
|
19
|
+
private processValidationWorkflow;
|
|
20
|
+
}
|