@tstdl/base 0.92.142 → 0.92.143
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 +1 -1
- package/ai/ai.service.js +3 -3
- package/ai/types.d.ts +1 -1
- package/api/client/client.d.ts +1 -1
- package/api/client/client.js +10 -4
- package/api/server/middlewares/content-type.middleware.js +8 -7
- package/api/types.js +1 -1
- package/authentication/client/authentication.service.js +3 -3
- package/authentication/server/authentication-ancillary.service.d.ts +11 -1
- package/authentication/server/authentication-ancillary.service.js +1 -1
- package/authentication/server/authentication-secret-requirements.validator.js +1 -1
- package/authentication/server/authentication.api-controller.js +22 -10
- package/authentication/server/authentication.service.d.ts +11 -5
- package/authentication/server/authentication.service.js +97 -49
- package/authentication/server/drizzle.config.js +2 -2
- package/authentication/server/module.js +1 -1
- package/cancellation/token.d.ts +2 -2
- package/cancellation/token.js +4 -4
- package/cookie/cookie.js +2 -2
- package/document-management/api/document-management.api.d.ts +122 -24
- package/document-management/api/document-management.api.js +17 -0
- package/document-management/{server/services → authorization}/document-management-authorization.service.d.ts +7 -7
- package/document-management/authorization/document-management-authorization.service.js +2 -0
- package/document-management/authorization/index.d.ts +2 -0
- package/document-management/authorization/index.js +2 -0
- package/document-management/authorization/policies.d.ts +38 -0
- package/document-management/authorization/policies.js +2 -0
- package/document-management/index.d.ts +1 -0
- package/document-management/index.js +1 -0
- package/document-management/models/document-assignment-scope.model.d.ts +1 -0
- package/document-management/models/document-assignment-scope.model.js +10 -3
- package/document-management/models/document-assignment-task.model.d.ts +1 -0
- package/document-management/models/document-assignment-task.model.js +8 -2
- package/document-management/models/document-category.model.d.ts +1 -0
- package/document-management/models/document-category.model.js +7 -1
- package/document-management/models/document-collection-assignment.model.d.ts +1 -0
- package/document-management/models/document-collection-assignment.model.js +12 -4
- package/document-management/models/document-collection.model.d.ts +2 -0
- package/document-management/models/document-collection.model.js +8 -2
- package/document-management/models/document-management-table.d.ts +3 -1
- package/document-management/models/document-management-table.js +2 -2
- package/document-management/models/document-property-value.model.d.ts +1 -0
- package/document-management/models/document-property-value.model.js +9 -3
- package/document-management/models/document-property.model.d.ts +1 -0
- package/document-management/models/document-property.model.js +8 -2
- package/document-management/models/document-request-collection-assignment.model.d.ts +1 -0
- package/document-management/models/document-request-collection-assignment.model.js +12 -4
- package/document-management/models/document-request-template.d.ts +1 -0
- package/document-management/models/document-request-template.js +6 -1
- package/document-management/models/document-request.model.d.ts +1 -0
- package/document-management/models/document-request.model.js +10 -1
- package/document-management/models/document-requests-template.d.ts +1 -0
- package/document-management/models/document-requests-template.js +7 -3
- package/document-management/models/document-tag-assignment.model.d.ts +8 -0
- package/document-management/models/document-tag-assignment.model.js +40 -0
- package/document-management/models/document-tag.model.d.ts +6 -0
- package/document-management/models/{document-request-submission.model.js → document-tag.model.js} +14 -18
- package/document-management/models/document-type-property.model.d.ts +1 -0
- package/document-management/models/document-type-property.model.js +7 -2
- package/document-management/models/document-type-validation.model.d.ts +1 -0
- package/document-management/models/document-type-validation.model.js +8 -2
- package/document-management/models/document-type.model.d.ts +1 -0
- package/document-management/models/document-type.model.js +7 -2
- package/document-management/models/document-validation-definition.model.d.ts +1 -0
- package/document-management/models/document-validation-definition.model.js +7 -2
- package/document-management/models/document-validation-execution-related-document.model.d.ts +1 -0
- package/document-management/models/document-validation-execution-related-document.model.js +10 -3
- package/document-management/models/document-validation-execution.model.d.ts +1 -0
- package/document-management/models/document-validation-execution.model.js +9 -3
- package/document-management/models/document-workflow.model.d.ts +4 -1
- package/document-management/models/document-workflow.model.js +16 -4
- package/document-management/models/document.model.d.ts +2 -2
- package/document-management/models/document.model.js +9 -8
- package/document-management/models/index.d.ts +2 -1
- package/document-management/models/index.js +2 -1
- package/document-management/server/api/document-management.api.d.ts +4 -1
- package/document-management/server/api/document-management.api.js +113 -22
- package/document-management/server/configure.d.ts +2 -2
- package/document-management/server/configure.js +7 -7
- package/document-management/server/drizzle/0000_parallel_mantis.sql +359 -0
- package/document-management/server/drizzle/meta/0000_snapshot.json +784 -260
- package/document-management/server/drizzle/meta/_journal.json +2 -2
- package/document-management/server/module.d.ts +2 -2
- package/document-management/server/module.js +2 -2
- package/document-management/server/schemas.d.ts +6 -5
- package/document-management/server/schemas.js +12 -11
- package/document-management/server/services/document-category-type.service.d.ts +19 -10
- package/document-management/server/services/document-category-type.service.js +34 -27
- package/document-management/server/services/document-collection.service.d.ts +13 -6
- package/document-management/server/services/document-collection.service.js +36 -12
- package/document-management/server/services/document-file.service.d.ts +8 -7
- package/document-management/server/services/document-file.service.js +28 -33
- package/document-management/server/services/document-management-ai.service.d.ts +5 -4
- package/document-management/server/services/document-management-ai.service.js +51 -28
- package/document-management/server/services/document-management-ancillary.service.d.ts +3 -21
- package/document-management/server/services/document-management-ancillary.service.js +0 -24
- package/document-management/server/services/document-management-observation.service.d.ts +15 -0
- package/document-management/server/services/document-management-observation.service.js +160 -0
- package/document-management/server/services/document-management.service.d.ts +6 -5
- package/document-management/server/services/document-management.service.js +112 -86
- package/document-management/server/services/document-property.service.d.ts +15 -7
- package/document-management/server/services/document-property.service.js +52 -20
- package/document-management/server/services/document-request.service.d.ts +13 -24
- package/document-management/server/services/document-request.service.js +39 -62
- package/document-management/server/services/document-tag.service.d.ts +10 -0
- package/document-management/server/services/document-tag.service.js +59 -0
- package/document-management/server/services/document-validation.service.d.ts +8 -8
- package/document-management/server/services/document-validation.service.js +41 -40
- package/document-management/server/services/document-workflow.service.d.ts +6 -5
- package/document-management/server/services/document-workflow.service.js +54 -43
- package/document-management/server/services/document.service.d.ts +12 -11
- package/document-management/server/services/document.service.js +64 -40
- package/document-management/server/services/index.d.ts +2 -1
- package/document-management/server/services/index.js +2 -1
- package/document-management/server/services/singleton.js +2 -2
- package/document-management/server/validators/ai-validation-executor.js +4 -4
- package/document-management/service-models/document-collection-metadata.service-model.d.ts +14 -0
- package/document-management/service-models/document-collection-metadata.service-model.js +1 -0
- package/document-management/service-models/document-folders.view-model.d.ts +1 -7
- package/document-management/service-models/document-folders.view-model.js +3 -15
- package/document-management/service-models/document-management.view-model.d.ts +20 -6
- package/document-management/service-models/document-management.view-model.js +62 -8
- package/document-management/service-models/document.service-model.d.ts +14 -11
- package/document-management/service-models/document.service-model.js +11 -2
- package/document-management/service-models/enriched/enriched-document-assignment.view.d.ts +1 -1
- package/document-management/service-models/enriched/enriched-document-assignment.view.js +0 -2
- package/document-management/service-models/enriched/enriched-document-category.view.d.ts +11 -1
- package/document-management/service-models/enriched/enriched-document-category.view.js +44 -1
- package/document-management/service-models/enriched/enriched-document-collection.view.d.ts +4 -2
- package/document-management/service-models/enriched/enriched-document-collection.view.js +13 -3
- package/document-management/service-models/enriched/enriched-document-management-data.view.d.ts +2 -0
- package/document-management/service-models/enriched/enriched-document-management-data.view.js +4 -2
- package/document-management/service-models/enriched/enriched-document-request.view.d.ts +1 -0
- package/document-management/service-models/enriched/enriched-document-request.view.js +2 -0
- package/document-management/service-models/enriched/enriched-document-type.view.d.ts +9 -1
- package/document-management/service-models/enriched/enriched-document-type.view.js +28 -1
- package/document-management/service-models/enriched/enriched-document.view.d.ts +7 -6
- package/document-management/service-models/enriched/enriched-document.view.js +29 -6
- package/document-management/service-models/{normalized-requests-template-data.model.d.ts → enriched/enriched-requests-template-data.model.d.ts} +6 -6
- package/document-management/service-models/{normalized-requests-template-data.model.js → enriched/enriched-requests-template-data.model.js} +1 -1
- package/document-management/service-models/enriched/index.d.ts +1 -0
- package/document-management/service-models/enriched/index.js +1 -0
- package/document-management/service-models/index.d.ts +2 -2
- package/document-management/service-models/index.js +2 -2
- package/examples/document-management/categories-and-types.d.ts +33 -31
- package/examples/document-management/categories-and-types.js +33 -0
- package/examples/document-management/main.d.ts +5 -4
- package/examples/document-management/main.js +13 -7
- package/function/log.js +2 -2
- package/http/server/node/module.d.ts +4 -1
- package/http/server/node/module.js +10 -1
- package/http/server/node/node-http-server.d.ts +3 -6
- package/http/server/node/node-http-server.js +68 -67
- package/injector/inject.js +6 -6
- package/injector/injector.js +3 -3
- package/jsx/is-component-class.js +1 -1
- package/key-value-store/key-value.store.d.ts +38 -7
- package/key-value-store/key-value.store.js +2 -1
- package/key-value-store/mongo/mongo-key-value.store.d.ts +1 -0
- package/key-value-store/mongo/mongo-key-value.store.js +14 -5
- package/key-value-store/postgres/drizzle/0000_shocking_slipstream.sql +12 -0
- package/key-value-store/postgres/drizzle/meta/0000_snapshot.json +97 -0
- package/key-value-store/postgres/drizzle/meta/_journal.json +13 -0
- package/key-value-store/postgres/drizzle.config.d.ts +2 -0
- package/key-value-store/postgres/drizzle.config.js +11 -0
- package/key-value-store/postgres/index.d.ts +2 -0
- package/key-value-store/postgres/index.js +2 -0
- package/key-value-store/postgres/key-value-store.service.d.ts +17 -0
- package/key-value-store/postgres/key-value-store.service.js +65 -0
- package/key-value-store/postgres/models/index.d.ts +2 -0
- package/key-value-store/postgres/models/index.js +2 -0
- package/key-value-store/postgres/models/key-value.model.d.ts +7 -0
- package/key-value-store/postgres/models/key-value.model.js +35 -0
- package/key-value-store/postgres/models/schemas.d.ts +3 -0
- package/key-value-store/postgres/models/schemas.js +4 -0
- package/key-value-store/postgres/module.d.ts +6 -0
- package/key-value-store/postgres/module.js +23 -0
- package/lock/web/web-lock.d.ts +0 -1
- package/lock/web/web-lock.js +6 -13
- package/orm/data-types/timestamp.js +1 -1
- package/orm/decorators.d.ts +37 -29
- package/orm/decorators.js +44 -24
- package/orm/entity.d.ts +1 -0
- package/orm/query.d.ts +10 -2
- package/orm/repository.types.d.ts +2 -1
- package/orm/schemas/json.d.ts +12 -6
- package/orm/schemas/json.js +12 -5
- package/orm/server/database.js +5 -2
- package/orm/server/drizzle/schema-converter.js +40 -11
- package/orm/server/query-converter.d.ts +2 -1
- package/orm/server/query-converter.js +57 -34
- package/orm/server/repository.d.ts +26 -43
- package/orm/server/repository.js +106 -39
- package/orm/server/transaction.d.ts +2 -1
- package/orm/server/transaction.js +3 -0
- package/orm/server/transactional.d.ts +5 -1
- package/orm/server/transactional.js +34 -4
- package/package.json +14 -11
- package/process/spawn.js +0 -1
- package/promise/deferred-promise.d.ts +4 -3
- package/promise/deferred-promise.js +13 -5
- package/queue/postgres/queue.js +8 -8
- package/reflection/utils.js +3 -3
- package/schema/decorators/class.js +0 -1
- package/schema/decorators/schema.js +1 -1
- package/schema/schemas/boolean.d.ts +1 -1
- package/schema/schemas/boolean.js +2 -2
- package/schema/schemas/number.js +3 -3
- package/schema/schemas/object.js +5 -6
- package/sse/server-sent-events-source.js +4 -1
- package/utils/compression.js +9 -9
- package/utils/date-time.d.ts +1 -0
- package/utils/date-time.js +18 -4
- package/utils/equals.d.ts +7 -0
- package/utils/equals.js +17 -2
- package/utils/function/memoize.js +10 -2
- package/utils/jwt.js +3 -3
- package/utils/object/property-name.d.ts +2 -2
- package/utils/timing.d.ts +2 -2
- package/utils/timing.js +12 -12
- package/document-management/models/document-request-submission.model.d.ts +0 -7
- package/document-management/server/drizzle/0000_moaning_luckman.sql +0 -305
- package/document-management/server/services/document-management-authorization.service.js +0 -28
|
@@ -68,19 +68,21 @@ import { arrayAgg } from '../../../orm/index.js';
|
|
|
68
68
|
import { injectRepository } from '../../../orm/server/index.js';
|
|
69
69
|
import { array, boolean, enumeration, integer, nullable, number, object, string } from '../../../schema/index.js';
|
|
70
70
|
import { distinct } from '../../../utils/array/index.js';
|
|
71
|
-
import {
|
|
71
|
+
import { numericDateToDateObject, tryDateObjectToNumericDate } from '../../../utils/date-time.js';
|
|
72
72
|
import { fromEntries, objectEntries } from '../../../utils/object/object.js';
|
|
73
73
|
import { assertDefined, assertDefinedPass, assertNotNull, isNotNull, isNull, isUndefined } from '../../../utils/type-guards.js';
|
|
74
74
|
import { Document, DocumentProperty, DocumentRequestState, DocumentTypeProperty } from '../../models/index.js';
|
|
75
75
|
import { documentCategory, documentRequest, documentRequestCollectionAssignment, documentType } from '../schemas.js';
|
|
76
76
|
import { DocumentCategoryTypeService } from './document-category-type.service.js';
|
|
77
|
+
import { DocumentCollectionService } from './document-collection.service.js';
|
|
77
78
|
import { DocumentFileService } from './document-file.service.js';
|
|
78
|
-
import { DocumentManagementAncillaryService } from './document-management-ancillary.service.js';
|
|
79
79
|
import { DocumentPropertyService } from './document-property.service.js';
|
|
80
|
+
import { DocumentTagService } from './document-tag.service.js';
|
|
80
81
|
import { DocumentManagementSingleton } from './singleton.js';
|
|
81
82
|
const MODEL = 'gemini-2.5-flash-preview-05-20';
|
|
82
83
|
let DocumentManagementAiService = DocumentManagementAiService_1 = class DocumentManagementAiService {
|
|
83
|
-
#
|
|
84
|
+
#documentCollectionService = inject(DocumentCollectionService);
|
|
85
|
+
#documentTagService = inject(DocumentTagService);
|
|
84
86
|
#documentCategoryTypeService = inject(DocumentCategoryTypeService);
|
|
85
87
|
#documentFileService = inject(DocumentFileService);
|
|
86
88
|
#documentPropertyService = inject(DocumentPropertyService);
|
|
@@ -89,14 +91,14 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
89
91
|
#documentRepository = injectRepository(Document);
|
|
90
92
|
#documentTypePropertyRepository = injectRepository(DocumentTypeProperty);
|
|
91
93
|
#logger = inject(Logger, DocumentManagementAiService_1.name);
|
|
92
|
-
async classifyDocumentType(documentId) {
|
|
94
|
+
async classifyDocumentType(tenantId, documentId) {
|
|
93
95
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
94
96
|
try {
|
|
95
|
-
const document = await this.#documentRepository.
|
|
96
|
-
const fileContentStream = this.#documentFileService.getContentStream(document
|
|
97
|
+
const document = await this.#documentRepository.loadByQuery({ tenantId, id: documentId });
|
|
98
|
+
const fileContentStream = this.#documentFileService.getContentStream(document);
|
|
97
99
|
const tmpFile = __addDisposableResource(env_1, await TemporaryFile.from(fileContentStream), true);
|
|
98
100
|
const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: document.mimeType });
|
|
99
|
-
const categories = await this.#documentCategoryTypeService.loadCategoryViews();
|
|
101
|
+
const categories = await this.#documentCategoryTypeService.loadCategoryViews(tenantId);
|
|
100
102
|
const typeLabelEntries = getDescriptiveTypeLabels(categories);
|
|
101
103
|
const typeLabels = typeLabelEntries.map(({ label }) => label);
|
|
102
104
|
this.#logger.trace(`Classifying document ${document.id}`);
|
|
@@ -136,19 +138,20 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
136
138
|
await result_1;
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
|
-
async extractDocumentInformation(documentId) {
|
|
141
|
+
async extractDocumentInformation(tenantId, documentId) {
|
|
140
142
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
141
143
|
try {
|
|
142
|
-
const document = await this.#documentRepository.
|
|
143
|
-
const
|
|
144
|
+
const document = await this.#documentRepository.loadByQuery({ tenantId, id: documentId });
|
|
145
|
+
const existingTags = await this.#documentTagService.loadTags(tenantId);
|
|
146
|
+
const fileContentStream = this.#documentFileService.getContentStream(document);
|
|
144
147
|
const tmpFile = __addDisposableResource(env_2, await TemporaryFile.from(fileContentStream), true);
|
|
145
148
|
const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: document.mimeType });
|
|
146
149
|
if (isNull(document.typeId)) {
|
|
147
150
|
throw new Error(`Document ${document.id} has no type`);
|
|
148
151
|
}
|
|
149
|
-
const typeProperties = await this.#documentTypePropertyRepository.loadManyByQuery({ typeId: document.typeId });
|
|
152
|
+
const typeProperties = await this.#documentTypePropertyRepository.loadManyByQuery({ tenantId: { $or: [null, tenantId] }, typeId: document.typeId });
|
|
150
153
|
const propertyIds = typeProperties.map((property) => property.propertyId);
|
|
151
|
-
const properties = (propertyIds.length > 0) ? await this.#documentPropertyRepository.loadManyByQuery({ id: { $in: propertyIds } }) : undefined;
|
|
154
|
+
const properties = (propertyIds.length > 0) ? await this.#documentPropertyRepository.loadManyByQuery({ tenantId: { $or: [null, tenantId] }, id: { $in: propertyIds } }) : undefined;
|
|
152
155
|
const propertiesSchemaEntries = properties?.map((property) => {
|
|
153
156
|
const schema = match(property.dataType)
|
|
154
157
|
.with('text', () => nullable(string()))
|
|
@@ -169,6 +172,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
169
172
|
? {}
|
|
170
173
|
: { documentProperties: object(fromEntries(propertiesSchemaEntries)) }),
|
|
171
174
|
});
|
|
175
|
+
const context = { existingTags };
|
|
172
176
|
this.#logger.trace(`Extracting document ${document.id}`);
|
|
173
177
|
const { json: extraction } = await this.#aiService.generate({
|
|
174
178
|
model: MODEL,
|
|
@@ -186,11 +190,15 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
186
190
|
parts: [
|
|
187
191
|
{ file: filePart.file },
|
|
188
192
|
{
|
|
189
|
-
text:
|
|
193
|
+
text: `<context>
|
|
194
|
+
${JSON.stringify(context, null, 2)}
|
|
195
|
+
</context>
|
|
196
|
+
Extrahiere den Inhalt des Dokuments in das angegebenen JSON Schema.
|
|
190
197
|
|
|
191
198
|
Vermeide es, den Titel im Untertitel zu wiederholen.
|
|
192
199
|
Gib in der summary ausführlich an, welche Informationen in dem Dokument vorkommen (ohne konkrete Werte).
|
|
193
|
-
Erstelle bis zu
|
|
200
|
+
Erstelle bis zu 5 Tags. Verwende vorhandene Tags, wenn sie passen. Erstelle neue Tags, wenn es keine passenden gibt.
|
|
201
|
+
Vermeide es, den Titel oder Untertitel als Tag zu verwenden.
|
|
194
202
|
Antworte auf deutsch.`,
|
|
195
203
|
},
|
|
196
204
|
],
|
|
@@ -198,7 +206,7 @@ Antworte auf deutsch.`,
|
|
|
198
206
|
],
|
|
199
207
|
});
|
|
200
208
|
const filteredDocumentTags = extraction.documentTags.filter((tag) => (tag != extraction.documentTitle) && (tag != extraction.documentSubtitle));
|
|
201
|
-
const date = isNotNull(extraction.documentDate) ?
|
|
209
|
+
const date = isNotNull(extraction.documentDate) ? tryAiOutputDateObjectToNumericDate(extraction.documentDate) : null;
|
|
202
210
|
const parsedProperties = isUndefined(extraction.documentProperties)
|
|
203
211
|
? []
|
|
204
212
|
: objectEntries(extraction.documentProperties)
|
|
@@ -208,8 +216,11 @@ Antworte auf deutsch.`,
|
|
|
208
216
|
}
|
|
209
217
|
const property = assertDefinedPass(properties?.find((property) => property.label == propertyLabel));
|
|
210
218
|
const value = match(rawValue)
|
|
211
|
-
.with({ year: P.number }, (
|
|
212
|
-
.otherwise((
|
|
219
|
+
.with({ year: P.number }, (value) => tryAiOutputDateObjectToNumericDate(value))
|
|
220
|
+
.otherwise((value) => value);
|
|
221
|
+
if (isNull(value)) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
213
224
|
return { propertyId: property.id, dataType: property.dataType, value };
|
|
214
225
|
})
|
|
215
226
|
.filter(isNotNull);
|
|
@@ -232,15 +243,18 @@ Antworte auf deutsch.`,
|
|
|
232
243
|
await result_2;
|
|
233
244
|
}
|
|
234
245
|
}
|
|
235
|
-
async findSuitableCollectionsForDocument(
|
|
236
|
-
const document = await this.#documentRepository.load(documentId);
|
|
246
|
+
async findSuitableCollectionsForDocument(document, collectionIds) {
|
|
237
247
|
assertNotNull(document.typeId, 'Document has no type');
|
|
238
|
-
const documentProperties = await
|
|
239
|
-
|
|
248
|
+
const [documentTags, documentProperties, collectionNamesMap] = await Promise.all([
|
|
249
|
+
this.#documentTagService.loadDocumentTags(document.tenantId, document.id),
|
|
250
|
+
this.#documentPropertyService.loadDocumentPropertyValues(document.tenantId, document.id),
|
|
251
|
+
this.#documentCollectionService.resolveMetadata(document.tenantId, collectionIds),
|
|
252
|
+
]);
|
|
240
253
|
const collections = collectionIds.map((collectionId, index) => ({
|
|
241
254
|
id: collectionId,
|
|
242
255
|
...assertDefinedPass(collectionNamesMap[index]),
|
|
243
256
|
}));
|
|
257
|
+
const documentTagLabels = documentTags.map((tag) => tag.label);
|
|
244
258
|
const propertyEntries = documentProperties.map((property) => [property.label, property.value]);
|
|
245
259
|
const context = {
|
|
246
260
|
document: {
|
|
@@ -248,7 +262,7 @@ Antworte auf deutsch.`,
|
|
|
248
262
|
subtitle: document.subtitle ?? undefined,
|
|
249
263
|
date: isNotNull(document.date) ? numericDateToDateObject(document.date) : undefined,
|
|
250
264
|
summary: document.summary ?? undefined,
|
|
251
|
-
tags: (
|
|
265
|
+
tags: (documentTagLabels.length > 0) ? documentTagLabels : undefined,
|
|
252
266
|
properties: fromEntries(propertyEntries),
|
|
253
267
|
},
|
|
254
268
|
collections,
|
|
@@ -278,11 +292,11 @@ Ordne das Dokument unter "document" einer oder mehreren passenden Collection unt
|
|
|
278
292
|
});
|
|
279
293
|
return result.json.collectionIds;
|
|
280
294
|
}
|
|
281
|
-
async findSuitableRequestForDocument(
|
|
295
|
+
async findSuitableRequestForDocument(document, collectionIds) {
|
|
282
296
|
const session = this.#documentPropertyRepository.session;
|
|
283
|
-
const document = await this.#documentRepository.load(documentId);
|
|
284
297
|
assertNotNull(document.typeId, 'Document has no type');
|
|
285
|
-
const
|
|
298
|
+
const documentTags = await this.#documentTagService.loadDocumentTags(document.tenantId, document.id);
|
|
299
|
+
const documentProperties = await this.#documentPropertyService.loadDocumentPropertyValues(document.tenantId, document.id);
|
|
286
300
|
const openRequestsWithoutDocument = await session
|
|
287
301
|
.select({
|
|
288
302
|
id: documentRequest.id,
|
|
@@ -295,10 +309,11 @@ Ordne das Dokument unter "document" einer oder mehreren passenden Collection unt
|
|
|
295
309
|
.innerJoin(documentRequestCollectionAssignment, eq(documentRequestCollectionAssignment.requestId, documentRequest.id))
|
|
296
310
|
.innerJoin(documentType, eq(documentType.id, documentRequest.typeId))
|
|
297
311
|
.innerJoin(documentCategory, eq(documentCategory.id, documentType.categoryId))
|
|
298
|
-
.where(and(inArray(documentRequestCollectionAssignment.collectionId, collectionIds), eq(documentRequest.typeId, document.typeId), eq(documentRequest.state, DocumentRequestState.Open), drizzleIsNull(documentRequest.documentId)))
|
|
312
|
+
.where(and(eq(documentRequest.tenantId, document.tenantId), inArray(documentRequestCollectionAssignment.collectionId, collectionIds), eq(documentRequest.typeId, document.typeId), eq(documentRequest.state, DocumentRequestState.Open), drizzleIsNull(documentRequest.documentId)))
|
|
299
313
|
.groupBy(documentRequest.id, documentCategory.label, documentType.label, documentRequest.comment);
|
|
314
|
+
const documentTagLabels = documentTags.map((tag) => tag.label);
|
|
300
315
|
const requestsCollectionIds = distinct(openRequestsWithoutDocument.flatMap((request) => request.collectionIds));
|
|
301
|
-
const collectionNamesMap = await this.#
|
|
316
|
+
const collectionNamesMap = await this.#documentCollectionService.resolveMetadataMap(document.tenantId, requestsCollectionIds);
|
|
302
317
|
const requests = openRequestsWithoutDocument.map((request) => ({
|
|
303
318
|
id: request.id,
|
|
304
319
|
collections: request.collectionIds.map((collectionId) => assertDefinedPass(collectionNamesMap[collectionId]).name),
|
|
@@ -311,7 +326,7 @@ Ordne das Dokument unter "document" einer oder mehreren passenden Collection unt
|
|
|
311
326
|
subtitle: document.subtitle ?? undefined,
|
|
312
327
|
date: isNotNull(document.date) ? numericDateToDateObject(document.date) : undefined,
|
|
313
328
|
summary: document.summary ?? undefined,
|
|
314
|
-
tags: (
|
|
329
|
+
tags: (documentTagLabels.length > 0) ? documentTagLabels : undefined,
|
|
315
330
|
properties: fromEntries(propertyEntries),
|
|
316
331
|
},
|
|
317
332
|
requests,
|
|
@@ -352,3 +367,11 @@ function getDescriptiveTypeLabels(categories, prefix = 'Category: ') {
|
|
|
352
367
|
...getDescriptiveTypeLabels(category.children, `${prefix}${category.label} -> `),
|
|
353
368
|
]);
|
|
354
369
|
}
|
|
370
|
+
function tryAiOutputDateObjectToNumericDate(dateObject) {
|
|
371
|
+
const date = tryDateObjectToNumericDate(dateObject);
|
|
372
|
+
if (isNull(date)) {
|
|
373
|
+
// try to interpret the date with swapped month and day
|
|
374
|
+
return tryDateObjectToNumericDate({ ...dateObject, month: dateObject.day, day: dateObject.month });
|
|
375
|
+
}
|
|
376
|
+
return date;
|
|
377
|
+
}
|
|
@@ -1,28 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* User-friendly name of the collection
|
|
5
|
-
* @example <name of person>
|
|
6
|
-
* @example <address of real estate>
|
|
7
|
-
*/
|
|
8
|
-
name: string;
|
|
9
|
-
/**
|
|
10
|
-
* Group of the collection, used to group multiple collections to the same "type"
|
|
11
|
-
* @example 'Applicants'
|
|
12
|
-
* @example 'Real estates'
|
|
13
|
-
*/
|
|
14
|
-
group: string | null;
|
|
15
|
-
};
|
|
1
|
+
import type { DocumentCollectionMetadata } from '../../../document-management/service-models/index.js';
|
|
2
|
+
import type { DocumentCollection } from '../../models/index.js';
|
|
16
3
|
export declare abstract class DocumentManagementAncillaryService {
|
|
17
|
-
#private;
|
|
18
|
-
resolveMetadata<const T extends (DocumentCollection | string)[]>(...collectionsOrIds: T): Promise<{
|
|
19
|
-
[K in keyof T]: DocumentCollectionMetadata;
|
|
20
|
-
}>;
|
|
21
|
-
resolveMetadataMap(...collectionsOrIds: (DocumentCollection | string)[]): Promise<Record<string, DocumentCollectionMetadata>>;
|
|
22
4
|
/**
|
|
23
5
|
* Resolves application-specific metadata for a list of document collections.
|
|
24
6
|
* @param collections An array of DocumentCollection entities.
|
|
25
7
|
* @returns A promise that resolves to an array of DocumentCollectionMetadata, corresponding to the input collections.
|
|
26
8
|
*/
|
|
27
|
-
abstract
|
|
9
|
+
abstract resolveMetadata(collections: DocumentCollection[]): DocumentCollectionMetadata[] | Promise<DocumentCollectionMetadata[]>;
|
|
28
10
|
}
|
|
@@ -1,26 +1,2 @@
|
|
|
1
|
-
import { injectRepository } from '../../../orm/server/index.js';
|
|
2
|
-
import { fromEntries } from '../../../utils/object/index.js';
|
|
3
|
-
import { assertDefinedPass, isString } from '../../../utils/type-guards.js';
|
|
4
|
-
import { DocumentCollection } from '../../models/index.js';
|
|
5
1
|
export class DocumentManagementAncillaryService {
|
|
6
|
-
#documentCollectionRepository = injectRepository(DocumentCollection);
|
|
7
|
-
async resolveMetadata(...collectionsOrIds) {
|
|
8
|
-
if (collectionsOrIds.length == 0) {
|
|
9
|
-
return [];
|
|
10
|
-
}
|
|
11
|
-
const loadIds = collectionsOrIds.filter((collection) => isString(collection));
|
|
12
|
-
if (loadIds.length == 0) {
|
|
13
|
-
return this._resolveMetadata(collectionsOrIds);
|
|
14
|
-
}
|
|
15
|
-
const loadedCollections = await this.#documentCollectionRepository.loadManyByQuery({ id: { $in: loadIds } });
|
|
16
|
-
const collections = collectionsOrIds.map((collectionOrId) => isString(collectionOrId)
|
|
17
|
-
? assertDefinedPass(loadedCollections.find((collection) => collection.id == collectionOrId), `Could not load collection "${collectionOrId}".`)
|
|
18
|
-
: collectionOrId);
|
|
19
|
-
return this._resolveMetadata(collections);
|
|
20
|
-
}
|
|
21
|
-
async resolveMetadataMap(...collectionsOrIds) {
|
|
22
|
-
const names = await this.resolveMetadata(...collectionsOrIds);
|
|
23
|
-
const entries = collectionsOrIds.map((collectionOrId, index) => [isString(collectionOrId) ? collectionOrId : collectionOrId.id, names[index]]);
|
|
24
|
-
return fromEntries(entries);
|
|
25
|
-
}
|
|
26
2
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { afterResolve } from '../../../injector/interfaces.js';
|
|
2
|
+
import { MessageBus } from '../../../message-bus/message-bus.js';
|
|
3
|
+
import { Database, type PgTransaction, type Transaction } from '../../../orm/server/index.js';
|
|
4
|
+
import type { OneOrMany } from '../../../types.js';
|
|
5
|
+
export declare class DocumentManagementObservationService {
|
|
6
|
+
#private;
|
|
7
|
+
readonly collectionsChangedMessageBus: MessageBus<string[]>;
|
|
8
|
+
[afterResolve](): void;
|
|
9
|
+
collectionChange(ids: OneOrMany<string>, transactionOrSession?: Transaction | Database | PgTransaction): void;
|
|
10
|
+
documentChange(ids: OneOrMany<string>, transactionOrSession?: Transaction | Database | PgTransaction): void;
|
|
11
|
+
workflowChange(ids: OneOrMany<string>, transactionOrSession?: Transaction | Database | PgTransaction): void;
|
|
12
|
+
requestChange(ids: OneOrMany<string>, transactionOrSession?: Transaction | Database | PgTransaction): void;
|
|
13
|
+
private notifyLoop;
|
|
14
|
+
private notify;
|
|
15
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
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
|
+
var _a;
|
|
8
|
+
var DocumentManagementObservationService_1;
|
|
9
|
+
import { eq, inArray } from 'drizzle-orm';
|
|
10
|
+
import { union } from 'drizzle-orm/pg-core';
|
|
11
|
+
import { CancellationSignal } from '../../../cancellation/token.js';
|
|
12
|
+
import { inject } from '../../../injector/inject.js';
|
|
13
|
+
import { afterResolve } from '../../../injector/interfaces.js';
|
|
14
|
+
import { Logger } from '../../../logger/logger.js';
|
|
15
|
+
import { MessageBus } from '../../../message-bus/message-bus.js';
|
|
16
|
+
import { Database, tryGetTstdlTransaction } from '../../../orm/server/index.js';
|
|
17
|
+
import { toArray } from '../../../utils/array/index.js';
|
|
18
|
+
import { cancelableTimeout } from '../../../utils/timing.js';
|
|
19
|
+
import { isDefined } from '../../../utils/type-guards.js';
|
|
20
|
+
import { documentAssignmentScope, documentAssignmentTask, documentCollectionAssignment, documentRequestCollectionAssignment, documentWorkflow } from '../schemas.js';
|
|
21
|
+
import { DocumentManagementSingleton } from './singleton.js';
|
|
22
|
+
let DocumentManagementObservationService = DocumentManagementObservationService_1 = class DocumentManagementObservationService {
|
|
23
|
+
#database = inject(Database);
|
|
24
|
+
#cancellationSignal = inject(CancellationSignal);
|
|
25
|
+
#logger = inject(Logger, DocumentManagementObservationService_1.name);
|
|
26
|
+
#collectionIds = new Set();
|
|
27
|
+
#documentIds = new Set();
|
|
28
|
+
#workflowIds = new Set();
|
|
29
|
+
#requestIds = new Set();
|
|
30
|
+
collectionsChangedMessageBus = inject((MessageBus), 'DocumentManagementObservation:collectionsChanged');
|
|
31
|
+
[afterResolve]() {
|
|
32
|
+
this.notifyLoop();
|
|
33
|
+
}
|
|
34
|
+
collectionChange(ids, transactionOrSession) {
|
|
35
|
+
const transaction = tryGetTstdlTransaction(transactionOrSession);
|
|
36
|
+
if (isDefined(transaction)) {
|
|
37
|
+
transaction.afterCommit$.subscribe(() => this.collectionChange(ids));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
for (const id of toArray(ids)) {
|
|
41
|
+
this.#collectionIds.add(id);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
documentChange(ids, transactionOrSession) {
|
|
46
|
+
const transaction = tryGetTstdlTransaction(transactionOrSession);
|
|
47
|
+
if (isDefined(transaction)) {
|
|
48
|
+
transaction.afterCommit$.subscribe(() => this.documentChange(ids));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
for (const id of toArray(ids)) {
|
|
52
|
+
this.#documentIds.add(id);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
workflowChange(ids, transactionOrSession) {
|
|
57
|
+
const transaction = tryGetTstdlTransaction(transactionOrSession);
|
|
58
|
+
if (isDefined(transaction)) {
|
|
59
|
+
transaction.afterCommit$.subscribe(() => this.workflowChange(ids));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
for (const id of toArray(ids)) {
|
|
63
|
+
this.#workflowIds.add(id);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
requestChange(ids, transactionOrSession) {
|
|
68
|
+
const transaction = tryGetTstdlTransaction(transactionOrSession);
|
|
69
|
+
if (isDefined(transaction)) {
|
|
70
|
+
transaction.afterCommit$.subscribe(() => this.requestChange(ids));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
for (const id of toArray(ids)) {
|
|
74
|
+
this.#requestIds.add(id);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
notifyLoop() {
|
|
79
|
+
void (async () => {
|
|
80
|
+
while (this.#cancellationSignal.isUnset) {
|
|
81
|
+
try {
|
|
82
|
+
if ((this.#collectionIds.size + this.#documentIds.size + this.#workflowIds.size + this.#requestIds.size) > 0) {
|
|
83
|
+
const timeoutResult = await cancelableTimeout(50, this.#cancellationSignal);
|
|
84
|
+
if (timeoutResult == 'canceled') {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
await this.notify();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
this.#logger.error(error);
|
|
92
|
+
await cancelableTimeout(2500, this.#cancellationSignal);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await cancelableTimeout(100, this.#cancellationSignal);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
})();
|
|
99
|
+
}
|
|
100
|
+
async notify() {
|
|
101
|
+
const collectionIds = Array.from(this.#collectionIds);
|
|
102
|
+
const documentIds = Array.from(this.#documentIds);
|
|
103
|
+
const workflowIds = Array.from(this.#workflowIds);
|
|
104
|
+
const requestIds = Array.from(this.#requestIds);
|
|
105
|
+
this.#collectionIds.clear();
|
|
106
|
+
this.#documentIds.clear();
|
|
107
|
+
this.#workflowIds.clear();
|
|
108
|
+
this.#requestIds.clear();
|
|
109
|
+
try {
|
|
110
|
+
const documentCollectionIds = this.#database
|
|
111
|
+
.selectDistinct({ collectionId: documentCollectionAssignment.collectionId })
|
|
112
|
+
.from(documentCollectionAssignment)
|
|
113
|
+
.where(inArray(documentCollectionAssignment.documentId, documentIds));
|
|
114
|
+
const documentAssignmentTaskCollectionIds = this.#database
|
|
115
|
+
.selectDistinct({ collectionId: documentAssignmentScope.collectionId })
|
|
116
|
+
.from(documentAssignmentTask)
|
|
117
|
+
.innerJoin(documentAssignmentScope, eq(documentAssignmentScope.taskId, documentAssignmentTask.id))
|
|
118
|
+
.where(inArray(documentAssignmentTask.documentId, documentIds));
|
|
119
|
+
const workflowDocumentCollectionIds = this.#database
|
|
120
|
+
.selectDistinct({ collectionId: documentCollectionAssignment.collectionId })
|
|
121
|
+
.from(documentWorkflow)
|
|
122
|
+
.innerJoin(documentCollectionAssignment, eq(documentCollectionAssignment.documentId, documentWorkflow.documentId))
|
|
123
|
+
.where(inArray(documentWorkflow.id, workflowIds));
|
|
124
|
+
const workflowDocumentAssignmentTaskCollectionIds = this.#database
|
|
125
|
+
.selectDistinct({ collectionId: documentAssignmentScope.collectionId })
|
|
126
|
+
.from(documentWorkflow)
|
|
127
|
+
.innerJoin(documentAssignmentTask, eq(documentAssignmentTask.documentId, documentWorkflow.documentId))
|
|
128
|
+
.innerJoin(documentAssignmentScope, eq(documentAssignmentScope.taskId, documentAssignmentTask.id))
|
|
129
|
+
.where(inArray(documentWorkflow.id, workflowIds));
|
|
130
|
+
const requestCollectionIds = this.#database
|
|
131
|
+
.selectDistinct({ collectionId: documentRequestCollectionAssignment.collectionId })
|
|
132
|
+
.from(documentRequestCollectionAssignment)
|
|
133
|
+
.where(inArray(documentRequestCollectionAssignment.requestId, requestIds));
|
|
134
|
+
const result = await union(documentCollectionIds, documentAssignmentTaskCollectionIds, workflowDocumentCollectionIds, workflowDocumentAssignmentTaskCollectionIds, requestCollectionIds);
|
|
135
|
+
const allCollectionIds = result.map((row) => row.collectionId);
|
|
136
|
+
if (allCollectionIds.length > 0) {
|
|
137
|
+
await this.collectionsChangedMessageBus.publish(allCollectionIds);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
for (const collectionId of collectionIds) {
|
|
142
|
+
this.#collectionIds.add(collectionId);
|
|
143
|
+
}
|
|
144
|
+
for (const documentId of documentIds) {
|
|
145
|
+
this.#documentIds.add(documentId);
|
|
146
|
+
}
|
|
147
|
+
for (const workflowId of workflowIds) {
|
|
148
|
+
this.#workflowIds.add(workflowId);
|
|
149
|
+
}
|
|
150
|
+
for (const requestId of requestIds) {
|
|
151
|
+
this.#requestIds.add(requestId);
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
DocumentManagementObservationService = DocumentManagementObservationService_1 = __decorate([
|
|
158
|
+
DocumentManagementSingleton()
|
|
159
|
+
], DocumentManagementObservationService);
|
|
160
|
+
export { DocumentManagementObservationService };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CancellationSignal } from '../../../cancellation/token.js';
|
|
1
2
|
import { Transactional } from '../../../orm/server/index.js';
|
|
2
3
|
import type { Record } from '../../../types.js';
|
|
3
4
|
import { DocumentCategory, DocumentType, type DocumentProperty, type DocumentPropertyDataType } from '../../models/index.js';
|
|
@@ -9,11 +10,11 @@ export declare class DocumentManagementService extends Transactional {
|
|
|
9
10
|
* This method is used to determine which collections a document is associated with, either directly or through requests and assignments.
|
|
10
11
|
* @param documentId The ID of the document to retrieve collection IDs for.
|
|
11
12
|
*/
|
|
12
|
-
getRelevantDocumentCollectionIds(documentId: string): Promise<string[]>;
|
|
13
|
-
loadDataStream(collectionIds: string[]):
|
|
14
|
-
loadData(collectionIds: string[]): Promise<DocumentManagementData>;
|
|
15
|
-
loadDocumentRequestsTemplateData(): Promise<DocumentRequestsTemplateData>;
|
|
16
|
-
initializeCategoriesAndTypes<CategoryKey extends string, TypeKey extends string, DocumentPropertyKey extends string>(categoryLabels: Record<CategoryKey, string>, categoryParents: Record<CategoryKey, CategoryKey | null>, typeLabels: Record<TypeKey, string>, typeCategories: Record<TypeKey, CategoryKey>, propertyKeys: Record<DocumentPropertyKey, [DocumentPropertyDataType, string]>, typeProperties: Record<TypeKey, DocumentPropertyKey[]>): Promise<{
|
|
13
|
+
getRelevantDocumentCollectionIds(tenantId: string, documentId: string): Promise<string[]>;
|
|
14
|
+
loadDataStream(tenantId: string, collectionIds: string[], cancellationSignal: CancellationSignal): AsyncIterableIterator<DocumentManagementData>;
|
|
15
|
+
loadData(tenantId: string, collectionIds: string[]): Promise<DocumentManagementData>;
|
|
16
|
+
loadDocumentRequestsTemplateData(tenantId: string | null): Promise<DocumentRequestsTemplateData>;
|
|
17
|
+
initializeCategoriesAndTypes<CategoryKey extends string, TypeKey extends string, DocumentPropertyKey extends string>(tenantId: string | null, categoryLabels: Record<CategoryKey, string>, categoryParents: Record<CategoryKey, CategoryKey | null>, typeLabels: Record<TypeKey, string>, typeCategories: Record<TypeKey, CategoryKey>, propertyKeys: Record<DocumentPropertyKey, [DocumentPropertyDataType, string]>, typeProperties: Record<TypeKey, DocumentPropertyKey[]>): Promise<{
|
|
17
18
|
categories: Record<CategoryKey, DocumentCategory>;
|
|
18
19
|
types: Record<TypeKey, DocumentType>;
|
|
19
20
|
properties: Record<DocumentPropertyKey, DocumentProperty>;
|