From 39a0f53142e268c04e06bb53989c21e0aae77cf1 Mon Sep 17 00:00:00 2001 From: naftis Date: Thu, 26 Sep 2024 21:37:40 +0300 Subject: [PATCH 01/22] feat: allow confirming and rejecting record externally --- docker-compose.dev.yml | 1 - .../src/declarations/submissionMiddleware.ts | 2 +- .../features/registration/root-resolvers.ts | 15 +++++ .../src/features/registration/schema.graphql | 22 +++++++ packages/gateway/src/graphql/schema.d.ts | 57 +++++++++++++++++++ packages/gateway/src/graphql/schema.graphql | 23 ++++++++ packages/gateway/src/workflow/index.ts | 38 ++++++++++++- packages/workflow/src/config/routes.ts | 9 ++- .../src/features/registration/handler.ts | 41 +------------ .../workflow/src/records/handler/confirm.ts | 53 +++++++++++++++++ 10 files changed, 214 insertions(+), 47 deletions(-) create mode 100644 packages/workflow/src/records/handler/confirm.ts diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index ec732943e5..468ccd92f6 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -78,7 +78,6 @@ services: - NODE_ENV=development - FHIR_URL=http://hearth:3447/fhir - AUTH_URL=http://auth:4040 - - CONFIRM_REGISTRATION_URL=http://workflow:5050/confirm/registration - CHECK_INVALID_TOKEN=true ports: - '3040:3040' diff --git a/packages/client/src/declarations/submissionMiddleware.ts b/packages/client/src/declarations/submissionMiddleware.ts index efc7b36130..7c1fd09b0f 100644 --- a/packages/client/src/declarations/submissionMiddleware.ts +++ b/packages/client/src/declarations/submissionMiddleware.ts @@ -43,12 +43,12 @@ import { NOT_A_DUPLICATE } from '@client/views/DataProvider/mutation' import { updateRegistrarWorkqueue } from '@client/workqueue' import { Action, Middleware, createAction } from '@reduxjs/toolkit' import { Dispatch } from 'redux' -// eslint-disable-next-line no-restricted-imports import { getReviewForm } from '@client/forms/register/review-selectors' import { IOfflineData } from '@client/offline/reducer' import { getOfflineData } from '@client/offline/selectors' import type { MutationToRequestRegistrationCorrectionArgs } from '@client/utils/gateway-deprecated-do-not-use' import { UserDetails } from '@client/utils/userUtils' +// eslint-disable-next-line no-restricted-imports import { captureException } from '@sentry/browser' import { submitAndWaitUntilRecordInWorkqueue } from './createRecord' diff --git a/packages/gateway/src/features/registration/root-resolvers.ts b/packages/gateway/src/features/registration/root-resolvers.ts index 68c4994221..5d5b134b9c 100644 --- a/packages/gateway/src/features/registration/root-resolvers.ts +++ b/packages/gateway/src/features/registration/root-resolvers.ts @@ -31,6 +31,7 @@ import { import { archiveRegistration, certifyRegistration, + confirmRegistration, createRegistration, duplicateRegistration, fetchRegistrationForDownloading, @@ -634,6 +635,20 @@ export const resolvers: GQLResolver = { ) return taskEntry.resource.id + }, + async confirmRegistration(_, { id, details }, { headers: authHeader }) { + if (!inScope(authHeader, ['register', 'validate'])) { + throw new Error('User does not have a register or validate scope') + } + + return confirmRegistration(id, authHeader, details as any) // Type 'string' is not assignable to type '"PASSPORT" | "NATIONAL_ID" | "MOSIP_PSUT_TOKEN_ID" | "DECEASED_PATIENT_ENTRY" | "BIRTH_PA... + }, + async rejectRegistration(_, { id, details }, { headers: authHeader }) { + if (!inScope(authHeader, ['register', 'validate'])) { + throw new Error('User does not have a register or validate scope') + } + + return rejectDeclaration(id, authHeader, details.comment, details.reason) } } } diff --git a/packages/gateway/src/features/registration/schema.graphql b/packages/gateway/src/features/registration/schema.graphql index 75a3374d29..8d89c17ded 100644 --- a/packages/gateway/src/features/registration/schema.graphql +++ b/packages/gateway/src/features/registration/schema.graphql @@ -563,6 +563,26 @@ input CorrectionRejectionInput { timeLoggedMS: Int! } +input IdentifierInput { + type: String! + value: String! +} +input ConfirmRegistrationInput { + childIdentifiers: [IdentifierInput!] + registrationNumber: String + trackingId: String +} + +enum RejectionReason { + other + duplicate +} + +input RejectRegistrationInput { + reason: RejectionReason! + comment: String! +} + type Mutation { # Generic correction handlers for all event types # Applying a correction request is made on a event level as payload is dependant on event type @@ -639,4 +659,6 @@ type Mutation { comment: String duplicateTrackingId: String ): ID! + confirmRegistration(id: ID!, details: ConfirmRegistrationInput!): ID! + rejectRegistration(id: ID!, details: RejectRegistrationInput!): ID! } diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index dfa91b6f87..0e03e2948d 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -87,6 +87,8 @@ export interface GQLMutation { markMarriageAsCertified: string markMarriageAsIssued: string markEventAsDuplicate: string + confirmRegistration: string + rejectRegistration: string createOrUpdateUser: GQLUser activateUser?: string changePassword?: string @@ -613,6 +615,17 @@ export interface GQLReinstated { registrationStatus?: GQLRegStatus } +export interface GQLConfirmRegistrationInput { + childIdentifiers?: Array + registrationNumber?: string + trackingId?: string +} + +export interface GQLRejectRegistrationInput { + reason: GQLRejectionReason + comment: string +} + export interface GQLUserInput { id?: string name: Array @@ -1221,6 +1234,16 @@ export const enum GQLRegStatus { ISSUED = 'ISSUED' } +export interface GQLIdentifierInput { + type: string + value: string +} + +export const enum GQLRejectionReason { + other = 'other', + duplicate = 'duplicate' +} + export interface GQLHumanNameInput { use?: string firstNames?: string @@ -2551,6 +2574,8 @@ export interface GQLMutationTypeResolver { markMarriageAsCertified?: MutationToMarkMarriageAsCertifiedResolver markMarriageAsIssued?: MutationToMarkMarriageAsIssuedResolver markEventAsDuplicate?: MutationToMarkEventAsDuplicateResolver + confirmRegistration?: MutationToConfirmRegistrationResolver + rejectRegistration?: MutationToRejectRegistrationResolver createOrUpdateUser?: MutationToCreateOrUpdateUserResolver activateUser?: MutationToActivateUserResolver changePassword?: MutationToChangePasswordResolver @@ -3083,6 +3108,38 @@ export interface MutationToMarkEventAsDuplicateResolver< ): TResult } +export interface MutationToConfirmRegistrationArgs { + id: string + details: GQLConfirmRegistrationInput +} +export interface MutationToConfirmRegistrationResolver< + TParent = any, + TResult = any +> { + ( + parent: TParent, + args: MutationToConfirmRegistrationArgs, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + +export interface MutationToRejectRegistrationArgs { + id: string + details: GQLRejectRegistrationInput +} +export interface MutationToRejectRegistrationResolver< + TParent = any, + TResult = any +> { + ( + parent: TParent, + args: MutationToRejectRegistrationArgs, + context: Context, + info: GraphQLResolveInfo + ): TResult +} + export interface MutationToCreateOrUpdateUserArgs { user: GQLUserInput } diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index e753e1e4f6..fbe9cf600e 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -223,6 +223,8 @@ type Mutation { comment: String duplicateTrackingId: String ): ID! + confirmRegistration(id: ID!, details: ConfirmRegistrationInput!): ID! + rejectRegistration(id: ID!, details: RejectRegistrationInput!): ID! createOrUpdateUser(user: UserInput!): User! activateUser( userId: String! @@ -728,6 +730,17 @@ type Reinstated { registrationStatus: RegStatus } +input ConfirmRegistrationInput { + childIdentifiers: [IdentifierInput!] + registrationNumber: String + trackingId: String +} + +input RejectRegistrationInput { + reason: RejectionReason! + comment: String! +} + input UserInput { id: ID name: [HumanNameInput!]! @@ -1312,6 +1325,16 @@ enum RegStatus { ISSUED } +input IdentifierInput { + type: String! + value: String! +} + +enum RejectionReason { + other + duplicate +} + input HumanNameInput { use: String firstNames: String diff --git a/packages/gateway/src/workflow/index.ts b/packages/gateway/src/workflow/index.ts index ba67e39d16..dd2f9ccc80 100644 --- a/packages/gateway/src/workflow/index.ts +++ b/packages/gateway/src/workflow/index.ts @@ -37,11 +37,12 @@ import { RejectedRecord, Resource, SavedBundle, + SupportedPatientIdentifierCode, ValidRecord } from '@opencrvs/commons/types' const createRequest = async ( - method: 'POST' | 'GET' | 'PUT' | 'DELETE', + method: 'POST' | 'GET' | 'PUT' | 'PATCH' | 'DELETE', path: string, authHeader: IAuthHeader, body?: Record @@ -393,3 +394,38 @@ export async function createHospitalNotification( bundle ) } + +type ConfirmRegistrationDetails = { + childIdentifiers?: { + type: SupportedPatientIdentifierCode + value: string + }[] +} +export async function confirmRegistration( + id: string, + authHeader: IAuthHeader, + details: ConfirmRegistrationDetails +) { + return createRequest( + 'POST', + `/records/${id}/confirm`, + authHeader, + details + ) +} + +type RejectRegistrationDetails = { + error: string +} +export async function rejectRegistration( + id: string, + authHeader: IAuthHeader, + details: RejectRegistrationDetails +) { + return createRequest( + 'POST', + `/records/${id}/reject`, + authHeader, + details + ) +} diff --git a/packages/workflow/src/config/routes.ts b/packages/workflow/src/config/routes.ts index 3f2eb8c98a..cbddd69d99 100644 --- a/packages/workflow/src/config/routes.ts +++ b/packages/workflow/src/config/routes.ts @@ -8,9 +8,9 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { markEventAsRegisteredCallbackHandler } from '@workflow/features/registration/handler' import { archiveRoute } from '@workflow/records/handler/archive' import { certifyRoute } from '@workflow/records/handler/certify' +import { confirmRegistrationHandler } from '@workflow/records/handler/confirm' import { approveCorrectionRoute } from '@workflow/records/handler/correction/approve' import { makeCorrectionRoute } from '@workflow/records/handler/correction/make-correction' import { rejectCorrectionRoute } from '@workflow/records/handler/correction/reject' @@ -60,12 +60,11 @@ export const getRoutes = () => { }, { method: 'POST', - path: '/confirm/registration', - handler: markEventAsRegisteredCallbackHandler, + path: '/records/{id}/confirm', + handler: confirmRegistrationHandler, config: { tags: ['api'], - description: - 'Register event based on tracking id and registration number.' + description: 'Confirm registration after external validation' } }, { diff --git a/packages/workflow/src/features/registration/handler.ts b/packages/workflow/src/features/registration/handler.ts index df3bedefa5..4a45c2c6a3 100644 --- a/packages/workflow/src/features/registration/handler.ts +++ b/packages/workflow/src/features/registration/handler.ts @@ -8,17 +8,9 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import * as Hapi from '@hapi/hapi' import { toTokenWithBearer } from '@opencrvs/commons' -import { - RecordValidatedPayload, - useExternalValidationQueue -} from '@opencrvs/commons/message-queue' -import { - isWaitingExternalValidation, - SupportedPatientIdentifierCode -} from '@opencrvs/commons/types' -import { REDIS_HOST } from '@workflow/constants' +import { RecordValidatedPayload } from '@opencrvs/commons/message-queue' +import { isWaitingExternalValidation } from '@opencrvs/commons/types' import { writeMetricsEvent } from '@workflow/records/audit' import { getRecordById } from '@workflow/records/index' import { @@ -28,7 +20,6 @@ import { import { indexBundleWithTransaction } from '@workflow/records/search' import { toRegistered } from '@workflow/records/state-transitions' import { invokeWebhooks } from '@workflow/records/webhooks' -import { getToken } from '@workflow/utils/auth-utils' import { getEventType } from './utils' export async function markEventAsRegistered({ @@ -73,31 +64,3 @@ export async function markEventAsRegistered({ return } - -const { recordValidated } = useExternalValidationQueue(REDIS_HOST) - -type RecordValidatedHTTPPayload = { - registrationNumber: string - childIdentifiers: { type: SupportedPatientIdentifierCode; value: string }[] - compositionId: string - trackingId: string -} - -export async function markEventAsRegisteredCallbackHandler( - request: Hapi.Request, - h: Hapi.ResponseToolkit -) { - const token = getToken(request) - const { registrationNumber, childIdentifiers, compositionId, trackingId } = - request.payload as RecordValidatedHTTPPayload - - await recordValidated({ - recordId: compositionId, - identifiers: childIdentifiers || [], - registrationNumber, - trackingId, - token - }) - - return h.response().code(200) -} diff --git a/packages/workflow/src/records/handler/confirm.ts b/packages/workflow/src/records/handler/confirm.ts new file mode 100644 index 0000000000..477a7968a8 --- /dev/null +++ b/packages/workflow/src/records/handler/confirm.ts @@ -0,0 +1,53 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * OpenCRVS is also distributed under the terms of the Civil Registration + * & Healthcare Disclaimer located at http://opencrvs.org/license. + * + * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. + */ +import * as z from 'zod' +import { getToken } from '@workflow/utils/auth-utils' +import { validateRequest } from '@workflow/utils/index' +import { useExternalValidationQueue } from '@opencrvs/commons/message-queue' +import { REDIS_HOST } from '@workflow/constants' +import { SUPPORTED_PATIENT_IDENTIFIER_CODES } from '@opencrvs/commons/types' +import * as Hapi from '@hapi/hapi' + +const requestSchema = z.object({ + registrationNumber: z.string(), + childIdentifiers: z + .array( + z.object({ + type: z.enum(SUPPORTED_PATIENT_IDENTIFIER_CODES), + value: z.string() + }) + ) + .optional(), + trackingId: z.string() +}) + +const { recordValidated } = useExternalValidationQueue(REDIS_HOST) + +export async function confirmRegistrationHandler( + request: Hapi.Request, + h: Hapi.ResponseToolkit +) { + const token = getToken(request) + const payload = validateRequest(requestSchema, request.payload) + const recordId = request.params.id + + const { registrationNumber, childIdentifiers, trackingId } = payload + + await recordValidated({ + recordId, + identifiers: childIdentifiers || [], + registrationNumber, + trackingId, + token + }) + + return h.response().code(202) +} From 420ec4df5bc5491313bed8beb51501e5e202c091 Mon Sep 17 00:00:00 2001 From: naftis Date: Thu, 26 Sep 2024 21:41:59 +0300 Subject: [PATCH 02/22] revert: no 'patch' needed after all it would be the correct REST action for the state changes: chose convention for now --- packages/gateway/src/workflow/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gateway/src/workflow/index.ts b/packages/gateway/src/workflow/index.ts index dd2f9ccc80..8e330b7b07 100644 --- a/packages/gateway/src/workflow/index.ts +++ b/packages/gateway/src/workflow/index.ts @@ -42,7 +42,7 @@ import { } from '@opencrvs/commons/types' const createRequest = async ( - method: 'POST' | 'GET' | 'PUT' | 'PATCH' | 'DELETE', + method: 'POST' | 'GET' | 'PUT' | 'DELETE', path: string, authHeader: IAuthHeader, body?: Record From 39b857b128ed4d1cdb6aaef6954e0d612de68ece Mon Sep 17 00:00:00 2001 From: naftis Date: Mon, 30 Sep 2024 12:26:11 +0300 Subject: [PATCH 03/22] fix: remove dummy definitions --- packages/gateway/src/graphql/index.graphql | 7 ------- packages/gateway/src/graphql/schema.d.ts | 18 ------------------ packages/gateway/src/graphql/schema.graphql | 4 ---- 3 files changed, 29 deletions(-) diff --git a/packages/gateway/src/graphql/index.graphql b/packages/gateway/src/graphql/index.graphql index ab8ca23a04..f03c833a68 100644 --- a/packages/gateway/src/graphql/index.graphql +++ b/packages/gateway/src/graphql/index.graphql @@ -21,10 +21,3 @@ # import Mutation from '../features/bookmarkAdvancedSearch/schema.graphql' # import Query.* from '../features/OIDPUserInfo/schema.graphql' # import * from 'common.graphql' - -# TODO -# https://github.com/prismagraphql/graphql-import/issues/180 -# https://github.com/prismagraphql/graphql-import/issues/45 -type Dummy { - dummy: String! -} diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index 0e03e2948d..a8536ab104 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -110,10 +110,6 @@ export interface GQLMutation { removeBookmarkedAdvancedSearch?: GQLBookMarkedSearches } -export interface GQLDummy { - dummy: string -} - export interface GQLNotificationResult { success: boolean } @@ -1752,7 +1748,6 @@ export interface GQLPaymentInput { export interface GQLResolver { Query?: GQLQueryTypeResolver Mutation?: GQLMutationTypeResolver - Dummy?: GQLDummyTypeResolver NotificationResult?: GQLNotificationResultTypeResolver BirthRegistration?: GQLBirthRegistrationTypeResolver Date?: GraphQLScalarType @@ -3415,19 +3410,6 @@ export interface MutationToRemoveBookmarkedAdvancedSearchResolver< ): TResult } -export interface GQLDummyTypeResolver { - dummy?: DummyToDummyResolver -} - -export interface DummyToDummyResolver { - ( - parent: TParent, - args: {}, - context: Context, - info: GraphQLResolveInfo - ): TResult -} - export interface GQLNotificationResultTypeResolver { success?: NotificationResultToSuccessResolver } diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index fbe9cf600e..64eab3274b 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -273,10 +273,6 @@ type Mutation { ): BookMarkedSearches } -type Dummy { - dummy: String! -} - type NotificationResult { success: Boolean! } From d9a9646bac5f7c55ce18dc161849f04565dcd500 Mon Sep 17 00:00:00 2001 From: naftis Date: Mon, 30 Sep 2024 14:33:29 +0300 Subject: [PATCH 04/22] refactor: improve typing on graphql gateway supported patient identifiers --- packages/commons/src/fhir/patient.ts | 4 ++++ .../features/registration/root-resolvers.ts | 2 +- .../src/features/registration/schema.graphql | 22 ++++++++++++++++++- packages/gateway/src/graphql/schema.d.ts | 21 +++++++++++++++++- packages/gateway/src/graphql/schema.graphql | 21 +++++++++++++++++- 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/packages/commons/src/fhir/patient.ts b/packages/commons/src/fhir/patient.ts index bddb6294ce..6d64867937 100644 --- a/packages/commons/src/fhir/patient.ts +++ b/packages/commons/src/fhir/patient.ts @@ -43,6 +43,10 @@ export type OpenCRVSPatientName = Omit & { use: string } +/** + * If you change this, also change packages/gateway/src/features/registration/schema.graphql SupportedPatientIdentifierCode + */ + export const SUPPORTED_PATIENT_IDENTIFIER_CODES = [ 'PASSPORT', 'NATIONAL_ID', diff --git a/packages/gateway/src/features/registration/root-resolvers.ts b/packages/gateway/src/features/registration/root-resolvers.ts index 5d5b134b9c..1904b66e2d 100644 --- a/packages/gateway/src/features/registration/root-resolvers.ts +++ b/packages/gateway/src/features/registration/root-resolvers.ts @@ -641,7 +641,7 @@ export const resolvers: GQLResolver = { throw new Error('User does not have a register or validate scope') } - return confirmRegistration(id, authHeader, details as any) // Type 'string' is not assignable to type '"PASSPORT" | "NATIONAL_ID" | "MOSIP_PSUT_TOKEN_ID" | "DECEASED_PATIENT_ENTRY" | "BIRTH_PA... + return confirmRegistration(id, authHeader, details) }, async rejectRegistration(_, { id, details }, { headers: authHeader }) { if (!inScope(authHeader, ['register', 'validate'])) { diff --git a/packages/gateway/src/features/registration/schema.graphql b/packages/gateway/src/features/registration/schema.graphql index 8d89c17ded..afdd6585db 100644 --- a/packages/gateway/src/features/registration/schema.graphql +++ b/packages/gateway/src/features/registration/schema.graphql @@ -563,8 +563,28 @@ input CorrectionRejectionInput { timeLoggedMS: Int! } +# if you change this, also change packages/commons/src/fhir/patient.ts SUPPORTED_PATIENT_IDENTIFIER_CODES +enum SupportedPatientIdentifierCode { + PASSPORT + NATIONAL_ID + MOSIP_PSUT_TOKEN_ID + DECEASED_PATIENT_ENTRY + BIRTH_PATIENT_ENTRY + DRIVING_LICENSE + REFUGEE_NUMBER + ALIEN_NUMBER + OTHER + SOCIAL_SECURITY_NO + BIRTH_REGISTRATION_NUMBER + DEATH_REGISTRATION_NUMBER + MARRIAGE_REGISTRATION_NUMBER + BIRTH_CONFIGURABLE_IDENTIFIER_1 + BIRTH_CONFIGURABLE_IDENTIFIER_2 + BIRTH_CONFIGURABLE_IDENTIFIER_3 +} + input IdentifierInput { - type: String! + type: SupportedPatientIdentifierCode! value: String! } input ConfirmRegistrationInput { diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index a8536ab104..c2be74a8d6 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -1231,7 +1231,7 @@ export const enum GQLRegStatus { } export interface GQLIdentifierInput { - type: string + type: GQLSupportedPatientIdentifierCode value: string } @@ -1658,6 +1658,25 @@ export interface GQLDeceasedInput { deathDate?: GQLPlainDate } +export const enum GQLSupportedPatientIdentifierCode { + PASSPORT = 'PASSPORT', + NATIONAL_ID = 'NATIONAL_ID', + MOSIP_PSUT_TOKEN_ID = 'MOSIP_PSUT_TOKEN_ID', + DECEASED_PATIENT_ENTRY = 'DECEASED_PATIENT_ENTRY', + BIRTH_PATIENT_ENTRY = 'BIRTH_PATIENT_ENTRY', + DRIVING_LICENSE = 'DRIVING_LICENSE', + REFUGEE_NUMBER = 'REFUGEE_NUMBER', + ALIEN_NUMBER = 'ALIEN_NUMBER', + OTHER = 'OTHER', + SOCIAL_SECURITY_NO = 'SOCIAL_SECURITY_NO', + BIRTH_REGISTRATION_NUMBER = 'BIRTH_REGISTRATION_NUMBER', + DEATH_REGISTRATION_NUMBER = 'DEATH_REGISTRATION_NUMBER', + MARRIAGE_REGISTRATION_NUMBER = 'MARRIAGE_REGISTRATION_NUMBER', + BIRTH_CONFIGURABLE_IDENTIFIER_1 = 'BIRTH_CONFIGURABLE_IDENTIFIER_1', + BIRTH_CONFIGURABLE_IDENTIFIER_2 = 'BIRTH_CONFIGURABLE_IDENTIFIER_2', + BIRTH_CONFIGURABLE_IDENTIFIER_3 = 'BIRTH_CONFIGURABLE_IDENTIFIER_3' +} + export interface GQLLabelInput { lang: string label: string diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index 64eab3274b..831a6b71ff 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -1322,7 +1322,7 @@ enum RegStatus { } input IdentifierInput { - type: String! + type: SupportedPatientIdentifierCode! value: String! } @@ -1748,6 +1748,25 @@ input DeceasedInput { deathDate: PlainDate } +enum SupportedPatientIdentifierCode { + PASSPORT + NATIONAL_ID + MOSIP_PSUT_TOKEN_ID + DECEASED_PATIENT_ENTRY + BIRTH_PATIENT_ENTRY + DRIVING_LICENSE + REFUGEE_NUMBER + ALIEN_NUMBER + OTHER + SOCIAL_SECURITY_NO + BIRTH_REGISTRATION_NUMBER + DEATH_REGISTRATION_NUMBER + MARRIAGE_REGISTRATION_NUMBER + BIRTH_CONFIGURABLE_IDENTIFIER_1 + BIRTH_CONFIGURABLE_IDENTIFIER_2 + BIRTH_CONFIGURABLE_IDENTIFIER_3 +} + input LabelInput { lang: String! label: String! From c2db318bdc74aecc3d0b3a72d0c87631a3b030aa Mon Sep 17 00:00:00 2001 From: naftis Date: Mon, 30 Sep 2024 17:09:18 +0300 Subject: [PATCH 05/22] refactor: use defined rejection types --- packages/client/graphql.schema.json | 404 ++++++++++++++++-- .../client/src/i18n/messages/views/reject.ts | 12 - packages/client/src/tests/languages.json | 4 - packages/client/src/utils/gateway.ts | 79 +++- .../src/views/DataProvider/birth/mutations.ts | 2 +- .../src/views/DataProvider/death/mutations.ts | 2 +- .../views/DataProvider/marriage/mutations.ts | 2 +- .../src/views/SearchResult/SearchResult.tsx | 20 +- .../src/features/registration/schema.graphql | 8 +- packages/gateway/src/graphql/schema.d.ts | 14 +- packages/gateway/src/graphql/schema.graphql | 18 +- 11 files changed, 473 insertions(+), 92 deletions(-) diff --git a/packages/client/graphql.schema.json b/packages/client/graphql.schema.json index ab9656a55c..b99a07a69a 100644 --- a/packages/client/graphql.schema.json +++ b/packages/client/graphql.schema.json @@ -3978,6 +3978,61 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "ConfirmRegistrationInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "childIdentifiers", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "IdentifierInput", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "registrationNumber", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "trackingId", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "ContactPoint", @@ -5299,33 +5354,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "OBJECT", - "name": "Dummy", - "description": null, - "fields": [ - { - "name": "dummy", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, { "kind": "OBJECT", "name": "DuplicatesInfo", @@ -6715,8 +6743,8 @@ "description": null, "args": [], "type": { - "kind": "SCALAR", - "name": "String", + "kind": "ENUM", + "name": "RejectionReason", "ofType": null }, "isDeprecated": false, @@ -6999,6 +7027,49 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "IdentifierInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "type", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SupportedPatientIdentifierCode", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "value", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "IdentityInput", @@ -9299,6 +9370,55 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "confirmRegistration", + "description": null, + "args": [ + { + "name": "details", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ConfirmRegistrationInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "createBirthRegistration", "description": null, @@ -10374,8 +10494,8 @@ "kind": "NON_NULL", "name": null, "ofType": { - "kind": "SCALAR", - "name": "String", + "kind": "ENUM", + "name": "RejectionReason", "ofType": null } }, @@ -10667,6 +10787,55 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "rejectRegistration", + "description": null, + "args": [ + { + "name": "details", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RejectRegistrationInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "rejectRegistrationCorrection", "description": null, @@ -16422,6 +16591,72 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "RejectRegistrationInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "comment", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reason", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RejectionReason", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RejectionReason", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "duplicate", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "other", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, { "kind": "OBJECT", "name": "RelatedPerson", @@ -17803,6 +18038,113 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "ENUM", + "name": "SupportedPatientIdentifierCode", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ALIEN_NUMBER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BIRTH_CONFIGURABLE_IDENTIFIER_1", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BIRTH_CONFIGURABLE_IDENTIFIER_2", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BIRTH_CONFIGURABLE_IDENTIFIER_3", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BIRTH_PATIENT_ENTRY", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BIRTH_REGISTRATION_NUMBER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DEATH_REGISTRATION_NUMBER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DECEASED_PATIENT_ENTRY", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DRIVING_LICENSE", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MARRIAGE_REGISTRATION_NUMBER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MOSIP_PSUT_TOKEN_ID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NATIONAL_ID", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OTHER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PASSPORT", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REFUGEE_NUMBER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SOCIAL_SECURITY_NO", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, { "kind": "OBJECT", "name": "System", diff --git a/packages/client/src/i18n/messages/views/reject.ts b/packages/client/src/i18n/messages/views/reject.ts index 940b1b4e2a..e609214bde 100644 --- a/packages/client/src/i18n/messages/views/reject.ts +++ b/packages/client/src/i18n/messages/views/reject.ts @@ -17,8 +17,6 @@ interface IRejectMessages rejectionForm: MessageDescriptor rejectionReason: MessageDescriptor rejectionReasonDuplicate: MessageDescriptor - rejectionReasonMisspelling: MessageDescriptor - rejectionReasonMissingSupportingDoc: MessageDescriptor rejectionReasonOther: MessageDescriptor rejectionCommentForHealthWorkerLabel: MessageDescriptor rejectionFormInstruction: MessageDescriptor @@ -63,16 +61,6 @@ const messagesToDefine: IRejectMessages = { defaultMessage: 'Mark as a duplicate', description: 'Label for rejection option duplicate' }, - rejectionReasonMisspelling: { - id: 'review.rejection.form.reasons.misspelling', - defaultMessage: 'Misspelling', - description: 'Label for rejection option misspelling' - }, - rejectionReasonMissingSupportingDoc: { - id: 'review.rej.form.reasons.missSupDoc', - defaultMessage: 'Missing supporting documents', - description: 'Label for rejection option missing supporting doc' - }, rejectionReasonOther: { id: 'review.rejection.form.reasons.other', defaultMessage: 'Other', diff --git a/packages/client/src/tests/languages.json b/packages/client/src/tests/languages.json index e3329737a3..5aeb76b2a4 100644 --- a/packages/client/src/tests/languages.json +++ b/packages/client/src/tests/languages.json @@ -1020,8 +1020,6 @@ "review.rejection.form.commentLabel": "Comments or instructions for health worker to rectify declaration", "review.rejection.form.reasons": "Reason(s) for rejection:", "review.rejection.form.reasons.duplicate": "Duplicate declaration", - "review.rej.form.reasons.missSupDoc": "Missing supporting documents", - "review.rejection.form.reasons.misspelling": "Misspelling", "review.rejection.form.reasons.other": "Other", "review.rejection.form.submitButton": "Submit rejection", "review.rejection.form.title": "What update does the declaration require?", @@ -2169,8 +2167,6 @@ "review.rejection.form.commentLabel": "আবেদন সংশোধন করতে স্বাস্থ্য কর্মীর জন্য নির্দেশাবলী", "review.rejection.form.reasons": "প্রত্যাখ্যানের কারণসমূহ:", "review.rejection.form.reasons.duplicate": "নকল আবেদন", - "review.rej.form.reasons.missSupDoc": "প্রমাণক অনুপস্থিত", - "review.rejection.form.reasons.misspelling": "ভুল বানান", "review.rejection.form.reasons.other": "অন্যান্য", "review.rejection.form.submitButton": "প্রত্যাখ্যান জমা দিন", "review.rejection.form.title": "আবেদনটির কী হালনাগাদ দরকার?", diff --git a/packages/client/src/utils/gateway.ts b/packages/client/src/utils/gateway.ts index a80ee81bdc..7da92c34a1 100644 --- a/packages/client/src/utils/gateway.ts +++ b/packages/client/src/utils/gateway.ts @@ -428,6 +428,12 @@ export type ComparisonInput = { nin?: InputMaybe> } +export type ConfirmRegistrationInput = { + childIdentifiers?: InputMaybe> + registrationNumber?: InputMaybe + trackingId?: InputMaybe +} + export type ContactPoint = { __typename?: 'ContactPoint' system?: Maybe @@ -558,11 +564,6 @@ export type DeclarationsStartedMetrics = { officeDeclarations: Scalars['Int'] } -export type Dummy = { - __typename?: 'Dummy' - dummy: Scalars['String'] -} - export type DuplicatesInfo = { __typename?: 'DuplicatesInfo' compositionId?: Maybe @@ -706,7 +707,7 @@ export type History = { output?: Maybe>> payment?: Maybe potentialDuplicates?: Maybe> - reason?: Maybe + reason?: Maybe regStatus?: Maybe requester?: Maybe requesterOther?: Maybe @@ -739,6 +740,11 @@ export type Identifier = { value?: Maybe } +export type IdentifierInput = { + type: SupportedPatientIdentifierCode + value: Scalars['String'] +} + export type IdentityInput = { fieldsModifiedByIdentity?: InputMaybe>> id?: InputMaybe @@ -927,6 +933,7 @@ export type Mutation = { changeEmail?: Maybe changePassword?: Maybe changePhone?: Maybe + confirmRegistration: Scalars['ID'] createBirthRegistration: Scalars['Void'] createBirthRegistrationCorrection: Scalars['ID'] createDeathRegistration: Scalars['Void'] @@ -959,6 +966,7 @@ export type Mutation = { reactivateSystem?: Maybe refreshSystemSecret?: Maybe registerSystem?: Maybe + rejectRegistration: Scalars['ID'] rejectRegistrationCorrection: Scalars['ID'] removeBookmarkedAdvancedSearch?: Maybe requestRegistrationCorrection: Scalars['ID'] @@ -1027,6 +1035,11 @@ export type MutationChangePhoneArgs = { verifyCode: Scalars['String'] } +export type MutationConfirmRegistrationArgs = { + details: ConfirmRegistrationInput + id: Scalars['ID'] +} + export type MutationCreateBirthRegistrationArgs = { details: BirthRegistrationInput } @@ -1145,7 +1158,7 @@ export type MutationMarkEventAsUnassignedArgs = { export type MutationMarkEventAsVoidedArgs = { comment: Scalars['String'] id: Scalars['String'] - reason: Scalars['String'] + reason: RejectionReason } export type MutationMarkMarriageAsCertifiedArgs = { @@ -1180,6 +1193,11 @@ export type MutationRegisterSystemArgs = { system?: InputMaybe } +export type MutationRejectRegistrationArgs = { + details: RejectRegistrationInput + id: Scalars['ID'] +} + export type MutationRejectRegistrationCorrectionArgs = { details: CorrectionRejectionInput id: Scalars['ID'] @@ -1832,6 +1850,16 @@ export type Reinstated = { taskEntryResourceID: Scalars['ID'] } +export type RejectRegistrationInput = { + comment: Scalars['String'] + reason: RejectionReason +} + +export enum RejectionReason { + Duplicate = 'duplicate', + Other = 'other' +} + export type RelatedPerson = { __typename?: 'RelatedPerson' _fhirID?: Maybe @@ -1982,6 +2010,25 @@ export type StatusWiseRegistrationCount = { status: Scalars['String'] } +export enum SupportedPatientIdentifierCode { + AlienNumber = 'ALIEN_NUMBER', + BirthConfigurableIdentifier_1 = 'BIRTH_CONFIGURABLE_IDENTIFIER_1', + BirthConfigurableIdentifier_2 = 'BIRTH_CONFIGURABLE_IDENTIFIER_2', + BirthConfigurableIdentifier_3 = 'BIRTH_CONFIGURABLE_IDENTIFIER_3', + BirthPatientEntry = 'BIRTH_PATIENT_ENTRY', + BirthRegistrationNumber = 'BIRTH_REGISTRATION_NUMBER', + DeathRegistrationNumber = 'DEATH_REGISTRATION_NUMBER', + DeceasedPatientEntry = 'DECEASED_PATIENT_ENTRY', + DrivingLicense = 'DRIVING_LICENSE', + MarriageRegistrationNumber = 'MARRIAGE_REGISTRATION_NUMBER', + MosipPsutTokenId = 'MOSIP_PSUT_TOKEN_ID', + NationalId = 'NATIONAL_ID', + Other = 'OTHER', + Passport = 'PASSPORT', + RefugeeNumber = 'REFUGEE_NUMBER', + SocialSecurityNo = 'SOCIAL_SECURITY_NO' +} + export type System = { __typename?: 'System' _id: Scalars['ID'] @@ -3077,7 +3124,7 @@ export type MarkBirthAsRegisteredMutation = { export type MarkEventAsVoidedMutationVariables = Exact<{ id: Scalars['String'] - reason: Scalars['String'] + reason: RejectionReason comment: Scalars['String'] }> @@ -3373,7 +3420,7 @@ export type FetchBirthRegistrationForReviewQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: string | null + reason?: RejectionReason | null duplicateOf?: string | null potentialDuplicates?: Array | null documents: Array<{ @@ -3707,7 +3754,7 @@ export type FetchBirthRegistrationForCertificateQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: string | null + reason?: RejectionReason | null otherReason?: string | null duplicateOf?: string | null potentialDuplicates?: Array | null @@ -4169,7 +4216,7 @@ export type FetchDeathRegistrationForReviewQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: string | null + reason?: RejectionReason | null duplicateOf?: string | null potentialDuplicates?: Array | null documents: Array<{ @@ -4888,7 +4935,7 @@ export type FetchMarriageRegistrationForReviewQuery = { action?: RegAction | null regStatus?: RegStatus | null dhis2Notification?: boolean | null - reason?: string | null + reason?: RejectionReason | null documents: Array<{ __typename?: 'Attachment' id: string @@ -5242,7 +5289,7 @@ export type FetchMarriageRegistrationForCertificateQuery = { action?: RegAction | null regStatus?: RegStatus | null dhis2Notification?: boolean | null - reason?: string | null + reason?: RejectionReason | null statusReason?: { __typename?: 'StatusReason' text?: string | null @@ -8001,7 +8048,7 @@ export type FetchViewRecordByCompositionQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: string | null + reason?: RejectionReason | null statusReason?: { __typename?: 'StatusReason' text?: string | null @@ -8387,7 +8434,7 @@ export type FetchViewRecordByCompositionQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: string | null + reason?: RejectionReason | null statusReason?: { __typename?: 'StatusReason' text?: string | null @@ -8705,7 +8752,7 @@ export type FetchViewRecordByCompositionQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: string | null + reason?: RejectionReason | null statusReason?: { __typename?: 'StatusReason' text?: string | null diff --git a/packages/client/src/views/DataProvider/birth/mutations.ts b/packages/client/src/views/DataProvider/birth/mutations.ts index a40694cb06..a964720654 100644 --- a/packages/client/src/views/DataProvider/birth/mutations.ts +++ b/packages/client/src/views/DataProvider/birth/mutations.ts @@ -35,7 +35,7 @@ const REGISTER_BIRTH_DECLARATION = gql` const REJECT_BIRTH_DECLARATION = gql` mutation markEventAsVoided( $id: String! - $reason: String! + $reason: RejectionReason! $comment: String! ) { markEventAsVoided(id: $id, reason: $reason, comment: $comment) diff --git a/packages/client/src/views/DataProvider/death/mutations.ts b/packages/client/src/views/DataProvider/death/mutations.ts index 53c5b926d5..8e3771d4cb 100644 --- a/packages/client/src/views/DataProvider/death/mutations.ts +++ b/packages/client/src/views/DataProvider/death/mutations.ts @@ -35,7 +35,7 @@ const REGISTER_DEATH_DECLARATION = gql` const REJECT_DEATH_DECLARATION = gql` mutation markEventAsVoided( $id: String! - $reason: String! + $reason: RejectionReason! $comment: String! ) { markEventAsVoided(id: $id, reason: $reason, comment: $comment) diff --git a/packages/client/src/views/DataProvider/marriage/mutations.ts b/packages/client/src/views/DataProvider/marriage/mutations.ts index 46d7c0988f..4bc43262e6 100644 --- a/packages/client/src/views/DataProvider/marriage/mutations.ts +++ b/packages/client/src/views/DataProvider/marriage/mutations.ts @@ -36,7 +36,7 @@ const REGISTER_MARRIAGE_DECLARATION = gql` const REJECT_MARRIAGE_DECLARATION = gql` mutation markEventAsVoided( $id: String! - $reason: String! + $reason: RejectionReason! $comment: String! ) { markEventAsVoided(id: $id, reason: $reason, comment: $comment) diff --git a/packages/client/src/views/SearchResult/SearchResult.tsx b/packages/client/src/views/SearchResult/SearchResult.tsx index a218871802..546df70997 100644 --- a/packages/client/src/views/SearchResult/SearchResult.tsx +++ b/packages/client/src/views/SearchResult/SearchResult.tsx @@ -47,7 +47,11 @@ import { ITheme } from '@opencrvs/components/lib/theme' import { Scope } from '@client/utils/authUtils' import { SEARCH_RESULT_SORT } from '@client/utils/constants' import { getUserLocation, UserDetails } from '@client/utils/userUtils' -import { SearchEventsQuery, SystemRoleType } from '@client/utils/gateway' +import { + SearchEventsQuery, + SystemRoleType, + RejectionReason +} from '@client/utils/gateway' import { ColumnContentAlignment, @@ -86,18 +90,14 @@ const ToolTipContainer = styled.span` text-align: center; ` -export function getRejectionReasonDisplayValue(reason: string) { - switch (reason.toLowerCase()) { - case 'duplicate': +export function getRejectionReasonDisplayValue(reason: RejectionReason) { + switch (reason) { + case RejectionReason.Duplicate: return rejectMessages.rejectionReasonDuplicate - case 'misspelling': - return rejectMessages.rejectionReasonMisspelling - case 'missing_supporting_doc': - return rejectMessages.rejectionReasonMissingSupportingDoc - case 'other': + case RejectionReason.Other: return rejectMessages.rejectionReasonOther default: - return rejectMessages.rejectionReasonOther + return reason satisfies never } } diff --git a/packages/gateway/src/features/registration/schema.graphql b/packages/gateway/src/features/registration/schema.graphql index afdd6585db..d7022f2d0d 100644 --- a/packages/gateway/src/features/registration/schema.graphql +++ b/packages/gateway/src/features/registration/schema.graphql @@ -155,7 +155,7 @@ type History { action: RegAction note: String statusReason: StatusReason - reason: String + reason: RejectionReason requester: String requesterOther: String hasShowedVerifiedDocument: Boolean @@ -645,7 +645,11 @@ type Mutation { markBirthAsRegistered(id: ID!, details: BirthRegistrationInput!): ID! # updates status to 'registered' - registration clerk has accepted the declaration, it is now official - internally call update if details exists markBirthAsCertified(id: ID!, details: BirthRegistrationInput!): ID! # updates status to 'certified' - a printed certificate has been produced - internally call update if details exists markBirthAsIssued(id: ID!, details: BirthRegistrationInput!): ID! # updates status to 'certified' - a printed certificate has been produced - internally call update if details exists - markEventAsVoided(id: String!, reason: String!, comment: String!): ID! # updated status to 'voided' - the registration was captured in error + markEventAsVoided( + id: String! + reason: RejectionReason! + comment: String! + ): ID! # updated status to 'voided' - the registration was captured in error markEventAsReinstated(id: String!): Reinstated # updates status to 'reinstated' markEventAsNotDuplicate(id: String!): ID! # removes duplicates from composition markEventAsArchived( diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index c2be74a8d6..7f59302c29 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -606,6 +606,11 @@ export interface GQLMarriageRegistrationInput { export type GQLVoid = any +export const enum GQLRejectionReason { + other = 'other', + duplicate = 'duplicate' +} + export interface GQLReinstated { taskEntryResourceID: string registrationStatus?: GQLRegStatus @@ -769,7 +774,7 @@ export interface GQLHistory { action?: GQLRegAction note?: string statusReason?: GQLStatusReason - reason?: string + reason?: GQLRejectionReason requester?: string requesterOther?: string hasShowedVerifiedDocument?: boolean @@ -1235,11 +1240,6 @@ export interface GQLIdentifierInput { value: string } -export const enum GQLRejectionReason { - other = 'other', - duplicate = 'duplicate' -} - export interface GQLHumanNameInput { use?: string firstNames?: string @@ -2836,7 +2836,7 @@ export interface MutationToMarkBirthAsIssuedResolver< export interface MutationToMarkEventAsVoidedArgs { id: string - reason: string + reason: GQLRejectionReason comment: string } export interface MutationToMarkEventAsVoidedResolver< diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index 831a6b71ff..5bb8d6f883 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -192,7 +192,11 @@ type Mutation { markBirthAsRegistered(id: ID!, details: BirthRegistrationInput!): ID! markBirthAsCertified(id: ID!, details: BirthRegistrationInput!): ID! markBirthAsIssued(id: ID!, details: BirthRegistrationInput!): ID! - markEventAsVoided(id: String!, reason: String!, comment: String!): ID! + markEventAsVoided( + id: String! + reason: RejectionReason! + comment: String! + ): ID! markEventAsReinstated(id: String!): Reinstated markEventAsNotDuplicate(id: String!): ID! markEventAsArchived( @@ -721,6 +725,11 @@ input MarriageRegistrationInput { scalar Void +enum RejectionReason { + other + duplicate +} + type Reinstated { taskEntryResourceID: ID! registrationStatus: RegStatus @@ -884,7 +893,7 @@ type History { action: RegAction note: String statusReason: StatusReason - reason: String + reason: RejectionReason requester: String requesterOther: String hasShowedVerifiedDocument: Boolean @@ -1326,11 +1335,6 @@ input IdentifierInput { value: String! } -enum RejectionReason { - other - duplicate -} - input HumanNameInput { use: String firstNames: String From af52157b7870164c65b576a508f8af3d534d1c26 Mon Sep 17 00:00:00 2001 From: naftis Date: Tue, 1 Oct 2024 10:05:24 +0300 Subject: [PATCH 06/22] refactor(tests): use defined rejection types --- .../src/views/SearchResult/SearchResult.test.tsx | 3 +-- .../gateway/src/features/search/type-resolvers.test.ts | 10 +++++----- .../test-data/sent-for-updates-request.json | 2 +- .../features/registration/test-data/task-history.json | 2 +- packages/search/src/test/utils.ts | 6 +++--- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/client/src/views/SearchResult/SearchResult.test.tsx b/packages/client/src/views/SearchResult/SearchResult.test.tsx index 856e4b2ff7..bee821e38a 100644 --- a/packages/client/src/views/SearchResult/SearchResult.test.tsx +++ b/packages/client/src/views/SearchResult/SearchResult.test.tsx @@ -141,8 +141,7 @@ describe('SearchResult tests', () => { duplicates: null, registeredLocationId: '308c35b4-04f8-4664-83f5-9790e790cde1', - reason: - 'duplicate,misspelling,missing_supporting_doc,other', + reason: 'duplicate', comment: 'Rejected' }, dateOfDeath: '2010-01-01', diff --git a/packages/gateway/src/features/search/type-resolvers.test.ts b/packages/gateway/src/features/search/type-resolvers.test.ts index 31266bf8fe..dcfb1dee1f 100644 --- a/packages/gateway/src/features/search/type-resolvers.test.ts +++ b/packages/gateway/src/features/search/type-resolvers.test.ts @@ -179,7 +179,7 @@ describe('Search type resolvers', () => { { operatedOn: '2019-12-12T15:24:53.586Z', operatorFirstNames: 'Mohammad', - rejectReason: 'missing_supporting_doc', + rejectReason: 'other', operatorFamilyName: 'Ashraful', rejectComment: 'No supporting documents provided.', operatorOfficeName: 'Alokbali Union Parishad', @@ -213,7 +213,7 @@ describe('Search type resolvers', () => { { operatedOn: '2019-12-12T15:24:53.586Z', operatorFirstNames: 'Mohammad', - rejectReason: 'missing_supporting_doc', + rejectReason: 'other', operatorFamilyName: 'Ashraful', rejectComment: 'No supporting documents provided.', operatorOfficeName: 'Alokbali Union Parishad', @@ -367,7 +367,7 @@ describe('Search type resolvers', () => { { operatedOn: '2019-12-12T15:24:53.586Z', operatorFirstNames: 'Mohammad', - rejectReason: 'missing_supporting_doc', + rejectReason: 'other', operatorFamilyName: 'Ashraful', rejectComment: 'No supporting documents provided.', operatorOfficeName: 'Alokbali Union Parishad', @@ -401,7 +401,7 @@ describe('Search type resolvers', () => { { operatedOn: '2019-12-12T15:24:53.586Z', operatorFirstNames: 'Mohammad', - rejectReason: 'missing_supporting_doc', + rejectReason: 'other', operatorFamilyName: 'Ashraful', rejectComment: 'No supporting documents provided.', operatorOfficeName: 'Alokbali Union Parishad', @@ -593,7 +593,7 @@ describe('Search type resolvers', () => { { operatedOn: '2019-12-12T15:24:53.586Z', operatorFirstNames: 'Mohammad', - rejectReason: 'missing_supporting_doc', + rejectReason: 'other', operatorFamilyName: 'Ashraful', rejectComment: 'No supporting documents provided.', operatorOfficeName: 'Alokbali Union Parishad', diff --git a/packages/metrics/src/features/registration/test-data/sent-for-updates-request.json b/packages/metrics/src/features/registration/test-data/sent-for-updates-request.json index bd739e256a..8d34ec5193 100644 --- a/packages/metrics/src/features/registration/test-data/sent-for-updates-request.json +++ b/packages/metrics/src/features/registration/test-data/sent-for-updates-request.json @@ -75,7 +75,7 @@ "id": "77124886-8e45-4506-b38a-cc21f75b8dde", "note": [ { - "text": "reason=missing_supporting_doc&comment=fdfdfz", + "text": "reason=other&comment=fdfdfz", "time": "Mon, 11 May 2020 12:15:29 GMT", "authorString": "Practitioner/2da11e94-1a0d-4a77-8ab0-19f29f57a41a" } diff --git a/packages/metrics/src/features/registration/test-data/task-history.json b/packages/metrics/src/features/registration/test-data/task-history.json index 34e2ed602f..b2ab01fe3c 100644 --- a/packages/metrics/src/features/registration/test-data/task-history.json +++ b/packages/metrics/src/features/registration/test-data/task-history.json @@ -81,7 +81,7 @@ "id": "723621be-3f14-45fd-b045-2cf92a9643b6", "note": [ { - "text": "reason=misspelling&comment=blah", + "text": "reason=other&comment=blah", "time": "Tue, 12 May 2020 07:14:30 GMT", "authorString": "Practitioner/2da11e94-1a0d-4a77-8ab0-19f29f57a41a" } diff --git a/packages/search/src/test/utils.ts b/packages/search/src/test/utils.ts index ebaa9f328a..7ebd90c71b 100644 --- a/packages/search/src/test/utils.ts +++ b/packages/search/src/test/utils.ts @@ -3216,7 +3216,7 @@ export const mockDeathRejectionTaskBundle = { id: 'be13e81f-0cd7-4ff3-a2d3-a1bc7a7f543a', note: [ { - text: 'reason=missing_supporting_doc&comment=No documents found!', + text: 'reason=other&comment=No documents found!', time: 'Wed, 27 Mar 2019 11:44:41 GMT', authorString: 'Practitioner/220ad6b8-346f-4a1d-8a5c-086ce38067c9' } @@ -3287,7 +3287,7 @@ export const mockMarriageRejectionTaskBundle = { id: 'be13e81f-0cd7-4ff3-a2d3-a1bc7a7f543a', note: [ { - text: 'reason=missing_supporting_doc&comment=No documents found!', + text: 'reason=other&comment=No documents found!', time: 'Wed, 27 Mar 2019 11:44:41 GMT', authorString: 'Practitioner/220ad6b8-346f-4a1d-8a5c-086ce38067c9' } @@ -3355,7 +3355,7 @@ export const mockDeathRejectionTaskBundleWithoutCompositionReference = { id: 'be13e81f-0cd7-4ff3-a2d3-a1bc7a7f543a', note: [ { - text: 'reason=missing_supporting_doc&comment=No documents found!', + text: 'reason=other&comment=No documents found!', time: 'Wed, 27 Mar 2019 11:44:41 GMT', authorString: 'Practitioner/220ad6b8-346f-4a1d-8a5c-086ce38067c9' } From 522f2cd9dd15f7cb235b309663b8d63745ceca42 Mon Sep 17 00:00:00 2001 From: naftis Date: Tue, 8 Oct 2024 15:28:46 +0300 Subject: [PATCH 07/22] fix: add some missing rejection reasons --- packages/client/graphql.schema.json | 30 +++++++++++++++++++ .../client/src/forms/correction/reason.ts | 19 ++++-------- packages/client/src/utils/gateway.ts | 8 +++-- .../ReviewCorrection/ReviewCorrection.tsx | 17 ++++++----- .../Performance/CorrectionsReport.tsx | 12 ++++---- .../src/features/registration/schema.graphql | 8 +++-- packages/gateway/src/graphql/schema.d.ts | 8 +++-- packages/gateway/src/graphql/schema.graphql | 8 +++-- 8 files changed, 76 insertions(+), 34 deletions(-) diff --git a/packages/client/graphql.schema.json b/packages/client/graphql.schema.json index b99a07a69a..2e22aecf39 100644 --- a/packages/client/graphql.schema.json +++ b/packages/client/graphql.schema.json @@ -16642,6 +16642,36 @@ "inputFields": null, "interfaces": null, "enumValues": [ + { + "name": "CLERICAL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "JUDICIAL_ORDER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MATERIAL_ERROR", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MATERIAL_OMISSION", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OTHER", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "duplicate", "description": null, diff --git a/packages/client/src/forms/correction/reason.ts b/packages/client/src/forms/correction/reason.ts index ba36b237d2..6249cab791 100644 --- a/packages/client/src/forms/correction/reason.ts +++ b/packages/client/src/forms/correction/reason.ts @@ -21,14 +21,7 @@ import { messages } from '@client/i18n/messages/views/correction' import { fieldValueSectionExchangeTransformer } from '@client/forms/register/mappings/mutation' import { required as requiredValidation } from '@opencrvs/client/src/utils/validate' import { validationMessages } from '@client/i18n/messages' - -export enum CorrectionReason { - CLERICAL_ERROR = 'CLERICAL_ERROR', - MATERIAL_ERROR = 'MATERIAL_ERROR', - MATERIAL_OMISSION = 'MATERIAL_OMISSION', - JUDICIAL_ORDER = 'JUDICIAL_ORDER', - OTHER = 'OTHER' -} +import { RejectionReason } from '@client/utils/gateway' export const correctRecordReasonSectionGroup: IFormSectionGroup = { id: 'recordCorrection', @@ -46,23 +39,23 @@ export const correctRecordReasonSectionGroup: IFormSectionGroup = { validator: [], options: [ { - value: CorrectionReason.CLERICAL_ERROR, + value: RejectionReason.ClericalError, label: messages.clericalError }, { - value: CorrectionReason.MATERIAL_ERROR, + value: RejectionReason.MaterialError, label: messages.materialError }, { - value: CorrectionReason.MATERIAL_OMISSION, + value: RejectionReason.MaterialOmission, label: messages.materialOmission }, { - value: CorrectionReason.JUDICIAL_ORDER, + value: RejectionReason.JudicialOrder, label: messages.judicialOrder }, { - value: CorrectionReason.OTHER, + value: RejectionReason.Other, label: formMessages.otherOption } ], diff --git a/packages/client/src/utils/gateway.ts b/packages/client/src/utils/gateway.ts index 7da92c34a1..ef049e168c 100644 --- a/packages/client/src/utils/gateway.ts +++ b/packages/client/src/utils/gateway.ts @@ -1856,8 +1856,12 @@ export type RejectRegistrationInput = { } export enum RejectionReason { - Duplicate = 'duplicate', - Other = 'other' + ClericalError = 'CLERICAL_ERROR', + JudicialOrder = 'JUDICIAL_ORDER', + MaterialError = 'MATERIAL_ERROR', + MaterialOmission = 'MATERIAL_OMISSION', + Duplicate = 'DUPLICATE', + Other = 'OTHER' } export type RelatedPerson = { diff --git a/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx b/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx index cc9db51995..6efb069ee9 100644 --- a/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx +++ b/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx @@ -26,7 +26,11 @@ import { WORKQUEUE_TABS } from '@client/components/interface/Navigation' import { RegisterForm } from '@client/views/RegisterForm/RegisterForm' import { useSelector } from 'react-redux' -import { CorrectionInput, History } from '@client/utils/gateway' +import { + CorrectionInput, + History, + RejectionReason +} from '@client/utils/gateway' import { getEventReviewForm } from '@client/forms/register/review-selectors' import { IStoreState } from '@client/store' @@ -52,7 +56,6 @@ import { rejectCorrection } from '@client/review/reject-correction' import { Summary } from '@opencrvs/components/lib/Summary' import { CorrectorRelationship } from '@client/forms/correction/corrector' import { messages } from '@client/i18n/messages/views/correction' -import { CorrectionReason } from '@client/forms/correction/reason' import { Text } from '@opencrvs/components/lib/Text' import { ColumnContentAlignment } from '@opencrvs/components/lib/common-types' import { @@ -185,15 +188,15 @@ const ReviewSummarySection = ({ declaration }: IPropsReviewSummarySection) => { const getReasonForRequest = () => { switch (correctionRequestTask.reason) { - case CorrectionReason.CLERICAL_ERROR: + case RejectionReason.ClericalError: return intl.formatMessage(messages.clericalError) - case CorrectionReason.MATERIAL_ERROR: + case RejectionReason.MaterialError: return intl.formatMessage(messages.materialError) - case CorrectionReason.MATERIAL_OMISSION: + case RejectionReason.MaterialOmission: return intl.formatMessage(messages.materialOmission) - case CorrectionReason.JUDICIAL_ORDER: + case RejectionReason.JudicialOrder: return intl.formatMessage(messages.judicialOrder) - case CorrectionReason.OTHER: + case RejectionReason.Other: return ( intl.formatMessage(messages.otherReason) + ' - ' + diff --git a/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx b/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx index 633830401b..f6a5a371f0 100644 --- a/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx +++ b/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx @@ -21,7 +21,7 @@ import { import type { GQLCorrectionMetric } from '@client/utils/gateway-deprecated-do-not-use' import { messages } from '@client/i18n/messages/views/performance' import { messages as correctionMessages } from '@client/i18n/messages/views/correction' -import { CorrectionReason } from '@client/forms/correction/reason' +import { RejectionReason } from '@client/utils/gateway' import { useIntl } from 'react-intl' interface CorrectionsReportProps { @@ -65,7 +65,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === CorrectionReason.CLERICAL_ERROR + ({ reason }) => reason === RejectionReason.ClericalError ) )} @@ -81,7 +81,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === CorrectionReason.MATERIAL_ERROR + ({ reason }) => reason === RejectionReason.MaterialError ) )} @@ -97,7 +97,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === CorrectionReason.MATERIAL_OMISSION + ({ reason }) => reason === RejectionReason.MaterialOmission ) )} @@ -113,7 +113,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === CorrectionReason.JUDICIAL_ORDER + ({ reason }) => reason === RejectionReason.JudicialOrder ) )} @@ -128,7 +128,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { value={ {calculateTotal( - data.filter(({ reason }) => reason === CorrectionReason.OTHER) + data.filter(({ reason }) => reason === RejectionReason.Other) )} } diff --git a/packages/gateway/src/features/registration/schema.graphql b/packages/gateway/src/features/registration/schema.graphql index d7022f2d0d..1178e382a1 100644 --- a/packages/gateway/src/features/registration/schema.graphql +++ b/packages/gateway/src/features/registration/schema.graphql @@ -594,8 +594,12 @@ input ConfirmRegistrationInput { } enum RejectionReason { - other - duplicate + DUPLICATE + CLERICAL_ERROR + MATERIAL_ERROR + MATERIAL_OMISSION + JUDICIAL_ORDER + OTHER } input RejectRegistrationInput { diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index 7f59302c29..98bdcd1e96 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -607,8 +607,12 @@ export interface GQLMarriageRegistrationInput { export type GQLVoid = any export const enum GQLRejectionReason { - other = 'other', - duplicate = 'duplicate' + DUPLICATE = 'DUPLICATE', + CLERICAL_ERROR = 'CLERICAL_ERROR', + MATERIAL_ERROR = 'MATERIAL_ERROR', + MATERIAL_OMISSION = 'MATERIAL_OMISSION', + JUDICIAL_ORDER = 'JUDICIAL_ORDER', + OTHER = 'OTHER' } export interface GQLReinstated { diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index 5bb8d6f883..8cc0abedb7 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -726,8 +726,12 @@ input MarriageRegistrationInput { scalar Void enum RejectionReason { - other - duplicate + DUPLICATE + CLERICAL_ERROR + MATERIAL_ERROR + MATERIAL_OMISSION + JUDICIAL_ORDER + OTHER } type Reinstated { From eb9c24046c7c38748c589ab7af8a8b240fccf7e4 Mon Sep 17 00:00:00 2001 From: naftis Date: Tue, 8 Oct 2024 15:42:01 +0300 Subject: [PATCH 08/22] fix: linter issues --- packages/client/src/declarations/createRecord.ts | 6 +++++- packages/client/src/declarations/submissionMiddleware.ts | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/client/src/declarations/createRecord.ts b/packages/client/src/declarations/createRecord.ts index 6a641d93b0..19762f27fc 100644 --- a/packages/client/src/declarations/createRecord.ts +++ b/packages/client/src/declarations/createRecord.ts @@ -41,6 +41,9 @@ const FETCH_RECORD_STATUS = gql` } ` +const waitWithIncreasingBackoff = (attemptNumber: number) => + new Promise((resolve) => setTimeout(resolve, 1000 + attemptNumber * 1000)) + export async function submitAndWaitUntilRecordInWorkqueue( mutation: DocumentNode, graphqlPayload: TransformedData, @@ -90,7 +93,8 @@ export async function submitAndWaitUntilRecordInWorkqueue( } } - await new Promise((resolve) => setTimeout(resolve, 1000 + nthTry * 1000)) + await waitWithIncreasingBackoff(nthTry) + nthTry++ } } diff --git a/packages/client/src/declarations/submissionMiddleware.ts b/packages/client/src/declarations/submissionMiddleware.ts index 7c1fd09b0f..0235d434b7 100644 --- a/packages/client/src/declarations/submissionMiddleware.ts +++ b/packages/client/src/declarations/submissionMiddleware.ts @@ -352,7 +352,6 @@ export const submissionMiddleware: Middleware<{}, IStoreState> = captureException(error) return } - console.log(error) updateDeclaration(dispatch, { ...declaration, From 04eaf603b4852694640d2eb0c227617b71152841 Mon Sep 17 00:00:00 2001 From: naftis Date: Tue, 8 Oct 2024 15:59:27 +0300 Subject: [PATCH 09/22] fix: named types not being included in the generated graphql query --- .../__snapshots__/type-resolvers.test.ts.snap | 12 ++++++++++++ packages/gateway/src/graphql/query-generator.ts | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/gateway/src/features/registration/__snapshots__/type-resolvers.test.ts.snap b/packages/gateway/src/features/registration/__snapshots__/type-resolvers.test.ts.snap index 02451a6d6a..1454dba80d 100644 --- a/packages/gateway/src/features/registration/__snapshots__/type-resolvers.test.ts.snap +++ b/packages/gateway/src/features/registration/__snapshots__/type-resolvers.test.ts.snap @@ -170,6 +170,7 @@ Object { "foetalDeathsToMother": null, "history": Array [ Object { + "action": "ASSIGNED", "certificates": Array [ null, ], @@ -216,6 +217,7 @@ Object { "output": Array [], "payment": null, "reason": null, + "regStatus": "WAITING_VALIDATION", "requester": "", "requesterOther": "", "signature": null, @@ -480,10 +482,12 @@ Object { "reason": null, "timeLogged": null, "timestamp": "2023-10-02T13:51:55.410Z", + "type": "WAITING_VALIDATION", "user": null, }, ], "trackingId": "B3VUXES", + "type": "BIRTH", "witnessOneSignature": null, "witnessTwoSignature": null, }, @@ -655,6 +659,7 @@ Object { "femaleDependentsOfDeceased": 4, "history": Array [ Object { + "action": "VIEWED", "certificates": Array [], "comments": Array [], "date": "2023-09-22T11:52:48.611+00:00", @@ -699,6 +704,7 @@ Object { "output": Array [], "payment": null, "reason": null, + "regStatus": "REGISTERED", "requester": "", "requesterOther": "", "signature": null, @@ -914,10 +920,12 @@ Object { "reason": null, "timeLogged": null, "timestamp": "2023-09-22T11:52:48.439Z", + "type": "REGISTERED", "user": null, }, ], "trackingId": "DL1W8FV", + "type": "DEATH", "witnessOneSignature": null, "witnessTwoSignature": null, }, @@ -1203,6 +1211,7 @@ Object { }, "history": Array [ Object { + "action": "ASSIGNED", "certificates": Array [], "comments": Array [], "date": "2023-09-22T08:54:57.825+00:00", @@ -1247,6 +1256,7 @@ Object { "output": Array [], "payment": null, "reason": null, + "regStatus": "REGISTERED", "requester": "", "requesterOther": "", "signature": null, @@ -1426,10 +1436,12 @@ Object { "reason": null, "timeLogged": null, "timestamp": "2023-09-22T08:54:57.632Z", + "type": "REGISTERED", "user": null, }, ], "trackingId": "MTNJUSI", + "type": "MARRIAGE", "witnessOneSignature": "/mock-presigned-url", "witnessTwoSignature": "/mock-presigned-url", }, diff --git a/packages/gateway/src/graphql/query-generator.ts b/packages/gateway/src/graphql/query-generator.ts index c7d74c1a34..da2b20e013 100644 --- a/packages/gateway/src/graphql/query-generator.ts +++ b/packages/gateway/src/graphql/query-generator.ts @@ -14,7 +14,8 @@ import { isListType, isNonNullType, isObjectType, - isScalarType + isScalarType, + isNamedType } from 'graphql' export function generateQueryForType( @@ -48,6 +49,8 @@ export function generateQueryForType( fieldStr += `${fieldName} { ${buildFields(fieldType)} } ` } else if (isScalarType(fieldType)) { fieldStr += `${fieldName} ` + } else if (isNamedType(fieldType)) { + fieldStr += `${fieldName} ` } } return fieldStr.trim() From 529d702c1fbc25153d919b33e16fb0a1944bfa84 Mon Sep 17 00:00:00 2001 From: naftis Date: Tue, 8 Oct 2024 16:03:59 +0300 Subject: [PATCH 10/22] fix: REVERT THIS? remove trivy from build --- .github/workflows/build-images-from-branch.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/build-images-from-branch.yml b/.github/workflows/build-images-from-branch.yml index cd629bbe75..f5ec96de55 100644 --- a/.github/workflows/build-images-from-branch.yml +++ b/.github/workflows/build-images-from-branch.yml @@ -112,9 +112,3 @@ jobs: opencrvs/ocrvs-${{ matrix.service }}:${{ needs.base.outputs.branch }} cache-from: type=registry,ref=opencrvs/ocrvs-${{ matrix.service }}:${{ needs.base.outputs.branch }} cache-to: type=inline - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@0.23.0 - with: - image-ref: 'opencrvs/ocrvs-${{ matrix.service }}:${{ needs.base.outputs.version }}' - trivy-config: trivy.yaml From cac78c3fd6ba17e93884787ec1ac2cc5faffa7d3 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 12:47:24 +0300 Subject: [PATCH 11/22] revert: typing work related to reasons --- packages/client/graphql.schema.json | 44 ++----------------- .../client/src/forms/correction/reason.ts | 19 +++++--- .../client/src/i18n/messages/views/reject.ts | 12 +++++ packages/client/src/utils/gateway.ts | 27 +++++------- .../src/views/DataProvider/birth/mutations.ts | 2 +- .../src/views/DataProvider/death/mutations.ts | 2 +- .../views/DataProvider/marriage/mutations.ts | 2 +- .../ReviewCorrection/ReviewCorrection.tsx | 17 +++---- .../Performance/CorrectionsReport.tsx | 12 ++--- .../src/features/registration/schema.graphql | 17 ++----- packages/gateway/src/graphql/schema.d.ts | 17 +++---- packages/gateway/src/graphql/schema.graphql | 21 +++------ 12 files changed, 72 insertions(+), 120 deletions(-) diff --git a/packages/client/graphql.schema.json b/packages/client/graphql.schema.json index 2e22aecf39..bc6cc73473 100644 --- a/packages/client/graphql.schema.json +++ b/packages/client/graphql.schema.json @@ -6743,8 +6743,8 @@ "description": null, "args": [], "type": { - "kind": "ENUM", - "name": "RejectionReason", + "kind": "SCALAR", + "name": "String", "ofType": null }, "isDeprecated": false, @@ -10494,8 +10494,8 @@ "kind": "NON_NULL", "name": null, "ofType": { - "kind": "ENUM", - "name": "RejectionReason", + "kind": "SCALAR", + "name": "String", "ofType": null } }, @@ -16642,47 +16642,11 @@ "inputFields": null, "interfaces": null, "enumValues": [ - { - "name": "CLERICAL_ERROR", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "JUDICIAL_ORDER", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "MATERIAL_ERROR", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "MATERIAL_OMISSION", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "OTHER", "description": null, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "duplicate", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "other", - "description": null, - "isDeprecated": false, - "deprecationReason": null } ], "possibleTypes": null diff --git a/packages/client/src/forms/correction/reason.ts b/packages/client/src/forms/correction/reason.ts index 6249cab791..ba36b237d2 100644 --- a/packages/client/src/forms/correction/reason.ts +++ b/packages/client/src/forms/correction/reason.ts @@ -21,7 +21,14 @@ import { messages } from '@client/i18n/messages/views/correction' import { fieldValueSectionExchangeTransformer } from '@client/forms/register/mappings/mutation' import { required as requiredValidation } from '@opencrvs/client/src/utils/validate' import { validationMessages } from '@client/i18n/messages' -import { RejectionReason } from '@client/utils/gateway' + +export enum CorrectionReason { + CLERICAL_ERROR = 'CLERICAL_ERROR', + MATERIAL_ERROR = 'MATERIAL_ERROR', + MATERIAL_OMISSION = 'MATERIAL_OMISSION', + JUDICIAL_ORDER = 'JUDICIAL_ORDER', + OTHER = 'OTHER' +} export const correctRecordReasonSectionGroup: IFormSectionGroup = { id: 'recordCorrection', @@ -39,23 +46,23 @@ export const correctRecordReasonSectionGroup: IFormSectionGroup = { validator: [], options: [ { - value: RejectionReason.ClericalError, + value: CorrectionReason.CLERICAL_ERROR, label: messages.clericalError }, { - value: RejectionReason.MaterialError, + value: CorrectionReason.MATERIAL_ERROR, label: messages.materialError }, { - value: RejectionReason.MaterialOmission, + value: CorrectionReason.MATERIAL_OMISSION, label: messages.materialOmission }, { - value: RejectionReason.JudicialOrder, + value: CorrectionReason.JUDICIAL_ORDER, label: messages.judicialOrder }, { - value: RejectionReason.Other, + value: CorrectionReason.OTHER, label: formMessages.otherOption } ], diff --git a/packages/client/src/i18n/messages/views/reject.ts b/packages/client/src/i18n/messages/views/reject.ts index e609214bde..940b1b4e2a 100644 --- a/packages/client/src/i18n/messages/views/reject.ts +++ b/packages/client/src/i18n/messages/views/reject.ts @@ -17,6 +17,8 @@ interface IRejectMessages rejectionForm: MessageDescriptor rejectionReason: MessageDescriptor rejectionReasonDuplicate: MessageDescriptor + rejectionReasonMisspelling: MessageDescriptor + rejectionReasonMissingSupportingDoc: MessageDescriptor rejectionReasonOther: MessageDescriptor rejectionCommentForHealthWorkerLabel: MessageDescriptor rejectionFormInstruction: MessageDescriptor @@ -61,6 +63,16 @@ const messagesToDefine: IRejectMessages = { defaultMessage: 'Mark as a duplicate', description: 'Label for rejection option duplicate' }, + rejectionReasonMisspelling: { + id: 'review.rejection.form.reasons.misspelling', + defaultMessage: 'Misspelling', + description: 'Label for rejection option misspelling' + }, + rejectionReasonMissingSupportingDoc: { + id: 'review.rej.form.reasons.missSupDoc', + defaultMessage: 'Missing supporting documents', + description: 'Label for rejection option missing supporting doc' + }, rejectionReasonOther: { id: 'review.rejection.form.reasons.other', defaultMessage: 'Other', diff --git a/packages/client/src/utils/gateway.ts b/packages/client/src/utils/gateway.ts index ef049e168c..aabe02a849 100644 --- a/packages/client/src/utils/gateway.ts +++ b/packages/client/src/utils/gateway.ts @@ -707,7 +707,7 @@ export type History = { output?: Maybe>> payment?: Maybe potentialDuplicates?: Maybe> - reason?: Maybe + reason?: Maybe regStatus?: Maybe requester?: Maybe requesterOther?: Maybe @@ -1158,7 +1158,7 @@ export type MutationMarkEventAsUnassignedArgs = { export type MutationMarkEventAsVoidedArgs = { comment: Scalars['String'] id: Scalars['String'] - reason: RejectionReason + reason: Scalars['String'] } export type MutationMarkMarriageAsCertifiedArgs = { @@ -1856,11 +1856,6 @@ export type RejectRegistrationInput = { } export enum RejectionReason { - ClericalError = 'CLERICAL_ERROR', - JudicialOrder = 'JUDICIAL_ORDER', - MaterialError = 'MATERIAL_ERROR', - MaterialOmission = 'MATERIAL_OMISSION', - Duplicate = 'DUPLICATE', Other = 'OTHER' } @@ -3128,7 +3123,7 @@ export type MarkBirthAsRegisteredMutation = { export type MarkEventAsVoidedMutationVariables = Exact<{ id: Scalars['String'] - reason: RejectionReason + reason: Scalars['String'] comment: Scalars['String'] }> @@ -3424,7 +3419,7 @@ export type FetchBirthRegistrationForReviewQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: RejectionReason | null + reason?: string | null duplicateOf?: string | null potentialDuplicates?: Array | null documents: Array<{ @@ -3758,7 +3753,7 @@ export type FetchBirthRegistrationForCertificateQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: RejectionReason | null + reason?: string | null otherReason?: string | null duplicateOf?: string | null potentialDuplicates?: Array | null @@ -4220,7 +4215,7 @@ export type FetchDeathRegistrationForReviewQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: RejectionReason | null + reason?: string | null duplicateOf?: string | null potentialDuplicates?: Array | null documents: Array<{ @@ -4939,7 +4934,7 @@ export type FetchMarriageRegistrationForReviewQuery = { action?: RegAction | null regStatus?: RegStatus | null dhis2Notification?: boolean | null - reason?: RejectionReason | null + reason?: string | null documents: Array<{ __typename?: 'Attachment' id: string @@ -5293,7 +5288,7 @@ export type FetchMarriageRegistrationForCertificateQuery = { action?: RegAction | null regStatus?: RegStatus | null dhis2Notification?: boolean | null - reason?: RejectionReason | null + reason?: string | null statusReason?: { __typename?: 'StatusReason' text?: string | null @@ -8052,7 +8047,7 @@ export type FetchViewRecordByCompositionQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: RejectionReason | null + reason?: string | null statusReason?: { __typename?: 'StatusReason' text?: string | null @@ -8438,7 +8433,7 @@ export type FetchViewRecordByCompositionQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: RejectionReason | null + reason?: string | null statusReason?: { __typename?: 'StatusReason' text?: string | null @@ -8756,7 +8751,7 @@ export type FetchViewRecordByCompositionQuery = { regStatus?: RegStatus | null dhis2Notification?: boolean | null ipAddress?: string | null - reason?: RejectionReason | null + reason?: string | null statusReason?: { __typename?: 'StatusReason' text?: string | null diff --git a/packages/client/src/views/DataProvider/birth/mutations.ts b/packages/client/src/views/DataProvider/birth/mutations.ts index a964720654..a40694cb06 100644 --- a/packages/client/src/views/DataProvider/birth/mutations.ts +++ b/packages/client/src/views/DataProvider/birth/mutations.ts @@ -35,7 +35,7 @@ const REGISTER_BIRTH_DECLARATION = gql` const REJECT_BIRTH_DECLARATION = gql` mutation markEventAsVoided( $id: String! - $reason: RejectionReason! + $reason: String! $comment: String! ) { markEventAsVoided(id: $id, reason: $reason, comment: $comment) diff --git a/packages/client/src/views/DataProvider/death/mutations.ts b/packages/client/src/views/DataProvider/death/mutations.ts index 8e3771d4cb..53c5b926d5 100644 --- a/packages/client/src/views/DataProvider/death/mutations.ts +++ b/packages/client/src/views/DataProvider/death/mutations.ts @@ -35,7 +35,7 @@ const REGISTER_DEATH_DECLARATION = gql` const REJECT_DEATH_DECLARATION = gql` mutation markEventAsVoided( $id: String! - $reason: RejectionReason! + $reason: String! $comment: String! ) { markEventAsVoided(id: $id, reason: $reason, comment: $comment) diff --git a/packages/client/src/views/DataProvider/marriage/mutations.ts b/packages/client/src/views/DataProvider/marriage/mutations.ts index 4bc43262e6..46d7c0988f 100644 --- a/packages/client/src/views/DataProvider/marriage/mutations.ts +++ b/packages/client/src/views/DataProvider/marriage/mutations.ts @@ -36,7 +36,7 @@ const REGISTER_MARRIAGE_DECLARATION = gql` const REJECT_MARRIAGE_DECLARATION = gql` mutation markEventAsVoided( $id: String! - $reason: RejectionReason! + $reason: String! $comment: String! ) { markEventAsVoided(id: $id, reason: $reason, comment: $comment) diff --git a/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx b/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx index 6efb069ee9..cc9db51995 100644 --- a/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx +++ b/packages/client/src/views/ReviewCorrection/ReviewCorrection.tsx @@ -26,11 +26,7 @@ import { WORKQUEUE_TABS } from '@client/components/interface/Navigation' import { RegisterForm } from '@client/views/RegisterForm/RegisterForm' import { useSelector } from 'react-redux' -import { - CorrectionInput, - History, - RejectionReason -} from '@client/utils/gateway' +import { CorrectionInput, History } from '@client/utils/gateway' import { getEventReviewForm } from '@client/forms/register/review-selectors' import { IStoreState } from '@client/store' @@ -56,6 +52,7 @@ import { rejectCorrection } from '@client/review/reject-correction' import { Summary } from '@opencrvs/components/lib/Summary' import { CorrectorRelationship } from '@client/forms/correction/corrector' import { messages } from '@client/i18n/messages/views/correction' +import { CorrectionReason } from '@client/forms/correction/reason' import { Text } from '@opencrvs/components/lib/Text' import { ColumnContentAlignment } from '@opencrvs/components/lib/common-types' import { @@ -188,15 +185,15 @@ const ReviewSummarySection = ({ declaration }: IPropsReviewSummarySection) => { const getReasonForRequest = () => { switch (correctionRequestTask.reason) { - case RejectionReason.ClericalError: + case CorrectionReason.CLERICAL_ERROR: return intl.formatMessage(messages.clericalError) - case RejectionReason.MaterialError: + case CorrectionReason.MATERIAL_ERROR: return intl.formatMessage(messages.materialError) - case RejectionReason.MaterialOmission: + case CorrectionReason.MATERIAL_OMISSION: return intl.formatMessage(messages.materialOmission) - case RejectionReason.JudicialOrder: + case CorrectionReason.JUDICIAL_ORDER: return intl.formatMessage(messages.judicialOrder) - case RejectionReason.Other: + case CorrectionReason.OTHER: return ( intl.formatMessage(messages.otherReason) + ' - ' + diff --git a/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx b/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx index f6a5a371f0..633830401b 100644 --- a/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx +++ b/packages/client/src/views/SysAdmin/Performance/CorrectionsReport.tsx @@ -21,7 +21,7 @@ import { import type { GQLCorrectionMetric } from '@client/utils/gateway-deprecated-do-not-use' import { messages } from '@client/i18n/messages/views/performance' import { messages as correctionMessages } from '@client/i18n/messages/views/correction' -import { RejectionReason } from '@client/utils/gateway' +import { CorrectionReason } from '@client/forms/correction/reason' import { useIntl } from 'react-intl' interface CorrectionsReportProps { @@ -65,7 +65,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === RejectionReason.ClericalError + ({ reason }) => reason === CorrectionReason.CLERICAL_ERROR ) )} @@ -81,7 +81,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === RejectionReason.MaterialError + ({ reason }) => reason === CorrectionReason.MATERIAL_ERROR ) )} @@ -97,7 +97,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === RejectionReason.MaterialOmission + ({ reason }) => reason === CorrectionReason.MATERIAL_OMISSION ) )} @@ -113,7 +113,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { {calculateTotal( data.filter( - ({ reason }) => reason === RejectionReason.JudicialOrder + ({ reason }) => reason === CorrectionReason.JUDICIAL_ORDER ) )} @@ -128,7 +128,7 @@ export function CorrectionsReport({ data }: CorrectionsReportProps) { value={ {calculateTotal( - data.filter(({ reason }) => reason === RejectionReason.Other) + data.filter(({ reason }) => reason === CorrectionReason.OTHER) )} } diff --git a/packages/gateway/src/features/registration/schema.graphql b/packages/gateway/src/features/registration/schema.graphql index 1178e382a1..26e8fdf92b 100644 --- a/packages/gateway/src/features/registration/schema.graphql +++ b/packages/gateway/src/features/registration/schema.graphql @@ -155,7 +155,7 @@ type History { action: RegAction note: String statusReason: StatusReason - reason: RejectionReason + reason: String requester: String requesterOther: String hasShowedVerifiedDocument: Boolean @@ -594,17 +594,12 @@ input ConfirmRegistrationInput { } enum RejectionReason { - DUPLICATE - CLERICAL_ERROR - MATERIAL_ERROR - MATERIAL_OMISSION - JUDICIAL_ORDER OTHER } input RejectRegistrationInput { - reason: RejectionReason! - comment: String! + reason: RejectionReason! # Rejection type + comment: String! # Free text comment for audit log } type Mutation { @@ -649,11 +644,7 @@ type Mutation { markBirthAsRegistered(id: ID!, details: BirthRegistrationInput!): ID! # updates status to 'registered' - registration clerk has accepted the declaration, it is now official - internally call update if details exists markBirthAsCertified(id: ID!, details: BirthRegistrationInput!): ID! # updates status to 'certified' - a printed certificate has been produced - internally call update if details exists markBirthAsIssued(id: ID!, details: BirthRegistrationInput!): ID! # updates status to 'certified' - a printed certificate has been produced - internally call update if details exists - markEventAsVoided( - id: String! - reason: RejectionReason! - comment: String! - ): ID! # updated status to 'voided' - the registration was captured in error + markEventAsVoided(id: String!, reason: String!, comment: String!): ID! # updated status to 'voided' - the registration was captured in error markEventAsReinstated(id: String!): Reinstated # updates status to 'reinstated' markEventAsNotDuplicate(id: String!): ID! # removes duplicates from composition markEventAsArchived( diff --git a/packages/gateway/src/graphql/schema.d.ts b/packages/gateway/src/graphql/schema.d.ts index 98bdcd1e96..6f14e9d66f 100644 --- a/packages/gateway/src/graphql/schema.d.ts +++ b/packages/gateway/src/graphql/schema.d.ts @@ -606,15 +606,6 @@ export interface GQLMarriageRegistrationInput { export type GQLVoid = any -export const enum GQLRejectionReason { - DUPLICATE = 'DUPLICATE', - CLERICAL_ERROR = 'CLERICAL_ERROR', - MATERIAL_ERROR = 'MATERIAL_ERROR', - MATERIAL_OMISSION = 'MATERIAL_OMISSION', - JUDICIAL_ORDER = 'JUDICIAL_ORDER', - OTHER = 'OTHER' -} - export interface GQLReinstated { taskEntryResourceID: string registrationStatus?: GQLRegStatus @@ -778,7 +769,7 @@ export interface GQLHistory { action?: GQLRegAction note?: string statusReason?: GQLStatusReason - reason?: GQLRejectionReason + reason?: string requester?: string requesterOther?: string hasShowedVerifiedDocument?: boolean @@ -1244,6 +1235,10 @@ export interface GQLIdentifierInput { value: string } +export const enum GQLRejectionReason { + OTHER = 'OTHER' +} + export interface GQLHumanNameInput { use?: string firstNames?: string @@ -2840,7 +2835,7 @@ export interface MutationToMarkBirthAsIssuedResolver< export interface MutationToMarkEventAsVoidedArgs { id: string - reason: GQLRejectionReason + reason: string comment: string } export interface MutationToMarkEventAsVoidedResolver< diff --git a/packages/gateway/src/graphql/schema.graphql b/packages/gateway/src/graphql/schema.graphql index 8cc0abedb7..bdccb8753a 100644 --- a/packages/gateway/src/graphql/schema.graphql +++ b/packages/gateway/src/graphql/schema.graphql @@ -192,11 +192,7 @@ type Mutation { markBirthAsRegistered(id: ID!, details: BirthRegistrationInput!): ID! markBirthAsCertified(id: ID!, details: BirthRegistrationInput!): ID! markBirthAsIssued(id: ID!, details: BirthRegistrationInput!): ID! - markEventAsVoided( - id: String! - reason: RejectionReason! - comment: String! - ): ID! + markEventAsVoided(id: String!, reason: String!, comment: String!): ID! markEventAsReinstated(id: String!): Reinstated markEventAsNotDuplicate(id: String!): ID! markEventAsArchived( @@ -725,15 +721,6 @@ input MarriageRegistrationInput { scalar Void -enum RejectionReason { - DUPLICATE - CLERICAL_ERROR - MATERIAL_ERROR - MATERIAL_OMISSION - JUDICIAL_ORDER - OTHER -} - type Reinstated { taskEntryResourceID: ID! registrationStatus: RegStatus @@ -897,7 +884,7 @@ type History { action: RegAction note: String statusReason: StatusReason - reason: RejectionReason + reason: String requester: String requesterOther: String hasShowedVerifiedDocument: Boolean @@ -1339,6 +1326,10 @@ input IdentifierInput { value: String! } +enum RejectionReason { + OTHER +} + input HumanNameInput { use: String firstNames: String From 201cec797c77198a0e891721e2c46ec78ea1c97a Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 15:12:30 +0300 Subject: [PATCH 12/22] refactor: stop using global interception in workflow tests --- .../fhir/fhir-bundle-modifier.test.ts | 4 +- .../src/features/registration/utils.test.ts | 6 +- .../workflow/src/features/user/utils.test.ts | 6 +- .../src/records/handler/archive.test.ts | 4 +- .../src/records/handler/certify.test.ts | 4 +- .../src/records/handler/create.test.ts | 56 +++++++++---------- .../src/records/handler/download.test.ts | 4 +- .../src/records/handler/duplicate.test.ts | 4 +- .../src/records/handler/issue.test.ts | 4 +- .../src/records/handler/not-duplicate.test.ts | 4 +- .../src/records/handler/register.test.ts | 4 +- .../src/records/handler/reinstate.test.ts | 4 +- .../src/records/handler/reject.test.ts | 4 +- .../src/records/handler/unassign.test.ts | 4 +- .../src/records/handler/update.test.ts | 4 +- .../src/records/handler/validate.test.ts | 4 +- .../src/records/handler/verify.test.ts | 4 +- .../workflow/src/records/handler/view.test.ts | 6 +- packages/workflow/test/setupServer.ts | 25 ++++++++- packages/workflow/test/setupTest.ts | 12 ---- 20 files changed, 104 insertions(+), 63 deletions(-) diff --git a/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts b/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts index 5f25a79e01..615f172ce3 100644 --- a/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts +++ b/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { server as mswServer } from '@test/setupServer' +import { useRequestMocks } from '@test/setupServer' import { rest } from 'msw' import { setupRegistrationWorkflow, @@ -219,6 +219,8 @@ describe('Verify fhir bundle modifier functions', () => { }) describe('validateDeceasedDetails functions', () => { + const mswServer = useRequestMocks() + let token: string let authHeader: { Authorization: string } beforeEach(async () => { diff --git a/packages/workflow/src/features/registration/utils.test.ts b/packages/workflow/src/features/registration/utils.test.ts index af04631409..a97c2f3db7 100644 --- a/packages/workflow/src/features/registration/utils.test.ts +++ b/packages/workflow/src/features/registration/utils.test.ts @@ -20,13 +20,15 @@ import { import * as fetchAny from 'jest-fetch-mock' import { EVENT_TYPE } from '@workflow/features/registration/fhir/constants' import { Bundle } from '@opencrvs/commons/types' -import { server as mswServer } from '@test/setupServer' import { rest } from 'msw' import { MOSIP_TOKEN_SEEDER_URL } from '@workflow/constants' +import { useRequestMocks } from '@test/setupServer' const fetch = fetchAny as any describe('Verify utility functions', () => { + const mswServer = useRequestMocks() + beforeEach(async () => { fetch.resetMocks() }) @@ -90,6 +92,8 @@ describe('Verify utility functions', () => { }) describe('getMosipUINToken functions', () => { + const mswServer = useRequestMocks() + beforeAll(() => { fetch.mockClear() }) diff --git a/packages/workflow/src/features/user/utils.test.ts b/packages/workflow/src/features/user/utils.test.ts index 4b69f9bc23..f0a3e9a92f 100644 --- a/packages/workflow/src/features/user/utils.test.ts +++ b/packages/workflow/src/features/user/utils.test.ts @@ -19,12 +19,14 @@ import * as jwt from 'jsonwebtoken' import * as fetchAny from 'jest-fetch-mock' import { Practitioner } from '@opencrvs/commons/types' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { useRequestMocks } from '@test/setupServer' import { USER_MANAGEMENT_URL } from '@workflow/__mocks__/constants' const fetch = fetchAny as any describe('Verify getLoggedInPractitionerResource', () => { + const mswServer = useRequestMocks() + it('Returns Location properly', async () => { mswServer.use( rest.post('http://localhost:3030/getUser', (_, res, ctx) => @@ -111,6 +113,8 @@ describe('Verify getLoggedInPractitionerResource', () => { }) }) describe('Verify getUser', () => { + const mswServer = useRequestMocks() + it('get user mobile throw an error in case of an bad response', async () => { mswServer.use( rest.post(`${USER_MANAGEMENT_URL}getUser`, (_, res, ctx) => diff --git a/packages/workflow/src/records/handler/archive.test.ts b/packages/workflow/src/records/handler/archive.test.ts index 8564e9dcbd..ba13a9e13e 100644 --- a/packages/workflow/src/records/handler/archive.test.ts +++ b/packages/workflow/src/records/handler/archive.test.ts @@ -8,7 +8,6 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { server as mswServer } from '@test/setupServer' import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import { rest } from 'msw' @@ -21,8 +20,11 @@ import { ValidRecord } from '@opencrvs/commons/types' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' +import { handlers, useRequestMocks } from '@test/setupServer' describe('archive record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/certify.test.ts b/packages/workflow/src/records/handler/certify.test.ts index 56a9af5e17..d0c7f1164a 100644 --- a/packages/workflow/src/records/handler/certify.test.ts +++ b/packages/workflow/src/records/handler/certify.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { getStatusFromTask, getTaskFromSavedBundle, @@ -23,6 +23,8 @@ import { import { REGISTERED_BIRTH_RECORD } from '@test/mocks/records/register' describe('Certify record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/create.test.ts b/packages/workflow/src/records/handler/create.test.ts index 6842c6cf7c..7f7d690b94 100644 --- a/packages/workflow/src/records/handler/create.test.ts +++ b/packages/workflow/src/records/handler/create.test.ts @@ -8,20 +8,23 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { createBirthRegistrationPayload } from '@test/mocks/createBirthRecord' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { rest } from 'msw' import { SavedBundle, SavedTask, TransactionResponse, URLReference, - SavedLocation + SavedLocation, + EVENT_TYPE } from '@opencrvs/commons/types' -import { UUID } from '@opencrvs/commons' +import { PlainToken, UUID } from '@opencrvs/commons' +import { startContainer, stopContainer } from '@workflow/test/redis' +import { StartedTestContainer } from 'testcontainers' +import { registerRecordHandler } from './create' const existingTaskBundle: SavedBundle = { resourceType: 'Bundle', @@ -44,17 +47,18 @@ const existingLocationBundle: SavedBundle = { ] } -describe('Create record endpoint', () => { - let server: Awaited> +let container: StartedTestContainer - beforeAll(async () => { - server = await createServer() - await server.start() - }) +beforeAll(async () => { + container = await startContainer() +}) - afterAll(async () => { - await server.stop() - }) +afterAll(async () => { + await stopContainer(container) +}) + +describe('Create record endpoint', () => { + const mswServer = useRequestMocks(...handlers) it('returns OK for a correctly authenticated user with birth declaration', async () => { const token = jwt.sign( @@ -65,7 +69,7 @@ describe('Create record endpoint', () => { issuer: 'opencrvs:auth-service', audience: 'opencrvs:workflow-user' } - ) + ) as PlainToken // used for checking already created composition with // the same draftId @@ -150,22 +154,12 @@ describe('Create record endpoint', () => { }) ) - const res = await server.server.inject({ - method: 'POST', - url: '/create-record', - payload: { - event: 'BIRTH', - record: createBirthRegistrationPayload - }, - headers: { - Authorization: `Bearer ${token}` - } - }) - expect(res.statusCode).toBe(200) - expect(JSON.parse(res.payload)).toMatchObject({ - trackingId: 'BYW6MFW', - compositionId: '3bd79ffd-5bd7-489f-b0d2-3c6133d36e1e', - isPotentiallyDuplicate: false - }) + const record = await registerRecordHandler( + createBirthRegistrationPayload, + EVENT_TYPE.BIRTH, + token + ) + + expect(record).toBeDefined() }) }) diff --git a/packages/workflow/src/records/handler/download.test.ts b/packages/workflow/src/records/handler/download.test.ts index 29b5e2b09d..018d9d0a97 100644 --- a/packages/workflow/src/records/handler/download.test.ts +++ b/packages/workflow/src/records/handler/download.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' import { getTaskFromSavedBundle, Task } from '@opencrvs/commons/types' @@ -23,6 +23,8 @@ function checkForDownloadExtenstion(task: Task) { } describe('download record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/duplicate.test.ts b/packages/workflow/src/records/handler/duplicate.test.ts index fc542dd7d4..d5a73539da 100644 --- a/packages/workflow/src/records/handler/duplicate.test.ts +++ b/packages/workflow/src/records/handler/duplicate.test.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import { rest } from 'msw' @@ -51,6 +51,8 @@ function findDuplicateTrackingId(task: SavedTask) { } describe('duplicate record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/issue.test.ts b/packages/workflow/src/records/handler/issue.test.ts index b780470191..1740912182 100644 --- a/packages/workflow/src/records/handler/issue.test.ts +++ b/packages/workflow/src/records/handler/issue.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { getStatusFromTask, getTaskFromSavedBundle, @@ -23,6 +23,8 @@ import { import { CERTIFIED_BIRTH_RECORD } from '@test/mocks/records/certify' describe('Issue record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/not-duplicate.test.ts b/packages/workflow/src/records/handler/not-duplicate.test.ts index 5d553973a6..6f49a2843c 100644 --- a/packages/workflow/src/records/handler/not-duplicate.test.ts +++ b/packages/workflow/src/records/handler/not-duplicate.test.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import { rest } from 'msw' @@ -30,6 +30,8 @@ function hasDeduplicateExtension(task: SavedTask) { } describe('not-duplicate record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/register.test.ts b/packages/workflow/src/records/handler/register.test.ts index de4dd9a711..e07255dfc0 100644 --- a/packages/workflow/src/records/handler/register.test.ts +++ b/packages/workflow/src/records/handler/register.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { getStatusFromTask, getTaskFromSavedBundle, @@ -24,6 +24,8 @@ import { updateBirthRegistrationPayload } from '@test/mocks/updateBirthRecord' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' describe('Register record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/reinstate.test.ts b/packages/workflow/src/records/handler/reinstate.test.ts index 3847e5db1b..46c764d459 100644 --- a/packages/workflow/src/records/handler/reinstate.test.ts +++ b/packages/workflow/src/records/handler/reinstate.test.ts @@ -11,7 +11,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { rest } from 'msw' import * as jwt from 'jsonwebtoken' import { @@ -29,6 +29,8 @@ function getRegStatus(record: ReadyForReviewRecord | RegisteredRecord) { } describe('reinstate record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/reject.test.ts b/packages/workflow/src/records/handler/reject.test.ts index e94cdd4079..7167de49c3 100644 --- a/packages/workflow/src/records/handler/reject.test.ts +++ b/packages/workflow/src/records/handler/reject.test.ts @@ -11,7 +11,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { rest } from 'msw' import { getStatusFromTask, @@ -28,6 +28,8 @@ function getReasonFromTask(task: SavedTask) { } describe('Reject record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/unassign.test.ts b/packages/workflow/src/records/handler/unassign.test.ts index 9a40b49841..c78fe7af29 100644 --- a/packages/workflow/src/records/handler/unassign.test.ts +++ b/packages/workflow/src/records/handler/unassign.test.ts @@ -13,7 +13,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { bundleWithAssignedTask } from '@test/mocks/unassignedTask' import { getTaskFromSavedBundle, Task } from '@opencrvs/commons/types' import { registrar } from '@test/mocks/user' @@ -25,6 +25,8 @@ function checkForUnassignExtenstion(task: Task) { } describe('unassign record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/update.test.ts b/packages/workflow/src/records/handler/update.test.ts index 5ea7a59a6b..fdebd30177 100644 --- a/packages/workflow/src/records/handler/update.test.ts +++ b/packages/workflow/src/records/handler/update.test.ts @@ -13,7 +13,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' import { getStatusFromTask, @@ -24,6 +24,8 @@ import { } from '@opencrvs/commons/types' describe('Update record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/validate.test.ts b/packages/workflow/src/records/handler/validate.test.ts index 4b7fa383af..99c066c65e 100644 --- a/packages/workflow/src/records/handler/validate.test.ts +++ b/packages/workflow/src/records/handler/validate.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' import { getStatusFromTask, @@ -23,6 +23,8 @@ import { } from '@opencrvs/commons/types' describe('Validate record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/verify.test.ts b/packages/workflow/src/records/handler/verify.test.ts index 38b40a04de..e258ef5f05 100644 --- a/packages/workflow/src/records/handler/verify.test.ts +++ b/packages/workflow/src/records/handler/verify.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { getTaskFromSavedBundle, REGISTERED_RECORD, @@ -33,6 +33,8 @@ function findVerificationIp(task: Task) { } describe('verify record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/view.test.ts b/packages/workflow/src/records/handler/view.test.ts index 4757432ece..e84a296d5c 100644 --- a/packages/workflow/src/records/handler/view.test.ts +++ b/packages/workflow/src/records/handler/view.test.ts @@ -9,13 +9,13 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { server as mswServer } from '@test/setupServer' +import { handlers, useRequestMocks } from '@test/setupServer' import { getTaskFromSavedBundle, Task } from '@opencrvs/commons/types' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' +import { createServer } from '@workflow/server' function checkForViewedExtenstion(task: Task) { return task.extension.find( @@ -24,6 +24,8 @@ function checkForViewedExtenstion(task: Task) { } describe('View record endpoint', () => { + const mswServer = useRequestMocks(...handlers) + let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/test/setupServer.ts b/packages/workflow/test/setupServer.ts index 66dc5d33d4..cdc0c64cb5 100644 --- a/packages/workflow/test/setupServer.ts +++ b/packages/workflow/test/setupServer.ts @@ -8,8 +8,29 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { RestHandler, MockedRequest, DefaultBodyType } from 'msw' import { setupServer } from 'msw/node' import handlers from './handlers' -// This configures a request mocking server with the given request handlers. -export const server = setupServer(...handlers) +/** Setups a test server with mock request handlers */ +export const useRequestMocks = ( + ...handlers: RestHandler>[] +) => { + const server = setupServer(...handlers) + + // Establish API mocking before all tests. + beforeAll(() => { + server.listen({ onUnhandledRequest: 'error' }) + }) + + // Reset any request handlers that we may add during the tests, + // so they don't affect other tests. + afterEach(() => server.resetHandlers()) + + // Clean up after the tests are finished. + afterAll(() => server.close()) + + return server +} + +export { handlers } diff --git a/packages/workflow/test/setupTest.ts b/packages/workflow/test/setupTest.ts index b52d817be3..176e20a5a1 100644 --- a/packages/workflow/test/setupTest.ts +++ b/packages/workflow/test/setupTest.ts @@ -8,17 +8,5 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { server } from './setupServer' jest.mock('@workflow/constants') -// Establish API mocking before all tests. -beforeAll(() => { - server.listen({ onUnhandledRequest: 'error' }) -}) - -// Reset any request handlers that we may add during the tests, -// so they don't affect other tests. -afterEach(() => server.resetHandlers()) - -// Clean up after the tests are finished. -afterAll(() => server.close()) From edb08fb48f61045d7cd3df89a6f72149d5e99538 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 16:29:24 +0300 Subject: [PATCH 13/22] chore: allow specifying the port to the queue --- packages/commons/src/message-queue/record.ts | 10 +++++----- packages/workflow/src/server.ts | 5 +++-- packages/workflow/src/workers.ts | 7 +++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/commons/src/message-queue/record.ts b/packages/commons/src/message-queue/record.ts index bde9a4313d..7a145492db 100644 --- a/packages/commons/src/message-queue/record.ts +++ b/packages/commons/src/message-queue/record.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { Job, Processor, Queue, Worker } from 'bullmq' +import { ConnectionOptions, Job, Processor, Queue, Worker } from 'bullmq' import { PlainToken } from '../http' import { logger } from '../logger' import { @@ -142,7 +142,7 @@ export function useRecordQueue(redisHost: string) { } export async function registerRecordWorker( - redisHost: string, + connection: ConnectionOptions, processJob: Processor ) { const worker = new Worker( @@ -151,7 +151,7 @@ export async function registerRecordWorker( return processJob(job) }, { - connection: { host: redisHost, port: 6379 } + connection } ) @@ -167,7 +167,7 @@ export async function registerRecordWorker( } export async function registerExternalValidationsWorker( - redisHost: string, + connection: ConnectionOptions, processJob: ( job: | Job @@ -184,7 +184,7 @@ export async function registerExternalValidationsWorker( return processJob(job) }, { - connection: { host: redisHost, port: 6379 } + connection } ) diff --git a/packages/workflow/src/server.ts b/packages/workflow/src/server.ts index 8581c9671e..8ed6add1db 100644 --- a/packages/workflow/src/server.ts +++ b/packages/workflow/src/server.ts @@ -14,7 +14,8 @@ import { HOST, PORT, CERT_PUBLIC_KEY_PATH, - DEFAULT_TIMEOUT + DEFAULT_TIMEOUT, + REDIS_HOST } from '@workflow/constants' import getPlugins from '@workflow/config/plugins' import { getRoutes } from '@workflow/config/routes' @@ -62,7 +63,7 @@ export async function createServer() { async function start() { await server.start() - await register() + await register({ host: REDIS_HOST, port: 6379 }) server.log('info', `Workflow server started on ${HOST}:${PORT}`) } diff --git a/packages/workflow/src/workers.ts b/packages/workflow/src/workers.ts index e95b7bff4e..193c70c907 100644 --- a/packages/workflow/src/workers.ts +++ b/packages/workflow/src/workers.ts @@ -13,7 +13,6 @@ import { registerExternalValidationsWorker, registerRecordWorker } from '@opencrvs/commons/message-queue' -import { REDIS_HOST } from './constants' import { invokeRegistrationValidation } from './features/registration/fhir/fhir-bundle-modifier' import { markEventAsRegistered } from './features/registration/handler' import { @@ -22,8 +21,8 @@ import { validateRecordHandler } from './records/handler/create' -export async function register() { - await registerExternalValidationsWorker(REDIS_HOST, async (job) => { +export async function register(connection: { host: string; port: number }) { + await registerExternalValidationsWorker(connection, async (job) => { if (job.name === 'send-to-external-validation') { const { token, record } = job.data return invokeRegistrationValidation( @@ -36,7 +35,7 @@ export async function register() { return markEventAsRegistered(job.data) } }) - await registerRecordWorker(REDIS_HOST, async (job) => { + await registerRecordWorker(connection, async (job) => { if (job.name === 'create-registration') { return registerRecordHandler( job.data.payload, From 767169fc83668fdd36112851bae451de0940b272 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 16:30:38 +0300 Subject: [PATCH 14/22] feat: add testcontainers --- packages/workflow/package.json | 1 + packages/workflow/src/test/redis.ts | 40 +++++++++++++++++++++ yarn.lock | 56 ++++++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 packages/workflow/src/test/redis.ts diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 2edfdef75e..9078f2e452 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -59,6 +59,7 @@ "msw": "^1.3.2", "nodemon": "^3.0.0", "prettier": "2.8.8", + "testcontainers": "^9.1.1", "ts-jest": "27.1.4", "ts-node": "^6.1.1", "typescript": "4.9.5" diff --git a/packages/workflow/src/test/redis.ts b/packages/workflow/src/test/redis.ts new file mode 100644 index 0000000000..72293561c9 --- /dev/null +++ b/packages/workflow/src/test/redis.ts @@ -0,0 +1,40 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * OpenCRVS is also distributed under the terms of the Civil Registration + * & Healthcare Disclaimer located at http://opencrvs.org/license. + * + * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. + */ +import { GenericContainer, type StartedTestContainer } from 'testcontainers' +import * as queueWorkers from '@workflow/workers' + +const REDIS_HTTP_PORT = 6379 + +const container = new GenericContainer('redis:5') + +export const startContainer = async () => { + const testContainer = await container + .withExposedPorts(REDIS_HTTP_PORT) + .withStartupTimeout(120_000) + .start() + + await queueWorkers.register({ + host: testContainer.getHost(), + port: testContainer.getMappedPort(REDIS_HTTP_PORT) + }) + + return testContainer +} + +export const stopContainer = async (container: StartedTestContainer) => { + try { + // @TODO: How to stop the client? + // await redisClient.stop() + } catch (error) { + } finally { + await container.stop() + } +} diff --git a/yarn.lock b/yarn.lock index cc0e5c373b..3a7b4591ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7891,7 +7891,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@18.3.1", "@types/react@>=16", "@types/react@^16": +"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@18.3.1", "@types/react@>=16": version "18.3.1" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.1.tgz#fed43985caa834a2084d002e4771e15dfcbdbe8e" integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw== @@ -7899,6 +7899,15 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/react@^16": + version "16.14.62" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.62.tgz#449e4e81caaf132d0c2c390644e577702db1dd9e" + integrity sha512-BWf7hqninZav6nerxXj+NeZT/mTpDeG6Lk2zREHAy63CrnXoOGPGtNqTFYFN/sqpSaREDP5otVV88axIXmKfGA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "^0.16" + csstype "^3.0.2" + "@types/readdir-glob@*": version "1.1.3" resolved "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.3.tgz" @@ -7967,6 +7976,11 @@ dependencies: htmlparser2 "^8.0.0" +"@types/scheduler@^0.16": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + "@types/semver@^7.3.4": version "7.5.4" resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz" @@ -13297,7 +13311,14 @@ fast-url-parser@1.1.3, fast-url-parser@^1.1.3: dependencies: punycode "^1.3.2" -fast-xml-parser@4.2.5, fast-xml-parser@4.4.1, fast-xml-parser@^4.1.3, fast-xml-parser@^4.2.2: +fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" + +fast-xml-parser@^4.1.3, fast-xml-parser@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz#86dbf3f18edf8739326447bcaac31b4ae7f6514f" integrity sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw== @@ -21838,7 +21859,16 @@ string-similarity@^4.0.1: resolved "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz" integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -21998,7 +22028,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -22019,6 +22049,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" @@ -24129,7 +24166,7 @@ workbox-window@7.1.0, workbox-window@^7.1.0: "@types/trusted-types" "^2.0.2" workbox-core "7.1.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -24156,6 +24193,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" From 5fca7b0a40213e651bc146241a985186d290498b Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 16:56:38 +0300 Subject: [PATCH 15/22] chore: add host&port to missing places --- packages/commons/src/message-queue/record.ts | 12 ++++-------- packages/workflow/src/records/handler/confirm.ts | 5 ++++- packages/workflow/src/records/handler/create.ts | 5 ++++- packages/workflow/src/records/handler/register.ts | 5 ++++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/commons/src/message-queue/record.ts b/packages/commons/src/message-queue/record.ts index 7a145492db..85325007a7 100644 --- a/packages/commons/src/message-queue/record.ts +++ b/packages/commons/src/message-queue/record.ts @@ -52,12 +52,10 @@ type Payload = token: PlainToken } -export function useExternalValidationQueue(redisHost: string) { +export function useExternalValidationQueue(connection: ConnectionOptions) { const queue = new Queue( 'external-validations', - { - connection: { host: redisHost, port: 6379 } - } + { connection } ) async function sendForExternalValidation(payload: ExternalValidationPayload) { @@ -90,10 +88,8 @@ export function useExternalValidationQueue(redisHost: string) { sendForExternalValidation } } -export function useRecordQueue(redisHost: string) { - const queue = new Queue('records', { - connection: { host: redisHost, port: 6379 } - }) +export function useRecordQueue(connection: ConnectionOptions) { + const queue = new Queue('records', { connection }) async function createDeclaration(payload: Payload) { await queue.waitUntilReady() diff --git a/packages/workflow/src/records/handler/confirm.ts b/packages/workflow/src/records/handler/confirm.ts index 477a7968a8..f547e1a640 100644 --- a/packages/workflow/src/records/handler/confirm.ts +++ b/packages/workflow/src/records/handler/confirm.ts @@ -29,7 +29,10 @@ const requestSchema = z.object({ trackingId: z.string() }) -const { recordValidated } = useExternalValidationQueue(REDIS_HOST) +const { recordValidated } = useExternalValidationQueue({ + host: REDIS_HOST, + port: 6379 +}) export async function confirmRegistrationHandler( request: Hapi.Request, diff --git a/packages/workflow/src/records/handler/create.ts b/packages/workflow/src/records/handler/create.ts index 9d6954bcf4..7a5be23aca 100644 --- a/packages/workflow/src/records/handler/create.ts +++ b/packages/workflow/src/records/handler/create.ts @@ -88,7 +88,10 @@ const requestSchema = z.object({ >() }) -const { sendForExternalValidation } = useExternalValidationQueue(REDIS_HOST) +const { sendForExternalValidation } = useExternalValidationQueue({ + host: REDIS_HOST, + port: 6379 +}) function findTask(bundle: Bundle) { const task = bundle.entry.map((e) => e.resource).find(isTask) diff --git a/packages/workflow/src/records/handler/register.ts b/packages/workflow/src/records/handler/register.ts index 33c9b077c4..c0e546a1c1 100644 --- a/packages/workflow/src/records/handler/register.ts +++ b/packages/workflow/src/records/handler/register.ts @@ -19,7 +19,10 @@ import { getToken } from '@workflow/utils/auth-utils' import { validateRequest } from '@workflow/utils/index' import * as z from 'zod' -const { sendForExternalValidation } = useExternalValidationQueue(REDIS_HOST) +const { sendForExternalValidation } = useExternalValidationQueue({ + host: REDIS_HOST, + port: 6379 +}) export const registerRoute = createRoute({ method: 'POST', From ed761f9311962e060af8744303232bff95a45e88 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 18:48:45 +0300 Subject: [PATCH 16/22] refactor: add port and host to redis call --- packages/workflow/src/constants.ts | 2 ++ packages/workflow/src/records/handler/confirm.ts | 4 ++-- packages/workflow/src/records/handler/create.ts | 4 ++-- packages/workflow/src/records/handler/register.ts | 4 ++-- packages/workflow/src/server.ts | 3 ++- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/workflow/src/constants.ts b/packages/workflow/src/constants.ts index e167123cf5..8d2c6e7e46 100644 --- a/packages/workflow/src/constants.ts +++ b/packages/workflow/src/constants.ts @@ -12,6 +12,7 @@ import { cleanEnv, str, num, url } from 'envalid' const env = cleanEnv(process.env, { REDIS_HOST: str({ devDefault: 'localhost' }), + REDIS_PORT: num({ default: 6379 }), HOST: str({ default: '0.0.0.0' }), PORT: num({ default: 5050 }), FHIR_URL: url({ devDefault: 'http://localhost:3447/fhir' }), @@ -32,6 +33,7 @@ const env = cleanEnv(process.env, { export const { REDIS_HOST, + REDIS_PORT, HOST, PORT, FHIR_URL, diff --git a/packages/workflow/src/records/handler/confirm.ts b/packages/workflow/src/records/handler/confirm.ts index f547e1a640..dc86dbea0a 100644 --- a/packages/workflow/src/records/handler/confirm.ts +++ b/packages/workflow/src/records/handler/confirm.ts @@ -12,7 +12,7 @@ import * as z from 'zod' import { getToken } from '@workflow/utils/auth-utils' import { validateRequest } from '@workflow/utils/index' import { useExternalValidationQueue } from '@opencrvs/commons/message-queue' -import { REDIS_HOST } from '@workflow/constants' +import { REDIS_HOST, REDIS_PORT } from '@workflow/constants' import { SUPPORTED_PATIENT_IDENTIFIER_CODES } from '@opencrvs/commons/types' import * as Hapi from '@hapi/hapi' @@ -31,7 +31,7 @@ const requestSchema = z.object({ const { recordValidated } = useExternalValidationQueue({ host: REDIS_HOST, - port: 6379 + port: REDIS_PORT }) export async function confirmRegistrationHandler( diff --git a/packages/workflow/src/records/handler/create.ts b/packages/workflow/src/records/handler/create.ts index 7a5be23aca..f9953d8794 100644 --- a/packages/workflow/src/records/handler/create.ts +++ b/packages/workflow/src/records/handler/create.ts @@ -62,7 +62,7 @@ import { } from '@workflow/records/fhir' import { useExternalValidationQueue } from '@opencrvs/commons/message-queue' -import { REDIS_HOST } from '@workflow/constants' +import { REDIS_HOST, REDIS_PORT } from '@workflow/constants' import { getRecordById } from '@workflow/records' import { isNotificationEnabled, @@ -90,7 +90,7 @@ const requestSchema = z.object({ const { sendForExternalValidation } = useExternalValidationQueue({ host: REDIS_HOST, - port: 6379 + port: REDIS_PORT }) function findTask(bundle: Bundle) { diff --git a/packages/workflow/src/records/handler/register.ts b/packages/workflow/src/records/handler/register.ts index c0e546a1c1..214e48e69c 100644 --- a/packages/workflow/src/records/handler/register.ts +++ b/packages/workflow/src/records/handler/register.ts @@ -10,7 +10,7 @@ */ import { useExternalValidationQueue } from '@opencrvs/commons/message-queue' import { getComposition } from '@opencrvs/commons/types' -import { REDIS_HOST } from '@workflow/constants' +import { REDIS_HOST, REDIS_PORT } from '@workflow/constants' import { writeMetricsEvent } from '@workflow/records/audit' import { indexBundle } from '@workflow/records/search' import { toWaitingForExternalValidationState } from '@workflow/records/state-transitions' @@ -21,7 +21,7 @@ import * as z from 'zod' const { sendForExternalValidation } = useExternalValidationQueue({ host: REDIS_HOST, - port: 6379 + port: REDIS_PORT }) export const registerRoute = createRoute({ diff --git a/packages/workflow/src/server.ts b/packages/workflow/src/server.ts index 8ed6add1db..d24a0e2b69 100644 --- a/packages/workflow/src/server.ts +++ b/packages/workflow/src/server.ts @@ -15,6 +15,7 @@ import { PORT, CERT_PUBLIC_KEY_PATH, DEFAULT_TIMEOUT, + REDIS_PORT, REDIS_HOST } from '@workflow/constants' import getPlugins from '@workflow/config/plugins' @@ -63,7 +64,7 @@ export async function createServer() { async function start() { await server.start() - await register({ host: REDIS_HOST, port: 6379 }) + await register({ host: REDIS_HOST, port: REDIS_PORT }) server.log('info', `Workflow server started on ${HOST}:${PORT}`) } From b72601b6f9b1af66301f35b28e1f8ca1c5f0b670 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 22:16:30 +0300 Subject: [PATCH 17/22] chore: clean up testcontainers --- packages/workflow/package.json | 1 - .../src/records/handler/register.test.ts | 102 ++---------------- packages/workflow/src/test/redis.ts | 40 ------- yarn.lock | 25 +---- 4 files changed, 13 insertions(+), 155 deletions(-) delete mode 100644 packages/workflow/src/test/redis.ts diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 9078f2e452..2edfdef75e 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -59,7 +59,6 @@ "msw": "^1.3.2", "nodemon": "^3.0.0", "prettier": "2.8.8", - "testcontainers": "^9.1.1", "ts-jest": "27.1.4", "ts-node": "^6.1.1", "typescript": "4.9.5" diff --git a/packages/workflow/src/records/handler/register.test.ts b/packages/workflow/src/records/handler/register.test.ts index e07255dfc0..d41aff75a7 100644 --- a/packages/workflow/src/records/handler/register.test.ts +++ b/packages/workflow/src/records/handler/register.test.ts @@ -26,18 +26,10 @@ import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForRevie describe('Register record endpoint', () => { const mswServer = useRequestMocks(...handlers) - let server: Awaited> - - beforeAll(async () => { - server = await createServer() + it('flows the registration to waiting for validation', async () => { + const server = await createServer() await server.start() - }) - - afterAll(async () => { - await server.stop() - }) - it('returns OK for a correctly authenticated user rejecting a birth declaration', async () => { const token = jwt.sign( { scope: ['register'] }, readFileSync('./test/cert.key'), @@ -58,13 +50,6 @@ describe('Register record endpoint', () => { ) ) - // Mock response from country-config - mswServer.use( - rest.post('http://localhost:3040/event-registration', (_, res, ctx) => { - return res(ctx.status(400)) - }) - ) - // Mock response from hearth mswServer.use( rest.post('http://localhost:3447/fhir', (_, res, ctx) => { @@ -85,6 +70,13 @@ describe('Register record endpoint', () => { }) ) + // Mock response from country-config + mswServer.use( + rest.post('http://localhost:3040/event-registration', (_, res, ctx) => { + return res(ctx.status(200)) + }) + ) + const response = await server.server.inject({ method: 'POST', url: '/records/7c3af302-08c9-41af-8701-92de9a71a3e4/register', @@ -104,79 +96,7 @@ describe('Register record endpoint', () => { const businessStatus = getStatusFromTask(task) expect(response.statusCode).toBe(200) - expect(businessStatus).toBe('REJECTED') - }) - - it('returns OK for a correctly authenticated user registering a birth declaration', async () => { - const token = jwt.sign( - { scope: ['register'] }, - readFileSync('./test/cert.key'), - { - algorithm: 'RS256', - issuer: 'opencrvs:auth-service', - audience: 'opencrvs:workflow-user' - } - ) - - // Gets record by id via getRecordById endpoint - mswServer.use( - rest.get( - 'http://localhost:9090/records/7c3af302-08c9-41af-8701-92de9a71a3e4', - (_, res, ctx) => { - return res(ctx.json(READY_FOR_REVIEW_BIRTH_RECORD)) - } - ) - ) - - // Mock response from hearth - mswServer.use( - rest.post('http://localhost:3447/fhir', (_, res, ctx) => { - const responseBundle: TransactionResponse = { - resourceType: 'Bundle', - type: 'batch-response', - entry: [ - { - response: { - status: '200', - location: - '/fhir/Task/f00e742a-0900-488b-b7c1-9625d7b7e456/_history/dc39332f-a5d7-4422-ba7b-bc99a958e8cb' as URLReference - } - }, - { - response: { - status: '200', - location: - '/fhir/Patient/8cb74e54-1c02-41a7-86a3-415c4031c9ba/_history/dc39332f-a5d7-4422-ba7b-bc99a958e8cb' as URLReference - } - } - ] - } - return res(ctx.json(responseBundle)) - }), - rest.post( - 'http://localhost:2525/events/birth/mark-registered', - (_, res, ctx) => res(ctx.status(200)) - ) - ) - - const response = await server.server.inject({ - method: 'POST', - url: '/confirm/registration', - payload: { - registrationNumber: '1234', - compositionId: '7c3af302-08c9-41af-8701-92de9a71a3e4' - }, - headers: { - Authorization: `Bearer ${token}` - } - }) - - const task = getTaskFromSavedBundle( - JSON.parse(response.payload) as ValidRecord - ) - const businessStatus = getStatusFromTask(task) - - expect(response.statusCode).toBe(200) - expect(businessStatus).toBe('REGISTERED') + expect(businessStatus).toBe('WAITING_VALIDATION') + await server.stop() }) }) diff --git a/packages/workflow/src/test/redis.ts b/packages/workflow/src/test/redis.ts deleted file mode 100644 index 72293561c9..0000000000 --- a/packages/workflow/src/test/redis.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * OpenCRVS is also distributed under the terms of the Civil Registration - * & Healthcare Disclaimer located at http://opencrvs.org/license. - * - * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. - */ -import { GenericContainer, type StartedTestContainer } from 'testcontainers' -import * as queueWorkers from '@workflow/workers' - -const REDIS_HTTP_PORT = 6379 - -const container = new GenericContainer('redis:5') - -export const startContainer = async () => { - const testContainer = await container - .withExposedPorts(REDIS_HTTP_PORT) - .withStartupTimeout(120_000) - .start() - - await queueWorkers.register({ - host: testContainer.getHost(), - port: testContainer.getMappedPort(REDIS_HTTP_PORT) - }) - - return testContainer -} - -export const stopContainer = async (container: StartedTestContainer) => { - try { - // @TODO: How to stop the client? - // await redisClient.stop() - } catch (error) { - } finally { - await container.stop() - } -} diff --git a/yarn.lock b/yarn.lock index 3a7b4591ac..162b126a28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7891,7 +7891,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@18.3.1", "@types/react@>=16": +"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@18.3.1", "@types/react@>=16", "@types/react@^16": version "18.3.1" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.1.tgz#fed43985caa834a2084d002e4771e15dfcbdbe8e" integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw== @@ -7899,15 +7899,6 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@^16": - version "16.14.62" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.62.tgz#449e4e81caaf132d0c2c390644e577702db1dd9e" - integrity sha512-BWf7hqninZav6nerxXj+NeZT/mTpDeG6Lk2zREHAy63CrnXoOGPGtNqTFYFN/sqpSaREDP5otVV88axIXmKfGA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "^0.16" - csstype "^3.0.2" - "@types/readdir-glob@*": version "1.1.3" resolved "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.3.tgz" @@ -7976,11 +7967,6 @@ dependencies: htmlparser2 "^8.0.0" -"@types/scheduler@^0.16": - version "0.16.8" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" - integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== - "@types/semver@^7.3.4": version "7.5.4" resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz" @@ -13311,14 +13297,7 @@ fast-url-parser@1.1.3, fast-url-parser@^1.1.3: dependencies: punycode "^1.3.2" -fast-xml-parser@4.2.5: - version "4.2.5" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" - integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== - dependencies: - strnum "^1.0.5" - -fast-xml-parser@^4.1.3, fast-xml-parser@^4.2.2: +fast-xml-parser@4.2.5, fast-xml-parser@4.4.1, fast-xml-parser@^4.1.3, fast-xml-parser@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz#86dbf3f18edf8739326447bcaac31b4ae7f6514f" integrity sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw== From 24430af4afadfe0cf5c786bc0cb1f4782b604fe0 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 22:21:41 +0300 Subject: [PATCH 18/22] fix: use defined redis port in gateway --- packages/gateway/src/constants.ts | 3 +++ packages/gateway/src/workflow/index.ts | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/gateway/src/constants.ts b/packages/gateway/src/constants.ts index ffda6697ff..b83acc2fb0 100644 --- a/packages/gateway/src/constants.ts +++ b/packages/gateway/src/constants.ts @@ -9,6 +9,9 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ export const REDIS_HOST = process.env.REDIS_HOST || 'localhost' +export const REDIS_PORT = process.env.REDIS_PORT + ? Number(process.env.REDIS_PORT) + : 6379 export const HOST = process.env.HOST || '0.0.0.0' export const PORT = process.env.PORT || 7070 export const HOSTNAME = process.env.DOMAIN || '*' diff --git a/packages/gateway/src/workflow/index.ts b/packages/gateway/src/workflow/index.ts index 8e330b7b07..8b0baf386d 100644 --- a/packages/gateway/src/workflow/index.ts +++ b/packages/gateway/src/workflow/index.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { REDIS_HOST, WORKFLOW_URL } from '@gateway/constants' +import { REDIS_HOST, REDIS_PORT, WORKFLOW_URL } from '@gateway/constants' import fetch from '@gateway/fetch' import { GQLBirthRegistrationInput, @@ -126,7 +126,10 @@ export function rejectRegistrationCorrection( ) } -const recordQueue = useRecordQueue(REDIS_HOST) +const recordQueue = useRecordQueue({ + host: REDIS_HOST, + port: REDIS_PORT +}) export async function createRegistration( record: From c0fd996ccc73c717fdf4de661d0d63226eae1e2f Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 22:26:22 +0300 Subject: [PATCH 19/22] Revert "refactor: stop using global interception in workflow tests" This reverts commit 201cec797c77198a0e891721e2c46ec78ea1c97a. --- .../fhir/fhir-bundle-modifier.test.ts | 4 +- .../src/features/registration/utils.test.ts | 6 +- .../workflow/src/features/user/utils.test.ts | 6 +- .../src/records/handler/archive.test.ts | 4 +- .../src/records/handler/certify.test.ts | 4 +- .../src/records/handler/create.test.ts | 56 +++++----- .../src/records/handler/download.test.ts | 4 +- .../src/records/handler/duplicate.test.ts | 4 +- .../src/records/handler/issue.test.ts | 4 +- .../src/records/handler/not-duplicate.test.ts | 4 +- .../src/records/handler/register.test.ts | 104 +++++++++++++++--- .../src/records/handler/reinstate.test.ts | 4 +- .../src/records/handler/reject.test.ts | 4 +- .../src/records/handler/unassign.test.ts | 4 +- .../src/records/handler/update.test.ts | 4 +- .../src/records/handler/validate.test.ts | 4 +- .../src/records/handler/verify.test.ts | 4 +- .../workflow/src/records/handler/view.test.ts | 6 +- packages/workflow/test/setupServer.ts | 25 +---- packages/workflow/test/setupTest.ts | 12 ++ 20 files changed, 153 insertions(+), 114 deletions(-) diff --git a/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts b/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts index 615f172ce3..5f25a79e01 100644 --- a/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts +++ b/packages/workflow/src/features/registration/fhir/fhir-bundle-modifier.test.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { rest } from 'msw' import { setupRegistrationWorkflow, @@ -219,8 +219,6 @@ describe('Verify fhir bundle modifier functions', () => { }) describe('validateDeceasedDetails functions', () => { - const mswServer = useRequestMocks() - let token: string let authHeader: { Authorization: string } beforeEach(async () => { diff --git a/packages/workflow/src/features/registration/utils.test.ts b/packages/workflow/src/features/registration/utils.test.ts index a97c2f3db7..af04631409 100644 --- a/packages/workflow/src/features/registration/utils.test.ts +++ b/packages/workflow/src/features/registration/utils.test.ts @@ -20,15 +20,13 @@ import { import * as fetchAny from 'jest-fetch-mock' import { EVENT_TYPE } from '@workflow/features/registration/fhir/constants' import { Bundle } from '@opencrvs/commons/types' +import { server as mswServer } from '@test/setupServer' import { rest } from 'msw' import { MOSIP_TOKEN_SEEDER_URL } from '@workflow/constants' -import { useRequestMocks } from '@test/setupServer' const fetch = fetchAny as any describe('Verify utility functions', () => { - const mswServer = useRequestMocks() - beforeEach(async () => { fetch.resetMocks() }) @@ -92,8 +90,6 @@ describe('Verify utility functions', () => { }) describe('getMosipUINToken functions', () => { - const mswServer = useRequestMocks() - beforeAll(() => { fetch.mockClear() }) diff --git a/packages/workflow/src/features/user/utils.test.ts b/packages/workflow/src/features/user/utils.test.ts index f0a3e9a92f..4b69f9bc23 100644 --- a/packages/workflow/src/features/user/utils.test.ts +++ b/packages/workflow/src/features/user/utils.test.ts @@ -19,14 +19,12 @@ import * as jwt from 'jsonwebtoken' import * as fetchAny from 'jest-fetch-mock' import { Practitioner } from '@opencrvs/commons/types' import { rest } from 'msw' -import { useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { USER_MANAGEMENT_URL } from '@workflow/__mocks__/constants' const fetch = fetchAny as any describe('Verify getLoggedInPractitionerResource', () => { - const mswServer = useRequestMocks() - it('Returns Location properly', async () => { mswServer.use( rest.post('http://localhost:3030/getUser', (_, res, ctx) => @@ -113,8 +111,6 @@ describe('Verify getLoggedInPractitionerResource', () => { }) }) describe('Verify getUser', () => { - const mswServer = useRequestMocks() - it('get user mobile throw an error in case of an bad response', async () => { mswServer.use( rest.post(`${USER_MANAGEMENT_URL}getUser`, (_, res, ctx) => diff --git a/packages/workflow/src/records/handler/archive.test.ts b/packages/workflow/src/records/handler/archive.test.ts index ba13a9e13e..8564e9dcbd 100644 --- a/packages/workflow/src/records/handler/archive.test.ts +++ b/packages/workflow/src/records/handler/archive.test.ts @@ -8,6 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { server as mswServer } from '@test/setupServer' import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import { rest } from 'msw' @@ -20,11 +21,8 @@ import { ValidRecord } from '@opencrvs/commons/types' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' -import { handlers, useRequestMocks } from '@test/setupServer' describe('archive record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/certify.test.ts b/packages/workflow/src/records/handler/certify.test.ts index d0c7f1164a..56a9af5e17 100644 --- a/packages/workflow/src/records/handler/certify.test.ts +++ b/packages/workflow/src/records/handler/certify.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { getStatusFromTask, getTaskFromSavedBundle, @@ -23,8 +23,6 @@ import { import { REGISTERED_BIRTH_RECORD } from '@test/mocks/records/register' describe('Certify record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/create.test.ts b/packages/workflow/src/records/handler/create.test.ts index 7f7d690b94..6842c6cf7c 100644 --- a/packages/workflow/src/records/handler/create.test.ts +++ b/packages/workflow/src/records/handler/create.test.ts @@ -8,23 +8,20 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { createBirthRegistrationPayload } from '@test/mocks/createBirthRecord' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { rest } from 'msw' import { SavedBundle, SavedTask, TransactionResponse, URLReference, - SavedLocation, - EVENT_TYPE + SavedLocation } from '@opencrvs/commons/types' -import { PlainToken, UUID } from '@opencrvs/commons' -import { startContainer, stopContainer } from '@workflow/test/redis' -import { StartedTestContainer } from 'testcontainers' -import { registerRecordHandler } from './create' +import { UUID } from '@opencrvs/commons' const existingTaskBundle: SavedBundle = { resourceType: 'Bundle', @@ -47,18 +44,17 @@ const existingLocationBundle: SavedBundle = { ] } -let container: StartedTestContainer - -beforeAll(async () => { - container = await startContainer() -}) +describe('Create record endpoint', () => { + let server: Awaited> -afterAll(async () => { - await stopContainer(container) -}) + beforeAll(async () => { + server = await createServer() + await server.start() + }) -describe('Create record endpoint', () => { - const mswServer = useRequestMocks(...handlers) + afterAll(async () => { + await server.stop() + }) it('returns OK for a correctly authenticated user with birth declaration', async () => { const token = jwt.sign( @@ -69,7 +65,7 @@ describe('Create record endpoint', () => { issuer: 'opencrvs:auth-service', audience: 'opencrvs:workflow-user' } - ) as PlainToken + ) // used for checking already created composition with // the same draftId @@ -154,12 +150,22 @@ describe('Create record endpoint', () => { }) ) - const record = await registerRecordHandler( - createBirthRegistrationPayload, - EVENT_TYPE.BIRTH, - token - ) - - expect(record).toBeDefined() + const res = await server.server.inject({ + method: 'POST', + url: '/create-record', + payload: { + event: 'BIRTH', + record: createBirthRegistrationPayload + }, + headers: { + Authorization: `Bearer ${token}` + } + }) + expect(res.statusCode).toBe(200) + expect(JSON.parse(res.payload)).toMatchObject({ + trackingId: 'BYW6MFW', + compositionId: '3bd79ffd-5bd7-489f-b0d2-3c6133d36e1e', + isPotentiallyDuplicate: false + }) }) }) diff --git a/packages/workflow/src/records/handler/download.test.ts b/packages/workflow/src/records/handler/download.test.ts index 018d9d0a97..29b5e2b09d 100644 --- a/packages/workflow/src/records/handler/download.test.ts +++ b/packages/workflow/src/records/handler/download.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' import { getTaskFromSavedBundle, Task } from '@opencrvs/commons/types' @@ -23,8 +23,6 @@ function checkForDownloadExtenstion(task: Task) { } describe('download record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/duplicate.test.ts b/packages/workflow/src/records/handler/duplicate.test.ts index d5a73539da..fc542dd7d4 100644 --- a/packages/workflow/src/records/handler/duplicate.test.ts +++ b/packages/workflow/src/records/handler/duplicate.test.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import { rest } from 'msw' @@ -51,8 +51,6 @@ function findDuplicateTrackingId(task: SavedTask) { } describe('duplicate record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/issue.test.ts b/packages/workflow/src/records/handler/issue.test.ts index 1740912182..b780470191 100644 --- a/packages/workflow/src/records/handler/issue.test.ts +++ b/packages/workflow/src/records/handler/issue.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { getStatusFromTask, getTaskFromSavedBundle, @@ -23,8 +23,6 @@ import { import { CERTIFIED_BIRTH_RECORD } from '@test/mocks/records/certify' describe('Issue record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/not-duplicate.test.ts b/packages/workflow/src/records/handler/not-duplicate.test.ts index 6f49a2843c..5d553973a6 100644 --- a/packages/workflow/src/records/handler/not-duplicate.test.ts +++ b/packages/workflow/src/records/handler/not-duplicate.test.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import { rest } from 'msw' @@ -30,8 +30,6 @@ function hasDeduplicateExtension(task: SavedTask) { } describe('not-duplicate record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/register.test.ts b/packages/workflow/src/records/handler/register.test.ts index d41aff75a7..de4dd9a711 100644 --- a/packages/workflow/src/records/handler/register.test.ts +++ b/packages/workflow/src/records/handler/register.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { getStatusFromTask, getTaskFromSavedBundle, @@ -24,12 +24,18 @@ import { updateBirthRegistrationPayload } from '@test/mocks/updateBirthRecord' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' describe('Register record endpoint', () => { - const mswServer = useRequestMocks(...handlers) + let server: Awaited> - it('flows the registration to waiting for validation', async () => { - const server = await createServer() + beforeAll(async () => { + server = await createServer() await server.start() + }) + afterAll(async () => { + await server.stop() + }) + + it('returns OK for a correctly authenticated user rejecting a birth declaration', async () => { const token = jwt.sign( { scope: ['register'] }, readFileSync('./test/cert.key'), @@ -50,6 +56,13 @@ describe('Register record endpoint', () => { ) ) + // Mock response from country-config + mswServer.use( + rest.post('http://localhost:3040/event-registration', (_, res, ctx) => { + return res(ctx.status(400)) + }) + ) + // Mock response from hearth mswServer.use( rest.post('http://localhost:3447/fhir', (_, res, ctx) => { @@ -70,13 +83,6 @@ describe('Register record endpoint', () => { }) ) - // Mock response from country-config - mswServer.use( - rest.post('http://localhost:3040/event-registration', (_, res, ctx) => { - return res(ctx.status(200)) - }) - ) - const response = await server.server.inject({ method: 'POST', url: '/records/7c3af302-08c9-41af-8701-92de9a71a3e4/register', @@ -96,7 +102,79 @@ describe('Register record endpoint', () => { const businessStatus = getStatusFromTask(task) expect(response.statusCode).toBe(200) - expect(businessStatus).toBe('WAITING_VALIDATION') - await server.stop() + expect(businessStatus).toBe('REJECTED') + }) + + it('returns OK for a correctly authenticated user registering a birth declaration', async () => { + const token = jwt.sign( + { scope: ['register'] }, + readFileSync('./test/cert.key'), + { + algorithm: 'RS256', + issuer: 'opencrvs:auth-service', + audience: 'opencrvs:workflow-user' + } + ) + + // Gets record by id via getRecordById endpoint + mswServer.use( + rest.get( + 'http://localhost:9090/records/7c3af302-08c9-41af-8701-92de9a71a3e4', + (_, res, ctx) => { + return res(ctx.json(READY_FOR_REVIEW_BIRTH_RECORD)) + } + ) + ) + + // Mock response from hearth + mswServer.use( + rest.post('http://localhost:3447/fhir', (_, res, ctx) => { + const responseBundle: TransactionResponse = { + resourceType: 'Bundle', + type: 'batch-response', + entry: [ + { + response: { + status: '200', + location: + '/fhir/Task/f00e742a-0900-488b-b7c1-9625d7b7e456/_history/dc39332f-a5d7-4422-ba7b-bc99a958e8cb' as URLReference + } + }, + { + response: { + status: '200', + location: + '/fhir/Patient/8cb74e54-1c02-41a7-86a3-415c4031c9ba/_history/dc39332f-a5d7-4422-ba7b-bc99a958e8cb' as URLReference + } + } + ] + } + return res(ctx.json(responseBundle)) + }), + rest.post( + 'http://localhost:2525/events/birth/mark-registered', + (_, res, ctx) => res(ctx.status(200)) + ) + ) + + const response = await server.server.inject({ + method: 'POST', + url: '/confirm/registration', + payload: { + registrationNumber: '1234', + compositionId: '7c3af302-08c9-41af-8701-92de9a71a3e4' + }, + headers: { + Authorization: `Bearer ${token}` + } + }) + + const task = getTaskFromSavedBundle( + JSON.parse(response.payload) as ValidRecord + ) + const businessStatus = getStatusFromTask(task) + + expect(response.statusCode).toBe(200) + expect(businessStatus).toBe('REGISTERED') }) }) diff --git a/packages/workflow/src/records/handler/reinstate.test.ts b/packages/workflow/src/records/handler/reinstate.test.ts index 46c764d459..3847e5db1b 100644 --- a/packages/workflow/src/records/handler/reinstate.test.ts +++ b/packages/workflow/src/records/handler/reinstate.test.ts @@ -11,7 +11,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { rest } from 'msw' import * as jwt from 'jsonwebtoken' import { @@ -29,8 +29,6 @@ function getRegStatus(record: ReadyForReviewRecord | RegisteredRecord) { } describe('reinstate record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/reject.test.ts b/packages/workflow/src/records/handler/reject.test.ts index 7167de49c3..e94cdd4079 100644 --- a/packages/workflow/src/records/handler/reject.test.ts +++ b/packages/workflow/src/records/handler/reject.test.ts @@ -11,7 +11,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { rest } from 'msw' import { getStatusFromTask, @@ -28,8 +28,6 @@ function getReasonFromTask(task: SavedTask) { } describe('Reject record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/unassign.test.ts b/packages/workflow/src/records/handler/unassign.test.ts index c78fe7af29..9a40b49841 100644 --- a/packages/workflow/src/records/handler/unassign.test.ts +++ b/packages/workflow/src/records/handler/unassign.test.ts @@ -13,7 +13,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { bundleWithAssignedTask } from '@test/mocks/unassignedTask' import { getTaskFromSavedBundle, Task } from '@opencrvs/commons/types' import { registrar } from '@test/mocks/user' @@ -25,8 +25,6 @@ function checkForUnassignExtenstion(task: Task) { } describe('unassign record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/update.test.ts b/packages/workflow/src/records/handler/update.test.ts index fdebd30177..5ea7a59a6b 100644 --- a/packages/workflow/src/records/handler/update.test.ts +++ b/packages/workflow/src/records/handler/update.test.ts @@ -13,7 +13,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' import { getStatusFromTask, @@ -24,8 +24,6 @@ import { } from '@opencrvs/commons/types' describe('Update record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/validate.test.ts b/packages/workflow/src/records/handler/validate.test.ts index 99c066c65e..4b7fa383af 100644 --- a/packages/workflow/src/records/handler/validate.test.ts +++ b/packages/workflow/src/records/handler/validate.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import * as jwt from 'jsonwebtoken' import { readFileSync } from 'fs' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' import { getStatusFromTask, @@ -23,8 +23,6 @@ import { } from '@opencrvs/commons/types' describe('Validate record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/verify.test.ts b/packages/workflow/src/records/handler/verify.test.ts index e258ef5f05..38b40a04de 100644 --- a/packages/workflow/src/records/handler/verify.test.ts +++ b/packages/workflow/src/records/handler/verify.test.ts @@ -12,7 +12,7 @@ import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { getTaskFromSavedBundle, REGISTERED_RECORD, @@ -33,8 +33,6 @@ function findVerificationIp(task: Task) { } describe('verify record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/src/records/handler/view.test.ts b/packages/workflow/src/records/handler/view.test.ts index e84a296d5c..4757432ece 100644 --- a/packages/workflow/src/records/handler/view.test.ts +++ b/packages/workflow/src/records/handler/view.test.ts @@ -9,13 +9,13 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { createServer } from '@workflow/server' import { readFileSync } from 'fs' import * as jwt from 'jsonwebtoken' import { rest } from 'msw' -import { handlers, useRequestMocks } from '@test/setupServer' +import { server as mswServer } from '@test/setupServer' import { getTaskFromSavedBundle, Task } from '@opencrvs/commons/types' import { READY_FOR_REVIEW_BIRTH_RECORD } from '@test/mocks/records/readyForReview' -import { createServer } from '@workflow/server' function checkForViewedExtenstion(task: Task) { return task.extension.find( @@ -24,8 +24,6 @@ function checkForViewedExtenstion(task: Task) { } describe('View record endpoint', () => { - const mswServer = useRequestMocks(...handlers) - let server: Awaited> beforeAll(async () => { diff --git a/packages/workflow/test/setupServer.ts b/packages/workflow/test/setupServer.ts index cdc0c64cb5..66dc5d33d4 100644 --- a/packages/workflow/test/setupServer.ts +++ b/packages/workflow/test/setupServer.ts @@ -8,29 +8,8 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { RestHandler, MockedRequest, DefaultBodyType } from 'msw' import { setupServer } from 'msw/node' import handlers from './handlers' -/** Setups a test server with mock request handlers */ -export const useRequestMocks = ( - ...handlers: RestHandler>[] -) => { - const server = setupServer(...handlers) - - // Establish API mocking before all tests. - beforeAll(() => { - server.listen({ onUnhandledRequest: 'error' }) - }) - - // Reset any request handlers that we may add during the tests, - // so they don't affect other tests. - afterEach(() => server.resetHandlers()) - - // Clean up after the tests are finished. - afterAll(() => server.close()) - - return server -} - -export { handlers } +// This configures a request mocking server with the given request handlers. +export const server = setupServer(...handlers) diff --git a/packages/workflow/test/setupTest.ts b/packages/workflow/test/setupTest.ts index 176e20a5a1..b52d817be3 100644 --- a/packages/workflow/test/setupTest.ts +++ b/packages/workflow/test/setupTest.ts @@ -8,5 +8,17 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ +import { server } from './setupServer' jest.mock('@workflow/constants') +// Establish API mocking before all tests. +beforeAll(() => { + server.listen({ onUnhandledRequest: 'error' }) +}) + +// Reset any request handlers that we may add during the tests, +// so they don't affect other tests. +afterEach(() => server.resetHandlers()) + +// Clean up after the tests are finished. +afterAll(() => server.close()) From bc318fca677d6c0d20b5cd9174bb7424ce55d019 Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 22:27:36 +0300 Subject: [PATCH 20/22] revert: yarn.lock changes --- yarn.lock | 67 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/yarn.lock b/yarn.lock index 162b126a28..8256404bda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7541,6 +7541,13 @@ resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.3.tgz" integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA== +"@types/http-proxy@^1.17.3": + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== + dependencies: + "@types/node" "*" + "@types/ioredis@^4.28.5": version "4.28.10" resolved "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.28.10.tgz" @@ -13007,7 +13014,7 @@ eventemitter3@^3.0.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -eventemitter3@^4.0.1, eventemitter3@^4.0.4: +eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -13107,7 +13114,7 @@ exponential-backoff@^3.1.1: resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz" integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== -express@^4.17.3: +express@^4.17.1, express@^4.17.3: version "4.19.2" resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== @@ -13573,6 +13580,11 @@ focus-visible@^5.0.2: resolved "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.0.tgz" integrity sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ== +follow-redirects@^1.0.0: + version "1.15.3" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" @@ -14645,6 +14657,26 @@ http-proxy-agent@^7.0.0: agent-base "^7.1.0" debug "^4.3.4" +http-proxy-middleware@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.21.0.tgz#c6b1ca05174b5fbc57bee9485ffa0fa2f0dabeb0" + integrity sha512-4Arcl5QQ6pRMRJmtM1WVHKHkFAQn5uvw83XuNeqnMTOikDiCoTxv5/vdudhKQsF+1mtaAawrK2SEB1v2tYecdQ== + dependencies: + "@types/http-proxy" "^1.17.3" + http-proxy "^1.18.0" + is-glob "^4.0.1" + lodash "^4.17.15" + micromatch "^4.0.2" + +http-proxy@^1.18.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + http-status@^1.5.2: version "1.7.3" resolved "https://registry.npmjs.org/http-status/-/http-status-1.7.3.tgz" @@ -21838,16 +21870,7 @@ string-similarity@^4.0.1: resolved "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz" integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -22007,7 +22030,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -22028,13 +22051,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" @@ -24145,7 +24161,7 @@ workbox-window@7.1.0, workbox-window@^7.1.0: "@types/trusted-types" "^2.0.2" workbox-core "7.1.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -24172,15 +24188,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" From 5387247ce5c36aa48dd5f5d8087f5d0f1914b5ce Mon Sep 17 00:00:00 2001 From: naftis Date: Wed, 9 Oct 2024 22:36:50 +0300 Subject: [PATCH 21/22] revert: typing efforts in client - add a todo comment to look into this --- .../src/views/SearchResult/SearchResult.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/client/src/views/SearchResult/SearchResult.tsx b/packages/client/src/views/SearchResult/SearchResult.tsx index 546df70997..0cc31fdd15 100644 --- a/packages/client/src/views/SearchResult/SearchResult.tsx +++ b/packages/client/src/views/SearchResult/SearchResult.tsx @@ -47,11 +47,7 @@ import { ITheme } from '@opencrvs/components/lib/theme' import { Scope } from '@client/utils/authUtils' import { SEARCH_RESULT_SORT } from '@client/utils/constants' import { getUserLocation, UserDetails } from '@client/utils/userUtils' -import { - SearchEventsQuery, - SystemRoleType, - RejectionReason -} from '@client/utils/gateway' +import { SearchEventsQuery, SystemRoleType } from '@client/utils/gateway' import { ColumnContentAlignment, @@ -89,15 +85,19 @@ const ErrorText = styled.div` const ToolTipContainer = styled.span` text-align: center; ` - -export function getRejectionReasonDisplayValue(reason: RejectionReason) { - switch (reason) { - case RejectionReason.Duplicate: +// @TODO: Get rid of these magic strings - they are outdated and will get more outdated as time passes +export function getRejectionReasonDisplayValue(reason: string) { + switch (reason.toLowerCase()) { + case 'duplicate': return rejectMessages.rejectionReasonDuplicate - case RejectionReason.Other: + case 'misspelling': + return rejectMessages.rejectionReasonMisspelling + case 'missing_supporting_doc': + return rejectMessages.rejectionReasonMissingSupportingDoc + case 'other': return rejectMessages.rejectionReasonOther default: - return reason satisfies never + return rejectMessages.rejectionReasonOther } } From cef4bb35d416782ee379299644e6887cb56f15d5 Mon Sep 17 00:00:00 2001 From: Pyry Date: Thu, 10 Oct 2024 16:08:09 +0300 Subject: [PATCH 22/22] Revert "fix: REVERT THIS? remove trivy from build" This reverts commit 529d702c1fbc25153d919b33e16fb0a1944bfa84. --- .github/workflows/build-images-from-branch.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-images-from-branch.yml b/.github/workflows/build-images-from-branch.yml index f5ec96de55..cd629bbe75 100644 --- a/.github/workflows/build-images-from-branch.yml +++ b/.github/workflows/build-images-from-branch.yml @@ -112,3 +112,9 @@ jobs: opencrvs/ocrvs-${{ matrix.service }}:${{ needs.base.outputs.branch }} cache-from: type=registry,ref=opencrvs/ocrvs-${{ matrix.service }}:${{ needs.base.outputs.branch }} cache-to: type=inline + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.23.0 + with: + image-ref: 'opencrvs/ocrvs-${{ matrix.service }}:${{ needs.base.outputs.version }}' + trivy-config: trivy.yaml