From 491d0f380a42711060870f6bdc9e6142458f0eec Mon Sep 17 00:00:00 2001 From: Devika Date: Sun, 26 Apr 2026 01:14:03 -0500 Subject: [PATCH 1/6] seed update --- prisma/seed.ts | 50 ++++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index 37c53db..77ac430 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -61,10 +61,8 @@ async function seedForms(userId: string) { }) // 3. PHQ-9 - const phqForm = await prisma.phqForm.upsert({ - where: { userId }, - update: {}, - create: { + const phqForm = await prisma.phqForm.create({ + data: { userId, status: 'COMPLETE', totalScore: 14, @@ -73,10 +71,8 @@ async function seedForms(userId: string) { }, }) - await prisma.phqQuestion.upsert({ - where: { formId: phqForm.id }, - update: {}, - create: { + await prisma.phqQuestion.create({ + data: { formId: phqForm.id, userId, q1: 2, @@ -130,11 +126,9 @@ async function seedForms(userId: string) { }, }) - // 5. ACE (Hardcoded Form) - const aceForm = await prisma.aceForm.upsert({ - where: { userId }, - update: {}, - create: { + // 5. ACE + const aceForm = await prisma.aceForm.create({ + data: { userId, status: 'COMPLETE', totalScore: 2, @@ -143,10 +137,8 @@ async function seedForms(userId: string) { }, }) - await prisma.aceQuestion.upsert({ - where: { formId: aceForm.id }, - update: {}, - create: { + await prisma.aceQuestion.create({ + data: { formId: aceForm.id, userId, a01: 'Yes', @@ -169,20 +161,16 @@ async function ensureBobBuilderSessionNotes(bobUserId: string, clinicianUserId: update: { status: 'ACTIVE', clinicianUserId }, create: { userId: bobUserId, status: 'ACTIVE', clinicianUserId }, }) - // Populate form dummy data if it doesn't exist + const existingApp = await prisma.appForm.count({ where: { userId: bobUserId } }) if (existingApp === 0) { await seedForms(bobUserId) console.log('Seeded clinical forms for Bob Builder.') } + return bobClient } -/** - * Seed a representative note in each workflow state so the multi-tier approval - * UI (draft / clinician-signed / fully-approved) has real data to exercise, - * and across both kinds (progress vs psychotherapy). - */ async function seedApprovalWorkflowNotes( clientId: string, clinicianUserId: string, @@ -199,7 +187,7 @@ async function seedApprovalWorkflowNotes( const now = new Date() - // 1. DRAFT progress note – still being written. + // 1. DRAFT progress note await prisma.sessionNote.create({ data: { clientId, @@ -213,7 +201,7 @@ async function seedApprovalWorkflowNotes( }, }) - // 2. CLINICIAN_SIGNED progress note – waiting for admin sign-off. + // 2. CLINICIAN_SIGNED progress note const pendingNote = await prisma.sessionNote.create({ data: { clientId, @@ -229,6 +217,7 @@ async function seedApprovalWorkflowNotes( clinicianSignatureData: PLACEHOLDER_SIG, }, }) + await prisma.notification.create({ data: { userId: adminUserId, @@ -240,7 +229,7 @@ async function seedApprovalWorkflowNotes( }, }) - // 3. FULLY_APPROVED progress note. + // 3. FULLY_APPROVED progress note await prisma.sessionNote.create({ data: { clientId, @@ -261,7 +250,7 @@ async function seedApprovalWorkflowNotes( }, }) - // 4. PSYCHOTHERAPY draft – separately stored per HIPAA. + // 4. PSYCHOTHERAPY draft await prisma.sessionNote.create({ data: { clientId, @@ -275,7 +264,7 @@ async function seedApprovalWorkflowNotes( }, }) - // 5. PSYCHOTHERAPY fully approved – demonstrates tier-2 sign-off on process notes. + // 5. PSYCHOTHERAPY fully approved await prisma.sessionNote.create({ data: { clientId, @@ -305,7 +294,6 @@ async function main() { await ensureDefaultDeclarationTemplates(prisma) await backfillSessionNotesRequestTemplates(prisma) - // Create / Upsert Alice (Admin — default approver for the note workflow) const alice = await prisma.user.upsert({ where: { email: 'alice@a.com' }, update: { role: 'ADMIN', name: 'Alice Wonderland' }, @@ -319,7 +307,6 @@ async function main() { }) console.log('Seeded Admin: alice@a.com') - // Create / Upsert Carl (Clinician) const carl = await prisma.user.upsert({ where: { email: 'carl@c.com' }, update: { role: 'CLINICIAN', name: 'Carl Karl' }, @@ -333,7 +320,6 @@ async function main() { }) console.log('Seeded Clinician: carl@c.com') - // Create / Upsert Bob (Client) const bob = await prisma.user.upsert({ where: { email: 'bob@b.com' }, update: { role: 'CLIENT', name: 'Bob Builder' }, @@ -361,4 +347,4 @@ main() console.error(e) await prisma.$disconnect() process.exit(1) - }) + }) \ No newline at end of file From fc16d98bfbae73f45b9df483a9b8b448436219ab Mon Sep 17 00:00:00 2001 From: Devika Date: Sun, 26 Apr 2026 10:56:51 -0500 Subject: [PATCH 2/6] seed fix --- prisma/seed.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index 77ac430..7c9387f 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -30,7 +30,7 @@ async function seedForms(userId: string) { userId, q01: 'Bob', q02: 'Builder', - q05: '1234567890', + q04: '1234567890', }, }) From ad7dfb4b9ca4dafc911764a5a78e5828da957384 Mon Sep 17 00:00:00 2001 From: Devika Date: Sun, 26 Apr 2026 18:07:14 -0500 Subject: [PATCH 3/6] current note won't display in the previous note section, draft notes(notes the user hasn't submitted shows in the current note), upcoming flag, forms veiwer works --- app/components/FormEditPanel.vue | 174 +++++++++ app/components/Notes.vue | 246 ++++++++----- app/composables/useApplicationOptions.ts | 57 +++ prisma/seed.ts | 334 ++++++++---------- .../api/clients/[id]/forms/[formKey].get.ts | 14 +- .../api/clients/[id]/forms/[formKey].patch.ts | 32 +- .../clients/[id]/forms/[formKey]/raw.get.ts | 41 +++ server/utils/clinical-form-display.ts | 33 +- 8 files changed, 659 insertions(+), 272 deletions(-) create mode 100644 app/components/FormEditPanel.vue create mode 100644 app/composables/useApplicationOptions.ts create mode 100644 server/api/clients/[id]/forms/[formKey]/raw.get.ts diff --git a/app/components/FormEditPanel.vue b/app/components/FormEditPanel.vue new file mode 100644 index 0000000..ec8746b --- /dev/null +++ b/app/components/FormEditPanel.vue @@ -0,0 +1,174 @@ +// The edit panel with 5-step stepper for application and radio inputs for clinical forms + + + \ No newline at end of file diff --git a/app/components/Notes.vue b/app/components/Notes.vue index c4e9916..9b3a2b5 100644 --- a/app/components/Notes.vue +++ b/app/components/Notes.vue @@ -247,6 +247,12 @@ } async function selectSessionNote(sn: SessionNoteRow) { + if (sn.status === 'DRAFT' && sn.appointmentId) { + selectedAppointmentId.value = sn.appointmentId + noteContent.value = sn.content + currentNoteKind.value = sn.kind ?? 'PROGRESS' + return + } selectedPreviousNote.value = null editingNoteId.value = null selectedSessionNoteId.value = sn.id @@ -287,7 +293,7 @@ const newFormModalSelection = ref('') function openNewFormVersion() { - newFormModalSelection.value = props.forms[0]?.label ?? '' + newFormModalSelection.value = props.forms.filter(f => f.label !== 'Application')[0]?.label ?? '' showNewFormModal.value = true } @@ -438,6 +444,25 @@ const formPreviewError = ref(null) const isEditingForm = ref(false) const editableAnswers = ref<{ label: string; answer: string }[]>([]) + + const viewerStep = ref(1) + + const APP_STEP_RANGES = [ + [0, 6], + [7, 17], + [18, 35], + [36, 45], + [46, 49], + ] + + const viewerStepLabels = ['Profile', 'Child', 'Guardian', 'Treatment', 'Therapy'] + + const viewerStepAnswers = computed(() => { + const range = APP_STEP_RANGES[viewerStep.value - 1] + if (!range) return editableAnswers.value + return editableAnswers.value.slice(range[0] ?? 0, (range[1] ?? 0) + 1) + }) + let formPreviewSeq = 0 function severityColor(label: string): string { @@ -502,18 +527,24 @@ } }) - async function saveFormEdits() { + async function onFormEditSave(answers: { label: string; answer: string }[]) { const key = FORM_LABEL_TO_KEY[selectedForm.value!] await $fetch(`/api/clients/${props.client.id}/forms/${key}`, { method: 'PATCH', - body: { answers: editableAnswers.value } + body: { answers }, }) - if (formPreviewData.value) { - formPreviewData.value.questions = [...editableAnswers.value] - } + + // Re-fetch to get updated score/severity + const data = await $fetch( + `/api/clients/${props.client.id}/forms/${key}` + ) + formPreviewData.value = data + editableAnswers.value = data.questions.map((q) => ({ ...q })) + if (data.score != null) formScores.value[selectedForm.value!] = data.score + if (data.severity != null) formSeverities.value[selectedForm.value!] = data.severity + isEditingForm.value = false } - const isEditingPreviousPanel = ref(false) const editingNoteId = ref(null) const editingSessionNoteId = ref(null) @@ -1021,6 +1052,35 @@ const diff = Math.floor((now.getTime() - date.getTime()) / 60000) return diff < 1 ? 'just now' : `${diff} min ago` } + + function formatAppAnswer(val: string): string { + if (!val) return '—' + if (val.includes('|||')) { + return val.split('|||').filter(Boolean).join(', ') + } + try { + const parsed = JSON.parse(val) + if (Array.isArray(parsed)) { + return parsed.map((item: any) => + typeof item === 'object' + ? Object.values(item).filter(Boolean).join(' ') + : String(item) + ).join(', ') + } + if (parsed && typeof parsed === 'object') { + if (Array.isArray(parsed.values)) { + return [...parsed.values, parsed.other].filter(Boolean).join(', ') + } + if (typeof parsed.value === 'string') return parsed.value + if (typeof parsed.firstName === 'string') { + return [parsed.firstName, parsed.middleInitial, parsed.lastName, parsed.age ? `(age ${parsed.age})` : '', parsed.relationship].filter(Boolean).join(' ') + } + } + } catch { + // plain text + } + return val.replace(/_/g, ' ') + } + \ No newline at end of file diff --git a/app/pages/forms/pcl.vue b/app/pages/forms/pcl.vue index 2eb82ee..943cfed 100644 --- a/app/pages/forms/pcl.vue +++ b/app/pages/forms/pcl.vue @@ -58,11 +58,29 @@ } function buildPayload() { - const body: Record = { worstEvent: worstEvent.value } - responses.value.forEach((val, i) => { - body[`q${i + 1}`] = val === -1 ? null : val - }) - return body + return { + worstEvent: worstEvent.value, + q01: responses.value[0], + q02: responses.value[1], + q03: responses.value[2], + q04: responses.value[3], + q05: responses.value[4], + q06: responses.value[5], + q07: responses.value[6], + q08: responses.value[7], + q09: responses.value[8], + q10: responses.value[9], + q11: responses.value[10], + q12: responses.value[11], + q13: responses.value[12], + q14: responses.value[13], + q15: responses.value[14], + q16: responses.value[15], + q17: responses.value[16], + q18: responses.value[17], + q19: responses.value[18], + q20: responses.value[19], + } } async function submitForm() { diff --git a/server/api/clients/[id]/forms/[formKey].get.ts b/server/api/clients/[id]/forms/[formKey].get.ts index 11f1186..ad5af96 100644 --- a/server/api/clients/[id]/forms/[formKey].get.ts +++ b/server/api/clients/[id]/forms/[formKey].get.ts @@ -187,6 +187,7 @@ export default defineEventHandler(async (event) => { formName: 'GAD-7', questions, submitted: gadForm?.status === 'COMPLETE', + submittedAt: gadForm?.submittedAt, score: gadForm?.totalScore, severity: gadForm?.severity, } @@ -204,11 +205,13 @@ export default defineEventHandler(async (event) => { formName: 'PHQ-9', questions, submitted: phqForm?.status === 'COMPLETE', + submittedAt: phqForm?.submittedAt, score: phqForm?.totalScore, severity: phqForm?.severity, } } + // ── PCL-5 ───────────────────────────────────────────────── if (formKey === 'pcl') { const pclForm = await prisma.pclForm.findFirst({ where: { userId: clientUserId }, @@ -221,7 +224,46 @@ export default defineEventHandler(async (event) => { (await prisma.pclQuestion.findFirst({ where: { formId: pclForm.id } })) ?? (await prisma.pclQuestion.findFirst({ where: { userId: clientUserId } })) } - const questions = await loadClinicalFormQuestions(prisma, clientUserId, 'pcl') + let questions = await loadClinicalFormQuestions(prisma, clientUserId, 'pcl') + + const OPTIONS = ['Not at all', 'A little bit', 'Moderately', 'Quite a bit', 'Extremely'] + + if (questions.length < 20 && pclForm) { // ← was `< 0`, which is never true + const PCL5_QUESTIONS = [ + 'Repeated, disturbing, and unwanted memories of the stressful experience?', + 'Repeated, disturbing dreams of the stressful experience?', + 'Suddenly feeling or acting as if the stressful experience were actually happening again?', + 'Feeling very upset when something reminded you of the stressful experience?', + 'Having strong physical reactions when something reminded you of the stressful experience?', + 'Avoiding memories, thoughts, or feelings related to the stressful experience?', + 'Avoiding external reminders of the stressful experience?', + 'Trouble remembering important parts of the stressful experience?', + 'Having strong negative beliefs about yourself, other people, or the world?', + 'Blaming yourself or someone else for the stressful experience or what happened after it?', + 'Having strong negative feelings such as fear, horror, anger, guilt, or shame?', + 'Loss of interest in activities that you used to enjoy?', + 'Feeling distant or cut off from other people?', + 'Trouble experiencing positive feelings?', + 'Irritable behavior, angry outbursts, or acting aggressively?', + 'Taking too many risks or doing things that could cause you harm?', + 'Being "superalert" or watchful or on guard?', + 'Feeling jumpy or easily startled?', + 'Having difficulty concentrating?', + 'Trouble falling or staying asleep?', + ] + + questions = [ + // worstEvent as the first question so it appears at the top + { label: 'Worst event', answer: q?.worstEvent ?? '' }, + ...PCL5_QUESTIONS.map((label, i) => { + const key = `q${String(i + 1).padStart(2, '0')}` as keyof typeof q + const raw = q?.[key] + const answer = typeof raw === 'number' && raw >= 0 && raw <= 4 ? (OPTIONS[raw] ?? '') : '' + return { label, answer } + }), + ] + } + let totalScore = pclForm?.totalScore ?? null if (q && totalScore == null) { totalScore = 0 @@ -248,6 +290,5 @@ export default defineEventHandler(async (event) => { severity, } } - throw createError({ statusCode: 400, statusMessage: 'Invalid form key' }) }) diff --git a/server/api/clients/[id]/forms/[formKey].patch.ts b/server/api/clients/[id]/forms/[formKey].patch.ts index 4992327..c688ab7 100644 --- a/server/api/clients/[id]/forms/[formKey].patch.ts +++ b/server/api/clients/[id]/forms/[formKey].patch.ts @@ -11,6 +11,13 @@ const PHQ_OPTIONS: Record = { 'Nearly every day': 3, } +const PHQ_DIFFICULTY_OPTIONS: Record = { + 'Not difficult at all': 0, + 'Somewhat difficult': 1, + 'Very difficult': 2, + 'Extremely difficult': 3, +} + const GAD_OPTIONS: Record = { 'Not at all': 0, 'Several days': 1, @@ -100,8 +107,13 @@ export default defineEventHandler(async (event) => { if (!form) throw createError({ statusCode: 404, statusMessage: 'Form not found' }) const keys = ['q1','q2','q3','q4','q5','q6','q7','q8','q9','q10'] const data: Record = {} - answers.forEach((a, i) => { if (keys[i]) data[keys[i]!] = toInt(a.answer, PHQ_OPTIONS) }) - await prisma.phqQuestion.update({ where: { formId: form.id }, data }) + answers.forEach((a, i) => { + if (!keys[i]) return + // q10 uses different options than q1-q9 + const map = keys[i] === 'q10' ? PHQ_DIFFICULTY_OPTIONS : PHQ_OPTIONS + data[keys[i]!] = toInt(a.answer, map) + }) + await prisma.phqQuestion.update({ where: { formId: form.id }, data }) // Recalculate score (q1-q9 only, q10 is difficulty) const total = ['q1','q2','q3','q4','q5','q6','q7','q8','q9'].reduce((sum, k) => sum + (data[k] ?? 0), 0) @@ -110,23 +122,41 @@ export default defineEventHandler(async (event) => { return { ok: true } } - // ── PCL-5 ───────────────────────────────────────────────── - if (formKey === 'pcl') { - const form = await prisma.pclForm.findFirst({ where: { userId: clientUserId }, orderBy: { id: 'desc' } }) - if (!form) throw createError({ statusCode: 404, statusMessage: 'Form not found' }) - const data: Record = {} - answers.forEach((a, i) => { - const key = `q${String(i + 1).padStart(2, '0')}` - data[key] = toInt(a.answer, PCL_OPTIONS) - }) - await prisma.pclQuestion.update({ where: { formId: form.id }, data }) +// ── PCL-5 ───────────────────────────────────────────────── +if (formKey === 'pcl') { + const form = await prisma.pclForm.findFirst({ where: { userId: clientUserId }, orderBy: { id: 'desc' } }) + if (!form) throw createError({ statusCode: 404, statusMessage: 'Form not found' }) - // Recalculate score - const total = Object.values(data).reduce((sum, v) => sum + (v ?? 0), 0) - const severity = total <= 20 ? 'Minimal' : total <= 40 ? 'Mild' : total <= 60 ? 'Moderate' : 'Severe' - await prisma.pclForm.update({ where: { id: form.id }, data: { totalScore: total, severity } }) - return { ok: true } + const worstEventAnswer = answers.find(a => a.label === 'Worst event') + const questionAnswers = answers.filter(a => a.label !== 'Worst event') + + const data: Record = {} + + if (worstEventAnswer !== undefined) { + data.worstEvent = worstEventAnswer.answer } + questionAnswers.forEach((a, i) => { + const key = `q${String(i + 1).padStart(2, '0')}` + data[key] = toInt(a.answer, PCL_OPTIONS) + }) + + await prisma.pclQuestion.update({ where: { formId: form.id }, data }) + + // Recalculate score (only scored questions, not worstEvent) + const total = questionAnswers.reduce((sum, a) => sum + (PCL_OPTIONS[a.answer] ?? 0), 0) + const severity = total <= 20 ? 'Minimal' : total <= 40 ? 'Mild' : total <= 60 ? 'Moderate' : 'Severe' + await prisma.pclForm.update({ + where: { id: form.id }, + data: { + totalScore: total, + severity, + status: 'COMPLETE', // ← add + submittedAt: new Date(), // ← add + } + }) + return { ok: true } +} + throw createError({ statusCode: 400, statusMessage: 'Invalid form key' }) }) \ No newline at end of file diff --git a/server/api/forms/pcl/save.post.ts b/server/api/forms/pcl/save.post.ts index 319e1d8..1def41a 100644 --- a/server/api/forms/pcl/save.post.ts +++ b/server/api/forms/pcl/save.post.ts @@ -42,7 +42,7 @@ export default defineEventHandler(async (event) => { let form = await prisma.pclForm.findFirst({ where: { userId }, - orderBy: { id: 'asc' }, + orderBy: { id: 'desc' }, }) if (!form) { @@ -102,8 +102,8 @@ export default defineEventHandler(async (event) => { await prisma.pclForm.update({ where: { id: form.id }, data: { - status: 'IN_PROGRESS', - submittedAt: null, + status: 'COMPLETE', + submittedAt: new Date(), totalScore, severity, }, diff --git a/server/api/forms/phq/save.post.ts b/server/api/forms/phq/save.post.ts index 9c2f9a4..94b484e 100644 --- a/server/api/forms/phq/save.post.ts +++ b/server/api/forms/phq/save.post.ts @@ -31,7 +31,7 @@ export default defineEventHandler(async (event) => { let form = await prisma.phqForm.findFirst({ where: { userId }, - orderBy: { id: 'asc' }, + orderBy: { id: 'desc' }, }) if (!form) { @@ -86,11 +86,12 @@ export default defineEventHandler(async (event) => { data, }) + // save score await prisma.phqForm.update({ where: { id: form.id }, data: { - status: 'IN_PROGRESS', - submittedAt: null, + status: 'COMPLETE', // ← was 'IN_PROGRESS' + submittedAt: new Date(), // ← was null totalScore, severity, }, From 6e0d8d331b55b01c87daaff3e1f44e885bfb9d2a Mon Sep 17 00:00:00 2001 From: Devika Date: Tue, 28 Apr 2026 14:30:08 -0500 Subject: [PATCH 5/6] additional form fixes --- app/components/FormEditPanel.vue | 12 +++-- app/components/Notes.vue | 54 +++++++++---------- .../api/clients/[id]/forms/[formKey].patch.ts | 6 ++- server/utils/clinical-form-display.ts | 23 +++++--- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/app/components/FormEditPanel.vue b/app/components/FormEditPanel.vue index 9e53131..0a1c55a 100644 --- a/app/components/FormEditPanel.vue +++ b/app/components/FormEditPanel.vue @@ -105,6 +105,8 @@ async function handleSave() { isSaving.value = false } } + +defineExpose({ handleSave }) @@ -169,10 +171,10 @@ async function handleSave() { -
+
\ No newline at end of file diff --git a/app/components/Notes.vue b/app/components/Notes.vue index 85ec834..178b430 100644 --- a/app/components/Notes.vue +++ b/app/components/Notes.vue @@ -138,6 +138,8 @@ const localPreviousNotes = ref([...props.previousNotes]) const localSessionNotes = ref([...props.sessionNotes]) + const formEditPanelRef = ref<{ handleSave: () => void } | null>(null) + watch( () => props.previousNotes, (v) => { @@ -1743,28 +1745,31 @@ description="Try again or open the client profile to view form answers." />
-

- {{ formPreviewData.submitted ? 'Submitted' : 'Not submitted' }} - - · - {{ - new Date( - formPreviewData.completedAt ?? formPreviewData.submittedAt ?? '' - ).toLocaleString('en-US') - }} + + {{ formPreviewData.submitted ? 'Submitted' : 'Not submitted' }} + + · + {{ + new Date( + formPreviewData.completedAt ?? formPreviewData.submittedAt ?? '' + ).toLocaleString('en-US') + }} + -

-
-
+
+ + +
+ +
+
- -
-
- -

No answers yet.

diff --git a/server/api/clients/[id]/forms/[formKey].patch.ts b/server/api/clients/[id]/forms/[formKey].patch.ts index c688ab7..392944c 100644 --- a/server/api/clients/[id]/forms/[formKey].patch.ts +++ b/server/api/clients/[id]/forms/[formKey].patch.ts @@ -91,7 +91,11 @@ export default defineEventHandler(async (event) => { if (!form) throw createError({ statusCode: 404, statusMessage: 'Form not found' }) const keys = ['g01','g02','g03','g04','g05','g06','g07','g08'] const data: Record = {} - answers.forEach((a, i) => { if (keys[i]) data[keys[i]!] = toInt(a.answer, GAD_OPTIONS) }) + answers.forEach((a, i) => { + if (!keys[i]) return + const map = keys[i] === 'g08' ? PHQ_DIFFICULTY_OPTIONS : GAD_OPTIONS + data[keys[i]!] = toInt(a.answer, map) + }) await prisma.gadQuestion.update({ where: { formId: form.id }, data }) // Recalculate score (g01-g07 only, g08 is difficulty) diff --git a/server/utils/clinical-form-display.ts b/server/utils/clinical-form-display.ts index 0d4f97b..4d68ce4 100644 --- a/server/utils/clinical-form-display.ts +++ b/server/utils/clinical-form-display.ts @@ -64,6 +64,13 @@ export const GAD_OPTIONS: Record = { 3: 'Nearly every day', } +export const DIFFICULTY_OPTIONS: Record = { + 0: 'Not difficult at all', + 1: 'Somewhat difficult', + 2: 'Very difficult', + 3: 'Extremely difficult', +} + export const PCL_OPTIONS: Record = { 0: 'Not at all', 1: 'A little bit', @@ -127,7 +134,9 @@ export async function loadClinicalFormQuestions( const answers = [q.g01, q.g02, q.g03, q.g04, q.g05, q.g06, q.g07, q.g08] return GAD_LABELS.slice(0, answers.length).map((label, i) => ({ label, - answer: answers[i] != null ? (GAD_OPTIONS[answers[i] as number] ?? String(answers[i])) : '', + answer: answers[i] != null + ? ((i === 7 ? DIFFICULTY_OPTIONS : GAD_OPTIONS)[answers[i] as number] ?? String(answers[i])) + : '', })) } @@ -145,7 +154,9 @@ export async function loadClinicalFormQuestions( const answers = [q.q1, q.q2, q.q3, q.q4, q.q5, q.q6, q.q7, q.q8, q.q9, q.q10] return PHQ_LABELS.slice(0, answers.length).map((label, i) => ({ label, - answer: answers[i] != null ? (PHQ_OPTIONS[answers[i] as number] ?? String(answers[i])) : '', + answer: answers[i] != null + ? ((i === 9 ? DIFFICULTY_OPTIONS : PHQ_OPTIONS)[answers[i] as number] ?? String(answers[i])) + : '', })) } @@ -161,14 +172,14 @@ export async function loadClinicalFormQuestions( (await prisma.pclQuestion.findFirst({ where: { userId } })) } if (!q) return [] - const questions: ClinicalFormQuestionRow[] = [] + const questions: ClinicalFormQuestionRow[] = [ + { label: 'Worst event', answer: q.worstEvent ?? '' }, + ] for (let i = 1; i <= 20; i++) { const key = `q${String(i).padStart(2, '0')}` as keyof typeof q const val = q[key] const numVal = typeof val === 'number' ? val : null - if (numVal != null && numVal >= 0) { - questions.push({ label: `Item ${i}`, answer: PCL_OPTIONS[numVal] ?? String(numVal) }) - } + questions.push({ label: PCL_LABELS[i - 1] ?? `Item ${i}`, answer: numVal != null ? (PCL_OPTIONS[numVal] ?? String(numVal)) : '' }) } return questions } From b768190ff57d20464e9512032a2d4c4549c5b28c Mon Sep 17 00:00:00 2001 From: Devika Date: Wed, 29 Apr 2026 01:46:20 -0500 Subject: [PATCH 6/6] forms-fix --- server/api/admin/backfill-absences.post.ts | 2 +- server/api/appointments/index.post.ts | 2 +- server/api/session-notes/pending-approvals.get.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/api/admin/backfill-absences.post.ts b/server/api/admin/backfill-absences.post.ts index 4a39ae6..23b4777 100644 --- a/server/api/admin/backfill-absences.post.ts +++ b/server/api/admin/backfill-absences.post.ts @@ -22,7 +22,7 @@ export default defineEventHandler(async (event) => { const calendarAbsences = await prisma.sessionNote.count({ where: { clientId: client.id, - attended: false, + attendanceStatus: 'no-show', }, }) diff --git a/server/api/appointments/index.post.ts b/server/api/appointments/index.post.ts index 4a1b91d..64df377 100644 --- a/server/api/appointments/index.post.ts +++ b/server/api/appointments/index.post.ts @@ -130,7 +130,7 @@ export default defineEventHandler(async (event) => { sessionName, sessionNumber, content: '', - attended: true, + attendanceStatus: 'show', }, }) } diff --git a/server/api/session-notes/pending-approvals.get.ts b/server/api/session-notes/pending-approvals.get.ts index 7409519..20e2198 100644 --- a/server/api/session-notes/pending-approvals.get.ts +++ b/server/api/session-notes/pending-approvals.get.ts @@ -15,7 +15,7 @@ export default defineEventHandler(async (event) => { typeof query.kind === 'string' ? query.kind.toUpperCase() : '' const kindFilter = kindParam === 'PROGRESS' || kindParam === 'PSYCHOTHERAPY' - ? { kind: kindParam } + ? { kind: kindParam as 'PROGRESS' | 'PSYCHOTHERAPY' } : {} const rows = await prisma.sessionNote.findMany({ @@ -55,7 +55,7 @@ export default defineEventHandler(async (event) => { kind: r.kind, status: r.status, content: r.content, - attended: r.attended, + attendanceStatus: r.attendanceStatus, appointmentId: r.appointmentId, appointmentStartTime: r.appointment?.startTime?.toISOString() ?? null, clinicianSignedAt: r.clinicianSignedAt?.toISOString() ?? null,