Skip to content

BUG-02: Wrong Patient Data Shown in Next Patient Dialogs #13

Description

@Iankodj

BUG-02 — Wrong Patient Data Shown in Next Patient Dialogs

Severity: Critical
Component: Home — Next Patient Card
File: src/app/home/home.ts
Status: Open


Summary

The "Reason for Visit" and "Allergy Alert" dialogs opened from the Next Patient card always display data for a hardcoded patient (Isabella Rossi, P-102563), regardless of who is actually loaded as nextPatient. A physician viewing these dialogs could act on the wrong patient's clinical information.


Description

The Home component shows a "Next Patient" card. The card correctly loads nextPatient from PATIENTS_DATA at runtime. However, the two dialogs that can be opened from this card — "Reason for Visit" and "Allergy Alert" — use entirely separate, hardcoded data objects that are never connected to nextPatient:

// home.ts — hardcoded regardless of actual next patient
public reasonForVisit = {
  patient: 'Isabella Rossi',
  patientId: 'P-102563',
  appointmentDate: 'Today, 9:30 AM',
  visitType: 'Cardiology Follow-up',
  primaryConcern: 'Post-procedure cardiac monitoring',
  // ...all data statically defined for one patient
};

public allergyAlert = {
  patient: 'Isabella Rossi',
  patientId: 'P-102563',
  allergen: 'Penicillin',
  allergyType: 'Drug Allergy',
  severity: 'Severe',
  reaction: 'Anaphylaxis',
  // ...all data statically defined for one patient
};

These objects are plain TypeScript class property literals. They are not derived from this.nextPatient and are never updated when nextPatient changes.

The nextPatient itself is also hardcoded to patient ID 3:

// home.ts — ngOnInit
this.nextPatient = PATIENTS_DATA.find((p) => p.id === 3) || null;

This means:

  • If the schedule is updated and a different patient is first up, nextPatient could theoretically change
  • But reasonForVisit and allergyAlert will always show Isabella Rossi's data
  • The dialogs display the patient name and ID prominently, misleading the physician into thinking the data belongs to whoever is shown on the card

Steps to Reproduce

  1. Navigate to the Home page: http://localhost:4200/#/
  2. Locate the Next Patient card (Isabella Rossi shown by default)
  3. Click the "Reason for Visit" link on the card
  4. Observe the dialog shows Isabella Rossi's specific clinical details
  5. Modify home.ts line with id === 3 to load a different patient (e.g., id === 1)
  6. Reload — the card now shows a different patient name, but the dialogs still show Isabella Rossi's allergy and visit data

Result: Allergy alert dialog shows Penicillin/Anaphylaxis for a patient who may have no such allergy.
Expected: Dialog data reflects the actual nextPatient loaded at runtime.


Root Cause

The reasonForVisit and allergyAlert objects were hardcoded as proof-of-concept values and never replaced with dynamic bindings to this.nextPatient. The feature was implemented in two disconnected halves — the card display (dynamic) and the dialog data (static).


Impact

  • Patient safety: A physician could read the wrong patient's severe allergy profile (Penicillin — Anaphylaxis) before prescribing medication for a different patient who has no such allergy.
  • Wrong visit reason shown: Clinical preparation based on the wrong chief complaint, background, or objectives.
  • No error or visual cue to alert the physician that the data is mismatched.

Fix Specification

Step 1 — Derive dialog data from nextPatient

Move reasonForVisit and allergyAlert from static object literals to computed getters (or populate them dynamically after nextPatient is set):

public get reasonForVisit() {
  if (!this.nextPatient) return null;
  return {
    patient: this.nextPatient.name,
    patientId: this.nextPatient.patientCode,
    visitType: this.nextPatient.diagnosis,           // or a dedicated field
    primaryConcern: this.nextPatient.primaryConcern, // extend PatientProfile if needed
    // ...map remaining fields from nextPatient or its next appointment
  };
}

public get allergyAlert() {
  if (!this.nextPatient || !this.nextPatient.allergies?.length) return null;
  const allergy = this.nextPatient.allergies[0];    // primary allergy
  return {
    patient: this.nextPatient.name,
    patientId: this.nextPatient.patientCode,
    allergen: allergy.name,
    severity: allergy.severity,
    reaction: allergy.reaction,
    // ...map remaining fields
  };
}

Step 2 — Extend PatientProfile data model

Add allergies, reasonForVisit, and nextAppointment fields to the PatientProfile interface in patients.data.ts so the data can be populated per patient.

Step 3 — Fix nextPatient to use actual schedule

Replace the hardcoded ID lookup with logic that reads from today's appointments:

ngOnInit(): void {
  this.appointments = this.appointmentsService.getTodaysAppointments();

  const upcomingAppointment = this.appointments.find(
    (a) => a.status === 'Upcoming' || a.status === 'In Progress'
  );

  if (upcomingAppointment) {
    const patient = PATIENTS_DATA.find(
      (p) => p.name === upcomingAppointment.patientName
    );
    this.nextPatient = patient ?? null;
  }
}

Step 4 — Guard dialogs when data is unavailable

If no allergy or visit data exists for the next patient, disable the corresponding buttons and show a "No data available" state inside the dialogs instead of showing wrong data.


Acceptance Criteria

  • "Reason for Visit" dialog shows visit data that belongs to the patient shown on the Next Patient card
  • "Allergy Alert" dialog shows allergy data that belongs to the patient shown on the Next Patient card
  • Changing which patient appears as nextPatient causes both dialogs to reflect the new patient's data
  • Dialogs show an empty/placeholder state if no data is available for the next patient
  • Patient name and ID displayed in the dialogs match the patient name shown on the card

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't workingDemoAdditions, Improvements or fixes in a demo item from public sites

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions