From d4a55eed04b75b6a2bce1579cc82c61e26edea54 Mon Sep 17 00:00:00 2001 From: lmd59 Date: Thu, 13 Jun 2024 14:19:20 -0400 Subject: [PATCH] bundle transaction checks and capability statement --- .../config/capabilityStatementResources.json | 20 +++++++++++++ service/src/services/BaseService.ts | 30 ++++++++----------- service/src/services/LibraryService.ts | 2 +- service/src/services/MeasureService.ts | 2 +- service/test/services/BaseService.test.ts | 7 +++-- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/service/src/config/capabilityStatementResources.json b/service/src/config/capabilityStatementResources.json index 06c22415..e51f1f0e 100644 --- a/service/src/config/capabilityStatementResources.json +++ b/service/src/config/capabilityStatementResources.json @@ -51,6 +51,16 @@ ], "code": "update", "documentation": "Update allows authoring workflows to update existing libraries in _draft_ (**revise**) status, add comments to existing libraries (**review** and **approve**), and **release** or **retire** a library." + }, + { + "extension" : [ + { + "url" : "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation", + "valueCode" : "SHALL" + } + ], + "code" : "delete", + "documentation" : "Delete allows authoring workflows to **withdraw** _draft_ libraries or **archive** _retired_ libraries." } ], "searchParam": [ @@ -207,6 +217,16 @@ ], "code": "update", "documentation": "Update allows authoring workflows to update existing measures in _draft_ (**revise**) status, add comments to existing measures (**review** and **approve**), and **release** or **retire** a measure." + }, + { + "extension" : [ + { + "url" : "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation", + "valueCode" : "SHALL" + } + ], + "code" : "delete", + "documentation" : "Delete allows authoring workflows to **withdraw** _draft_ measures or **archive** _retired_ measures." } ], "searchParam": [ diff --git a/service/src/services/BaseService.ts b/service/src/services/BaseService.ts index 388a8db4..687ef51d 100644 --- a/service/src/services/BaseService.ts +++ b/service/src/services/BaseService.ts @@ -1,8 +1,8 @@ import { loggers, constants, resolveSchema } from '@projecttacoma/node-fhir-server-core'; import { BadRequestError } from '../util/errorUtils'; -import { checkContentTypeHeader } from '../util/inputUtils'; +import { checkContentTypeHeader, checkFieldsForCreate, checkFieldsForUpdate } from '../util/inputUtils'; import { v4 as uuidv4 } from 'uuid'; -import { createResource, updateResource } from '../db/dbOperations'; +import { createResource, findResourceById, updateResource } from '../db/dbOperations'; import path from 'path'; import { DetailedEntry, addIsOwnedExtension, addLibraryIsOwned, replaceReferences } from '../util/baseUtils'; @@ -73,23 +73,10 @@ async function uploadResourcesFromBundle(entries: DetailedEntry[]) { * Inserts Library or Measure resources from Bundle into the database through create or update. */ async function insertBundleResources(entry: DetailedEntry) { + // TODO: make updates here for AUHTHORING/PUBLISHABLE if (entry.resource?.resourceType === 'Library' || entry.resource?.resourceType === 'Measure') { - if (entry.resource.status != 'active') { - entry.resource.status = 'active'; - entry.outcome = { - resourceType: 'OperationOutcome', - issue: [ - { - severity: 'warning', - code: 'value', // code from: https://build.fhir.org/valueset-issue-type.html - details: { text: 'Artifact status has been coerced to active to meet server specifications' }, - expression: [`${entry.resource.resourceType}.status`] - } - ] - }; - } - if (entry.isPost) { + checkFieldsForCreate(entry.resource); entry.resource.id = uuidv4(); const { id } = await createResource(entry.resource, entry.resource.resourceType); if (id != null) { @@ -98,6 +85,15 @@ async function insertBundleResources(entry: DetailedEntry) { } } else { if (entry.resource.id) { + const oldResource = (await findResourceById( + entry.resource.id, + entry.resource.resourceType + )) as fhir4.Library | null; + if (oldResource) { + checkFieldsForUpdate(entry.resource, oldResource); + } else { + checkFieldsForCreate(entry.resource); + } const { id, created } = await updateResource(entry.resource.id, entry.resource, entry.resource.resourceType); if (created === true) { entry.status = 201; diff --git a/service/src/services/LibraryService.ts b/service/src/services/LibraryService.ts index 27f2dabc..3fce6b25 100644 --- a/service/src/services/LibraryService.ts +++ b/service/src/services/LibraryService.ts @@ -133,7 +133,7 @@ export class LibraryService implements Service { * result of sending a DELETE request to {BASE_URL}/4_0_1/Library/{id} * deletes the library with the passed in id if it exists in the database */ - async remove(args: RequestArgs, { req }: RequestCtx) { + async remove(args: RequestArgs) { const resource = (await findResourceById(args.id, 'Library')) as fhir4.Library | null; if (!resource) { throw new ResourceNotFoundError(`Existing resource not found with id ${args.id}`); diff --git a/service/src/services/MeasureService.ts b/service/src/services/MeasureService.ts index 570f85e0..0432e438 100644 --- a/service/src/services/MeasureService.ts +++ b/service/src/services/MeasureService.ts @@ -136,7 +136,7 @@ export class MeasureService implements Service { * result of sending a DELETE request to {BASE_URL}/4_0_1/Library/{id} * deletes the library with the passed in id if it exists in the database */ - async remove(args: RequestArgs, { req }: RequestCtx) { + async remove(args: RequestArgs) { const resource = (await findResourceById(args.id, 'Measure')) as fhir4.Measure | null; if (!resource) { throw new ResourceNotFoundError(`Existing resource not found with id ${args.id}`); diff --git a/service/test/services/BaseService.test.ts b/service/test/services/BaseService.test.ts index 3975b4a6..afefb7fb 100644 --- a/service/test/services/BaseService.test.ts +++ b/service/test/services/BaseService.test.ts @@ -96,7 +96,8 @@ const VALID_PUT_REQ = { resource: { resourceType: 'Measure', id: 'test-measure', - library: ['Library/test-library'] + library: ['Library/test-library'], + status: 'draft' }, request: { method: 'PUT', @@ -113,7 +114,8 @@ const VALID_POST_REQ = { { resource: { resourceType: 'Library', - id: 'test-library' + id: 'test-library', + status: 'draft' }, request: { method: 'POST', @@ -126,6 +128,7 @@ const VALID_POST_REQ = { describe('BaseService', () => { beforeAll(async () => { server = initialize(serverConfig, app); + process.env.AUTHORING = 'true'; return setupTestDatabase([]); });