@tstdl/base 0.92.142 → 0.92.144

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.
Files changed (223) hide show
  1. package/ai/ai-file.service.js +1 -1
  2. package/ai/ai.service.js +3 -3
  3. package/ai/types.d.ts +1 -1
  4. package/api/client/client.d.ts +1 -1
  5. package/api/client/client.js +10 -4
  6. package/api/server/middlewares/content-type.middleware.js +8 -7
  7. package/api/types.js +1 -1
  8. package/authentication/client/authentication.service.js +3 -3
  9. package/authentication/server/authentication-ancillary.service.d.ts +11 -1
  10. package/authentication/server/authentication-ancillary.service.js +1 -1
  11. package/authentication/server/authentication-secret-requirements.validator.js +1 -1
  12. package/authentication/server/authentication.api-controller.js +22 -10
  13. package/authentication/server/authentication.service.d.ts +11 -5
  14. package/authentication/server/authentication.service.js +97 -49
  15. package/authentication/server/drizzle.config.js +2 -2
  16. package/authentication/server/module.js +1 -1
  17. package/cancellation/token.d.ts +2 -2
  18. package/cancellation/token.js +4 -4
  19. package/cookie/cookie.js +2 -2
  20. package/document-management/api/document-management.api.d.ts +122 -24
  21. package/document-management/api/document-management.api.js +17 -0
  22. package/document-management/{server/services → authorization}/document-management-authorization.service.d.ts +7 -7
  23. package/document-management/authorization/document-management-authorization.service.js +2 -0
  24. package/document-management/authorization/index.d.ts +2 -0
  25. package/document-management/authorization/index.js +2 -0
  26. package/document-management/authorization/policies.d.ts +38 -0
  27. package/document-management/authorization/policies.js +2 -0
  28. package/document-management/index.d.ts +1 -0
  29. package/document-management/index.js +1 -0
  30. package/document-management/models/document-assignment-scope.model.d.ts +1 -0
  31. package/document-management/models/document-assignment-scope.model.js +10 -3
  32. package/document-management/models/document-assignment-task.model.d.ts +1 -0
  33. package/document-management/models/document-assignment-task.model.js +8 -2
  34. package/document-management/models/document-category.model.d.ts +1 -0
  35. package/document-management/models/document-category.model.js +7 -1
  36. package/document-management/models/document-collection-assignment.model.d.ts +1 -0
  37. package/document-management/models/document-collection-assignment.model.js +12 -4
  38. package/document-management/models/document-collection.model.d.ts +2 -0
  39. package/document-management/models/document-collection.model.js +8 -2
  40. package/document-management/models/document-management-table.d.ts +3 -1
  41. package/document-management/models/document-management-table.js +2 -2
  42. package/document-management/models/document-property-value.model.d.ts +1 -0
  43. package/document-management/models/document-property-value.model.js +9 -3
  44. package/document-management/models/document-property.model.d.ts +1 -0
  45. package/document-management/models/document-property.model.js +8 -2
  46. package/document-management/models/document-request-collection-assignment.model.d.ts +1 -0
  47. package/document-management/models/document-request-collection-assignment.model.js +12 -4
  48. package/document-management/models/document-request-template.d.ts +1 -0
  49. package/document-management/models/document-request-template.js +6 -1
  50. package/document-management/models/document-request.model.d.ts +1 -0
  51. package/document-management/models/document-request.model.js +10 -1
  52. package/document-management/models/document-requests-template.d.ts +1 -0
  53. package/document-management/models/document-requests-template.js +7 -3
  54. package/document-management/models/document-tag-assignment.model.d.ts +8 -0
  55. package/document-management/models/document-tag-assignment.model.js +40 -0
  56. package/document-management/models/document-tag.model.d.ts +6 -0
  57. package/document-management/models/{document-request-submission.model.js → document-tag.model.js} +14 -18
  58. package/document-management/models/document-type-property.model.d.ts +1 -0
  59. package/document-management/models/document-type-property.model.js +7 -2
  60. package/document-management/models/document-type-validation.model.d.ts +1 -0
  61. package/document-management/models/document-type-validation.model.js +8 -2
  62. package/document-management/models/document-type.model.d.ts +1 -0
  63. package/document-management/models/document-type.model.js +7 -2
  64. package/document-management/models/document-validation-definition.model.d.ts +1 -0
  65. package/document-management/models/document-validation-definition.model.js +7 -2
  66. package/document-management/models/document-validation-execution-related-document.model.d.ts +1 -0
  67. package/document-management/models/document-validation-execution-related-document.model.js +10 -3
  68. package/document-management/models/document-validation-execution.model.d.ts +1 -0
  69. package/document-management/models/document-validation-execution.model.js +9 -3
  70. package/document-management/models/document-workflow.model.d.ts +4 -1
  71. package/document-management/models/document-workflow.model.js +16 -4
  72. package/document-management/models/document.model.d.ts +2 -2
  73. package/document-management/models/document.model.js +9 -8
  74. package/document-management/models/index.d.ts +2 -1
  75. package/document-management/models/index.js +2 -1
  76. package/document-management/server/api/document-management.api.d.ts +4 -1
  77. package/document-management/server/api/document-management.api.js +113 -22
  78. package/document-management/server/configure.d.ts +2 -2
  79. package/document-management/server/configure.js +7 -7
  80. package/document-management/server/drizzle/0000_parallel_mantis.sql +359 -0
  81. package/document-management/server/drizzle/meta/0000_snapshot.json +784 -260
  82. package/document-management/server/drizzle/meta/_journal.json +2 -2
  83. package/document-management/server/module.d.ts +2 -2
  84. package/document-management/server/module.js +2 -2
  85. package/document-management/server/schemas.d.ts +6 -5
  86. package/document-management/server/schemas.js +12 -11
  87. package/document-management/server/services/document-category-type.service.d.ts +19 -10
  88. package/document-management/server/services/document-category-type.service.js +34 -27
  89. package/document-management/server/services/document-collection.service.d.ts +13 -6
  90. package/document-management/server/services/document-collection.service.js +36 -12
  91. package/document-management/server/services/document-file.service.d.ts +8 -7
  92. package/document-management/server/services/document-file.service.js +28 -33
  93. package/document-management/server/services/document-management-ai.service.d.ts +5 -4
  94. package/document-management/server/services/document-management-ai.service.js +51 -28
  95. package/document-management/server/services/document-management-ancillary.service.d.ts +3 -21
  96. package/document-management/server/services/document-management-ancillary.service.js +0 -24
  97. package/document-management/server/services/document-management-observation.service.d.ts +15 -0
  98. package/document-management/server/services/document-management-observation.service.js +160 -0
  99. package/document-management/server/services/document-management.service.d.ts +6 -5
  100. package/document-management/server/services/document-management.service.js +112 -86
  101. package/document-management/server/services/document-property.service.d.ts +15 -7
  102. package/document-management/server/services/document-property.service.js +52 -20
  103. package/document-management/server/services/document-request.service.d.ts +13 -24
  104. package/document-management/server/services/document-request.service.js +39 -62
  105. package/document-management/server/services/document-tag.service.d.ts +10 -0
  106. package/document-management/server/services/document-tag.service.js +59 -0
  107. package/document-management/server/services/document-validation.service.d.ts +8 -8
  108. package/document-management/server/services/document-validation.service.js +41 -40
  109. package/document-management/server/services/document-workflow.service.d.ts +6 -5
  110. package/document-management/server/services/document-workflow.service.js +54 -43
  111. package/document-management/server/services/document.service.d.ts +12 -11
  112. package/document-management/server/services/document.service.js +66 -40
  113. package/document-management/server/services/index.d.ts +2 -1
  114. package/document-management/server/services/index.js +2 -1
  115. package/document-management/server/services/singleton.js +2 -2
  116. package/document-management/server/validators/ai-validation-executor.js +4 -4
  117. package/document-management/service-models/document-collection-metadata.service-model.d.ts +14 -0
  118. package/document-management/service-models/document-collection-metadata.service-model.js +1 -0
  119. package/document-management/service-models/document-folders.view-model.d.ts +1 -7
  120. package/document-management/service-models/document-folders.view-model.js +3 -15
  121. package/document-management/service-models/document-management.view-model.d.ts +20 -6
  122. package/document-management/service-models/document-management.view-model.js +62 -8
  123. package/document-management/service-models/document.service-model.d.ts +14 -11
  124. package/document-management/service-models/document.service-model.js +11 -2
  125. package/document-management/service-models/enriched/enriched-document-assignment.view.d.ts +1 -1
  126. package/document-management/service-models/enriched/enriched-document-assignment.view.js +0 -2
  127. package/document-management/service-models/enriched/enriched-document-category.view.d.ts +11 -1
  128. package/document-management/service-models/enriched/enriched-document-category.view.js +44 -1
  129. package/document-management/service-models/enriched/enriched-document-collection.view.d.ts +4 -2
  130. package/document-management/service-models/enriched/enriched-document-collection.view.js +13 -3
  131. package/document-management/service-models/enriched/enriched-document-management-data.view.d.ts +2 -0
  132. package/document-management/service-models/enriched/enriched-document-management-data.view.js +4 -2
  133. package/document-management/service-models/enriched/enriched-document-request.view.d.ts +1 -0
  134. package/document-management/service-models/enriched/enriched-document-request.view.js +2 -0
  135. package/document-management/service-models/enriched/enriched-document-type.view.d.ts +9 -1
  136. package/document-management/service-models/enriched/enriched-document-type.view.js +28 -1
  137. package/document-management/service-models/enriched/enriched-document.view.d.ts +7 -6
  138. package/document-management/service-models/enriched/enriched-document.view.js +29 -6
  139. package/document-management/service-models/{normalized-requests-template-data.model.d.ts → enriched/enriched-requests-template-data.model.d.ts} +6 -6
  140. package/document-management/service-models/{normalized-requests-template-data.model.js → enriched/enriched-requests-template-data.model.js} +1 -1
  141. package/document-management/service-models/enriched/index.d.ts +1 -0
  142. package/document-management/service-models/enriched/index.js +1 -0
  143. package/document-management/service-models/index.d.ts +2 -2
  144. package/document-management/service-models/index.js +2 -2
  145. package/examples/document-management/categories-and-types.d.ts +33 -31
  146. package/examples/document-management/categories-and-types.js +33 -0
  147. package/examples/document-management/main.d.ts +5 -4
  148. package/examples/document-management/main.js +13 -7
  149. package/function/log.js +2 -2
  150. package/http/server/node/module.d.ts +4 -1
  151. package/http/server/node/module.js +10 -1
  152. package/http/server/node/node-http-server.d.ts +3 -6
  153. package/http/server/node/node-http-server.js +68 -67
  154. package/injector/inject.js +6 -6
  155. package/injector/injector.js +3 -3
  156. package/jsx/is-component-class.js +1 -1
  157. package/key-value-store/key-value.store.d.ts +38 -7
  158. package/key-value-store/key-value.store.js +2 -1
  159. package/key-value-store/mongo/mongo-key-value.store.d.ts +1 -0
  160. package/key-value-store/mongo/mongo-key-value.store.js +14 -5
  161. package/key-value-store/postgres/drizzle/0000_shocking_slipstream.sql +12 -0
  162. package/key-value-store/postgres/drizzle/meta/0000_snapshot.json +97 -0
  163. package/key-value-store/postgres/drizzle/meta/_journal.json +13 -0
  164. package/key-value-store/postgres/drizzle.config.d.ts +2 -0
  165. package/key-value-store/postgres/drizzle.config.js +11 -0
  166. package/key-value-store/postgres/index.d.ts +2 -0
  167. package/key-value-store/postgres/index.js +2 -0
  168. package/key-value-store/postgres/key-value-store.service.d.ts +17 -0
  169. package/key-value-store/postgres/key-value-store.service.js +65 -0
  170. package/key-value-store/postgres/models/index.d.ts +2 -0
  171. package/key-value-store/postgres/models/index.js +2 -0
  172. package/key-value-store/postgres/models/key-value.model.d.ts +7 -0
  173. package/key-value-store/postgres/models/key-value.model.js +35 -0
  174. package/key-value-store/postgres/models/schemas.d.ts +3 -0
  175. package/key-value-store/postgres/models/schemas.js +4 -0
  176. package/key-value-store/postgres/module.d.ts +6 -0
  177. package/key-value-store/postgres/module.js +23 -0
  178. package/lock/web/web-lock.d.ts +0 -1
  179. package/lock/web/web-lock.js +6 -13
  180. package/orm/data-types/timestamp.js +1 -1
  181. package/orm/decorators.d.ts +37 -29
  182. package/orm/decorators.js +44 -24
  183. package/orm/entity.d.ts +1 -0
  184. package/orm/query.d.ts +10 -2
  185. package/orm/repository.types.d.ts +2 -1
  186. package/orm/schemas/json.d.ts +12 -6
  187. package/orm/schemas/json.js +12 -5
  188. package/orm/server/database.js +5 -2
  189. package/orm/server/drizzle/schema-converter.js +40 -11
  190. package/orm/server/query-converter.d.ts +2 -1
  191. package/orm/server/query-converter.js +57 -34
  192. package/orm/server/repository.d.ts +26 -43
  193. package/orm/server/repository.js +106 -39
  194. package/orm/server/transaction.d.ts +2 -1
  195. package/orm/server/transaction.js +3 -0
  196. package/orm/server/transactional.d.ts +5 -1
  197. package/orm/server/transactional.js +34 -4
  198. package/package.json +14 -11
  199. package/process/spawn.js +0 -1
  200. package/promise/deferred-promise.d.ts +4 -3
  201. package/promise/deferred-promise.js +13 -5
  202. package/queue/postgres/queue.js +8 -8
  203. package/reflection/utils.js +3 -3
  204. package/schema/decorators/class.js +0 -1
  205. package/schema/decorators/schema.js +1 -1
  206. package/schema/schemas/boolean.d.ts +1 -1
  207. package/schema/schemas/boolean.js +2 -2
  208. package/schema/schemas/number.js +3 -3
  209. package/schema/schemas/object.js +5 -6
  210. package/sse/server-sent-events-source.js +4 -1
  211. package/utils/compression.js +9 -9
  212. package/utils/date-time.d.ts +1 -0
  213. package/utils/date-time.js +18 -4
  214. package/utils/equals.d.ts +7 -0
  215. package/utils/equals.js +17 -2
  216. package/utils/function/memoize.js +10 -2
  217. package/utils/jwt.js +3 -3
  218. package/utils/object/property-name.d.ts +2 -2
  219. package/utils/timing.d.ts +2 -2
  220. package/utils/timing.js +12 -12
  221. package/document-management/models/document-request-submission.model.d.ts +0 -7
  222. package/document-management/server/drizzle/0000_moaning_luckman.sql +0 -305
  223. package/document-management/server/services/document-management-authorization.service.js +0 -28
@@ -4,109 +4,125 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
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
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { eq } from 'drizzle-orm';
7
+ var _a;
8
+ var DocumentManagementService_1;
9
+ import { and, eq } from 'drizzle-orm';
8
10
  import { union } from 'drizzle-orm/pg-core';
9
11
  import { Enumerable } from '../../../enumerable/index.js';
10
12
  import { inject } from '../../../injector/index.js';
11
- import { Transactional, injectRepository } from '../../../orm/server/index.js';
13
+ import { Logger } from '../../../logger/logger.js';
14
+ import { Transactional, injectRepository, injectTransactional } from '../../../orm/server/index.js';
15
+ import { DeferredPromise } from '../../../promise/deferred-promise.js';
12
16
  import { distinct } from '../../../utils/array/index.js';
13
- import { compareByValueSelectionToOrder } from '../../../utils/comparison.js';
17
+ import { compareByValueSelection } from '../../../utils/comparison.js';
14
18
  import { groupToMap, groupToSingleMap } from '../../../utils/iterable-helpers/index.js';
15
19
  import { fromEntries, objectEntries } from '../../../utils/object/index.js';
16
- import { timeout } from '../../../utils/timing.js';
17
20
  import { assertDefinedPass, isDefined, isNotNull, isNotNullOrUndefined, isNull, isUndefined } from '../../../utils/type-guards.js';
18
- import { DocumentApproval, DocumentAssignmentScope, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestTemplate, DocumentRequestsTemplate, DocumentType, DocumentTypeProperty, DocumentValidationExecution, DocumentWorkflowStep } from '../../models/index.js';
21
+ import { filter, merge } from 'rxjs';
22
+ import { DocumentAssignmentScope, DocumentAssignmentTask, DocumentCategory, DocumentCollectionAssignment, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestTemplate, DocumentRequestsTemplate, DocumentType, DocumentTypeProperty, DocumentValidationExecution, DocumentWorkflowStep } from '../../models/index.js';
19
23
  import { documentAssignmentScope, documentAssignmentTask, documentCollectionAssignment, documentRequest, documentRequestCollectionAssignment } from '../schemas.js';
20
24
  import { DocumentCategoryTypeService } from './document-category-type.service.js';
21
- import { DocumentManagementAncillaryService } from './document-management-ancillary.service.js';
25
+ import { DocumentCollectionService } from './document-collection.service.js';
26
+ import { DocumentManagementObservationService } from './document-management-observation.service.js';
22
27
  import { DocumentPropertyService } from './document-property.service.js';
28
+ import { DocumentTagService } from './document-tag.service.js';
23
29
  import { DocumentWorkflowService } from './document-workflow.service.js';
24
30
  import { DocumentService } from './document.service.js';
25
31
  import { enumTypeKey } from './enum-type-key.js';
26
32
  import { DocumentManagementSingleton } from './singleton.js';
27
- let DocumentManagementService = class DocumentManagementService extends Transactional {
28
- #ancillaryService = inject(DocumentManagementAncillaryService);
29
- #documentCategoryTypeService = inject(DocumentCategoryTypeService);
30
- #documentCollectionRepository = injectRepository(DocumentCollection);
31
- #documentCategoryRepository = injectRepository(DocumentCategory);
33
+ let DocumentManagementService = DocumentManagementService_1 = class DocumentManagementService extends Transactional {
34
+ #documentCollectionService = injectTransactional(DocumentCollectionService);
35
+ #documentCategoryTypeService = injectTransactional(DocumentCategoryTypeService);
36
+ #documentService = injectTransactional(DocumentService);
37
+ #documentPropertyService = injectTransactional(DocumentPropertyService);
38
+ #documentWorkflowService = injectTransactional(DocumentWorkflowService);
39
+ #documentTagService = injectTransactional(DocumentTagService);
32
40
  #documentCollectionAssignmentRepository = injectRepository(DocumentCollectionAssignment);
33
- #documentService = inject(DocumentService);
34
- #documentPropertyService = inject(DocumentPropertyService);
35
41
  #documentRequestCollectionAssignmentRepository = injectRepository(DocumentRequestCollectionAssignment);
36
42
  #documentAssignmentTaskRepository = injectRepository(DocumentAssignmentTask);
37
43
  #documentAssignmentScopeRepository = injectRepository(DocumentAssignmentScope);
38
44
  #documentRequestRepository = injectRepository(DocumentRequest);
39
45
  #documentRequestsTemplateRepository = injectRepository(DocumentRequestsTemplate);
40
46
  #documentRequestTemplateRepository = injectRepository(DocumentRequestTemplate);
41
- #documentTypeRepository = injectRepository(DocumentType);
42
47
  #documentTypePropertyRepository = injectRepository(DocumentTypeProperty);
43
- #documentWorkflowService = inject(DocumentWorkflowService);
44
48
  #documentValidationExecutionRepository = injectRepository(DocumentValidationExecution);
49
+ #observationService = inject(DocumentManagementObservationService);
50
+ #logger = inject(Logger, DocumentManagementService_1.name);
45
51
  /**
46
52
  * Get all relevant document collection IDs for a given document. This includes direct assignments, request assignments, and assignment scopes.
47
53
  * This method is used to determine which collections a document is associated with, either directly or through requests and assignments.
48
54
  * @param documentId The ID of the document to retrieve collection IDs for.
49
55
  */
50
- async getRelevantDocumentCollectionIds(documentId) {
51
- const directAssignments = this.#documentCollectionRepository.session.$with('directAssignments').as((qb) => qb
56
+ async getRelevantDocumentCollectionIds(tenantId, documentId) {
57
+ const directAssignments = this.#documentCollectionService.session.$with('directAssignments').as((qb) => qb
52
58
  .select({ collectionId: documentCollectionAssignment.id })
53
59
  .from(documentCollectionAssignment)
54
- .where(eq(documentCollectionAssignment.documentId, documentId)));
60
+ .where(and(eq(documentCollectionAssignment.tenantId, tenantId), eq(documentCollectionAssignment.documentId, documentId))));
55
61
  const requestAssignments = this.#documentRequestCollectionAssignmentRepository.session.$with('requestAssignments').as((qb) => qb
56
62
  .select({ collectionId: documentRequestCollectionAssignment.collectionId })
57
63
  .from(documentRequest)
58
64
  .innerJoin(documentRequestCollectionAssignment, eq(documentRequestCollectionAssignment.requestId, documentRequest.id))
59
- .where(eq(documentRequest.documentId, documentId)));
65
+ .where(and(eq(documentRequest.tenantId, tenantId), eq(documentRequest.documentId, documentId))));
60
66
  const assignmentScopes = this.#documentAssignmentScopeRepository.session.$with('assignmentScopes').as((qb) => qb
61
67
  .select({ collectionId: documentAssignmentScope.collectionId })
62
68
  .from(documentAssignmentTask)
63
69
  .innerJoin(documentAssignmentScope, eq(documentAssignmentScope.taskId, documentAssignmentTask.id))
64
- .where(eq(documentAssignmentTask.documentId, documentId)));
65
- const result = await union(this.#documentService.session.with(directAssignments).selectDistinct().from(directAssignments), this.#documentService.session.with(requestAssignments).selectDistinct().from(requestAssignments), this.#documentService.session.with(assignmentScopes).selectDistinct().from(assignmentScopes));
70
+ .where(and(eq(documentAssignmentTask.tenantId, tenantId), eq(documentAssignmentTask.documentId, documentId))));
71
+ const result = await union(this.#documentService.session.with(directAssignments).select().from(directAssignments), this.#documentService.session.with(requestAssignments).select().from(requestAssignments), this.#documentService.session.with(assignmentScopes).select().from(assignmentScopes));
66
72
  return result.map((row) => row.collectionId);
67
73
  }
68
- loadDataStream(collectionIds) {
69
- return new ReadableStream({
70
- pull: async (controller) => {
71
- const data = await this.loadData(collectionIds);
72
- controller.enqueue(data);
73
- await timeout(1000);
74
- },
75
- });
74
+ async *loadDataStream(tenantId, collectionIds, cancellationSignal) {
75
+ const continuePromise = new DeferredPromise();
76
+ const newData$ = this.#observationService.collectionsChangedMessageBus.allMessages$.pipe(filter((changedCollectionIds) => collectionIds.some((id) => changedCollectionIds.includes(id))));
77
+ const subscription = merge(newData$, cancellationSignal).subscribe(() => continuePromise.resolveIfPending());
78
+ try {
79
+ while (cancellationSignal.isUnset) {
80
+ yield await this.loadData(tenantId, collectionIds);
81
+ await continuePromise;
82
+ continuePromise.reset();
83
+ }
84
+ }
85
+ finally {
86
+ subscription.unsubscribe();
87
+ }
76
88
  }
77
- async loadData(collectionIds) {
89
+ async loadData(tenantId, collectionIds) {
78
90
  return await this.transaction(async (tx) => {
79
- const [collections, collectionsMetadataMap, documentCollectionAssignments, requestAssignments, assignmentScopes, categories, types] = await Promise.all([
80
- this.#documentCollectionRepository.withTransaction(tx).loadMany(collectionIds),
81
- this.#ancillaryService.resolveMetadataMap(...collectionIds),
82
- this.#documentCollectionAssignmentRepository.withTransaction(tx).loadManyByQuery({ collectionId: { $in: collectionIds } }),
83
- this.#documentRequestCollectionAssignmentRepository.withTransaction(tx).loadManyByQuery({ collectionId: { $in: collectionIds } }),
84
- this.#documentAssignmentScopeRepository.withTransaction(tx).loadManyByQuery({ collectionId: { $in: collectionIds } }),
85
- this.#documentCategoryRepository.withTransaction(tx).loadManyByQuery({}, { order: 'label' }),
86
- this.#documentTypeRepository.withTransaction(tx).loadManyByQuery({}, { order: 'label' }),
91
+ const [collections, documentCollectionAssignments, requestAssignments, assignmentScopes, { categories, types }] = await Promise.all([
92
+ this.#documentCollectionService.repository.withTransaction(tx).loadManyByQuery({ tenantId, id: { $in: collectionIds } }),
93
+ this.#documentCollectionAssignmentRepository.withTransaction(tx).loadManyByQuery({ tenantId, collectionId: { $in: collectionIds } }),
94
+ this.#documentRequestCollectionAssignmentRepository.withTransaction(tx).loadManyByQuery({ tenantId, collectionId: { $in: collectionIds } }),
95
+ this.#documentAssignmentScopeRepository.withTransaction(tx).loadManyByQuery({ tenantId, collectionId: { $in: collectionIds } }),
96
+ this.#documentCategoryTypeService.withTransaction(tx).loadCategoriesAndTypes(tenantId),
87
97
  ]);
98
+ const collectionsMetadataMap = await this.#documentCollectionService.withTransaction(tx).resolveMetadataMap(tenantId, collections);
88
99
  const requestIds = requestAssignments.map((requestCollection) => requestCollection.requestId);
89
100
  const taskIds = assignmentScopes.map((scope) => scope.taskId);
90
101
  const [requests, assignmentTasks] = await Promise.all([
91
- this.#documentRequestRepository.withTransaction(tx).loadManyByQuery({ id: { $in: requestIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
92
- this.#documentAssignmentTaskRepository.withTransaction(tx).loadMany(taskIds),
102
+ this.#documentRequestRepository.withTransaction(tx).loadManyByQuery({ tenantId, id: { $in: requestIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
103
+ this.#documentAssignmentTaskRepository.withTransaction(tx).loadManyByQuery({ tenantId, ids: { $in: taskIds } }),
93
104
  ]);
94
105
  const assignmentDocumentIds = documentCollectionAssignments.map((assignment) => assignment.documentId);
95
106
  const requestDocumentIds = requests.map((request) => request.documentId).filter(isNotNull);
96
107
  const assignmentTaskDocumentIds = assignmentTasks.map((task) => task.documentId);
97
108
  const documentIds = distinct([...assignmentDocumentIds, ...requestDocumentIds, ...assignmentTaskDocumentIds]);
98
- const [documents, propertyValues] = await Promise.all([
99
- this.#documentService.withTransaction(tx).repository.loadManyByQuery({ id: { $in: documentIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
100
- this.#documentPropertyService.withTransaction(tx).loadDocumentProperties(documentIds),
109
+ const [documents, propertyViews, propertyValues, workflows] = await Promise.all([
110
+ this.#documentService.repository.withTransaction(tx).loadManyByQuery({ tenantId, id: { $in: documentIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
111
+ this.#documentPropertyService.withTransaction(tx).loadViews(tenantId),
112
+ this.#documentPropertyService.withTransaction(tx).loadDocumentPropertyValues(tenantId, documentIds),
113
+ this.#documentWorkflowService.withTransaction(tx).loadWorkflows(tenantId, documentIds),
101
114
  ]);
102
- const workflowRelevantDocumentIds = documents.map((document) => (document.approval == DocumentApproval.Pending) ? document.id : null).filter(isNotNull);
103
- const currentWorkflows = await this.#documentWorkflowService.loadLatestWorkflows(workflowRelevantDocumentIds);
104
- const documentWorkflowMap = groupToSingleMap(currentWorkflows, (workflow) => workflow.documentId);
115
+ const documentTagAssignments = await this.#documentTagService.tagAssignmentRepository.withTransaction(tx).loadManyByQuery({ tenantId, documentId: { $in: documentIds } });
116
+ const tags = await this.#documentTagService.withTransaction(tx).loadTags(tenantId);
117
+ const documentTagsMap = groupToMap(documentTagAssignments, (assignment) => assignment.documentId);
118
+ const documentWorkflowsMap = groupToMap(workflows, (workflow) => workflow.documentId);
105
119
  const valuesMap = Enumerable.from(propertyValues).groupToMap((value) => value.documentId);
106
- const validationWorkflowIds = currentWorkflows.map((workflow) => (workflow.step == DocumentWorkflowStep.Validation) ? workflow.id : null).filter(isNotNull);
107
- const validations = await this.#documentValidationExecutionRepository.loadManyByQuery({ workflowId: { $in: validationWorkflowIds } });
108
- const workflowValidationMap = groupToMap(validations, (validation) => validation.workflowId);
109
- const collectionViews = collections.toSorted(compareByValueSelectionToOrder(collectionIds, (collection) => collection.id)).map((collection) => {
120
+ const validationWorkflowIds = workflows.map((workflow) => (workflow.step == DocumentWorkflowStep.Validation) ? workflow.id : null).filter(isNotNull);
121
+ const validations = await this.#documentValidationExecutionRepository.withTransaction(tx).loadManyByQuery({ tenantId, workflowId: { $in: validationWorkflowIds } });
122
+ const workflowValidationsMap = groupToMap(validations, (validation) => validation.workflowId);
123
+ const collectionViews = collections
124
+ .toSorted(compareByValueSelection((collection) => collectionIds.indexOf(collection.id)))
125
+ .map((collection) => {
110
126
  const metadata = assertDefinedPass(collectionsMetadataMap[collection.id]);
111
127
  return ({
112
128
  ...collection,
@@ -115,21 +131,22 @@ let DocumentManagementService = class DocumentManagementService extends Transact
115
131
  });
116
132
  });
117
133
  const documentViews = documents.map((document) => {
118
- const currentWorkflow = documentWorkflowMap.get(document.id) ?? null;
119
- const validations = (isNotNull(currentWorkflow) && (currentWorkflow.step == DocumentWorkflowStep.Validation)) ? workflowValidationMap.get(currentWorkflow.id) ?? [] : null;
120
- const assignmentTask = assignmentTasks.find((task) => task.documentId == document.id);
121
- const assignmentTaskScope = isDefined(assignmentTask) ? assignmentScopes.filter((scope) => scope.taskId == assignmentTask.id).map((scope) => scope.collectionId) : [];
134
+ const documentWorkflows = documentWorkflowsMap.get(document.id) ?? [];
135
+ const documentValidations = documentWorkflows.flatMap((workflow) => workflowValidationsMap.get(workflow.id) ?? []);
136
+ const documentAssignmentTask = assignmentTasks.find((task) => task.documentId == document.id);
137
+ const documentAssignmentTaskScope = isDefined(documentAssignmentTask) ? assignmentScopes.filter((scope) => scope.taskId == documentAssignmentTask.id).map((scope) => scope.collectionId) : [];
122
138
  return {
123
139
  ...document,
124
140
  assignment: {
125
141
  collections: documentCollectionAssignments.filter((collectionDocument) => collectionDocument.documentId == document.id),
126
- assignmentTask: isDefined(assignmentTask)
127
- ? { target: assignmentTask.target, scope: assignmentTaskScope }
142
+ assignmentTask: isDefined(documentAssignmentTask)
143
+ ? { target: documentAssignmentTask.target, scope: documentAssignmentTaskScope }
128
144
  : null,
129
145
  },
146
+ tagIds: documentTagsMap.get(document.id)?.map((assignment) => assignment.tagId) ?? [],
130
147
  properties: valuesMap.get(document.id) ?? [],
131
- currentWorkflow,
132
- validations,
148
+ workflows: documentWorkflows,
149
+ validations: documentValidations,
133
150
  };
134
151
  });
135
152
  const requestViews = requests.map((request) => ({
@@ -142,14 +159,16 @@ let DocumentManagementService = class DocumentManagementService extends Transact
142
159
  requests: requestViews,
143
160
  categories,
144
161
  types,
162
+ tags,
163
+ properties: propertyViews,
145
164
  };
146
165
  });
147
166
  }
148
- async loadDocumentRequestsTemplateData() {
167
+ async loadDocumentRequestsTemplateData(tenantId) {
149
168
  return await this.transaction(async (tx) => {
150
169
  const [requestsTemplates, requestTemplates] = await Promise.all([
151
- this.#documentRequestsTemplateRepository.withTransaction(tx).loadManyByQuery({}, { order: 'label' }),
152
- this.#documentRequestTemplateRepository.withTransaction(tx).loadManyByQuery({}),
170
+ this.#documentRequestsTemplateRepository.withTransaction(tx).loadManyByQuery({ tenantId }, { order: 'label' }),
171
+ this.#documentRequestTemplateRepository.withTransaction(tx).loadManyByQuery({ tenantId }),
153
172
  ]);
154
173
  const templates = requestsTemplates.map((requestsTemplate) => ({
155
174
  ...requestsTemplate,
@@ -158,64 +177,71 @@ let DocumentManagementService = class DocumentManagementService extends Transact
158
177
  return { templates };
159
178
  });
160
179
  }
161
- async initializeCategoriesAndTypes(categoryLabels, categoryParents, typeLabels, typeCategories, propertyKeys, typeProperties) {
180
+ async initializeCategoriesAndTypes(tenantId, categoryLabels, categoryParents, typeLabels, typeCategories, propertyKeys, typeProperties) {
162
181
  const categoryEntries = objectEntries(categoryLabels);
163
182
  const typeEntries = objectEntries(typeLabels);
164
183
  const propertyEntries = objectEntries(propertyKeys);
165
184
  const { categoryMap, typeMap, propertyMap } = await this.transaction(async (tx) => {
166
- const { categories: dbCategories, types: dbTypes } = await this.#documentCategoryTypeService.withTransaction(tx).loadCategoriesAndTypes();
167
- const dbProperties = await this.#documentPropertyService.withTransaction(tx).repository.loadAll();
185
+ const { categories: dbCategories, types: dbTypes } = await this.#documentCategoryTypeService.withTransaction(tx).loadCategoriesAndTypes(tenantId);
186
+ const dbProperties = await this.#documentPropertyService.withTransaction(tx).repository.loadManyByQuery({ tenantId });
168
187
  const categories = dbCategories.filter((category) => isNotNullOrUndefined(category.metadata.attributes[enumTypeKey]));
169
188
  const types = dbTypes.filter((type) => isNotNullOrUndefined(type.metadata.attributes[enumTypeKey]));
170
189
  const properties = dbProperties.filter((property) => isNotNullOrUndefined(property.metadata.attributes[enumTypeKey]));
171
190
  const enumKeyCategoryMap = groupToSingleMap(categories, (category) => category.metadata.attributes[enumTypeKey]);
172
191
  const enumKeyTypeMap = groupToSingleMap(types, (type) => type.metadata.attributes[enumTypeKey]);
173
192
  const enumKeyPropertyMap = groupToSingleMap(properties, (property) => property.metadata.attributes[enumTypeKey]);
174
- for (const [key, label] of categoryEntries) {
175
- const category = enumKeyCategoryMap.get(key);
176
- const parentKey = assertDefinedPass(categoryParents[key], `Parent category not defined for ${key}`);
193
+ for (const [enumKey, label] of categoryEntries) {
194
+ const category = enumKeyCategoryMap.get(enumKey);
195
+ const parentKey = assertDefinedPass(categoryParents[enumKey], `Parent category not defined for ${enumKey}`);
177
196
  const parentCategory = isNull(parentKey) ? null : assertDefinedPass(enumKeyCategoryMap.get(parentKey));
178
197
  const parentCategoryId = parentCategory?.id ?? null;
179
198
  if (isUndefined(category)) {
180
- const category = await this.#documentCategoryTypeService.withTransaction(tx).createCategory(label, parentCategoryId, key);
181
- enumKeyCategoryMap.set(key, category);
199
+ const category = await this.#documentCategoryTypeService.withTransaction(tx).createCategory({ tenantId, label, parentId: parentCategoryId, enumKey });
200
+ enumKeyCategoryMap.set(enumKey, category);
201
+ this.#logger.info(`Created category ${category.label}`);
182
202
  }
183
203
  else if ((category.label != label) || (category.parentId != parentCategoryId)) {
184
- const updatedCategory = await this.#documentCategoryTypeService.withTransaction(tx).updateCategory(category.id, { label, parentId: parentCategoryId });
185
- enumKeyCategoryMap.set(key, updatedCategory);
204
+ const updatedCategory = await this.#documentCategoryTypeService.withTransaction(tx).updateCategory(tenantId, category.id, { label, parentId: parentCategoryId });
205
+ enumKeyCategoryMap.set(enumKey, updatedCategory);
206
+ this.#logger.info(`Updated category ${updatedCategory.label}`);
186
207
  }
187
208
  }
188
- for (const [key, label] of typeEntries) {
189
- const type = enumKeyTypeMap.get(key);
190
- const enumCategory = typeCategories[key];
209
+ for (const [enumKey, label] of typeEntries) {
210
+ const type = enumKeyTypeMap.get(enumKey);
211
+ const enumCategory = typeCategories[enumKey];
191
212
  const category = assertDefinedPass(enumKeyCategoryMap.get(enumCategory));
192
213
  if (isUndefined(type)) {
193
- const type = await this.#documentCategoryTypeService.withTransaction(tx).createType(label, category.id, key);
194
- enumKeyTypeMap.set(key, type);
214
+ const type = await this.#documentCategoryTypeService.withTransaction(tx).createType({ tenantId, label, categoryId: category.id, enumKey });
215
+ enumKeyTypeMap.set(enumKey, type);
216
+ this.#logger.info(`Created type ${type.label} in category ${category.label}`);
195
217
  }
196
218
  else if ((type.categoryId != category.id) || (type.label != label)) {
197
- const updatedType = await this.#documentCategoryTypeService.withTransaction(tx).updateType(type.id, { categoryId: category.id, label: label });
198
- enumKeyTypeMap.set(key, updatedType);
219
+ const updatedType = await this.#documentCategoryTypeService.withTransaction(tx).updateType(tenantId, type.id, { categoryId: category.id, label: label });
220
+ enumKeyTypeMap.set(enumKey, updatedType);
221
+ this.#logger.info(`Updated type ${updatedType.label} in category ${category.label}`);
199
222
  }
200
223
  }
201
- for (const [key, [dataType, label]] of propertyEntries) {
202
- const property = enumKeyPropertyMap.get(key);
224
+ for (const [enumKey, [dataType, label]] of propertyEntries) {
225
+ const property = enumKeyPropertyMap.get(enumKey);
203
226
  if (isUndefined(property)) {
204
- const newProperty = await this.#documentPropertyService.withTransaction(tx).createProperty(label, dataType, key);
205
- enumKeyPropertyMap.set(key, newProperty);
227
+ const newProperty = await this.#documentPropertyService.withTransaction(tx).createProperty({ tenantId, label, dataType, enumKey });
228
+ enumKeyPropertyMap.set(enumKey, newProperty);
229
+ this.#logger.info(`Created property ${newProperty.label} of type ${dataType}`);
206
230
  }
207
231
  else if ((property.label != label) || (property.dataType != dataType)) {
208
- const updatedProperty = await this.#documentPropertyService.withTransaction(tx).updateProperty(property.id, { label, dataType });
209
- enumKeyPropertyMap.set(key, updatedProperty);
232
+ const updatedProperty = await this.#documentPropertyService.withTransaction(tx).updateProperty(tenantId, property.id, { label, dataType });
233
+ enumKeyPropertyMap.set(enumKey, updatedProperty);
234
+ this.#logger.info(`Updated property ${updatedProperty.label} of type ${updatedProperty.dataType}`);
210
235
  }
211
236
  }
212
237
  for (const [typeKey, propertyKeys] of objectEntries(typeProperties)) {
213
238
  const type = assertDefinedPass(enumKeyTypeMap.get(typeKey), `Type ${typeKey} not found.`);
214
239
  const newEntities = propertyKeys.map((propertyKey) => ({
240
+ tenantId,
215
241
  typeId: type.id,
216
242
  propertyId: assertDefinedPass(enumKeyPropertyMap.get(propertyKey), 'Could not get property').id,
217
243
  }));
218
- await this.#documentTypePropertyRepository.withTransaction(tx).upsertMany(['typeId', 'propertyId'], newEntities);
244
+ await this.#documentTypePropertyRepository.withTransaction(tx).upsertMany(['tenantId', 'typeId', 'propertyId'], newEntities);
219
245
  }
220
246
  return { categoryMap: enumKeyCategoryMap, typeMap: enumKeyTypeMap, propertyMap: enumKeyPropertyMap };
221
247
  });
@@ -229,7 +255,7 @@ let DocumentManagementService = class DocumentManagementService extends Transact
229
255
  };
230
256
  }
231
257
  };
232
- DocumentManagementService = __decorate([
258
+ DocumentManagementService = DocumentManagementService_1 = __decorate([
233
259
  DocumentManagementSingleton()
234
260
  ], DocumentManagementService);
235
261
  export { DocumentManagementService };
@@ -1,13 +1,15 @@
1
1
  import { Transactional } from '../../../orm/server/index.js';
2
2
  import type { OneOrMany } from '../../../types.js';
3
- import { DocumentProperty, DocumentPropertyDataType } from '../../models/index.js';
4
- import type { DocumentPropertyValueView, SetDocumentPropertyParameters } from '../../service-models/index.js';
3
+ import { DocumentProperty, DocumentPropertyDataType, type Document } from '../../models/index.js';
4
+ import type { DocumentPropertyValueView, DocumentPropertyView, SetDocumentPropertyParameters } from '../../service-models/index.js';
5
5
  export declare class DocumentPropertyService extends Transactional {
6
6
  #private;
7
7
  readonly repository: import("../../../orm/server/repository.js").EntityRepository<DocumentProperty>;
8
8
  readonly documentProperties: import("drizzle-orm/pg-core").WithSubqueryWithSelection<{
9
9
  documentId: import("drizzle-orm").SQL.Aliased<string>;
10
10
  propertyId: import("drizzle-orm").SQL.Aliased<string>;
11
+ documentTenantId: import("drizzle-orm").SQL.Aliased<string>;
12
+ propertyTenantId: import("drizzle-orm").SQL.Aliased<string>;
11
13
  label: import("drizzle-orm/pg-core").PgColumn<{
12
14
  name: "label";
13
15
  tableName: "document_property";
@@ -44,12 +46,18 @@ export declare class DocumentPropertyService extends Transactional {
44
46
  }, {}, {}>;
45
47
  value: import("drizzle-orm").SQL.Aliased<string | number | boolean | null>;
46
48
  }, "documentProperties">;
47
- createProperty(label: string, dataType: DocumentPropertyDataType, enumKey?: string): Promise<DocumentProperty>;
48
- updateProperty(id: string, update: {
49
+ loadViews(tenantId: string | null): Promise<DocumentPropertyView[]>;
50
+ createProperty(data: {
51
+ tenantId: string | null;
52
+ label: string;
53
+ dataType: DocumentPropertyDataType;
54
+ enumKey?: string;
55
+ }): Promise<DocumentProperty>;
56
+ updateProperty(tenantId: string | null, id: string, update: {
49
57
  label?: string;
50
58
  dataType?: DocumentPropertyDataType;
51
59
  }): Promise<DocumentProperty>;
52
- assignPropertyToType(typeId: string, propertyId: string): Promise<void>;
53
- loadDocumentProperties(documentId: OneOrMany<string>, includeNulls?: boolean): Promise<DocumentPropertyValueView[]>;
54
- setPropertyValues(documentId: string, propertyValues: SetDocumentPropertyParameters[]): Promise<void>;
60
+ assignPropertyToType(tenantId: string | null, typeId: string, propertyId: string): Promise<void>;
61
+ loadDocumentPropertyValues(tenantId: string, documentId: OneOrMany<string>, includeNulls?: boolean): Promise<DocumentPropertyValueView[]>;
62
+ setPropertyValues(document: Document, propertyValues: SetDocumentPropertyParameters[]): Promise<void>;
55
63
  }
@@ -4,15 +4,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
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
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { and, isNotNull as drizzleIsNotNull, eq, inArray } from 'drizzle-orm';
7
+ import { and, isNotNull as drizzleIsNotNull, isNull as drizzleIsNull, eq, inArray, or } from 'drizzle-orm';
8
8
  import { BadRequestError } from '../../../errors/bad-request.error.js';
9
+ import { NotFoundError } from '../../../errors/not-found.error.js';
10
+ import { inject } from '../../../injector/index.js';
9
11
  import { autoAlias, coalesce, getEntityMap, toJsonb } from '../../../orm/index.js';
10
12
  import { Transactional } from '../../../orm/server/index.js';
11
13
  import { injectRepository } from '../../../orm/server/repository.js';
12
14
  import { toArray } from '../../../utils/array/index.js';
13
- import { assertBooleanPass, assertDefinedPass, assertNumberPass, assertStringPass, isBoolean, isNotNull, isNull, isNumber, isString } from '../../../utils/type-guards.js';
15
+ import { assertBooleanPass, assertNumberPass, assertStringPass, isBoolean, isNotNull, isNull, isNumber, isString, isUndefined } from '../../../utils/type-guards.js';
14
16
  import { DocumentProperty, DocumentPropertyDataType, DocumentPropertyValue, DocumentTypeProperty } from '../../models/index.js';
15
17
  import { document, documentProperty, documentPropertyValue, documentType, documentTypeProperty } from '../schemas.js';
18
+ import { DocumentManagementObservationService } from './document-management-observation.service.js';
16
19
  import { enumTypeKey } from './enum-type-key.js';
17
20
  import { DocumentManagementSingleton } from './singleton.js';
18
21
  const documentPropertyValueValidators = {
@@ -26,30 +29,54 @@ let DocumentPropertyService = class DocumentPropertyService extends Transactiona
26
29
  #documentPropertyRepository = injectRepository(DocumentProperty);
27
30
  #documentPropertyValueRepository = injectRepository(DocumentPropertyValue);
28
31
  #documentTypePropertyRepository = injectRepository(DocumentTypeProperty);
29
- repository = injectRepository(DocumentProperty).withSession(this.session);
32
+ #observationService = inject(DocumentManagementObservationService);
33
+ repository = injectRepository(DocumentProperty);
30
34
  documentProperties = this.session.$with('documentProperties').as((qb) => qb
31
35
  .select({
32
36
  documentId: autoAlias(document.id),
33
37
  propertyId: autoAlias(documentProperty.id),
38
+ documentTenantId: autoAlias(document.tenantId),
39
+ propertyTenantId: autoAlias(documentProperty.tenantId),
34
40
  label: documentProperty.label,
35
41
  dataType: documentProperty.dataType,
36
42
  value: coalesce(toJsonb(documentPropertyValue.text), toJsonb(documentPropertyValue.integer), toJsonb(documentPropertyValue.decimal), toJsonb(documentPropertyValue.boolean), toJsonb(documentPropertyValue.date)).as('value'),
37
43
  })
38
44
  .from(document)
39
- .innerJoin(documentType, eq(documentType.id, document.typeId))
40
- .innerJoin(documentTypeProperty, eq(documentTypeProperty.typeId, documentType.id))
41
- .innerJoin(documentProperty, eq(documentProperty.id, documentTypeProperty.propertyId))
42
- .leftJoin(documentPropertyValue, and(eq(documentPropertyValue.documentId, document.id), eq(documentPropertyValue.propertyId, documentProperty.id))));
43
- async createProperty(label, dataType, enumKey) {
44
- return await this.#documentPropertyRepository.insert({ label, dataType, metadata: { attributes: { [enumTypeKey]: enumKey } } });
45
+ .innerJoin(documentType, and(eq(documentType.id, document.typeId), or(drizzleIsNull(documentType.tenantId), eq(documentType.tenantId, document.tenantId))))
46
+ .innerJoin(documentTypeProperty, and(eq(documentTypeProperty.typeId, documentType.id), or(drizzleIsNull(documentTypeProperty.tenantId), eq(documentTypeProperty.tenantId, document.tenantId))))
47
+ .innerJoin(documentProperty, and(eq(documentProperty.id, documentTypeProperty.propertyId), or(drizzleIsNull(documentProperty.tenantId), eq(documentProperty.tenantId, document.tenantId))))
48
+ .leftJoin(documentPropertyValue, and(eq(documentPropertyValue.tenantId, document.tenantId), eq(documentPropertyValue.documentId, document.id), eq(documentPropertyValue.propertyId, documentProperty.id))));
49
+ async loadViews(tenantId) {
50
+ const properties = await this.#documentPropertyRepository.loadManyByQuery({ tenantId: { $or: [null, tenantId] } });
51
+ const typeProperties = await this.#documentTypePropertyRepository.loadManyByQuery({ tenantId: { $or: [null, tenantId] } });
52
+ return properties.map((property) => {
53
+ const typeIds = typeProperties
54
+ .filter((typeProperty) => typeProperty.propertyId == property.id)
55
+ .map((typeProperty) => typeProperty.typeId);
56
+ return {
57
+ id: property.id,
58
+ tenantId: property.tenantId,
59
+ label: property.label,
60
+ dataType: property.dataType,
61
+ typeIds,
62
+ };
63
+ });
64
+ }
65
+ async createProperty(data) {
66
+ return await this.#documentPropertyRepository.insert({
67
+ tenantId: data.tenantId,
68
+ label: data.label,
69
+ dataType: data.dataType,
70
+ metadata: { attributes: { [enumTypeKey]: data.enumKey } },
71
+ });
45
72
  }
46
- async updateProperty(id, update) {
47
- return await this.#documentPropertyRepository.update(id, update);
73
+ async updateProperty(tenantId, id, update) {
74
+ return await this.#documentPropertyRepository.updateByQuery({ tenantId, id }, update);
48
75
  }
49
- async assignPropertyToType(typeId, propertyId) {
50
- await this.#documentTypePropertyRepository.insert({ typeId, propertyId });
76
+ async assignPropertyToType(tenantId, typeId, propertyId) {
77
+ await this.#documentTypePropertyRepository.insert({ tenantId, typeId, propertyId });
51
78
  }
52
- async loadDocumentProperties(documentId, includeNulls = false) {
79
+ async loadDocumentPropertyValues(tenantId, documentId, includeNulls = false) {
53
80
  return await this.session
54
81
  .with(this.documentProperties)
55
82
  .select({
@@ -60,21 +87,25 @@ let DocumentPropertyService = class DocumentPropertyService extends Transactiona
60
87
  value: this.documentProperties.value,
61
88
  })
62
89
  .from(this.documentProperties)
63
- .where(and(inArray(this.documentProperties.documentId, toArray(documentId)), includeNulls ? undefined : drizzleIsNotNull(this.documentProperties.value)));
90
+ .where(and(eq(this.documentProperties.documentTenantId, tenantId), inArray(this.documentProperties.documentId, toArray(documentId)), inArray(this.documentProperties.propertyTenantId, [null, tenantId]), includeNulls ? undefined : drizzleIsNotNull(this.documentProperties.value)));
64
91
  }
65
- async setPropertyValues(documentId, propertyValues) {
92
+ async setPropertyValues(document, propertyValues) {
66
93
  if ((propertyValues.length == 0)) {
67
94
  return;
68
95
  }
69
96
  await this.transaction(async (tx) => {
70
97
  const propertyIds = propertyValues.map((property) => property.propertyId);
71
- const properties = await this.#documentPropertyRepository.withTransaction(tx).loadManyByQuery({ id: { $in: propertyIds } });
98
+ const properties = await this.#documentPropertyRepository.withTransaction(tx).loadManyByQuery({ tenantId: { $or: [null, document.tenantId] }, id: { $in: propertyIds } });
72
99
  const propertiesMap = getEntityMap(properties);
73
100
  const upserts = propertyValues.filter((value) => isNotNull(value.value)).map(({ propertyId, value, metadata }) => {
74
- const property = assertDefinedPass(propertiesMap.get(propertyId));
101
+ const property = propertiesMap.get(propertyId);
102
+ if (isUndefined(property)) {
103
+ throw new NotFoundError(`Property "${propertyId}" not found.`);
104
+ }
75
105
  validatePropertyValue(propertyId, property.dataType, value);
76
106
  return {
77
- documentId,
107
+ tenantId: document.tenantId,
108
+ documentId: document.id,
78
109
  propertyId,
79
110
  text: (property.dataType == 'text') ? assertStringPass(value) : null,
80
111
  integer: (property.dataType == 'integer') ? assertNumberPass(value) : null,
@@ -85,8 +116,9 @@ let DocumentPropertyService = class DocumentPropertyService extends Transactiona
85
116
  };
86
117
  });
87
118
  const deletePropertyIds = propertyValues.filter((value) => isNull(value.value)).map(({ propertyId }) => propertyId);
88
- await this.#documentPropertyValueRepository.withTransaction(tx).hardDeleteManyByQuery({ documentId, propertyId: { $in: deletePropertyIds } });
119
+ await this.#documentPropertyValueRepository.withTransaction(tx).hardDeleteManyByQuery({ tenantId: document.tenantId, documentId: document.id, propertyId: { $in: deletePropertyIds } });
89
120
  await this.#documentPropertyValueRepository.withTransaction(tx).upsertMany(['documentId', 'propertyId'], upserts);
121
+ this.#observationService.documentChange(document.id, tx);
90
122
  });
91
123
  }
92
124
  };
@@ -1,30 +1,19 @@
1
1
  import type { RequestStats } from '../../../document-management/service-models/index.js';
2
2
  import { Transactional } from '../../../orm/server/index.js';
3
3
  import type { OneOrMany } from '../../../types.js';
4
- import { DocumentRequest, DocumentRequestTemplate, DocumentRequestsTemplate } from '../../models/index.js';
4
+ import { DocumentRequest, DocumentRequestTemplate, DocumentRequestsTemplate, type Document } from '../../models/index.js';
5
5
  export declare class DocumentRequestService extends Transactional {
6
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>;
7
+ getRequestStats(tenantId: string, collectionIds: OneOrMany<string>): Promise<RequestStats>;
8
+ createRequestsTemplate(tenantId: string | null, parameters: Pick<DocumentRequestsTemplate, 'label' | 'description'>): Promise<DocumentRequestsTemplate>;
9
+ updateRequestsTemplate(tenantId: string | null, id: string, parameters: Pick<DocumentRequestsTemplate, 'label' | 'description' | 'metadata'>): Promise<DocumentRequestsTemplate>;
10
+ applyRequestsTemplate(tenantId: string, id: string, collectionIds: string[]): Promise<void>;
11
+ deleteRequestsTemplate(tenantId: string, id: string): Promise<DocumentRequestsTemplate>;
12
+ createRequestTemplate(tenantId: string, requestsTemplateId: string, typeId: string, comment: string): Promise<DocumentRequestTemplate>;
13
+ updateRequestTemplate(tenantId: string, id: string, parameters: Pick<DocumentRequestTemplate, 'typeId' | 'comment'>): Promise<DocumentRequestTemplate>;
14
+ deleteRequestTemplate(tenantId: string, id: string): Promise<DocumentRequestTemplate>;
15
+ createRequest(tenantId: string, typeId: string, collectionIds: string[], comment: string | null): Promise<DocumentRequest>;
16
+ updateRequest(tenantId: string, id: string, update: Partial<Pick<DocumentRequest, 'typeId' | 'comment'>>): Promise<void>;
17
+ deleteRequest(tenantId: string, id: string): Promise<void>;
18
+ assignDocument(document: Document, requestId: string): Promise<void>;
30
19
  }