Kulcare Docs
Test reportsSessions

Session 8: Add Patient & Booking Flow

Date: 2026-06-11 Module: Add Patient - Federated Search URL:


📊 Test Results Summary

CategoryTested✅ Passed❌ Failed
Federated Search - Name211
Federated Search - Phone110
Import from Kulcare431
Create Patient - Happy Path330
Create Patient - Validation725
Patient List110
Total18117

🐛 Bugs Found

Bug #DescriptionSeverityStatus
31Federated Search - partial name works, full name doesn't🟡 HighOpen
32DOB not auto-filled when importing from Kulcare🟡 HighOpen
34No validation for patient form (Frontend + Backend)🟠 MediumOpen
34bBackend accepts empty/whitespace for last_name🟠 MediumOpen
34cBackend accepts whitespace for phone_number🟠 MediumOpen
35Patient list date range filter not working🟠 MediumOpen

🔍 Detailed Test Results

#Test CaseResultBugNotes
FS-04Search by partial name ("mohit")✅ PASS-Returns results
FS-05Search by full name ("mohit goyal")❌ FAIL#31No results returned

Federated Search - Phone

#Test CaseResultBugNotes
FS-01Search by phone✅ PASS-Works correctly

Import from Kulcare

#Test CaseResultBugNotes
SP-03Import in-Kulcare patient - check DOB❌ FAIL#32DOB not auto-filled
SP-04Import in-Kulcare patient - check name✅ PASS-Name auto-fills
SP-05Import in-Kulcare patient - check phone✅ PASS-Phone auto-fills
SP-06Import in-Kulcare patient - check gender✅ PASS-Gender auto-fills

Create Patient - Happy Path

#Test CaseResultNotes
CP-01Create with all required fields✅ PASSPatient created successfully
CP-02Create with required only✅ PASSPatient created successfully
CP-03Create with all fields✅ PASSPatient created with all data

Create Patient - Validation

#Test CaseResultBugNotes
CP-04Empty first name✅ PASSBackend gives error: "First name can't be blank"
CP-05Empty last name❌ FAILBug #34bBackend accepts empty/whitespace
CP-06Empty phone✅ PASSPhone is required
CP-07Invalid phone (letters)❌ FAILBug #34Form accepts invalid data
CP-07bPhone with whitespace❌ FAILBug #34cBackend accepts whitespace " "
CP-08Long name (100+ chars)❌ FAILBug #34Form accepts invalid data
CP-09Future DOB❌ FAILBug #34Form accepts invalid data
CP-10Missing gender✅ PASSGender is optional
CP-11Invalid gender✅ PASSHandled correctly

Patient List & Management

#Test CaseResultBugNotes
PL-01View patient list✅ PASS-Shows patients with pagination
PL-02Search patient✅ PASS-Returns matching patients by name/phone
PL-06Multi-clinic patient visibility✅ PASS-Confirmed with dev team - expected behavior

🐛 Bug Details

Bug #31: Federated Search - Partial Name Works, Full Name Doesn't

FieldValue
Severity🟡 High
Bug #31
AreaAdd Patient - Federated Search
Session08-add-patient-booking
StatusOpen

Description: Search by partial name (e.g., "mohit") returns results, but search by full name (e.g., "mohit goyal") returns no results.

Steps to Reproduce:

  1. Search by "mohit" → ✅ Results found
  2. Search by "mohit goyal" → ❌ No results

Expected: Full name search should return results Actual: Only partial name search works

API Evidence:

# Partial name - WORKS
curl 'https://api-stg.kulcare.com/clinical/patients/federated_search?name=mohit' \
  -H 'Authorization: Bearer ...'
# Returns: Patient "Mohit Goyal" found

# Full name - FAILS
curl 'https://api-stg.kulcare.com/clinical/patients/federated_search?name=mohit%20goyal' \
  -H 'Authorization: Bearer ...'
# Returns: No results

Root Cause (Suspected): The name search uses LIKE with % prefix, which matches partial names but not multi-word full names correctly.

Recommendation: Investigate the name search logic in FederatedSearchService#apply_name_filter:

def apply_name_filter(scope)
  scope.where('LOWER(first_name) LIKE :q OR LOWER(last_name) LIKE :q', q: safe_like_term(@name))
end

The current implementation searches first_name OR last_name separately, not full name as a phrase.


Bug #32: DOB Not Auto-filled When Importing from Kulcare

FieldValue
Severity🟡 High
Bug #32
AreaAdd Patient - Import from Kulcare
Session08-add-patient-booking
StatusOpen

Description: When importing a patient from Kulcare network (in_kulcare bucket), the DOB is not auto-filled even though the patient has DOB set in their Patient App profile.

Steps to Reproduce:

  1. Patient "Mohit Goyal" has DOB set in Patient App
  2. Search in Clinic App → Find in "Elsewhere on Kulcare"
  3. Click "Import" → Form auto-fills
  4. Check DOB field → ❌ Empty

Expected: DOB should be auto-filled from Kulcare profile Actual: DOB field is empty (phone, name, gender are auto-filled correctly)

Root Cause (Suspected): The serialize_in_kulcare method in FederatedSearchService doesn't include birth_date in the response.

Recommendation: Add birth_date to the serialize_in_kulcare method:

def serialize_in_kulcare(identity_patient)
  {
    identity_patient_id: identity_patient.id,
    name: identity_patient.display_name,
    phone: identity_patient.phone_number,
    phone_country_code: identity_patient.phone_country_code,
    age: identity_patient.respond_to?(:age) ? identity_patient.age : nil,
    gender: identity_patient.gender,
    birth_date: identity_patient.birth_date,  # Add this line
    registered_via: identity_patient.user_id.present? ? 'patient_app' : 'another_clinic'
  }
end

Bug #34: No Validation for Patient Form (Frontend + Backend)

FieldValue
Severity🟠 Medium
Bug #34
AreaAdd Patient - Form Validation
Session08-add-patient-booking
StatusOpen

Description: Patient form accepts invalid data without validation. BOTH frontend AND backend accepted:

FieldInvalid InputExpectedActual
first_name100+ charactersErrorAccepted ✅
last_name100+ charactersErrorAccepted ✅
phone_number"dsadasdsadsads" (letters)ErrorAccepted ✅
birth_date2026-06-15 (future)ErrorAccepted ✅

Steps to Reproduce:

  1. Open Add Patient form
  2. Enter very long name (100+ chars)
  3. Enter letters in phone field
  4. Select future DOB
  5. Submit → ❌ Form accepts invalid data
  6. API stores invalid data → ❌ Backend accepts it

API Request That Succeeded:

curl 'https://api-stg.kulcare.com/clinical/patients' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer ...' \
  --data-raw '{
    "first_name":"ddasdsadsadasdsadsadsadsadsafsdfsdfsdfdsfsdfsfdsfdsfdsfdsfdfadsfdsfadsfdsdsadsadsadsadsadsadsa",
    "last_name":"dsadsadsadsadsadsadfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsfdsf",
    "phone_number":"dsadasdsadsads",
    "phone_country_code":"91",
    "gender":"male",
    "birth_date":"2026-06-15"
  }'

API Response: 200 OK - Patient created successfully

Issues Found:

  1. Frontend (AddPatientModal.tsx):

    • No validation for name length
    • No validation for phone format (letters accepted)
    • No validation for DOB (future dates allowed)
  2. Backend (Clinical::PatientsController#patient_params):

    • No length validation on name fields
    • No format validation on phone
    • No date validation on birth_date

Recommendation:

Frontend - Add validation in AddPatientModal:

const validationSchema = z.object({
  first_name: z.string().min(2, "Min 2 chars").max(50, "Max 50 chars"),
  last_name: z.string().min(2, "Min 2 chars").max(50, "Max 50 chars"),
  phone_number: z.string().regex(/^\d{10}$/, "Must be 10 digits"),
  birth_date: z.string().refine(
    (date) => new Date(date) <= new Date(),
    "DOB cannot be in future"
  ),
});

Backend - Add validation in Clinical::Patient model:

validates :first_name, length: { minimum: 2, maximum: 50 }
validates :last_name, length: { minimum: 2, maximum: 50 }
validates :phone_number, format: { with: /\A\d{10}\z/ }
validate :birth_date_not_in_future

def birth_date_not_in_future
  errors.add(:birth_date, "cannot be in future") if birth_date.present? && birth_date > Date.current
end

Bug #34b: Backend Accepts Empty/Whitespace for last_name

FieldValue
Severity🟠 Medium
Bug #34b
AreaAdd Patient - Form Validation
Session08-add-patient-booking
StatusOpen

Description: Backend accepts empty/whitespace for last_name field. first_name is correctly validated, but last_name allows empty strings.

API Evidence:

# Empty last_name - ACCEPTS
curl 'https://api-stg.kulcare.com/clinical/patients' \
  --data-raw '{
    "first_name":"Harsh",
    "last_name":"",
    "phone_number":"1234567890",
    "phone_country_code":"91",
    "gender":"male",
    "birth_date":"2026-06-15"
  }'
# Response: 200 OK - Patient created with last_name: ""

Recommendation:

Frontend - Add validation:

last_name: z.string().min(1, "Required").transform(val => val?.trim())

Backend - Add validation:

validates :last_name, presence: true, unless: -> { last_name.nil? }
before_validation :normalize_names

def normalize_names
  self.last_name = last_name&.strip
end

Bug #34c: Backend Accepts Whitespace for phone_number

FieldValue
Severity🟠 Medium
Bug #34c
AreaAdd Patient - Form Validation
Session08-add-patient-booking
StatusOpen

Description: Backend accepts whitespace for phone_number field. Empty spaces pass validation.

API Evidence:

# Whitespace phone - ACCEPTS
curl 'https://api-stg.kulcare.com/clinical/patients' \
  --data-raw '{
    "first_name":"Chugh",
    "last_name":"",
    "phone_number":"          ",
    "phone_country_code":"91",
    "gender":"male",
    "birth_date":"2026-06-15"
  }'
# Response: 200 OK - Patient created with phone_number: "          "

Recommendation:

Frontend - Add validation:

phone_number: z.string()
  .min(10, "Min 10 digits")
  .max(10, "Max 10 digits")
  .regex(/^\d+$/, "Only digits allowed")

Backend - Add validation:

before_validation :normalize_phone

def normalize_phone
  self.phone_number = phone_number&.gsub(/\D/, '')
end

validates :phone_number, presence: true, format: { with: /\A\d{10}\z/ }

Add phone validation to strip whitespace and validate format:

before_validation :normalize_phone

def normalize_phone
  self.phone_number = phone_number&.strip
end

validates :phone_number, presence: true, format: { with: /\A\d{10}\z/ }

📋 Validation Summary - Bugs #34, #34b, #34c

All three bugs require validation on BOTH frontend AND backend:

BugIssueFrontend FixBackend Fix
#34No validation for name/phone/DOBAdd Zod schema validationAdd model validations
#34bEmpty/whitespace for last_nameTrim input, show error if emptyStrip whitespace, add presence validation
#34cWhitespace for phone_numberOnly allow digits, show errorStrip whitespace, format validation

Bug #35: Patient List Date Range Filter Not Working

FieldValue
Severity🟠 Medium
Bug #35
AreaPatient List
Session08-add-patient-booking
StatusOpen

Description: Patient list page has a date range filter UI, but it is NOT being passed to the API query params.

Root Cause: In PatientsPage.tsx, the date filter state is not included in queryParams:

const queryParams = {
  search: debouncedSearch || undefined,
  page: filters.page,
  per_page: filters.perPage,
  // dateRange NOT included here
};

Recommendation: Add date range params to queryParams:

birth_date_from: filters.dateRange?.from,
birth_date_to: filters.dateRange?.to,

✅ Confirmed Working Features

FeatureStatusNotes
Federated Search - Phone✅ WorksPhone search works correctly
Federated Search - Partial Name✅ WorksPartial name search returns results
Import from Kulcare - Name✅ WorksName auto-fills
Import from Kulcare - Phone✅ WorksPhone auto-fills
Import from Kulcare - Gender✅ WorksGender auto-fills
Multi-clinic Patient Visibility✅ WorksExpected behavior - patients shared in same tenant
Create Patient - Happy Path✅ WorksCP-01, CP-02, CP-03 all pass
Create Patient - first_name validation✅ WorksBackend rejects empty first_name
Create Patient - gender optional✅ WorksGender is optional, works correctly
Create Patient - invalid gender✅ WorksHandled correctly

📋 Test Data Used

PatientPhoneEmailDOBSourceNotes
Mohit Goyal9988776655-SetPatient AppHas DOB set, used for import testing

✅ Recommendations

PriorityRecommendationBug
P0Investigate name search logic in federated_search API#31
P0Include DOB in InKulcareIdentityPatient response#32
P1Add frontend validation for patient form#34
P1Add backend validation for patient form#34

📝 Pending Tests

SectionTest CasesStatus
Federated Search - EmailFS-06Pending
Federated Search - Edge casesFS-07, FS-08, FS-09, FS-10Pending
Create New Patient FormCP-01 to CP-06Pending
Patient ListPL-01 to PL-05Pending
Appointment BookingAB-01 to QM-05Pending

Session Status: 🔄 In Progress Last Updated: 2026-06-11

On this page