246 lines
6.7 KiB
TypeScript
246 lines
6.7 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import { get, post, put, del, patch, uploadFile } from '../api/client'
|
|
import type {
|
|
BatchDetailResponse,
|
|
BatchDraft,
|
|
DraftPatient,
|
|
DraftEncounter,
|
|
DraftObservation,
|
|
BatchListResponse,
|
|
FieldCheck,
|
|
PatientDigitizationHistoryResponse,
|
|
} from '../types'
|
|
|
|
export const useBatchStore = defineStore('batches', () => {
|
|
const batches = ref<BatchDetailResponse[]>([])
|
|
const currentBatch = ref<BatchDetailResponse | null>(null)
|
|
const currentDraft = ref<BatchDraft | null>(null)
|
|
const totalCount = ref(0)
|
|
const loading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
const documentUrl = computed(() => currentBatch.value?.documentUrl ?? null)
|
|
|
|
async function listBatches(params: {
|
|
status?: string
|
|
batchType?: string
|
|
assignedTo?: string
|
|
track?: string
|
|
page?: number
|
|
pageSize?: number
|
|
}): Promise<void> {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const response = await get<BatchListResponse>(
|
|
'digitization-batches',
|
|
params as Record<string, unknown>
|
|
)
|
|
if (response.success && response.data) {
|
|
batches.value = response.data.items
|
|
totalCount.value = response.data.totalCount
|
|
}
|
|
} catch (e: unknown) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to load batches'
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function getBatch(id: string): Promise<void> {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const response = await get<BatchDetailResponse>(
|
|
`digitization-batches/${id}`
|
|
)
|
|
if (response.success && response.data) {
|
|
currentBatch.value = response.data
|
|
}
|
|
} catch (e: unknown) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to load batch'
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function uploadBatch(
|
|
file: File,
|
|
batchType: string,
|
|
track: string,
|
|
patientId?: string,
|
|
supersedesBatchId?: string,
|
|
coverSheetCode?: string,
|
|
): Promise<BatchDetailResponse | null> {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const fields: Record<string, string> = { track }
|
|
if (batchType) fields.batchType = batchType
|
|
if (patientId) fields.patientId = patientId
|
|
if (supersedesBatchId) fields.supersedesBatchId = supersedesBatchId
|
|
if (coverSheetCode) fields.coverSheetCode = coverSheetCode
|
|
|
|
const response = await uploadFile<BatchDetailResponse>(
|
|
'digitization-batches',
|
|
file,
|
|
fields
|
|
)
|
|
if (response.success && response.data) {
|
|
return response.data
|
|
}
|
|
return null
|
|
} catch (e: unknown) {
|
|
error.value = e instanceof Error ? e.message : 'Upload failed'
|
|
return null
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function assignBatch(batchId: string, entryClerkUserId: string): Promise<void> {
|
|
const response = await patch<BatchDetailResponse>(`digitization-batches/${batchId}/assign`, {
|
|
entryClerkUserId,
|
|
})
|
|
if (!response.success) {
|
|
throw new Error(response.error?.message ?? 'Assignment failed')
|
|
}
|
|
}
|
|
|
|
async function getDraft(batchId: string): Promise<void> {
|
|
loading.value = true
|
|
try {
|
|
const response = await get<BatchDraft>(
|
|
`digitization-batches/${batchId}/draft`
|
|
)
|
|
if (response.success && response.data) {
|
|
currentDraft.value = response.data
|
|
}
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function saveDraftPatient(
|
|
batchId: string,
|
|
patient: Partial<DraftPatient>
|
|
): Promise<void> {
|
|
await put<DraftPatient>(
|
|
`digitization-batches/${batchId}/draft/patient`,
|
|
patient
|
|
)
|
|
}
|
|
|
|
async function saveDraftEncounter(
|
|
batchId: string,
|
|
encounter: Partial<DraftEncounter>
|
|
): Promise<void> {
|
|
await put<DraftEncounter>(
|
|
`digitization-batches/${batchId}/draft/encounter`,
|
|
encounter
|
|
)
|
|
}
|
|
|
|
async function addObservation(
|
|
batchId: string,
|
|
observation: Partial<DraftObservation>
|
|
): Promise<void> {
|
|
await post<DraftObservation>(
|
|
`digitization-batches/${batchId}/draft/observations`,
|
|
observation
|
|
)
|
|
await getDraft(batchId) // refresh draft to get new observation ID
|
|
}
|
|
|
|
async function updateObservation(
|
|
batchId: string,
|
|
obsId: string,
|
|
observation: Partial<DraftObservation>
|
|
): Promise<void> {
|
|
await put<DraftObservation>(
|
|
`digitization-batches/${batchId}/draft/observations/${obsId}`,
|
|
observation
|
|
)
|
|
}
|
|
|
|
async function deleteObservation(batchId: string, obsId: string): Promise<void> {
|
|
await del<void>(`digitization-batches/${batchId}/draft/observations/${obsId}`)
|
|
await getDraft(batchId)
|
|
}
|
|
|
|
async function submitForVerification(batchId: string): Promise<void> {
|
|
await post<void>(`digitization-batches/${batchId}/submit-for-verification`)
|
|
}
|
|
|
|
async function verifyBatch(
|
|
batchId: string,
|
|
fieldChecks: FieldCheck[],
|
|
passed: boolean
|
|
): Promise<void> {
|
|
await post<void>(`digitization-batches/${batchId}/verify`, {
|
|
fieldChecks,
|
|
passed,
|
|
})
|
|
}
|
|
|
|
async function rejectBatch(batchId: string, reason: string): Promise<void> {
|
|
await post<void>(`digitization-batches/${batchId}/reject`, { reason })
|
|
}
|
|
|
|
async function approveBatch(
|
|
batchId: string,
|
|
enableRetroactiveAlerts: boolean = false
|
|
): Promise<{ status?: number; data?: { mrn: string; encounterId: string; observationIds: string[] } }> {
|
|
const response = await post<{ mrn: string; encounterId: string; observationIds: string[] }>(
|
|
`digitization-batches/${batchId}/approve`,
|
|
{ enableRetroactiveAlerts },
|
|
{ 'Idempotency-Key': crypto.randomUUID() }
|
|
)
|
|
return { data: response.data ?? undefined }
|
|
}
|
|
|
|
async function getPatientHistory(patientId: string): Promise<PatientDigitizationHistoryResponse | null> {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const response = await get<PatientDigitizationHistoryResponse>(
|
|
`patients/${patientId}/digitization-history`,
|
|
)
|
|
if (response.success && response.data) {
|
|
return response.data
|
|
}
|
|
return null
|
|
} catch (e: unknown) {
|
|
error.value = e instanceof Error ? e.message : 'Failed to load patient history'
|
|
return null
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
return {
|
|
batches,
|
|
currentBatch,
|
|
currentDraft,
|
|
documentUrl,
|
|
totalCount,
|
|
loading,
|
|
error,
|
|
listBatches,
|
|
getBatch,
|
|
uploadBatch,
|
|
assignBatch,
|
|
getDraft,
|
|
saveDraftPatient,
|
|
saveDraftEncounter,
|
|
addObservation,
|
|
updateObservation,
|
|
deleteObservation,
|
|
submitForVerification,
|
|
verifyBatch,
|
|
rejectBatch,
|
|
approveBatch,
|
|
getPatientHistory,
|
|
}
|
|
}) |