Skip to content

Commit

Permalink
feat(elation): add members to the thread message
Browse files Browse the repository at this point in the history
  • Loading branch information
bejoinka committed Nov 12, 2024
1 parent 8e6cb33 commit 940732e
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 91 deletions.
46 changes: 17 additions & 29 deletions extensions/elation/actions/__tests__/createMessageThread.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { generateTestPayload } from '@/tests'
import { ZodError } from 'zod'
import { makeAPIClient } from '../../client'
import { createMessageThread } from '../createMessageThread'

Expand Down Expand Up @@ -66,15 +67,12 @@ describe('createMessageThread action', () => {
messageBody: 'Initial message in the thread',
})

await createMessageThread.onActivityCreated!(payload, onComplete, onError)

expect(onError).toHaveBeenCalled()
expect(onError.mock.calls[0][0].events[0].error).toEqual(
expect.objectContaining({
category: 'SERVER_ERROR',
message: expect.stringContaining('Validation error'),
})
const response = createMessageThread.onActivityCreated!(
payload,
onComplete,
onError
)
await expect(response).rejects.toThrow(ZodError)
})

it('should fail with missing required messageBody', async () => {
Expand All @@ -88,15 +86,12 @@ describe('createMessageThread action', () => {
messageBody: undefined as unknown as string,
})

await createMessageThread.onActivityCreated!(payload, onComplete, onError)

expect(onError).toHaveBeenCalled()
expect(onError.mock.calls[0][0].events[0].error).toEqual(
expect.objectContaining({
category: 'SERVER_ERROR',
message: expect.stringContaining('Validation error'),
})
const response = createMessageThread.onActivityCreated!(
payload,
onComplete,
onError
)
await expect(response).rejects.toThrow(ZodError)
})

it('should handle API error gracefully', async () => {
Expand All @@ -116,19 +111,12 @@ describe('createMessageThread action', () => {
messageBody: 'Initial message in the thread',
})

await createMessageThread.onActivityCreated!(payload, onComplete, onError)

const response = createMessageThread.onActivityCreated!(
payload,
onComplete,
onError
)
await expect(response).rejects.toThrowError(new Error('API error'))
expect(onComplete).not.toHaveBeenCalled()
expect(onError).toHaveBeenCalledWith({
events: expect.arrayContaining([
expect.objectContaining({
text: { en: 'API error' },
error: expect.objectContaining({
category: 'SERVER_ERROR',
message: 'API error',
}),
}),
]),
})
})
})
109 changes: 47 additions & 62 deletions extensions/elation/actions/createMessageThread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { type settings } from '../settings'
import { makeAPIClient } from '../client'
import { fromZodError } from 'zod-validation-error'
import { messageThreadSchema } from '../validation/messageThread.zod'
import { isNil } from 'lodash'

const fields = {
patientId: {
Expand Down Expand Up @@ -54,6 +55,13 @@ const fields = {
type: FieldType.STRING,
required: true,
},
groupId: {
id: 'groupId',
label: 'Group ID',
description: 'The ID of the group to which the thread member belongs',
type: FieldType.NUMERIC,
required: false,
},
isUrgent: {
id: 'isUrgent',
label: 'Urgent',
Expand Down Expand Up @@ -83,71 +91,48 @@ export const createMessageThread: Action<
previewable: true,
dataPoints,
onActivityCreated: async (payload, onComplete, onError): Promise<void> => {
try {
const {
patientId,
senderId,
practiceId,
documentDate,
chartDate,
messageBody,
isUrgent,
} = payload.fields

const messageThread = messageThreadSchema.parse({
patient: patientId,
sender: senderId,
practice: practiceId,
document_date: documentDate,
chart_date: chartDate,
is_urgent: isUrgent,
messages: [
{
body: messageBody,
send_date: new Date().toISOString(),
sender: senderId,
},
],
})

const api = makeAPIClient(payload.settings)
const { id } = await api.createMessageThread(messageThread)
const {
patientId,
senderId,
practiceId,
documentDate,
chartDate,
messageBody,
isUrgent,
groupId,
} = payload.fields

await onComplete({
data_points: {
messageThreadId: String(id),
const messageThread = messageThreadSchema.parse({
patient: patientId,
sender: senderId,
practice: practiceId,
document_date: documentDate,
chart_date: chartDate,
is_urgent: isUrgent,
messages: [
{
body: messageBody,
send_date: new Date().toISOString(),
sender: senderId,
},
})
} catch (err) {
if (err instanceof ZodError) {
const error = fromZodError(err)
await onError({
events: [
],
members: !isNil(groupId)
? [
{
date: new Date().toISOString(),
text: { en: error.message },
error: {
category: 'SERVER_ERROR',
message: error.message,
},
group: groupId,
status: 'Requiring Action',
},
],
})
} else {
const message = (err as Error).message
await onError({
events: [
{
date: new Date().toISOString(),
text: { en: message },
error: {
category: 'SERVER_ERROR',
message,
},
},
],
})
}
}
]
: [],
})

const api = makeAPIClient(payload.settings)
const { id } = await api.createMessageThread(messageThread)

await onComplete({
data_points: {
messageThreadId: String(id),
},
})
},
}
25 changes: 25 additions & 0 deletions extensions/elation/validation/messageThread.zod.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
import { z } from 'zod'

export const ThreadMemberSchema = z
.object({
id: z.number().int().positive(),
thread: z.number().int().positive(),
user: z.number().int().positive().nullable(),
group: z.number().int().positive().nullable(),
status: z.enum(['Addressed', 'Requiring Action']), // Updated status values
ack_time: z
.string()
.nullable()
.refine((val) => val === null || !isNaN(Date.parse(val)), {
message: "Invalid date format for 'ack_time'",
}),
})
.refine((data) => !(data.user !== null && data.group !== null), {
message:
'Should only ever be one of either a user or group set for the thread member', // Updated error message to match docs
})

const CreateThreadMemberSchema = z.object({
group: z.number().int().positive().nullable(),
status: z.enum(['Addressed', 'Requiring Action']),
})

export const messageThreadSchema = z.object({
patient: z.number().int().positive(),
sender: z.number().int().positive(),
Expand All @@ -11,6 +35,7 @@ export const messageThreadSchema = z.object({
message: "Invalid date format for 'chart_date'",
}),
is_urgent: z.boolean(),
members: z.array(CreateThreadMemberSchema),
messages: z.array(
z.object({
body: z.string().min(1, 'Message body is required'),
Expand Down

0 comments on commit 940732e

Please sign in to comment.