Skip to content

Commit

Permalink
chore: update point generation for user role in metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
Nil20 committed Oct 28, 2024
1 parent 33ca59d commit 4fd6668
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 62 deletions.
4 changes: 2 additions & 2 deletions packages/metrics/src/features/audit/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as Hapi from '@hapi/hapi'
import { generateAuditPoint } from '@metrics/features/registration/pointGenerator'
import { writePoints } from '@metrics/influxdb/client'
import { internal } from '@hapi/boom'
import { IUserAuditBody } from '@metrics/features/registration'
import { IUserAuditBody, IUserModelData } from '@metrics/features/registration'
import { PRACTITIONER_ID } from '@metrics/features/getTimeLogged/constants'
import { countUserAuditEvents, getUserAuditEvents } from './service'
import { getClientIdFromToken } from '@metrics/utils/authUtils'
Expand Down Expand Up @@ -60,7 +60,7 @@ export async function newAuditHandler(
export async function getUser(
userId: string,
authHeader: { Authorization: string }
) {
): Promise<IUserModelData> {
const res = await fetch(`${USER_MANAGEMENT_URL}/getUser`, {
method: 'POST',
body: JSON.stringify({ userId }),
Expand Down
32 changes: 8 additions & 24 deletions packages/metrics/src/features/registration/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
} from '@metrics/features/registration/pointGenerator'
import { badRequest, internal } from '@hapi/boom'
import { populateBundleFromPayload } from '@metrics/features/registration/utils'
import { Events } from '@metrics/features/metrics/constants'
import { IPoints } from '@metrics/features/registration'
import { createUserAuditPointFromFHIR } from '@metrics/features/audit/service'
import {
Expand All @@ -37,7 +36,6 @@ import {
} from '@metrics/features/registration/fhirUtils'
import { EventType } from '@metrics/config/routes'
import { fetchTaskHistory } from '@metrics/api'
import { hasScope } from '@opencrvs/commons/authentication'

export async function waitingExternalValidationHandler(
request: Hapi.Request,
Expand Down Expand Up @@ -121,8 +119,6 @@ export async function sentNotificationForReviewHandler(
) {
const points = []

const authHeader = { Authorization: request.headers.authorization }

await createUserAuditPointFromFHIR('DECLARED', request)

try {
Expand All @@ -133,18 +129,10 @@ export async function sentNotificationForReviewHandler(
})
)
points.push(
await generateDeclarationStartedPoint(
request.payload as fhir.Bundle,
{
Authorization: request.headers.authorization,
'x-correlation-id': request.headers['x-correlation-id']
},
hasScope(authHeader, 'validate')
? Events.VALIDATED
: hasScope(authHeader, 'register')
? Events.WAITING_EXTERNAL_VALIDATION
: Events.READY_FOR_REVIEW
)
await generateDeclarationStartedPoint(request.payload as fhir.Bundle, {
Authorization: request.headers.authorization,
'x-correlation-id': request.headers['x-correlation-id']
})
)

await writePoints(points)
Expand Down Expand Up @@ -175,14 +163,10 @@ export async function sentNotificationHandler(
})
)
points.push(
await generateDeclarationStartedPoint(
request.payload as fhir.Bundle,
{
Authorization: request.headers.authorization,
'x-correlation-id': request.headers['x-correlation-id']
},
Events.INCOMPLETE
)
await generateDeclarationStartedPoint(request.payload as fhir.Bundle, {
Authorization: request.headers.authorization,
'x-correlation-id': request.headers['x-correlation-id']
})
)

await writePoints(points)
Expand Down
18 changes: 18 additions & 0 deletions packages/metrics/src/features/registration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@ export interface IUserAuditBody {
action: USER_ACTION | string
additionalData?: Record<string, any>
}
export interface IUserModelData {
_id: string
username: string
name: {
use: string
family: string
given: string[]
}[]
email: string
emailForNotification?: string
mobile?: string
status: string
role: string
creationDate?: string
practitionerId: string
primaryOfficeId: string
device: string
}
export interface IPaymentPoints {
measurement: string
tags: ILocationTags & {
Expand Down
75 changes: 63 additions & 12 deletions packages/metrics/src/features/registration/pointGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,66 @@ import {
testDeathCertPayload
} from '@metrics/features/registration/testUtils'
import { cloneDeep } from 'lodash'
import { Events } from '@metrics/features/metrics/constants'

import * as api from '@metrics/api'
import { getUser } from '@metrics/features/audit/handler'
jest.mock('@metrics/features/audit/handler')

const fetchLocation = api.fetchLocation as jest.Mock
const fetchTaskHistory = api.fetchTaskHistory as jest.Mock
const fetchUser = getUser as jest.Mock

const AUTH_HEADER = {
Authorization: 'Bearer mock-token'
Authorization:
'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJyZWNvcmQuZGVjbGFyZS1iaXJ0aCIsInJlY29yZC5kZWNsYXJlLWRlYXRoIiwicmVjb3JkLmRlY2xhcmUtbWFycmlhZ2UiLCJyZWNvcmQuZGVjbGFyYXRpb24tcmV2aWV3IiwicmVjb3JkLnN1Ym1pdC1mb3ItdXBkYXRlcyIsInJlY29yZC5yZXZpZXctZHVwbGljYXRlcyIsInJlY29yZC5kZWNsYXJhdGlvbi1hcmNoaXZlIiwicmVjb3JkLmRlY2xhcmF0aW9uLXJlaW5zdGF0ZSIsInJlY29yZC5yZWdpc3RlciIsInJlY29yZC5yZWdpc3RyYXRpb24tY29ycmVjdCIsInJlY29yZC5wcmludC1yZWNvcmRzIiwicmVjb3JkLnByaW50LXJlY29yZHMtc3VwcG9ydGluZy1kb2N1bWVudHMiLCJyZWNvcmQuZXhwb3J0LXJlY29yZHMiLCJyZWNvcmQucHJpbnQtaXNzdWUtY2VydGlmaWVkLWNvcGllcyIsInJlY29yZC5yZWdpc3RyYXRpb24tdmVyaWZ5LWNlcnRpZmllZC1jb3BpZXMiLCJyZWNvcmQuY3JlYXRlLWNvbW1lbnRzIiwicmVjb3JkLmNlcnRpZnkiLCJwZXJmb3JtYW5jZS5yZWFkIiwicGVyZm9ybWFuY2UucmVhZC1kYXNoYm9hcmRzIiwib3JnYW5pc2F0aW9uLnJlYWQiLCJvcmdhbmlzYXRpb24ucmVhZC1sb2NhdGlvbnM6bXktb2ZmaWNlIiwic2VhcmNoLmJpcnRoIiwic2VhcmNoLmRlYXRoIiwic2VhcmNoLm1hcnJpYWdlIiwicmVjb3JkLnJlYWQiLCJyZWNvcmQucmVhZC1hdWRpdCIsInJlY29yZC5yZWFkLWNvbW1lbnRzIiwiZGVtbyJdLCJpYXQiOjE3MzAxMTAzNTMsImV4cCI6MTczMDcxNTE1MywiYXVkIjpbIm9wZW5jcnZzOmF1dGgtdXNlciIsIm9wZW5jcnZzOnVzZXItbWdudC11c2VyIiwib3BlbmNydnM6aGVhcnRoLXVzZXIiLCJvcGVuY3J2czpnYXRld2F5LXVzZXIiLCJvcGVuY3J2czpub3RpZmljYXRpb24tdXNlciIsIm9wZW5jcnZzOndvcmtmbG93LXVzZXIiLCJvcGVuY3J2czpzZWFyY2gtdXNlciIsIm9wZW5jcnZzOm1ldHJpY3MtdXNlciIsIm9wZW5jcnZzOmNvdW50cnljb25maWctdXNlciIsIm9wZW5jcnZzOndlYmhvb2tzLXVzZXIiLCJvcGVuY3J2czpjb25maWctdXNlciIsIm9wZW5jcnZzOmRvY3VtZW50cy11c2VyIl0sImlzcyI6Im9wZW5jcnZzOmF1dGgtc2VydmljZSIsInN1YiI6IjY3MWY2MzBiMjNlY2Y4YmVjZTdlZDZmMSJ9.X-zLm4Kqq-J0WIGGR6HyvtB5plhFCPzRBCk1m8QLZ-6zd5j8ZDA8C19P4dOGmiTTN9Ya7IKIVLZE2XHQLDQrTGqltAYk6LOV0V7UIoWQzJutaA9DYIymQvSFo_MbMi9P1GDMwspFo_Dr17uScyz-7KjS3e4htdlKvHVyduijxYSj513FOzYT1CRAPxB-6wd7awz1MKVyjC3658R6nTS6MblMhZpwkU-RUsXr_AUnYL9UARpO_9JeMwK1Ijtzf51NqW6NZgVvFdk5sZ0wptWaiklw9MdWSOwBoLysyDdox52cccqvZodhG3N9GyQcn-TWivlL08FOcpxqfsCNrW3IpQ'
}

const REGISTRATION_AGENT = {
name: [
{
use: 'en',
given: ['Felix'],
family: 'Katongo'
}
],
username: 'f.katongo',
role: 'REGISTRATION_AGENT'
}

const FIELD_AGENT = {
name: [
{
use: 'en',
given: ['Kalush'],
family: 'Bwalya'
}
],
username: 'k.bwalya',
role: 'FIELD_AGENT'
}

const REGISTRAR = {
name: [
{
use: 'en',
given: ['Kennedy'],
family: 'Mweene'
}
],
username: 'k.bwalya',
role: 'REGISTRAR'
}

const RECORD_SEARCH_API = {
name: [
{
use: 'en',
given: ['abc'],
family: 'def'
}
],
username: 'a.def',
role: 'NOTIFICATION_API_USER'
}

export const location = {
Expand Down Expand Up @@ -281,10 +332,10 @@ describe('Verify point generation', () => {
).rejects.toThrowError('Payment reconciliation not found')
})
it('returns declarations started point for field agent', async () => {
fetchUser.mockResolvedValueOnce(FIELD_AGENT)
const point = await generateDeclarationStartedPoint(
cloneDeep(testDeclaration),
AUTH_HEADER,
Events.READY_FOR_REVIEW
AUTH_HEADER
)
expect(point).toMatchObject({
measurement: 'declarations_started',
Expand All @@ -301,10 +352,10 @@ describe('Verify point generation', () => {
})
})
it('returns declarations started point for registration agent', async () => {
fetchUser.mockResolvedValueOnce(REGISTRATION_AGENT)
const point = await generateDeclarationStartedPoint(
cloneDeep(testDeclaration),
AUTH_HEADER,
Events.VALIDATED
AUTH_HEADER
)
expect(point).toMatchObject({
measurement: 'declarations_started',
Expand All @@ -321,10 +372,10 @@ describe('Verify point generation', () => {
})
})
it('returns declarations started point for registrar', async () => {
fetchUser.mockResolvedValueOnce(REGISTRAR)
const point = await generateDeclarationStartedPoint(
cloneDeep(testDeclaration),
AUTH_HEADER,
Events.WAITING_EXTERNAL_VALIDATION
AUTH_HEADER
)
expect(point).toMatchObject({
measurement: 'declarations_started',
Expand All @@ -339,10 +390,10 @@ describe('Verify point generation', () => {
})
})
it('returns declarations started point for field agent', async () => {
fetchUser.mockResolvedValueOnce(FIELD_AGENT)
const point = await generateDeclarationStartedPoint(
cloneDeep(testDeclaration),
AUTH_HEADER,
Events.INCOMPLETE
AUTH_HEADER
)
expect(point).toMatchObject({
measurement: 'declarations_started',
Expand All @@ -359,13 +410,13 @@ describe('Verify point generation', () => {
})
})
it('returns declarations started point for notification api', async () => {
fetchUser.mockResolvedValueOnce(RECORD_SEARCH_API)
const payload = cloneDeep(testDeclaration)
payload.entry[0].resource.type!.coding[0].code = 'birth-notification'

const point = await generateDeclarationStartedPoint(
cloneDeep(payload),
AUTH_HEADER,
Events.INCOMPLETE
AUTH_HEADER
)
expect(point).toMatchObject({
measurement: 'declarations_started',
Expand Down
33 changes: 9 additions & 24 deletions packages/metrics/src/features/registration/pointGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
getRecordInitiator,
getPaymentReconciliation,
getObservationValueByCode,
isNotification,
MANNER_OF_DEATH_CODE,
CAUSE_OF_DEATH_CODE,
getPractionerIdFromTask,
Expand All @@ -65,12 +64,11 @@ import {
getAgeLabel,
getdaysAfterEvent
} from '@metrics/features/registration/utils'
import {
OPENCRVS_SPECIFICATION_URL,
Events
} from '@metrics/features/metrics/constants'
import { OPENCRVS_SPECIFICATION_URL } from '@metrics/features/metrics/constants'
import { fetchTaskHistory } from '@metrics/api'
import { EVENT_TYPE } from '@metrics/features/metrics/utils'
import { getTokenPayload } from '@metrics/utils/authUtils'
import { getUser } from '@metrics/features/audit/handler'

export const generateInCompleteFieldPoints = async (
payload: fhir.Bundle,
Expand Down Expand Up @@ -503,11 +501,14 @@ export async function generateTimeLoggedPoint(

export async function generateDeclarationStartedPoint(
payload: fhir.Bundle,
authHeader: IAuthHeader,
status: string
authHeader: IAuthHeader
): Promise<IDeclarationsStartedPoints> {
const composition = getComposition(payload)
const task = getTask(payload)
const tokenPayload = getTokenPayload(authHeader.Authorization)

const userId = tokenPayload.sub
const user = await getUser(userId, authHeader)

if (!composition) {
throw new Error('composition not found')
Expand All @@ -517,23 +518,7 @@ export async function generateDeclarationStartedPoint(
throw new Error('Task not found')
}

let role = ''

if (status === Events.INCOMPLETE) {
isNotification(composition)
? (role = 'NOTIFICATION_API_USER')
: (role = 'FIELD_AGENT')
} else if (status === Events.VALIDATED) {
role = 'REGISTRATION_AGENT'
} else if (status === Events.WAITING_EXTERNAL_VALIDATION) {
role = 'REGISTRAR'
} else if (status === Events.READY_FOR_REVIEW) {
role = 'FIELD_AGENT'
}

if (role === '') {
throw new Error('Role not found')
}
const role = user.role

const fields: IDeclarationsStartedFields = {
role,
Expand Down

0 comments on commit 4fd6668

Please sign in to comment.