@twin.org/document-management-service 0.0.1-next.10 → 0.0.1-next.12

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.
@@ -224,7 +224,101 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
224
224
  }
225
225
  ]
226
226
  };
227
- const documentManagementRemoveRoute = {
227
+ const documentManagementGetRevisionRoute = {
228
+ operationId: "DocumentManagementGetRevision",
229
+ summary: "Get the data for a document revision from document management",
230
+ tag: tagsDocumentManagement[0].name,
231
+ method: "GET",
232
+ path: `${baseRouteName}/:auditableItemGraphDocumentId/:revision`,
233
+ handler: async (httpRequestContext, request) => documentManagementGetRevision(httpRequestContext, componentName, request),
234
+ requestType: {
235
+ type: "IDocumentManagementGetRequest",
236
+ examples: [
237
+ {
238
+ id: "DocumentManagementGetRevisionRequestExample",
239
+ request: {
240
+ pathParams: {
241
+ auditableItemGraphDocumentId: "aig:123456",
242
+ revision: "1"
243
+ }
244
+ }
245
+ }
246
+ ]
247
+ },
248
+ responseType: [
249
+ {
250
+ type: "IDocumentManagementGetRevisionResponse",
251
+ examples: [
252
+ {
253
+ id: "DocumentManagementGetRevisionResponseExample",
254
+ response: {
255
+ body: {
256
+ "@context": [
257
+ documentManagementModels.DocumentContexts.ContextRoot,
258
+ documentManagementModels.DocumentContexts.ContextRootCommon,
259
+ standardsSchemaOrg.SchemaOrgContexts.ContextRoot
260
+ ],
261
+ type: documentManagementModels.DocumentTypes.Document,
262
+ id: "2721000:0",
263
+ documentId: "2721000",
264
+ documentIdFormat: "bol",
265
+ documentCode: standardsUnece.UneceDocumentCodes.BillOfLading,
266
+ documentRevision: 1,
267
+ blobStorageId: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
268
+ blobHash: "sha256:123456",
269
+ dateCreated: "2024-01-01T00:00:00Z",
270
+ annotationObject: {
271
+ "@context": "https://schema.org",
272
+ "@type": "DigitalDocument",
273
+ name: "myfile.pdf"
274
+ },
275
+ nodeIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
276
+ userIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
277
+ }
278
+ }
279
+ }
280
+ ]
281
+ },
282
+ {
283
+ type: "IDocumentManagementGetRevisionResponse",
284
+ mimeType: web.MimeTypes.JsonLd,
285
+ examples: [
286
+ {
287
+ id: "DocumentManagementGetRevisionResponseExample",
288
+ response: {
289
+ body: {
290
+ "@context": [
291
+ documentManagementModels.DocumentContexts.ContextRoot,
292
+ documentManagementModels.DocumentContexts.ContextRootCommon,
293
+ standardsSchemaOrg.SchemaOrgContexts.ContextRoot
294
+ ],
295
+ type: documentManagementModels.DocumentTypes.Document,
296
+ id: "2721000:0",
297
+ documentId: "2721000",
298
+ documentIdFormat: "bol",
299
+ documentCode: standardsUnece.UneceDocumentCodes.BillOfLading,
300
+ documentRevision: 1,
301
+ blobStorageId: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
302
+ blobHash: "sha256:123456",
303
+ dateCreated: "2024-01-01T00:00:00Z",
304
+ annotationObject: {
305
+ "@context": "https://schema.org",
306
+ "@type": "DigitalDocument",
307
+ name: "myfile.pdf"
308
+ },
309
+ nodeIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
310
+ userIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
311
+ }
312
+ }
313
+ }
314
+ ]
315
+ },
316
+ {
317
+ type: "INotFoundResponse"
318
+ }
319
+ ]
320
+ };
321
+ const documentManagementRemoveRevisionRoute = {
228
322
  operationId: "DocumentManagementRemove",
229
323
  summary: "Remove an document from an auditable item graph vertex",
230
324
  tag: tagsDocumentManagement[0].name,
@@ -343,7 +437,8 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
343
437
  documentManagementCreateRoute,
344
438
  documentManagementUpdateRoute,
345
439
  documentManagementGetRoute,
346
- documentManagementRemoveRoute,
440
+ documentManagementGetRevisionRoute,
441
+ documentManagementRemoveRevisionRoute,
347
442
  documentManagementQueryRoute
348
443
  ];
349
444
  }
@@ -388,7 +483,9 @@ async function documentManagementGet(httpRequestContext, componentName, request)
388
483
  includeBlobStorageMetadata: core.Coerce.boolean(request.query?.includeBlobStorageMetadata),
389
484
  includeBlobStorageData: core.Coerce.boolean(request.query?.includeBlobStorageData),
390
485
  includeAttestation: core.Coerce.boolean(request.query?.includeAttestation),
391
- includeRemoved: core.Coerce.boolean(request.query?.includeRemoved)
486
+ includeRemoved: core.Coerce.boolean(request.query?.includeRemoved),
487
+ extractRuleGroupId: request.query?.extractRuleGroupId,
488
+ extractMimeType: request.query?.extractMimeType
392
489
  }, request.query?.cursor, core.Coerce.integer(request.query?.pageSize), httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
393
490
  return {
394
491
  headers: {
@@ -398,7 +495,36 @@ async function documentManagementGet(httpRequestContext, componentName, request)
398
495
  };
399
496
  }
400
497
  /**
401
- * UPdate the document from the auditable item graph vertex.
498
+ * Get the document revision from the auditable item graph vertex.
499
+ * @param httpRequestContext The request context for the API.
500
+ * @param componentName The name of the component to use in the routes.
501
+ * @param request The request.
502
+ * @returns The response object with additional http response properties.
503
+ */
504
+ async function documentManagementGetRevision(httpRequestContext, componentName, request) {
505
+ core.Guards.object(ROUTES_SOURCE, "request", request);
506
+ core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
507
+ core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.auditableItemGraphDocumentId", request.pathParams.auditableItemGraphDocumentId);
508
+ const revision = core.Coerce.integer(request.pathParams.revision);
509
+ core.Guards.integer(ROUTES_SOURCE, "revision", revision);
510
+ const mimeType = request.headers?.[web.HeaderTypes.Accept] === web.MimeTypes.JsonLd ? "jsonld" : "json";
511
+ const component = core.ComponentFactory.get(componentName);
512
+ const result = await component.getRevision(request.pathParams.auditableItemGraphDocumentId, revision, {
513
+ includeBlobStorageMetadata: core.Coerce.boolean(request.query?.includeBlobStorageMetadata),
514
+ includeBlobStorageData: core.Coerce.boolean(request.query?.includeBlobStorageData),
515
+ includeAttestation: core.Coerce.boolean(request.query?.includeAttestation),
516
+ extractRuleGroupId: request.query?.extractRuleGroupId,
517
+ extractMimeType: request.query?.extractMimeType
518
+ }, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
519
+ return {
520
+ headers: {
521
+ [web.HeaderTypes.ContentType]: mimeType === "json" ? web.MimeTypes.Json : web.MimeTypes.JsonLd
522
+ },
523
+ body: result
524
+ };
525
+ }
526
+ /**
527
+ * Update the document from the auditable item graph vertex.
402
528
  * @param httpRequestContext The request context for the API.
403
529
  * @param componentName The name of the component to use in the routes.
404
530
  * @param request The request.
@@ -482,6 +608,11 @@ class DocumentManagementService {
482
608
  * @internal
483
609
  */
484
610
  _attestationComponent;
611
+ /**
612
+ * The connector for the data processing.
613
+ * @internal
614
+ */
615
+ _dataProcessingComponent;
485
616
  /**
486
617
  * Create a new instance of DocumentManagementService.
487
618
  * @param options The options for the service.
@@ -490,6 +621,7 @@ class DocumentManagementService {
490
621
  this._auditableItemGraphComponent = core.ComponentFactory.get(options?.auditableItemGraphComponentType ?? "auditable-item-graph");
491
622
  this._blobStorageComponent = core.ComponentFactory.get(options?.blobStorageComponentType ?? "blob-storage");
492
623
  this._attestationComponent = core.ComponentFactory.get(options?.attestationComponentType ?? "attestation");
624
+ this._dataProcessingComponent = core.ComponentFactory.get(options?.dataProcessingComponentType ?? "data-processing");
493
625
  standardsSchemaOrg.SchemaOrgDataTypes.registerRedirects();
494
626
  }
495
627
  /**
@@ -544,7 +676,7 @@ class DocumentManagementService {
544
676
  standardsSchemaOrg.SchemaOrgContexts.ContextRoot
545
677
  ],
546
678
  type: documentManagementModels.DocumentTypes.Document,
547
- id: `${documentId}:0`,
679
+ id: this.createDocumentId(documentId, 0),
548
680
  documentId,
549
681
  documentIdFormat,
550
682
  documentCode,
@@ -598,12 +730,13 @@ class DocumentManagementService {
598
730
  core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
599
731
  core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
600
732
  try {
601
- const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId);
733
+ const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId, { includeDeleted: true });
602
734
  if (core.Is.empty(documentVertex.resources)) {
603
735
  throw new core.NotFoundError(this.CLASS_NAME, "documentRevisionNone");
604
736
  }
605
737
  const documents = await this.getDocumentsFromVertex(documentVertex);
606
738
  const latestRevision = documents.documents[0];
739
+ documentVertex.resources = documentVertex.resources.filter(r => core.Is.empty(r.dateDeleted));
607
740
  if (core.Is.empty(latestRevision)) {
608
741
  throw new core.NotFoundError(this.CLASS_NAME, "documentRevisionNone");
609
742
  }
@@ -634,7 +767,7 @@ class DocumentManagementService {
634
767
  const blobStorageId = await this._blobStorageComponent.create(core.Converter.bytesToBase64(blob), undefined, undefined, undefined, undefined, userIdentity, nodeIdentity);
635
768
  const newRevision = core.ObjectHelper.clone(latestRevision);
636
769
  newRevision.documentRevision++;
637
- newRevision.id = `${newRevision.documentId}:${newRevision.documentRevision}`;
770
+ newRevision.id = this.createDocumentId(newRevision.documentId, newRevision.documentRevision);
638
771
  newRevision.blobHash = newBlobHash;
639
772
  newRevision.blobStorageId = blobStorageId;
640
773
  newRevision.annotationObject = annotationObject;
@@ -685,6 +818,8 @@ class DocumentManagementService {
685
818
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
686
819
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
687
820
  * @param options.includeRemoved Flag to include deleted documents, defaults to false.
821
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
822
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
688
823
  * @param cursor The cursor to get the next chunk of revisions.
689
824
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
690
825
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -706,6 +841,43 @@ class DocumentManagementService {
706
841
  throw new core.GeneralError(this.CLASS_NAME, "getFailed", undefined, error);
707
842
  }
708
843
  }
844
+ /**
845
+ * Get a document revision using it's auditable item graph vertex id.
846
+ * @param auditableItemGraphDocumentId The auditable item graph vertex id which contains the document.
847
+ * @param revision The revision id for the document.
848
+ * @param options Additional options for the get operation.
849
+ * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
850
+ * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
851
+ * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
852
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
853
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
854
+ * @param userIdentity The identity to perform the auditable item graph operation with.
855
+ * @param nodeIdentity The node identity to use for vault operations.
856
+ * @returns The documents and revisions if requested, ordered by revision descending, cursor is set if there are more document revisions.
857
+ */
858
+ async getRevision(auditableItemGraphDocumentId, revision, options, userIdentity, nodeIdentity) {
859
+ core.Urn.guard(this.CLASS_NAME, "auditableItemGraphDocumentId", auditableItemGraphDocumentId);
860
+ core.Guards.integer(this.CLASS_NAME, "revision", revision);
861
+ try {
862
+ const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId, { includeDeleted: true });
863
+ if (core.Is.empty(documentVertex.resources)) {
864
+ throw new core.NotFoundError(this.CLASS_NAME, "documentRevisionNone");
865
+ }
866
+ documentVertex.resources = documentVertex.resources.filter(d => d.resourceObject?.documentRevision === revision);
867
+ if (documentVertex.resources.length === 0) {
868
+ throw new core.NotFoundError(this.CLASS_NAME, "documentRevisionNotFound", revision.toString());
869
+ }
870
+ // Populate the document and revisions with the options set
871
+ const docList = await this.getDocumentsFromVertex(documentVertex, options, undefined, undefined, userIdentity, nodeIdentity);
872
+ return dataJsonLd.JsonLdProcessor.compact(docList.documents[0], docList.documents[0]["@context"]);
873
+ }
874
+ catch (error) {
875
+ if (core.BaseError.someErrorName(error, "NotFoundError")) {
876
+ throw error;
877
+ }
878
+ throw new core.GeneralError(this.CLASS_NAME, "getRevisionFailed", undefined, error);
879
+ }
880
+ }
709
881
  /**
710
882
  * Remove an auditable item graph vertex using it's id.
711
883
  * The document dateDeleted will be set, but can still be queried with the includeRemoved flag.
@@ -918,7 +1090,8 @@ class DocumentManagementService {
918
1090
  * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
919
1091
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
920
1092
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
921
- * @param options.includeRemoved Flag to include deleted documents, defaults to false.
1093
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
1094
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
922
1095
  * @param cursor The cursor to get the next chunk of revisions.
923
1096
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
924
1097
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -948,15 +1121,31 @@ class DocumentManagementService {
948
1121
  const includeBlobStorageMetadata = options?.includeBlobStorageMetadata ?? false;
949
1122
  const includeBlobStorageData = options?.includeBlobStorageData ?? false;
950
1123
  const includeAttestation = options?.includeAttestation ?? false;
1124
+ const extractData = core.Is.stringValue(options?.extractRuleGroupId);
951
1125
  for (let i = 0; i < slicedResources.length; i++) {
952
1126
  const document = slicedResources[i].resourceObject;
953
1127
  if (core.Is.object(document)) {
954
1128
  docList.documents.push(document);
955
- if (includeBlobStorageMetadata || includeBlobStorageData) {
956
- const blobEntry = await this._blobStorageComponent.get(document.blobStorageId, includeBlobStorageData, userIdentity, nodeIdentity);
957
- document.blobStorageEntry = blobEntry;
958
- if (!docList["@context"].includes(blobStorageModels.BlobStorageContexts.ContextRoot)) {
959
- docList["@context"].push(blobStorageModels.BlobStorageContexts.ContextRoot);
1129
+ const blobRequired = includeBlobStorageMetadata || includeBlobStorageData;
1130
+ if (blobRequired || extractData) {
1131
+ const blobEntry = await this._blobStorageComponent.get(document.blobStorageId, includeBlobStorageData || extractData, userIdentity, nodeIdentity);
1132
+ if (blobRequired) {
1133
+ document.blobStorageEntry = blobEntry;
1134
+ if (!docList["@context"].includes(blobStorageModels.BlobStorageContexts.ContextRoot)) {
1135
+ docList["@context"].push(blobStorageModels.BlobStorageContexts.ContextRoot);
1136
+ }
1137
+ }
1138
+ if (core.Is.stringValue(options?.extractRuleGroupId) && core.Is.stringValue(blobEntry.blob)) {
1139
+ const binaryBlob = core.Converter.base64ToBytes(blobEntry.blob);
1140
+ document.extractedData = await this._dataProcessingComponent.extract(options.extractRuleGroupId, binaryBlob, undefined, options?.extractMimeType);
1141
+ }
1142
+ // If we have the blob data due to extraction but we weren't asked for it
1143
+ // then we remove it from the document
1144
+ if (!blobRequired) {
1145
+ delete document.blobStorageEntry;
1146
+ }
1147
+ else if (!includeBlobStorageData) {
1148
+ delete document.blobStorageEntry?.blob;
960
1149
  }
961
1150
  }
962
1151
  if (includeAttestation && core.Is.stringValue(document.attestationId)) {
@@ -1003,6 +1192,17 @@ class DocumentManagementService {
1003
1192
  };
1004
1193
  return this._attestationComponent.create(documentAttestation, undefined, userIdentity, nodeIdentity);
1005
1194
  }
1195
+ /**
1196
+ * Create a document id from the document id and revision.
1197
+ * @param documentId The document id to create.
1198
+ * @param revision The revision of the document.
1199
+ * @returns The document id.
1200
+ * @internal
1201
+ */
1202
+ createDocumentId(documentId, revision) {
1203
+ const documentIdHash = core.Converter.bytesToBase64Url(crypto.Sha256.sum256(core.Converter.utf8ToBytes(documentId)));
1204
+ return `document:${documentIdHash}:${revision}`;
1205
+ }
1006
1206
  }
1007
1207
 
1008
1208
  const restEntryPoints = [
@@ -1017,6 +1217,7 @@ const restEntryPoints = [
1017
1217
  exports.DocumentManagementService = DocumentManagementService;
1018
1218
  exports.documentManagementCreate = documentManagementCreate;
1019
1219
  exports.documentManagementGet = documentManagementGet;
1220
+ exports.documentManagementGetRevision = documentManagementGetRevision;
1020
1221
  exports.documentManagementQuery = documentManagementQuery;
1021
1222
  exports.documentManagementRemove = documentManagementRemove;
1022
1223
  exports.documentManagementUpdate = documentManagementUpdate;
@@ -222,7 +222,101 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
222
222
  }
223
223
  ]
224
224
  };
225
- const documentManagementRemoveRoute = {
225
+ const documentManagementGetRevisionRoute = {
226
+ operationId: "DocumentManagementGetRevision",
227
+ summary: "Get the data for a document revision from document management",
228
+ tag: tagsDocumentManagement[0].name,
229
+ method: "GET",
230
+ path: `${baseRouteName}/:auditableItemGraphDocumentId/:revision`,
231
+ handler: async (httpRequestContext, request) => documentManagementGetRevision(httpRequestContext, componentName, request),
232
+ requestType: {
233
+ type: "IDocumentManagementGetRequest",
234
+ examples: [
235
+ {
236
+ id: "DocumentManagementGetRevisionRequestExample",
237
+ request: {
238
+ pathParams: {
239
+ auditableItemGraphDocumentId: "aig:123456",
240
+ revision: "1"
241
+ }
242
+ }
243
+ }
244
+ ]
245
+ },
246
+ responseType: [
247
+ {
248
+ type: "IDocumentManagementGetRevisionResponse",
249
+ examples: [
250
+ {
251
+ id: "DocumentManagementGetRevisionResponseExample",
252
+ response: {
253
+ body: {
254
+ "@context": [
255
+ DocumentContexts.ContextRoot,
256
+ DocumentContexts.ContextRootCommon,
257
+ SchemaOrgContexts.ContextRoot
258
+ ],
259
+ type: DocumentTypes.Document,
260
+ id: "2721000:0",
261
+ documentId: "2721000",
262
+ documentIdFormat: "bol",
263
+ documentCode: UneceDocumentCodes.BillOfLading,
264
+ documentRevision: 1,
265
+ blobStorageId: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
266
+ blobHash: "sha256:123456",
267
+ dateCreated: "2024-01-01T00:00:00Z",
268
+ annotationObject: {
269
+ "@context": "https://schema.org",
270
+ "@type": "DigitalDocument",
271
+ name: "myfile.pdf"
272
+ },
273
+ nodeIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
274
+ userIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
275
+ }
276
+ }
277
+ }
278
+ ]
279
+ },
280
+ {
281
+ type: "IDocumentManagementGetRevisionResponse",
282
+ mimeType: MimeTypes.JsonLd,
283
+ examples: [
284
+ {
285
+ id: "DocumentManagementGetRevisionResponseExample",
286
+ response: {
287
+ body: {
288
+ "@context": [
289
+ DocumentContexts.ContextRoot,
290
+ DocumentContexts.ContextRootCommon,
291
+ SchemaOrgContexts.ContextRoot
292
+ ],
293
+ type: DocumentTypes.Document,
294
+ id: "2721000:0",
295
+ documentId: "2721000",
296
+ documentIdFormat: "bol",
297
+ documentCode: UneceDocumentCodes.BillOfLading,
298
+ documentRevision: 1,
299
+ blobStorageId: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
300
+ blobHash: "sha256:123456",
301
+ dateCreated: "2024-01-01T00:00:00Z",
302
+ annotationObject: {
303
+ "@context": "https://schema.org",
304
+ "@type": "DigitalDocument",
305
+ name: "myfile.pdf"
306
+ },
307
+ nodeIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
308
+ userIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
309
+ }
310
+ }
311
+ }
312
+ ]
313
+ },
314
+ {
315
+ type: "INotFoundResponse"
316
+ }
317
+ ]
318
+ };
319
+ const documentManagementRemoveRevisionRoute = {
226
320
  operationId: "DocumentManagementRemove",
227
321
  summary: "Remove an document from an auditable item graph vertex",
228
322
  tag: tagsDocumentManagement[0].name,
@@ -341,7 +435,8 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
341
435
  documentManagementCreateRoute,
342
436
  documentManagementUpdateRoute,
343
437
  documentManagementGetRoute,
344
- documentManagementRemoveRoute,
438
+ documentManagementGetRevisionRoute,
439
+ documentManagementRemoveRevisionRoute,
345
440
  documentManagementQueryRoute
346
441
  ];
347
442
  }
@@ -386,7 +481,9 @@ async function documentManagementGet(httpRequestContext, componentName, request)
386
481
  includeBlobStorageMetadata: Coerce.boolean(request.query?.includeBlobStorageMetadata),
387
482
  includeBlobStorageData: Coerce.boolean(request.query?.includeBlobStorageData),
388
483
  includeAttestation: Coerce.boolean(request.query?.includeAttestation),
389
- includeRemoved: Coerce.boolean(request.query?.includeRemoved)
484
+ includeRemoved: Coerce.boolean(request.query?.includeRemoved),
485
+ extractRuleGroupId: request.query?.extractRuleGroupId,
486
+ extractMimeType: request.query?.extractMimeType
390
487
  }, request.query?.cursor, Coerce.integer(request.query?.pageSize), httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
391
488
  return {
392
489
  headers: {
@@ -396,7 +493,36 @@ async function documentManagementGet(httpRequestContext, componentName, request)
396
493
  };
397
494
  }
398
495
  /**
399
- * UPdate the document from the auditable item graph vertex.
496
+ * Get the document revision from the auditable item graph vertex.
497
+ * @param httpRequestContext The request context for the API.
498
+ * @param componentName The name of the component to use in the routes.
499
+ * @param request The request.
500
+ * @returns The response object with additional http response properties.
501
+ */
502
+ async function documentManagementGetRevision(httpRequestContext, componentName, request) {
503
+ Guards.object(ROUTES_SOURCE, "request", request);
504
+ Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
505
+ Guards.stringValue(ROUTES_SOURCE, "request.pathParams.auditableItemGraphDocumentId", request.pathParams.auditableItemGraphDocumentId);
506
+ const revision = Coerce.integer(request.pathParams.revision);
507
+ Guards.integer(ROUTES_SOURCE, "revision", revision);
508
+ const mimeType = request.headers?.[HeaderTypes.Accept] === MimeTypes.JsonLd ? "jsonld" : "json";
509
+ const component = ComponentFactory.get(componentName);
510
+ const result = await component.getRevision(request.pathParams.auditableItemGraphDocumentId, revision, {
511
+ includeBlobStorageMetadata: Coerce.boolean(request.query?.includeBlobStorageMetadata),
512
+ includeBlobStorageData: Coerce.boolean(request.query?.includeBlobStorageData),
513
+ includeAttestation: Coerce.boolean(request.query?.includeAttestation),
514
+ extractRuleGroupId: request.query?.extractRuleGroupId,
515
+ extractMimeType: request.query?.extractMimeType
516
+ }, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
517
+ return {
518
+ headers: {
519
+ [HeaderTypes.ContentType]: mimeType === "json" ? MimeTypes.Json : MimeTypes.JsonLd
520
+ },
521
+ body: result
522
+ };
523
+ }
524
+ /**
525
+ * Update the document from the auditable item graph vertex.
400
526
  * @param httpRequestContext The request context for the API.
401
527
  * @param componentName The name of the component to use in the routes.
402
528
  * @param request The request.
@@ -480,6 +606,11 @@ class DocumentManagementService {
480
606
  * @internal
481
607
  */
482
608
  _attestationComponent;
609
+ /**
610
+ * The connector for the data processing.
611
+ * @internal
612
+ */
613
+ _dataProcessingComponent;
483
614
  /**
484
615
  * Create a new instance of DocumentManagementService.
485
616
  * @param options The options for the service.
@@ -488,6 +619,7 @@ class DocumentManagementService {
488
619
  this._auditableItemGraphComponent = ComponentFactory.get(options?.auditableItemGraphComponentType ?? "auditable-item-graph");
489
620
  this._blobStorageComponent = ComponentFactory.get(options?.blobStorageComponentType ?? "blob-storage");
490
621
  this._attestationComponent = ComponentFactory.get(options?.attestationComponentType ?? "attestation");
622
+ this._dataProcessingComponent = ComponentFactory.get(options?.dataProcessingComponentType ?? "data-processing");
491
623
  SchemaOrgDataTypes.registerRedirects();
492
624
  }
493
625
  /**
@@ -542,7 +674,7 @@ class DocumentManagementService {
542
674
  SchemaOrgContexts.ContextRoot
543
675
  ],
544
676
  type: DocumentTypes.Document,
545
- id: `${documentId}:0`,
677
+ id: this.createDocumentId(documentId, 0),
546
678
  documentId,
547
679
  documentIdFormat,
548
680
  documentCode,
@@ -596,12 +728,13 @@ class DocumentManagementService {
596
728
  Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
597
729
  Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
598
730
  try {
599
- const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId);
731
+ const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId, { includeDeleted: true });
600
732
  if (Is.empty(documentVertex.resources)) {
601
733
  throw new NotFoundError(this.CLASS_NAME, "documentRevisionNone");
602
734
  }
603
735
  const documents = await this.getDocumentsFromVertex(documentVertex);
604
736
  const latestRevision = documents.documents[0];
737
+ documentVertex.resources = documentVertex.resources.filter(r => Is.empty(r.dateDeleted));
605
738
  if (Is.empty(latestRevision)) {
606
739
  throw new NotFoundError(this.CLASS_NAME, "documentRevisionNone");
607
740
  }
@@ -632,7 +765,7 @@ class DocumentManagementService {
632
765
  const blobStorageId = await this._blobStorageComponent.create(Converter.bytesToBase64(blob), undefined, undefined, undefined, undefined, userIdentity, nodeIdentity);
633
766
  const newRevision = ObjectHelper.clone(latestRevision);
634
767
  newRevision.documentRevision++;
635
- newRevision.id = `${newRevision.documentId}:${newRevision.documentRevision}`;
768
+ newRevision.id = this.createDocumentId(newRevision.documentId, newRevision.documentRevision);
636
769
  newRevision.blobHash = newBlobHash;
637
770
  newRevision.blobStorageId = blobStorageId;
638
771
  newRevision.annotationObject = annotationObject;
@@ -683,6 +816,8 @@ class DocumentManagementService {
683
816
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
684
817
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
685
818
  * @param options.includeRemoved Flag to include deleted documents, defaults to false.
819
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
820
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
686
821
  * @param cursor The cursor to get the next chunk of revisions.
687
822
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
688
823
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -704,6 +839,43 @@ class DocumentManagementService {
704
839
  throw new GeneralError(this.CLASS_NAME, "getFailed", undefined, error);
705
840
  }
706
841
  }
842
+ /**
843
+ * Get a document revision using it's auditable item graph vertex id.
844
+ * @param auditableItemGraphDocumentId The auditable item graph vertex id which contains the document.
845
+ * @param revision The revision id for the document.
846
+ * @param options Additional options for the get operation.
847
+ * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
848
+ * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
849
+ * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
850
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
851
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
852
+ * @param userIdentity The identity to perform the auditable item graph operation with.
853
+ * @param nodeIdentity The node identity to use for vault operations.
854
+ * @returns The documents and revisions if requested, ordered by revision descending, cursor is set if there are more document revisions.
855
+ */
856
+ async getRevision(auditableItemGraphDocumentId, revision, options, userIdentity, nodeIdentity) {
857
+ Urn.guard(this.CLASS_NAME, "auditableItemGraphDocumentId", auditableItemGraphDocumentId);
858
+ Guards.integer(this.CLASS_NAME, "revision", revision);
859
+ try {
860
+ const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId, { includeDeleted: true });
861
+ if (Is.empty(documentVertex.resources)) {
862
+ throw new NotFoundError(this.CLASS_NAME, "documentRevisionNone");
863
+ }
864
+ documentVertex.resources = documentVertex.resources.filter(d => d.resourceObject?.documentRevision === revision);
865
+ if (documentVertex.resources.length === 0) {
866
+ throw new NotFoundError(this.CLASS_NAME, "documentRevisionNotFound", revision.toString());
867
+ }
868
+ // Populate the document and revisions with the options set
869
+ const docList = await this.getDocumentsFromVertex(documentVertex, options, undefined, undefined, userIdentity, nodeIdentity);
870
+ return JsonLdProcessor.compact(docList.documents[0], docList.documents[0]["@context"]);
871
+ }
872
+ catch (error) {
873
+ if (BaseError.someErrorName(error, "NotFoundError")) {
874
+ throw error;
875
+ }
876
+ throw new GeneralError(this.CLASS_NAME, "getRevisionFailed", undefined, error);
877
+ }
878
+ }
707
879
  /**
708
880
  * Remove an auditable item graph vertex using it's id.
709
881
  * The document dateDeleted will be set, but can still be queried with the includeRemoved flag.
@@ -916,7 +1088,8 @@ class DocumentManagementService {
916
1088
  * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
917
1089
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
918
1090
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
919
- * @param options.includeRemoved Flag to include deleted documents, defaults to false.
1091
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
1092
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
920
1093
  * @param cursor The cursor to get the next chunk of revisions.
921
1094
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
922
1095
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -946,15 +1119,31 @@ class DocumentManagementService {
946
1119
  const includeBlobStorageMetadata = options?.includeBlobStorageMetadata ?? false;
947
1120
  const includeBlobStorageData = options?.includeBlobStorageData ?? false;
948
1121
  const includeAttestation = options?.includeAttestation ?? false;
1122
+ const extractData = Is.stringValue(options?.extractRuleGroupId);
949
1123
  for (let i = 0; i < slicedResources.length; i++) {
950
1124
  const document = slicedResources[i].resourceObject;
951
1125
  if (Is.object(document)) {
952
1126
  docList.documents.push(document);
953
- if (includeBlobStorageMetadata || includeBlobStorageData) {
954
- const blobEntry = await this._blobStorageComponent.get(document.blobStorageId, includeBlobStorageData, userIdentity, nodeIdentity);
955
- document.blobStorageEntry = blobEntry;
956
- if (!docList["@context"].includes(BlobStorageContexts.ContextRoot)) {
957
- docList["@context"].push(BlobStorageContexts.ContextRoot);
1127
+ const blobRequired = includeBlobStorageMetadata || includeBlobStorageData;
1128
+ if (blobRequired || extractData) {
1129
+ const blobEntry = await this._blobStorageComponent.get(document.blobStorageId, includeBlobStorageData || extractData, userIdentity, nodeIdentity);
1130
+ if (blobRequired) {
1131
+ document.blobStorageEntry = blobEntry;
1132
+ if (!docList["@context"].includes(BlobStorageContexts.ContextRoot)) {
1133
+ docList["@context"].push(BlobStorageContexts.ContextRoot);
1134
+ }
1135
+ }
1136
+ if (Is.stringValue(options?.extractRuleGroupId) && Is.stringValue(blobEntry.blob)) {
1137
+ const binaryBlob = Converter.base64ToBytes(blobEntry.blob);
1138
+ document.extractedData = await this._dataProcessingComponent.extract(options.extractRuleGroupId, binaryBlob, undefined, options?.extractMimeType);
1139
+ }
1140
+ // If we have the blob data due to extraction but we weren't asked for it
1141
+ // then we remove it from the document
1142
+ if (!blobRequired) {
1143
+ delete document.blobStorageEntry;
1144
+ }
1145
+ else if (!includeBlobStorageData) {
1146
+ delete document.blobStorageEntry?.blob;
958
1147
  }
959
1148
  }
960
1149
  if (includeAttestation && Is.stringValue(document.attestationId)) {
@@ -1001,6 +1190,17 @@ class DocumentManagementService {
1001
1190
  };
1002
1191
  return this._attestationComponent.create(documentAttestation, undefined, userIdentity, nodeIdentity);
1003
1192
  }
1193
+ /**
1194
+ * Create a document id from the document id and revision.
1195
+ * @param documentId The document id to create.
1196
+ * @param revision The revision of the document.
1197
+ * @returns The document id.
1198
+ * @internal
1199
+ */
1200
+ createDocumentId(documentId, revision) {
1201
+ const documentIdHash = Converter.bytesToBase64Url(Sha256.sum256(Converter.utf8ToBytes(documentId)));
1202
+ return `document:${documentIdHash}:${revision}`;
1203
+ }
1004
1204
  }
1005
1205
 
1006
1206
  const restEntryPoints = [
@@ -1012,4 +1212,4 @@ const restEntryPoints = [
1012
1212
  }
1013
1213
  ];
1014
1214
 
1015
- export { DocumentManagementService, documentManagementCreate, documentManagementGet, documentManagementQuery, documentManagementRemove, documentManagementUpdate, generateRestRoutesDocumentManagement, restEntryPoints, tagsDocumentManagement };
1215
+ export { DocumentManagementService, documentManagementCreate, documentManagementGet, documentManagementGetRevision, documentManagementQuery, documentManagementRemove, documentManagementUpdate, generateRestRoutesDocumentManagement, restEntryPoints, tagsDocumentManagement };
@@ -1,5 +1,5 @@
1
1
  import type { ICreatedResponse, IHttpRequestContext, INoContentResponse, IRestRoute, ITag } from "@twin.org/api-models";
2
- import { type IDocumentManagementCreateRequest, type IDocumentManagementGetRequest, type IDocumentManagementGetResponse, type IDocumentManagementQueryRequest, type IDocumentManagementQueryResponse, type IDocumentManagementRemoveRequest, type IDocumentManagementUpdateRequest } from "@twin.org/document-management-models";
2
+ import { type IDocumentManagementGetRevisionRequest, type IDocumentManagementGetRevisionResponse, type IDocumentManagementCreateRequest, type IDocumentManagementGetRequest, type IDocumentManagementGetResponse, type IDocumentManagementQueryRequest, type IDocumentManagementQueryResponse, type IDocumentManagementRemoveRequest, type IDocumentManagementUpdateRequest } from "@twin.org/document-management-models";
3
3
  /**
4
4
  * The tag to associate with the routes.
5
5
  */
@@ -28,7 +28,15 @@ export declare function documentManagementCreate(httpRequestContext: IHttpReques
28
28
  */
29
29
  export declare function documentManagementGet(httpRequestContext: IHttpRequestContext, componentName: string, request: IDocumentManagementGetRequest): Promise<IDocumentManagementGetResponse>;
30
30
  /**
31
- * UPdate the document from the auditable item graph vertex.
31
+ * Get the document revision from the auditable item graph vertex.
32
+ * @param httpRequestContext The request context for the API.
33
+ * @param componentName The name of the component to use in the routes.
34
+ * @param request The request.
35
+ * @returns The response object with additional http response properties.
36
+ */
37
+ export declare function documentManagementGetRevision(httpRequestContext: IHttpRequestContext, componentName: string, request: IDocumentManagementGetRevisionRequest): Promise<IDocumentManagementGetRevisionResponse>;
38
+ /**
39
+ * Update the document from the auditable item graph vertex.
32
40
  * @param httpRequestContext The request context for the API.
33
41
  * @param componentName The name of the component to use in the routes.
34
42
  * @param request The request.
@@ -1,6 +1,6 @@
1
1
  import { type IAuditableItemGraphVertexList } from "@twin.org/auditable-item-graph-models";
2
2
  import { type IJsonLdNodeObject } from "@twin.org/data-json-ld";
3
- import { type IDocumentList, type IDocumentManagementComponent } from "@twin.org/document-management-models";
3
+ import { type IDocument, type IDocumentList, type IDocumentManagementComponent } from "@twin.org/document-management-models";
4
4
  import { UneceDocumentCodes } from "@twin.org/standards-unece";
5
5
  import type { IDocumentManagementServiceConstructorOptions } from "./models/IDocumentManagementStorageServiceConstructorOptions";
6
6
  /**
@@ -72,6 +72,8 @@ export declare class DocumentManagementService implements IDocumentManagementCom
72
72
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
73
73
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
74
74
  * @param options.includeRemoved Flag to include deleted documents, defaults to false.
75
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
76
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
75
77
  * @param cursor The cursor to get the next chunk of revisions.
76
78
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
77
79
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -83,7 +85,30 @@ export declare class DocumentManagementService implements IDocumentManagementCom
83
85
  includeBlobStorageData?: boolean;
84
86
  includeAttestation?: boolean;
85
87
  includeRemoved?: boolean;
88
+ extractRuleGroupId?: string;
89
+ extractMimeType?: string;
86
90
  }, cursor?: string, pageSize?: number, userIdentity?: string, nodeIdentity?: string): Promise<IDocumentList>;
91
+ /**
92
+ * Get a document revision using it's auditable item graph vertex id.
93
+ * @param auditableItemGraphDocumentId The auditable item graph vertex id which contains the document.
94
+ * @param revision The revision id for the document.
95
+ * @param options Additional options for the get operation.
96
+ * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
97
+ * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
98
+ * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
99
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
100
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
101
+ * @param userIdentity The identity to perform the auditable item graph operation with.
102
+ * @param nodeIdentity The node identity to use for vault operations.
103
+ * @returns The documents and revisions if requested, ordered by revision descending, cursor is set if there are more document revisions.
104
+ */
105
+ getRevision(auditableItemGraphDocumentId: string, revision: number, options?: {
106
+ includeBlobStorageMetadata?: boolean;
107
+ includeBlobStorageData?: boolean;
108
+ includeAttestation?: boolean;
109
+ extractRuleGroupId?: string;
110
+ extractMimeType?: string;
111
+ }, userIdentity?: string, nodeIdentity?: string): Promise<IDocument>;
87
112
  /**
88
113
  * Remove an auditable item graph vertex using it's id.
89
114
  * The document dateDeleted will be set, but can still be queried with the includeRemoved flag.
@@ -18,6 +18,11 @@ export interface IDocumentManagementServiceConstructorOptions {
18
18
  * @default attestation
19
19
  */
20
20
  attestationComponentType?: string;
21
+ /**
22
+ * The type of the data processing component.
23
+ * @default data-processing
24
+ */
25
+ dataProcessingComponentType?: string;
21
26
  /**
22
27
  * The configuration for the service.
23
28
  */
package/docs/changelog.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @twin.org/document-management-service - Changelog
2
2
 
3
+ ## [0.0.1-next.12](https://github.com/twinfoundation/document-management/compare/document-management-service-v0.0.1-next.11...document-management-service-v0.0.1-next.12) (2025-04-30)
4
+
5
+
6
+ ### Features
7
+
8
+ * get document revision ([080eddc](https://github.com/twinfoundation/document-management/commit/080eddcc024c622dda6bb36f60f5fa80a86cf5bb))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/document-management-models bumped from 0.0.1-next.11 to 0.0.1-next.12
16
+
17
+ ## [0.0.1-next.11](https://github.com/twinfoundation/document-management/compare/document-management-service-v0.0.1-next.10...document-management-service-v0.0.1-next.11) (2025-04-28)
18
+
19
+
20
+ ### Features
21
+
22
+ * document get can perform extraction ([#6](https://github.com/twinfoundation/document-management/issues/6)) ([5ce6d37](https://github.com/twinfoundation/document-management/commit/5ce6d37432ad271ca5783f422846f4be98ec2215))
23
+
24
+
25
+ ### Dependencies
26
+
27
+ * The following workspace dependencies were updated
28
+ * dependencies
29
+ * @twin.org/document-management-models bumped from 0.0.1-next.10 to 0.0.1-next.11
30
+
3
31
  ## [0.0.1-next.10](https://github.com/twinfoundation/document-management/compare/document-management-service-v0.0.1-next.9...document-management-service-v0.0.1-next.10) (2025-04-25)
4
32
 
5
33
 
@@ -477,6 +477,24 @@
477
477
  "type": "boolean"
478
478
  }
479
479
  },
480
+ {
481
+ "name": "extractRuleGroupId",
482
+ "description": "If provided will extract data from the document using the specified rule group id.",
483
+ "in": "query",
484
+ "required": false,
485
+ "schema": {
486
+ "type": "string"
487
+ }
488
+ },
489
+ {
490
+ "name": "extractMimeType",
491
+ "description": "By default extraction will auto detect the mime type of the document, this can be used to override the detection.",
492
+ "in": "query",
493
+ "required": false,
494
+ "schema": {
495
+ "type": "string"
496
+ }
497
+ },
480
498
  {
481
499
  "name": "pageSize",
482
500
  "description": "Page size of items to return, defaults to 1 so only most recent is returned.",
@@ -680,6 +698,191 @@
680
698
  }
681
699
  },
682
700
  "/document-management/{auditableItemGraphDocumentId}/{revision}": {
701
+ "get": {
702
+ "operationId": "DocumentManagementGetRevision",
703
+ "summary": "Get the data for a document revision from document management",
704
+ "tags": [
705
+ "Document Management"
706
+ ],
707
+ "parameters": [
708
+ {
709
+ "name": "auditableItemGraphDocumentId",
710
+ "description": "",
711
+ "in": "path",
712
+ "required": true,
713
+ "schema": {
714
+ "type": "string"
715
+ },
716
+ "style": "simple",
717
+ "example": "aig:123456"
718
+ },
719
+ {
720
+ "name": "revision",
721
+ "description": "",
722
+ "in": "path",
723
+ "required": true,
724
+ "schema": {
725
+ "type": "string"
726
+ },
727
+ "style": "simple",
728
+ "example": "1"
729
+ }
730
+ ],
731
+ "security": [
732
+ {
733
+ "jwtBearerAuthScheme": []
734
+ }
735
+ ],
736
+ "responses": {
737
+ "200": {
738
+ "description": "Response to get a document revision from an auditable item graph vertex.",
739
+ "content": {
740
+ "application/json": {
741
+ "schema": {
742
+ "$ref": "#/components/schemas/Document"
743
+ },
744
+ "examples": {
745
+ "DocumentManagementGetRevisionResponseExample": {
746
+ "value": {
747
+ "@context": [
748
+ "https://schema.twindev.org/documents/",
749
+ "https://schema.twindev.org/common/",
750
+ "https://schema.org"
751
+ ],
752
+ "type": "Document",
753
+ "id": "2721000:0",
754
+ "documentId": "2721000",
755
+ "documentIdFormat": "bol",
756
+ "documentCode": "unece:DocumentCodeList#705",
757
+ "documentRevision": 1,
758
+ "blobStorageId": "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
759
+ "blobHash": "sha256:123456",
760
+ "dateCreated": "2024-01-01T00:00:00Z",
761
+ "annotationObject": {
762
+ "@context": "https://schema.org",
763
+ "@type": "DigitalDocument",
764
+ "name": "myfile.pdf"
765
+ },
766
+ "nodeIdentity": "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
767
+ "userIdentity": "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
768
+ }
769
+ }
770
+ }
771
+ },
772
+ "application/ld+json": {
773
+ "schema": {
774
+ "$ref": "#/components/schemas/Document"
775
+ },
776
+ "examples": {
777
+ "DocumentManagementGetRevisionResponseExample": {
778
+ "value": {
779
+ "@context": [
780
+ "https://schema.twindev.org/documents/",
781
+ "https://schema.twindev.org/common/",
782
+ "https://schema.org"
783
+ ],
784
+ "type": "Document",
785
+ "id": "2721000:0",
786
+ "documentId": "2721000",
787
+ "documentIdFormat": "bol",
788
+ "documentCode": "unece:DocumentCodeList#705",
789
+ "documentRevision": 1,
790
+ "blobStorageId": "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
791
+ "blobHash": "sha256:123456",
792
+ "dateCreated": "2024-01-01T00:00:00Z",
793
+ "annotationObject": {
794
+ "@context": "https://schema.org",
795
+ "@type": "DigitalDocument",
796
+ "name": "myfile.pdf"
797
+ },
798
+ "nodeIdentity": "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
799
+ "userIdentity": "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
800
+ }
801
+ }
802
+ }
803
+ }
804
+ }
805
+ },
806
+ "400": {
807
+ "description": "The server cannot process the request, see the content for more details.",
808
+ "content": {
809
+ "application/json": {
810
+ "schema": {
811
+ "$ref": "#/components/schemas/Error"
812
+ },
813
+ "examples": {
814
+ "exampleResponse": {
815
+ "value": {
816
+ "name": "GeneralError",
817
+ "message": "component.error",
818
+ "properties": {
819
+ "foo": "bar"
820
+ }
821
+ }
822
+ }
823
+ }
824
+ }
825
+ }
826
+ },
827
+ "401": {
828
+ "description": "You are not authorized to use the API or no credentials were supplied, see the content for more details.",
829
+ "content": {
830
+ "application/json": {
831
+ "schema": {
832
+ "$ref": "#/components/schemas/Error"
833
+ },
834
+ "examples": {
835
+ "exampleResponse": {
836
+ "value": {
837
+ "name": "UnauthorizedError",
838
+ "message": "component.error"
839
+ }
840
+ }
841
+ }
842
+ }
843
+ }
844
+ },
845
+ "404": {
846
+ "description": "The resource you tried to access does not exist, see the content for more details.",
847
+ "content": {
848
+ "application/json": {
849
+ "schema": {
850
+ "$ref": "#/components/schemas/NotFoundResponse"
851
+ },
852
+ "examples": {
853
+ "exampleResponse": {
854
+ "value": {
855
+ "name": "NotFoundError",
856
+ "message": "component.error",
857
+ "properties": {
858
+ "notFoundId": "1"
859
+ }
860
+ }
861
+ }
862
+ }
863
+ }
864
+ }
865
+ },
866
+ "500": {
867
+ "description": "The server has encountered a situation it does not know how to handle, see the content for more details.",
868
+ "content": {
869
+ "application/json": {
870
+ "schema": {
871
+ "$ref": "#/components/schemas/Error"
872
+ },
873
+ "examples": {
874
+ "exampleResponse": {
875
+ "value": {
876
+ "name": "InternalServerError",
877
+ "message": "component.error"
878
+ }
879
+ }
880
+ }
881
+ }
882
+ }
883
+ }
884
+ }
885
+ },
683
886
  "delete": {
684
887
  "operationId": "DocumentManagementRemove",
685
888
  "summary": "Remove an document from an auditable item graph vertex",
@@ -1467,6 +1670,9 @@
1467
1670
  "blobStorageEntry": {
1468
1671
  "$ref": "#/components/schemas/BlobStorageEntry"
1469
1672
  },
1673
+ "extractedData": {
1674
+ "description": "The data extracted from the document using data extraction services."
1675
+ },
1470
1676
  "attestationId": {
1471
1677
  "type": "string",
1472
1678
  "description": "The attestation for the document if one was created."
@@ -240,6 +240,18 @@ Flag to include the attestation information for the document, defaults to false.
240
240
 
241
241
  Flag to include deleted documents, defaults to false.
242
242
 
243
+ ###### extractRuleGroupId?
244
+
245
+ `string`
246
+
247
+ If provided will extract data from the document using the specified rule group id.
248
+
249
+ ###### extractMimeType?
250
+
251
+ `string`
252
+
253
+ By default extraction will auto detect the mime type of the document, this can be used to override the detection.
254
+
243
255
  ##### cursor?
244
256
 
245
257
  `string`
@@ -276,6 +288,84 @@ The documents and revisions if requested, ordered by revision descending, cursor
276
288
 
277
289
  ***
278
290
 
291
+ ### getRevision()
292
+
293
+ > **getRevision**(`auditableItemGraphDocumentId`, `revision`, `options?`, `userIdentity?`, `nodeIdentity?`): `Promise`\<`IDocument`\>
294
+
295
+ Get a document revision using it's auditable item graph vertex id.
296
+
297
+ #### Parameters
298
+
299
+ ##### auditableItemGraphDocumentId
300
+
301
+ `string`
302
+
303
+ The auditable item graph vertex id which contains the document.
304
+
305
+ ##### revision
306
+
307
+ `number`
308
+
309
+ The revision id for the document.
310
+
311
+ ##### options?
312
+
313
+ Additional options for the get operation.
314
+
315
+ ###### includeBlobStorageMetadata?
316
+
317
+ `boolean`
318
+
319
+ Flag to include the blob storage metadata for the document, defaults to false.
320
+
321
+ ###### includeBlobStorageData?
322
+
323
+ `boolean`
324
+
325
+ Flag to include the blob storage data for the document, defaults to false.
326
+
327
+ ###### includeAttestation?
328
+
329
+ `boolean`
330
+
331
+ Flag to include the attestation information for the document, defaults to false.
332
+
333
+ ###### extractRuleGroupId?
334
+
335
+ `string`
336
+
337
+ If provided will extract data from the document using the specified rule group id.
338
+
339
+ ###### extractMimeType?
340
+
341
+ `string`
342
+
343
+ By default extraction will auto detect the mime type of the document, this can be used to override the detection.
344
+
345
+ ##### userIdentity?
346
+
347
+ `string`
348
+
349
+ The identity to perform the auditable item graph operation with.
350
+
351
+ ##### nodeIdentity?
352
+
353
+ `string`
354
+
355
+ The node identity to use for vault operations.
356
+
357
+ #### Returns
358
+
359
+ `Promise`\<`IDocument`\>
360
+
361
+ The documents and revisions if requested, ordered by revision descending, cursor is set if there are more document revisions.
362
+
363
+ #### Implementation of
364
+
365
+ `IDocumentManagementComponent.getRevision`
366
+
367
+ ***
368
+
279
369
  ### removeRevision()
280
370
 
281
371
  > **removeRevision**(`auditableItemGraphDocumentId`, `revision`, `userIdentity?`, `nodeIdentity?`): `Promise`\<`void`\>
@@ -0,0 +1,31 @@
1
+ # Function: documentManagementGetRevision()
2
+
3
+ > **documentManagementGetRevision**(`httpRequestContext`, `componentName`, `request`): `Promise`\<`IDocumentManagementGetRevisionResponse`\>
4
+
5
+ Get the document revision from the auditable item graph vertex.
6
+
7
+ ## Parameters
8
+
9
+ ### httpRequestContext
10
+
11
+ `IHttpRequestContext`
12
+
13
+ The request context for the API.
14
+
15
+ ### componentName
16
+
17
+ `string`
18
+
19
+ The name of the component to use in the routes.
20
+
21
+ ### request
22
+
23
+ `IDocumentManagementGetRevisionRequest`
24
+
25
+ The request.
26
+
27
+ ## Returns
28
+
29
+ `Promise`\<`IDocumentManagementGetRevisionResponse`\>
30
+
31
+ The response object with additional http response properties.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **documentManagementUpdate**(`httpRequestContext`, `componentName`, `request`): `Promise`\<`INoContentResponse`\>
4
4
 
5
- UPdate the document from the auditable item graph vertex.
5
+ Update the document from the auditable item graph vertex.
6
6
 
7
7
  ## Parameters
8
8
 
@@ -19,6 +19,7 @@
19
19
  - [generateRestRoutesDocumentManagement](functions/generateRestRoutesDocumentManagement.md)
20
20
  - [documentManagementCreate](functions/documentManagementCreate.md)
21
21
  - [documentManagementGet](functions/documentManagementGet.md)
22
+ - [documentManagementGetRevision](functions/documentManagementGetRevision.md)
22
23
  - [documentManagementUpdate](functions/documentManagementUpdate.md)
23
24
  - [documentManagementRemove](functions/documentManagementRemove.md)
24
25
  - [documentManagementQuery](functions/documentManagementQuery.md)
@@ -46,6 +46,20 @@ attestation
46
46
 
47
47
  ***
48
48
 
49
+ ### dataProcessingComponentType?
50
+
51
+ > `optional` **dataProcessingComponentType**: `string`
52
+
53
+ The type of the data processing component.
54
+
55
+ #### Default
56
+
57
+ ```ts
58
+ data-processing
59
+ ```
60
+
61
+ ***
62
+
49
63
  ### config?
50
64
 
51
65
  > `optional` **config**: [`IDocumentManagementServiceConfig`](IDocumentManagementServiceConfig.md)
package/locales/en.json CHANGED
@@ -4,10 +4,11 @@
4
4
  "createFailed": "Failed to create document",
5
5
  "updateFailed": "Failed to update document",
6
6
  "getFailed": "Failed to get document",
7
+ "getRevisionFailed": "Failed to get document revision",
7
8
  "removeRevision": "Failed to remove document revision",
8
9
  "queryFailed": "Failed to query document",
9
10
  "documentRevisionNone": "There are no revisions in the document",
10
- "documentRevisionNotFound": "There is no revision number \"{revision}\" in the document",
11
+ "documentRevisionNotFound": "There is no revision number \"{notFoundId}\" in the document",
11
12
  "namespaceMismatch": "The namespace in the urn \"{id}\" does not match the namespace of the Document Management component \"{namespace}\""
12
13
  }
13
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/document-management-service",
3
- "version": "0.0.1-next.10",
3
+ "version": "0.0.1-next.12",
4
4
  "description": "Document management contract implementation and REST endpoint definitions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,8 @@
21
21
  "@twin.org/core": "next",
22
22
  "@twin.org/crypto": "next",
23
23
  "@twin.org/data-json-ld": "next",
24
- "@twin.org/document-management-models": "0.0.1-next.10",
24
+ "@twin.org/data-processing-models": "next",
25
+ "@twin.org/document-management-models": "0.0.1-next.12",
25
26
  "@twin.org/entity": "next",
26
27
  "@twin.org/entity-storage-models": "next",
27
28
  "@twin.org/nameof": "next",