Kulcare Docs
Test reportsBugs

Staging Bugs - All Issues

Document Version: 5.0 Last Updated: 2026-06-25 Total Bugs: 62 Resolved & Verified: 49 | Pending: 13


✅ QA Verification Summary (PR #1735)

Source: GitHub PR #1735 Verified by: SinglaKartik Dates: 2026-06-24, 2026-06-25

CategoryCountBug Numbers
🔴 Critical Bugs5#10, #17, #24, #26, #29
🟡 High Priority19#1, #2, #8, #9, #19, #21, #31, #32, #36, #38, #44, #45, #46, #47, #51, #55, #56, #62
🟠 Medium Priority16#5, #14, #15, #18, #20, #22, #23, #25, #31, #34, #48, #49, #52, #53, #54
🟢 Low Priority2(included in above)
✅ Patient App (2026-06-25)7#3, #4, #5, #6, #7, #35, #6b
TOTAL VERIFIED~49

✨ New Feature Added (2026-06-25)

  • Confirm Follow-Up Flow: Added confirm button, confirmation modal, and "Confirmed" tab in Follow-ups page

🔧 Bug Fixes (2026-06-25)

  • Bug #3: OTP paste in reset password - Fixed missing paste handler in Patient App
  • Bug #4: Photo upload preview - Already working, verified
  • Bug #5: DOB allows future dates - Added .refine() validation + max date attribute
  • Bug #6: No format validation on pincode/phone - Added regex validation (6 digits for pincode, 10-15 for phone)
  • Bug #6b: Clear form fields not saved - Fixed backend to clear empty JSONB fields
  • Bug #7: Special characters in name fields - Added regex to allow only letters, spaces, hyphens, apostrophes
  • Bug #35: Email field missing in Patient App - Added email field to profile form
  • Backend Fix: Rails update doesn't clear empty JSONB fields - Added explicit clearing logic

Bug Summary by Status

CategoryCountNotes
✅ Verified Fixed49All bugs fixed and tested
🔧 Deferred (New Billing)5#11, #12, #13, #50, #37, #57, #60
🔧 Deferred (Architecture)2#58, #59
⚠️ DevOps1#30 - Sidekiq down on staging
✅ Not a Bug2#33 (expected), #15 (fixed by #14)
TOTAL~59Excludes duplicate entries

🔴 Critical Bugs (Block Production)

Bug #10: Cross-App Authentication Not Enforced

FieldValue
Severity🔴 CRITICAL
Bug #10
AreaAuthentication
Session03-clinic-app-auth
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Users can login to applications they shouldn't have access to based on their role.

Resolution: Backend ALLOWED_APPS role-to-app gate in SessionsController. CMS login sends app: 'cms', patient login sends app: 'patient' as top-level param. Gate checks before issuing tokens — 403 APP_ACCESS_DENIED on cross-app attempts.

Issues Identified:

  • Patient accounts can login to Clinic/CMS app
  • Staff/Doctor/Admin accounts can login to Patient app

Expected Behavior:

  • Patient account → Patient app ONLY
  • Staff/Doctor/Admin → Clinic app ONLY

Actual Behavior:

  • No app-level authentication enforcement
  • Any registered phone can login to either app

Bug #17: Cross-App Forgot Password Not Enforced

FieldValue
Severity🔴 CRITICAL
Bug #17
AreaAuthentication - Forgot Password
Related toBug #10
Session03-clinic-app-auth
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Forgot password allows cross-app password reset.

Resolution: Cross-app check moved BEFORE ResetService.call in PasswordsController#reset — SMS never sent if user can't access the requesting app. Frontend forgot-password pages check response message and stay on page (no OTP navigation) when blocked.

Issues Identified:

  • Patient account can reset password via Clinic app
  • Clinic account can reset password via Patient app

Bug #24: Invite Sent to Registered Email

FieldValue
Severity🔴 CRITICAL
Bug #24
AreaInvite Flow
Session05-clinic-app-invite-flow
Status✅ Closed

Description: Invite sent to email that already exists in system.

Current Flow:

  1. Invite created ✅
  2. User opens link
  3. Signup fails ❌ - "email already exists"

Expected: Block invite creation Actual: Invite created, acceptance fails


Bug #26: Invite to Active User

FieldValue
Severity🔴 CRITICAL
Bug #26
AreaInvite Flow
Session05-clinic-app-invite-flow
Status✅ Closed

Description: Already active clinic members can receive new invites.

Expected: Block with error "User is already a member of this clinic" Actual: Invite created successfully


Bug #29: Doctor Can Set Other Doctor's Schedule — ✅ RESOLVED

FieldValue
Severity🔴 CRITICAL
Bug #29
AreaAvailability - Authorization
Session06-availability-booking
Status✅ Closed (2026-06-23) ✅ VERIFIED

Resolution: Fixed in commit 7c713c176 — fix(identity): restrict practitioner schedule writes to owner/admin or self (#1689). The PractitionerSchedulePolicy now correctly gates create?/update?/destroy? on tenant_admin? || tenant_owner? || owns_practitioner_role?.


🟡 High Priority Bugs

Bug #2: Resend OTP Not Working (Patient)

FieldValue
Severity🟡 High
Bug #2
AreaPatient Signup
Session01-patient-app-auth
Status✅ Closed

Description: Resend OTP not working in patient signup flow.


Bug #9: Resend OTP 500 Error (Clinic)

FieldValue
Severity🟡 High
Bug #9
AreaClinic Signup
Session03-clinic-app-auth
Status✅ Closed

Description: Resend OTP gives 500 Internal Server Error.


Bug #19: Backend Validation Error Not Displayed

FieldValue
Severity🟡 High
Bug #19
AreaInvite Flow
Session05-clinic-app-invite-flow
Status✅ Closed

Description: Frontend shows generic toast instead of backend error message.

Backend Response:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Invite already exists"
  }
}

Frontend shows: "Unable to send. Please try again." Should show: "Invite already exists"


Bug #21: Practitioner Invite to Existing Patient

FieldValue
Severity🟡 High
Bug #21
AreaInvite Flow
Session05-clinic-app-invite-flow
Status✅ Closed

Description: Mobile registered as patient can still receive doctor invite.

Expected: Block invite creation Actual: Invite created successfully


Bug #27: Set Consultation Fee (PATCH API)

FieldValue
Severity🟡 High
Bug #27
AreaOnline Booking
Session06-availability-booking
Status✅ Closed

Description: Unable to set consultation fee via PATCH API.

API: PATCH /identity/practitioner_roles/:id


Bug #28: Set Telemedicine Fees (PATCH API)

FieldValue
Severity🟡 High
Bug #28
AreaOnline Booking
Session06-availability-booking
Status✅ Closed

Description: Unable to set telemedicine fees via PATCH API.

API: PATCH /identity/practitioner_roles/:id


FieldValue
Severity🟡 High
Bug #30
AreaPatient Search
Session07-patient-search
Status✅ Closed

Description: Search functionality is working correctly (UI, filters, pagination), but newly created doctors and hospitals are not appearing in search results.

Root Cause: Data synchronization issue between database and Typesense search index.


🟠 Medium Priority Bugs

Bug #DescriptionAreaSessionStatus
1Error message not user-friendly (Patient)Patient Signup01-patient-app-auth✅ Closed
3OTP paste in reset passwordForgot Password01-patient-app-auth✅ Verified Fixed (2026-06-25)
4Photo upload preview not showingProfile02-patient-app-profile✅ Verified Fixed (2026-06-25)
5DOB allows future datesProfile02-patient-app-profile✅ Verified Fixed (2026-06-25)
6No format validation on pincode/phoneProfile02-patient-app-profile✅ Verified Fixed (2026-06-25)
6bClear form fields not savedProfile02-patient-app-profile✅ Verified Fixed (2026-06-25)
7Special characters in name fieldsProfile02-patient-app-profile✅ Verified Fixed (2026-06-25)
8Error message not user-friendly (Clinic)Clinic Signup03-clinic-app-auth✅ Closed
11Edit service not working (PATCH)Clinic Settings04-clinic-app-settings🔧 Deferred
12Edit procedure not working (PATCH)Clinic Settings04-clinic-app-settings🔧 Deferred
13Edit vital not working (PATCH)Clinic Settings04-clinic-app-settings🔧 Deferred
14Duplicate name (exact) not rejectedPatient Categories04-clinic-app-settings✅ Closed
15Duplicate name (case-insensitive)Patient Categories04-clinic-app-settings✅ Closed
18Active practitioner API missing phoneInvite Flow05-clinic-app-invite-flow✅ Closed
20Whitespace-only first/last name allowedInvite Flow05-clinic-app-invite-flow✅ Closed
22Cancelled invites not visibleInvite Flow05-clinic-app-invite-flow✅ Closed
23Duplicate invite with same emailInvite Flow05-clinic-app-invite-flow✅ Closed
25Invite modal form state not resetInvite Flow05-clinic-app-invite-flow✅ Closed
31Federated search full nameAdd Patient08-add-patient-booking✅ Closed
32DOB not auto-filled from KulcareAdd Patient08-add-patient-booking✅ Closed
33Patient visible across clinicsAdd Patient08-add-patient-booking✅ Expected Behavior
34No validation for patient formAdd Patient08-add-patient-booking✅ Closed
35Email field missing in Patient AppPatient App - Profile02-patient-app-profile✅ Verified Fixed (2026-06-25)
48Out-of-queue split inconsistentQueue10-queue-booking✅ Closed
49No couple session indicatorQueue10-queue-booking✅ Closed
52Delete dialog reason not clearedReports12-reports✅ Closed
53Phone not shown in follow-upsFollow-ups11-follow-ups✅ Closed
54✓ icon = edit, not confirmFollow-ups11-follow-ups✅ Closed
58Case-sensitive service groupingRevenue12-reports🔧 Deferred
59Visit type breakdown incorrectRevenue12-reports🔧 Deferred

✅ Not a Bug

Bug #DescriptionNotes
16Unregistered phone - forgot password"User not found" shown correctly

🆕 New Bugs (Session 08 - Add Patient & Booking)

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

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

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 '/clinical/patients/federated_search?name=mohit'
# Returns: Patient "Mohit Goyal" found

# Full name - FAILS
curl '/clinical/patients/federated_search?name=mohit%20goyal'
# Returns: No results

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

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

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)


Bug #33: Patient Visible Across Multiple Clinics

FieldValue
Severity🟠 Medium
Bug #33
AreaAdd Patient - Multi-clinic
Session08-add-patient-booking
Status✅ Expected Behavior

Description: When an admin has access to multiple clinics within the same tenant, patients added in one clinic are visible in other clinics.

Verified with Dev Team: ✅ This is expected behavior.

Explanation:

  • Patients in the same tenant are shared across all clinics within that tenant
  • This is by design for the federated search flow
  • Patients can be found and booked across clinics in the same tenant

Architecture:

  • Clinical::Patient is tenant-scoped via RLS
  • FederatedSearchService.in_clinic searches within the current tenant
  • All clinics in the same tenant share the patient pool

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

FieldValue
Severity🟠 Medium
Bug #34
AreaAdd Patient - Form Validation
Session08-add-patient-booking
Status✅ Closed (2026-06-24) ✅ VERIFIED

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

  • First name: 100+ characters
  • Last name: 100+ characters
  • Phone: "dsadasdsadsads" (letters in phone field)
  • DOB: Future date (2026-06-15)

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' \
  --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: No validation for name length, phone format, future DOB
  2. Backend: No validation for name length, phone format, future DOB

Recommendation: Add validation on BOTH frontend AND backend:

  • Name length: min 2 chars, max 50-100 chars
  • Phone: digits only, exactly 10 digits
  • DOB: must not be future date

Bug #35: Email Field Missing in Patient App Profile Edit

FieldValue
Severity🟠 Medium
Bug #35
AreaPatient App - Profile Edit
Session02-patient-app-profile
Status✅ Closed

Description: Patient signs up with email, but the email field is not visible in the profile edit page. Patient cannot update their email later.

Steps to Reproduce:

  1. Patient signs up with email "test@example.com"
  2. Go to Profile → Edit
  3. Check for email field → Not visible ❌

Expected: Email field should be editable in profile settings Actual: Email field missing from edit form

API Evidence: Patient profile PUT request (no email field in payload):

curl 'https://api-stg.kulcare.com/patient/profile' \
  -X 'PUT' \
  -H 'Authorization: Bearer ...' \
  --data-raw '{
    "profile": {
      "first_name": "Uday",
      "last_name": "Bisht",
      "birth_date": "2016-01-22",
      "gender": "male"
    }
  }'

API Response (shows email is stored but null):

{
  "data": {
    "id": "019ecefa-da2e-71cc-bb60-cd7d53ee8aa5",
    "first_name": "Uday",
    "last_name": "Bisht",
    "phone_number": "9988776655",
    "email": null
  }
}

Impact: Patients cannot update their email address after signup


🆕 New Bugs (Session 09 - Patient Management List)

Bug #36: Phone Search Returns No Results on Patient List

FieldValue
Severity🟡 High
Bug #36
AreaPatient List - Search
Session09-patient-management-list
Test IDLIST-12
Status✅ Closed

Description: Searching by phone number on the patient list page returns no results, even when patients with that phone number exist in the list.

Steps to Reproduce:

  1. Note a patient's phone number (e.g., ending in "988") from the patient list
  2. Type the phone digits in the search bar
  3. Observe: no results returned

API Evidence:

curl 'https://api-stg.kulcare.com/clinical/patients?search=988&page=1&per_page=10' \
  -H 'Authorization: Bearer <token>'
# Returns: empty results, even though patient with phone containing "988" exists

Root Cause (Suspected): The PatientsController#index search scope only queries first_name and last_name columns, not phone_number. Unlike the federated search endpoint which searches across multiple fields, the patient list search is name-only.

Expected: Phone number search should match phone_number column Actual: Only name fields are searched

Recommendation: Add phone_number to the search scope in Clinical::PatientsController#index:

scope.where('first_name ILIKE :q OR last_name ILIKE :q OR phone_number ILIKE :q', q: "%#{search}%")

Bug #37: Export Report API Fails - EFS Permission Denied (Staging)

FieldValue
Severity🟡 High
Bug #37
AreaPatient List - Export
Session09-patient-management-list
Test IDLIST-51
Status✅ Closed

Description: Patient export report (POST /clinical/patients/generate_report) fails with a filesystem permission error on staging. The EFS mount path /opt/kulcare-efs-stg/patient_reports_staging either doesn't exist or the Rails process lacks write permissions.

Steps to Reproduce:

  1. Go to Patient List → Click Export → Confirm
  2. Observe: error toast appears

API Evidence:

curl 'https://api-stg.kulcare.com/clinical/patients/generate_report?facility_id=<id>' \
  -X POST \
  -H 'Authorization: Bearer <token>' \
  --data-raw '{}'

# Response: 422 Unprocessable Entity
{
  "data": null,
  "error": {
    "code": "validation_failed",
    "message": "Permission denied @ dir_s_mkdir - /opt/kulcare-efs-stg/patient_reports_staging",
    "details": [{
      "field": "base",
      "message": "Permission denied @ dir_s_mkdir - /opt/kulcare-efs-stg/patient_reports_staging"
    }]
  },
  "meta": { "request_id": "da9231c1-734b-4d77-97c0-095c9d473cdc" }
}

Root Cause: Staging infrastructure issue — Dir.mkdir fails with EACCES on the EFS mount path. The directory is either:

  1. Not mounted on the staging Rails server
  2. Missing write permissions for the Rails process user (deploy)

Expected: Report should be generated and emailed to the user Actual: Ruby Dir.mkdir raises Errno::EACCES — Permission denied

Recommendation:

  • Verify EFS mount exists on staging: ls -la /opt/kulcare-efs-stg/
  • Ensure correct permissions: chown deploy:deploy /opt/kulcare-efs-stg/patient_reports_staging
  • Consider adding a fallback to /tmp if EFS is unavailable

Bug #38: Cross-Clinic Patient Flow Incomplete — No Facility Record Created

FieldValue
Severity🟡 High
Bug #38
AreaPatient List - Cross-Clinic
Session09-patient-management-list
Test IDLIST-42
Status✅ Closed (2026-06-24) ✅ VERIFIED

Resolution: Two-part fix — (1) FindOrCreateService#auto_register_patient_facility creates facility link on search/view (commit 47118d2a9). (2) PatientsController#auto_register_facility_links batch-registers missing links on the patient LIST page before returning results. Uses a NOT IN subquery to find unlinked patients and creates PatientFacility records idempotently — one query on first load, zero queries on subsequent loads. All patients in the list now have valid patient_facility_id, all clickable, no crashes.

Files changed: find_or_create_service.rb, patients_controller.rb

Description: Patient "Mohit" was added in Clinic A. The clinic admin switches to Clinic B (same tenant). The patient appears in Clinic B's list — which is correct, patients are shared within a tenant. But the cross-clinic experience falls apart:

Real user flow (what happens today):

  1. Staff sees patient "Mohit" in Clinic B's list
  2. Tries to 👁️ View details → ❌ Broken (/cms/patient/{id}/null)
  3. Staff can ✏️ Edit the patient — it opens (uses patient.id, not facility ID)
  4. Staff can 📅 Book an appointment — the booking submits successfully
  5. But after booking, staff STILL can't 👁️ View the patient they just booked
  6. The appointment exists in Clinic B's queue, but the patient has no facility record in Clinic B — so the appointment has patient_facility_id: null

This is confusing for users: "I just booked a patient, why can't I see their details? The appointment is in my queue!"

Architectural Gap (how healthcare apps handle this):

In healthcare systems, a patient's relationship with a facility is a first-class concept. There are two common patterns:

PatternBehaviorUsed By
Explicit registrationPatient must be formally registered in each clinic before any actionLarge hospital chains with strict data boundaries
Implicit/Lazy registrationFirst access (view, edit, book) auto-creates the facility relationshipMost clinic management apps (Practo, Phreesia, etc.)

Kulcare currently does neither — it's in an inconsistent middle ground:

  • ✅ Patient is visible cross-clinic (tenant-scoped data)
  • ❌ No facility record is created on access
  • ❌ Booking succeeds but leaves the appointment orphaned
  • ❌ View is broken because the URL depends on a relationship that was never established

Decision needed: Should Kulcare adopt implicit registration (auto-create facility record on first access)? This is the standard for multi-clinic platforms where patients flow between clinics naturally. The alternative is to explicitly scope the patient list to only show patients registered in the current facility.

Root Cause: When a cross-clinic patient is accessed (viewed, edited, booked), no Clinical::PatientFacility record is auto-created for the current facility. Two places are affected:

  1. PatientBlueprint — resolves patient_facility_id only for current facility → null for cross-clinic patients → View link breaks
  2. FindOrCreateService#find_patient_facility_by_patient — returns nil for existing patients without a facility record in the current facility → Appointment created without patient_facility_id

Why booking "works" but shouldn't: Clinical::Appointment model has belongs_to :patient_facility, optional: true — the appointment is created without validation errors, but it's orphaned from the facility context.

Recommended Fix: Auto-create PatientFacility record on first access. In FindOrCreateService:

if patient_id_provided? && find_by_id
  facility = find_patient_facility_by_patient
  facility ||= create_patient_facility(find_by_id)  # auto-register
  return success({ patient: find_by_id, patient_facility: facility })
end

This is the standard healthcare pattern — the act of providing care at a facility establishes the patient-facility relationship. After this fix: View works, appointments carry proper facility context, and the user experience is consistent.


Bug #44: Appointment Duration Not Validated — Allows Overlapping Bookings

FieldValue
Severity🟡 High
Bug #44
AreaAppointment Booking — Duration & Overlap
Session10-queue-booking
Test IDB-51
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Two related issues in duration handling:

Issue 1 — Duration not enforced: Zod has max(120) but per-step validateCurrentStep() bypasses it (only checks doctor + time slot). Backend CreateService has no duration validation at all. User can set 500+ minutes and booking succeeds.

Issue 2 — Overlap check uses hardcoded 15-min, not actual duration: AvailabilityService#slot_conflict? had slot_duration = 15 hardcoded. Books 6:45 with 120 min → only checks 6:45 is free, ignores 7:00 and 7:15 which are already booked. Full 6:45→8:45 window overlaps booked slots but validation passes → double-booking.

Resolution (3-part fix):

  1. UTC timezone fix — utc_datetime helper builds UTC Time directly instead of Time.zone.parse, which re-interpreted UTC HH:MM strings as server local time, shifting the overlap window by the timezone offset.
  2. Appointment conflict check — Added conflicting_appointments method to check standalone appointment rows (not just encounters). Freshly booked CMS appointments have no encounter yet, so the old encounter-only check missed them.
  3. Proper overlap formula — existing.start < new.end AND existing.end > new.start instead of BETWEEN, which falsely flagged back-to-back non-overlapping slots as conflicts.

Files changed: availability_service.rb


Bug #48: Out-of-Queue Split Inconsistent — Finished Patients Stay in Queue

FieldValue
Severity🟠 Medium
Bug #48
AreaQueue Page — Active/Completed Split
Session10-queue-booking
Status✅ Closed

Description: The queue API splits patients inconsistently:

ActionStatusIn queue[]In out_of_queue[]
New bookingbooked✅❌
Start encounterin_progress✅❌
Finish encounterfinished✅ (read-only badge)❌
Manual → Completedfulfilled❌✅
Cancelcancelled❌❌ (disappears)

Three issues:

  1. Finished (encounter) never moves to out_of_queue — "finished" status stays in the main queue as a read-only badge. Only manual "Completed" triggers the OoQ split.
  2. No path from finished → completed — once encounter finishes, status becomes read-only. No dropdown to transition to completed.
  3. Cancelled disappears entirely — removed from both lists. Staff has no visibility into cancelled appointments.

Fix: Backend should consistently split based on status — finished AND fulfilled → out_of_queue[]. Encounter-finish flow should auto-transition appointment status to fulfilled so it moves naturally. Cancelled should appear in out_of_queue[] instead of disappearing.

# QueueService — consistent split logic
active_statuses = %w[proposed pending booked arrived]
out_of_queue_statuses = %w[fulfilled finished cancelled noshow]

Bug #49: No Couple Session Indicator in Queue Row

FieldValue
Severity🟠 Medium
Bug #49
AreaQueue Page — Display
Session10-queue-booking
Status✅ Closed

Description: API returns couple_session: true + spouse info but QueueRow renders nothing — no icon, badge, or spouse name. Staff can't tell it's a couple session from the queue.

Fix: Add indicator when item.couple_session === true — Users icon + "Couple" badge, or show spouse name under patient.


Bug #45: Invite Role Mismatch — Registered User Only Sees Matching Role Invites

FieldValue
Severity🟡 High
Bug #45
AreaInvite Flow — Role Scoping
Session05-clinic-app-invite-flow
Status✅ Closed

Description: Admin sends staff invite to a phone registered as "staff". If admin selects role "staff" → invite appears ✅. If admin selects any other role (doctor/admin/vendor) → invite does NOT appear for the user ❌.

Steps: 1) User registered as "staff" 2) Admin sends invite with role "doctor" 3) User checks invites → empty.

Expected: All invites to the user's phone should be visible, or block mismatched invites at creation time.


Bug #46: Invite Role Overwritten at Signup — Always Registers as Staff

FieldValue
Severity🟡 High
Bug #46
AreaInvite Flow — Role Assignment
Session05-clinic-app-invite-flow
Status✅ Closed

Description: Admin selects role "doctor" for an unregistered user invite. When user signs up via invite link, role is always "staff" — the selected role is not carried through to signup.

Steps: 1) Admin invites unregistered user as "doctor" 2) User completes signup 3) Role = "staff".

Expected: Invite role should be assigned at signup.


FieldValue
Severity🟡 High
Bug #47
AreaInvite Flow — SMS Link
Session05-clinic-app-invite-flow
Status✅ Closed

Description: When inviting an already registered phone number, SMS always contains a signup link. User is already registered — should receive an "accept invite" link to add the clinic role, not re-register.

Steps: 1) User registered in Clinic A 2) Admin in Clinic B invites same phone 3) SMS = signup link 4) User sees signup form, not accept flow.

Expected: Registered users → "Accept Invite" link. Unregistered users → "Signup" link.


Bug #50: Gateway Payment Method Returns 500 Internal Server Error

FieldValue
Severity🟡 High
Bug #50
AreaBilling — Payments
Session11-billing
Test IDBILL-44
Status✅ Closed

Description: Gateway payment method crashes with 500. Cash/Card/UPI/Bank work.

API: POST /billing/patient_facilities/:id/payments with payment_method: "gateway" → 500.


Bug #51: Next Visit — Specific Date Fails "Outside Working Hours"

FieldValue
Severity🟡 High
Bug #51
AreaBilling — Follow-up
Session11-billing
Test IDBILL-94
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Absolute date mode fails — "Appointment time is outside working hours". Interval mode works.

API: next_visit_date: "2026-06-20" → 422. next_visit_value: 7, next_visit_units: "weeks" → 200.

Fix: Absolute mode should default to a working-hour time or skip time validation for follow-ups.


Bug #52: Delete/Cancel Dialog — Reason Not Cleared on Close

FieldValue
Severity🟢 Low
Bug #52
AreaBilling — UI
Session11-billing
Test IDBILL-57
Status✅ Closed

Description: Click outside delete dialog → closes → reopen → previous reason text still filled.

Fix: Reset deleteReason/cancelReason state in dialog's onOpenChange handler.


Bug #53: Phone Not Shown in Follow-ups List

FieldValue
Severity🟠 Medium
Bug #53
AreaFollow-ups — Display
Session11-follow-ups
Test IDFU-15
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Appointment API returns patient: { display, mrn } — no phone field. Frontend tries to show phone via formatPatientPhone() but has no data.

Fix: Include patient.phone_number in appointment blueprint or make a separate patient lookup.


Bug #54: ✓ Icon = Edit, Not Confirm — Confusing UX

FieldValue
Severity🟠 Medium
Bug #54
AreaFollow-ups — UX
Session11-follow-ups
Test IDFU-20
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Green ✓ (check) icon on follow-up rows opens UpdateAppointmentModal — it edits, not confirms. The icon suggests "done/completed" but actually edits. Users expect check = complete, not check = edit.

Fix: Change icon to ✏️ Pencil for edit, or add a separate Confirm flow that marks as completed.


Bug #55: Telemedicine Follow-ups Disappear

FieldValue
Severity🟡 High
Bug #55
AreaFollow-ups — Filter
Session11-follow-ups
Test IDFU-25
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: follow_up=true filters by by_type('fixed') in controller. Changing follow-up to telemedicine type → removed from list. The filter is hardcoded to fixed only.

Fix: Include telemedicine in follow_up filter: scope.by_type(['fixed', 'telemedicine']) if params[:follow_up] == 'true'


Bug #56: Patient Reports Row Click — Wrong URL (patientId Used Twice)

FieldValue
Severity🟡 High
Bug #56
AreaPatient Reports — Navigation
Session12-reports
Test IDREP-24
Status✅ Closed (2026-06-24) ✅ VERIFIED

Description: Clicking a patient row in Patient Reports navigates to /cms/patient/v2/{patientId}/{patientId} — uses patientId for both URL segments instead of patientId + patientFacilityId. The detail page can't load.

Code: PatientReportsPageV2.tsx line 106:

navigate(`/cms/patient/v2/${patientId}/${patientId}`)
// Should be:
navigate(`/cms/patient/v2/${patientId}/${patientFacilityId}`)

Bug #57: Revenue Summary — Payments Not Reflected (All Zeros)

FieldValue
Severity🟡 High
Bug #57
AreaRevenue — Summary API
Session12-reports
Test IDREV-01
Status✅ Closed

Description: Summary returns zero for all payment fields despite ₹2600 in actual payments (₹2500 cash + ₹100 card). Services list is correct, but earnings + billing_summary show zeros.

API Evidence: bills[].amount all ₹0, billing_summary.{paid,unpaid,billed}_amount all ₹0, earnings.{total_revenue,amount_received,amount_pending} all ₹0. Only earnings.billed_amount = ₹7390 is correct.

Root cause: SummaryService#calculate_billing_summary or bills_by_payment_mode not aggregating from Payment/PaymentAllocation tables.


Bug #58: Revenue Summary — Case-Sensitive Service Grouping

FieldValue
Severity🟢 Low
Bug #58
AreaRevenue — Summary API
Session12-reports
Test IDREV-04
Status✅ Closed

Description: "Sugar Test" and "sugar test" counted separately. Should be case-insensitive grouped.

API Evidence: services[] shows Sugar Test (count: 3, ₹6000) + sugar test (count: 2, ₹390).


Bug #59: Revenue Summary — Visit Type Breakdown Incorrect

FieldValue
Severity🟠 Medium
Bug #59
AreaRevenue — Summary API
Session12-reports
Test IDREV-02
Status✅ Closed

Description: All ₹7390 shown under "Walkin" — services from fixed/telemedicine appointments also counted as Walkin.

API Evidence: visit_types[] = Walkin: ₹7390, Virtual: ₹0, Fixed: ₹0 but services exist across walk_in, fixed, and telemedicine appointments.


Bug #60: Revenue Export — Bill Report API Fails

FieldValue
Severity🟡 High
Bug #60
AreaRevenue — Export
Session12-reports
Test IDREV-63
Status✅ Closed

Description: POST /billing/report_exports/bill_report fails. Revenue export generates no report.

API Evidence: Request with facility_id, from_date, to_date → error response.


FieldValue
Severity🟢 Low
Bug #61
AreaRevenue — Services Tab UX
Session12-reports
Test IDSV-01
Status✅ Closed

Description: After typing in service name search and debounce triggers API call, the input loses focus when data reloads. User gets interrupted mid-typing.


Bug #62: Services Tab — Patient Name Null Causes NA Display + Search 500

FieldValue
Severity🟡 High
Bug #62
AreaRevenue — Services Tab
Session12-reports
Test IDSV-02, SV-15
Status✅ Closed

Description: useAllServices API returns patient.name: null for all services. This causes:

  • Patient column shows "NA" in the table
  • Patient name search (?patient_name=) returns 500 Internal Server Error
  • Delete modal shows {{patientName}} template instead of actual name

Root cause: Service creation via billing panel doesn't populate patient.name in the service record.


Bug Status Legend

StatusDescription
✅ ClosedBug fixed and verified through QA testing
🔧 DevOpsInfrastructure/configuration issue
⏸️ DeferredPlanned for future release
⏳ OpenBug confirmed, not yet fixed

Sprint 1 Resolutions (2026-06-23)

Bug #10: Cross-App Authentication Not Enforced — ✅ RESOLVED

FieldValue
Severity🔴 CRITICAL
Bug #10
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added ALLOWED_APPS role-to-app mapping in SessionsController. Login now rejects users whose signed_up_as doesn't match the requesting app. PasswordsController also gated.

Files changed: sessions_controller.rb, passwords_controller.rb


Bug #17: Cross-App Forgot Password — ✅ RESOLVED

FieldValue
Severity🔴 CRITICAL
Bug #17
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Same app gate applied to PasswordsController#reset. Returns generic success message to avoid leaking user existence.

Files changed: passwords_controller.rb


Bug #24: Invite Sent to Registered Email — ✅ RESOLVED

FieldValue
Severity🔴 CRITICAL
Bug #24
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: InviteService now runs check_existing_membership before creating invites. Blocks if user already has an active membership in the tenant.

Files changed: invite_service.rb


Bug #26: Invite to Active User — ✅ RESOLVED

FieldValue
Severity🔴 CRITICAL
Bug #26
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Same as #24 — check_existing_membership blocks invites to users who already have active memberships.

Files changed: invite_service.rb, staff_services/invite_service.rb


Bug #21: Practitioner Invite to Existing Patient — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #21
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: check_existing_membership also checks signed_up_as. Patient accounts blocked from receiving practitioner invites with message "Cannot invite a patient account as a practitioner".

Files changed: invite_service.rb


Bug #45: Invite Role Mismatch — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #45
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: check_existing_membership blocks invites when user's signed_up_as is incompatible with the invite (e.g., staff user receiving practitioner invite).

Files changed: invite_service.rb, staff_services/invite_service.rb


Bug #46: Invite Role Overwritten at Signup — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #46
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: VerificationWithProfileService now checks for invite_token during OTP verification. If present, overrides the user's signed_up_as to match the invite's intended role before profile creation.

Files changed: verification_with_profile_service.rb, registrations_controller.rb


FieldValue
Severity🟡 High
Bug #47
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: send_sms_notification now branches: if the target user already has an account → sends /signin?next=/identity/my/invites link. If no account → sends the signup link with invite token.

Files changed: invite_service.rb, staff_services/invite_service.rb


Bug #19: Backend Validation Error Not Displayed — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #19
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: AddDoctorModal and AddStaffModal catch blocks now surface error.response?.data?.error?.message instead of generic "Failed to send invite."

Files changed: AddDoctorModal.tsx, AddStaffModal.tsx


Bug #20: Whitespace-Only Names Allowed — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #20
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Zod schemas in both modals now use .refine(val => val.trim().length > 0) to reject whitespace-only names.

Files changed: AddDoctorModal.tsx, AddStaffModal.tsx


Bug #25: Invite Modal Form State Not Reset — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #25
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added handleOpenChange handler that resets the form when the dialog closes (via outside click, Escape, or Cancel button).

Files changed: AddDoctorModal.tsx, AddStaffModal.tsx


Bug #23: Duplicate Invite with Same Email — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #23
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Covered by the existing check_existing_invite + new check_existing_membership. Duplicate invites to the same phone/email in the same clinic are blocked before creation.

Files changed: invite_service.rb


🔴 Critical Bugs (Block Production) — 4 Remaining, 1 Resolved

Bug #IssueStatus
#10Cross-app auth not enforced✅ Closed (2026-06-23) ✅ VERIFIED
#17Cross-app forgot password✅ Closed (2026-06-23) ✅ VERIFIED
#24Invite sent to registered email✅ Closed (2026-06-23) ✅ VERIFIED
#26Invite to active user✅ Closed (2026-06-23) ✅ VERIFIED
#29Doctor can set other doctor's schedule✅ Closed

🧪 Sprint 1 Testing Checklist

Use this to verify each fix on staging before marking bugs as Closed.

Auth — Cross-App Enforcement (#10, #17)

#Test CaseExpected Result
1Login to Patient App with a patient account✅ Success
2Login to Patient App with a doctor/staff account❌ Error: "practitioner account cannot access the patient app"
3Login to CMS/Clinic App with a doctor/staff account✅ Success
4Login to CMS/Clinic App with a patient account❌ Error: "patient account cannot access the cms app"
5Forgot Password on Patient App with a doctor phoneReturns generic "If an account exists..." message, no reset code sent
6Forgot Password on Clinic App with a patient phoneReturns generic "If an account exists..." message, no reset code sent

Invite — Backend Validation (#24, #26, #21, #23, #45)

#Test CaseExpected Result
7Invite a phone that's already an active member of this clinic❌ Toast: "User is already an active member of this clinic"
8Invite a phone registered as patient as a practitioner❌ Toast: "Cannot invite a patient account as a practitioner"
9Invite a phone registered as staff as a practitioner❌ Toast: "This user is registered as staff"
10Invite a phone registered as vendor as a practitioner❌ Toast: "Cannot invite a vendor account as a practitioner"
11Invite same phone+email that has a pending invite already❌ Toast: "Invite already exists"
12Invite a brand new phone number (not registered, not a member)✅ Invite created, SMS sent

Invite — Role Carry-Through (#46)

#Test CaseExpected Result
13Admin sends practitioner invite to unregistered phoneUser signs up via invite link → role = practitioner (not staff)
14Admin sends staff invite to unregistered phoneUser signs up via invite link → role = staff
15Admin sends invite with staff_role=admin to unregistered phoneUser signs up → role = staff, membership role = admin
#Test CaseExpected Result
16Invite a phone that already has a Kulcare accountSMS contains sign-in link (not sign-up link). User sees invites in their inbox.
17Invite a phone that does NOT have a Kulcare accountSMS contains sign-up link with invite token. User signs up and auto-accepts.

Frontend — Error Messages (#19)

#Test CaseExpected Result
18Trigger any invite error (e.g., invite existing member)Toast shows the actual backend error message (e.g., "User is already an active member"), NOT "Failed to send invite. Please try again."
19Trigger a network error (disconnect internet, try to send invite)Toast shows a fallback error message

Frontend — Whitespace Names (#20)

#Test CaseExpected Result
20Type spaces only (" ") in First Name field, try to submit❌ Zod error: "First name cannot be only spaces"
21Type spaces only (" ") in Last Name field, try to submit❌ Zod error: "Last name cannot be only spaces"
22Type a real name like "John" → submit✅ Accepted

Frontend — Form Reset (#25)

#Test CaseExpected Result
23Open Doctor Invite modal, fill all fields, click outside to closeReopen → all fields are blank
24Open Doctor Invite modal, fill all fields, press Escape to closeReopen → all fields are blank
25Open Staff Invite modal, fill all fields, click CancelModal closes. Reopen → all fields blank.
26Open Doctor Invite modal, fill all fields, successfully send inviteModal closes. Reopen → all fields blank.

Already Fixed — Verify (#29)

#Test CaseExpected Result
27Login as Doctor A. Try to edit Doctor B's schedule.❌ Should NOT be able to see/edit Doctor B's schedule (only own schedule)
28Login as Clinic Admin/Owner. Try to edit any doctor's schedule.✅ Should be able to manage any doctor's schedule

Sprint 2 Resolutions (2026-06-23)

Bug #36: Phone Search Returns No Results — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #36
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added phone_number to search_columns in PatientsController#index. Was searching only first_name, last_name, display_name, mrn — now also matches phone.

Files changed: patients_controller.rb (line 27)


Bug #56: Patient Reports Row Click — Wrong URL — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #56
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: handlePatientClick now accepts patientFacilityId as second argument. Navigates to /cms/patient/v2/{patientId}/{patientFacilityId} instead of /{patientId}/{patientId}. Updated types in PatientReportsTableV2 and PatientTableSection.

Files changed: PatientReportsPageV2.tsx, PatientReportsTableV2.tsx, PatientTableSection.tsx


Bug #55: Telemedicine Follow-Ups Disappear — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #55
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Changed follow_up filter from by_type('fixed') to by_type(%w[fixed telemedicine]) so telemedicine follow-ups appear in the list.

Files changed: appointments_controller.rb (line 169)


Bug #32: DOB Not Auto-Filled When Importing from Kulcare — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #32
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Auto-fill approximate birth date from the age field returned by federated search API. The API intentionally excludes exact DOB for privacy — age-based year is a reasonable starting point. Applied in both AddPatientModal and appointment booking PatientInformation step.

Files changed: AddPatientModal.tsx, PatientInformation.tsx


Bug #38: Cross-Clinic Patient Flow Incomplete — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #38
Status✅ Closed (2026-06-24) ✅ VERIFIED

Fix: Two-part fix:

  1. FindOrCreateService#auto_register_patient_facility — auto-creates facility link when a patient is searched for or viewed from a different clinic within the same tenant (commit 47118d2a9).
  2. PatientsController#auto_register_facility_links — batch-registers missing facility links on the patient LIST page before returning results. Uses a NOT IN subquery to find unlinked patients and creates one PatientFacility record each (idempotent — skips on subsequent requests). This ensures the patient list never shows rows with null patient_facility_id, and all patients are clickable without crashing the detail view.

Files changed: find_or_create_service.rb, patients_controller.rb


Bug #44: Appointment Duration/Overlap Not Validated — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #44
Status✅ Closed (2026-06-24) ✅ VERIFIED

Fix (3-part):

  1. utc_datetime helper — builds UTC Time from UTC HH:MM instead of Time.zone.parse which re-interpreted UTC strings as local time, shifting the overlap window by the server timezone offset.
  2. conflicting_appointments — added appointment overlap check alongside the existing encounter check. Previously only encounters were checked, but freshly booked CMS appointments have no encounter yet.
  3. Proper overlap formula — existing.start < new.end AND existing.end > new.start instead of BETWEEN which falsely flagged back-to-back slots.

Files changed: availability_service.rb


🧪 Sprint 2 Testing Checklist

Phone Search (#36)

#Test CaseExpected Result
29Go to Patient List, type a phone number that exists (e.g., digits from a known patient)Results show matching patients
30Search by partial phone number (e.g., last 4 digits)Results show matching patients
31Search by name (regression check)Still works as before

Patient Reports URL (#56)

#Test CaseExpected Result
32Go to Reports → Patient Reports, click a patient row that has a facility recordNavigates to patient detail page (not broken URL)
33Verify URL format is /cms/patient/v2/{patientId}/{facilityId}URL contains two different IDs

Telemedicine Follow-Ups (#55)

#Test CaseExpected Result
34Create a telemedicine follow-up appointmentIt appears in the Follow-ups list
35Create a fixed (in-person) follow-up appointmentIt also appears in the Follow-ups list
36Create a walk-in appointment (not a follow-up)Does NOT appear in Follow-ups list

DOB Auto-Fill (#32)

#Test CaseExpected Result
37Add Patient → search for a Kulcare patient who has age set → click ImportDOB field shows approximate year (e.g., "2001-01-01" for age 25)
38Book Appointment → search for Kulcare patient with age → click ImportDOB field auto-filled in the booking form
39Import a Kulcare patient without age setDOB field remains empty (no crash)

Cross-Clinic Patient Auto-Registration (#38)

#Test CaseExpected Result
40Add Patient "A" in Clinic 1. Switch to Clinic 2 (same tenant). Search for Patient A. Click View.Patient detail page loads successfully (not broken URL)
41In Clinic 2, book an appointment for Patient AAppointment is created with proper facility context
42After booking in Clinic 2, view Patient A's detail againPatient now shows Clinic 2 in their facility list
43Patient A's original data in Clinic 1 is unchangedClinic 1 data intact, no data corruption

Appointment Duration / Overlap (#44)

#Test CaseExpected Result
44Doctor has slots: 6:30 free, 6:45 free, 7:00 BOOKED, 7:15 BOOKED. Try to book 6:45 with 120 min duration.❌ Rejected: "Appointment slot is already booked" (overlaps 7:00)
45Doctor has slots: 6:30 free, 6:45 free, 7:00 free. Book 6:45 with 30 min duration.✅ Accepted (6:45-7:15, all free)
46Same setup as #45, now try to book 7:00 with 15 min duration✅ Accepted (7:00-7:15, all free)
47Book a walk-in appointment (no time slot)✅ Accepted (walk-ins don't check overlap)

Sprint 3 Resolutions (2026-06-23)

Bug #5: DOB Allows Future Dates — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #5
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added birth_date_not_in_future validation to Clinical::Patient model.

Files changed: patient.rb


Bug #34: No Backend Validation for Patient Form — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #34
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added phone digit-only format validation to Clinical::Patient. Future DOB blocked by #5 fix.

Files changed: patient.rb


Bug #14+#15: Duplicate Category Names (Case-Insensitive) — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #14, 15
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added case_sensitive: false to FacilityCategory uniqueness validation.

Files changed: facility_category.rb


Bug #48: Out-of-Queue Split Inconsistent — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #48
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: GenerateToday now includes finished/cancelled/noshow in out_of_queue. Removed .not_cancelled filter.

Files changed: generate_today.rb


Bug #53: Phone Not Shown in Follow-Ups List — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #53
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added phone field to appointment blueprint queue view.

Files changed: appointment_blueprint.rb


Bug #18: Practitioner API Missing Phone — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #18
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added phone_number + phone_country_code to PractitionerBlueprint (from identifiers JSONB).

Files changed: practitioner_blueprint.rb


Bug #22: Cancelled Invites Not Visible — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #22
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Removed hardcoded status: 'pending' filter from DoctorsTab + StaffTab queries.

Files changed: DoctorsTab.tsx, StaffTab.tsx


Bug #49: No Couple Session Indicator in Queue — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #49
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Added "Couple" badge with Users icon in QueueRow when couple_session is true.

Files changed: QueueRow.tsx


Bug #54: ✓ Icon = Edit, Not Confirm — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #54
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Changed Check→Pencil icon in FollowUpsTableRow + neutral styling (was green/success).

Files changed: FollowUpsTableRow.tsx


🧪 Sprint 3 Testing Checklist

Validation (#5, #34)

#Test CaseExpected Result
48Add Patient with future DOB (2027-01-01)❌ "birth_date cannot be in the future"
49Add Patient with letters in phone ("abc123")❌ "phone_number must contain only digits"
50Add Patient with valid phone + today's DOB✅ Accepted

Duplicate Categories (#14, #15)

#Test CaseExpected Result
51Create "Diabetes", create "Diabetes" again❌ Name already taken
52Create "Diabetes", create "diabetes"❌ Name already taken (case-insensitive)

Out-of-Queue (#48)

#Test CaseExpected Result
53Finish encounter → check queuePatient moves to Out of Queue
54Cancel appointment → check queueShows in OoQ with "Cancelled" (not disappeared)
55Mark "Completed" → check queueMoves to OoQ (unchanged)

Phone in Follow-Ups + Practitioner API (#53, #18)

#Test CaseExpected Result
56Follow-ups page → check phone columnShows patient phone number
57Invite flow → search practitionersAPI returns phone_number + phone_country_code

Cancelled Invites (#22)

#Test CaseExpected Result
58Send + cancel doctor invite → Doctors tabCancelled invite visible
59Send + cancel staff invite → Staff tabCancelled invite visible

Couple Session Indicator (#49)

#Test CaseExpected Result
60Book couple session → queue"Couple" badge with Users icon
61Book regular appointment → queueNo "Couple" badge

Edit Icon (#54)

#Test CaseExpected Result
62Follow-ups → Pending tab → action iconsPencil (✏️) instead of check (✓)
63Click pencil iconEdit modal opens

Sprint 3.5 — Extra Fixes (2026-06-23)

Bug #31: Federated Search — Full Name Now Works — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #31
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: FederatedSearchService now splits name into words. "Mohit Goyal" matches first_name + last_name separately. Applied to both in_clinic and in_kulcare paths.

Files changed: federated_search_service.rb


Bug #52: Delete Dialog — Reason Cleared on Overlay Click — ✅ RESOLVED

FieldValue
Severity🟢 Low
Bug #52
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: Overlay backdrop click now resets deleteReason + closes modal. Previously only Cancel button cleared state.

Files changed: ServicesTabV2.tsx


Bug #1: Error Messages on Signup (Patient) — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #1
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: SignUpPage catch block now extracts err?.response?.data?.error?.message from API response instead of showing generic Axios error text. The auth service's parseBackendError already maps technical messages to user-friendly text.

Files changed: SignUpPage.tsx


Bug #8: Error Messages on Signup (Clinic) — ✅ RESOLVED

FieldValue
Severity🟠 Medium
Bug #8
Status✅ Closed (2026-06-23) ✅ VERIFIED

Fix: SignInPage already uses parseBackendError which extracts and maps API error messages to user-friendly text. SignUpPage now has the same fallback. Both pages show actual backend errors instead of generic messages.

Files changed: SignUpPage.tsx (SignInPage.tsx already correct)


Bug #51: Next Visit — Absolute Date Now Works — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #51
Status✅ Closed (2026-06-24) ✅ VERIFIED

Root cause (v1): Time.parse interpreted date-only strings as midnight UTC, which is never within any practitioner's working hours — availability check always rejected.

Root cause (v2): parse_date parsed the date in server timezone first via Time.parse, then converted to facility timezone via in_time_zone. When server TZ ≠ facility TZ (e.g. server IST, facility UTC), the date shifted backwards by the offset — landing on the previous day, which is always in the past.

Fix (final): Time.use_zone(facility_timezone) { Time.zone.parse("2026-06-25 09:00:00") } — parses 9 AM directly in the facility's timezone with no conversion hop. Frontend date pickers now enforce min={tomorrow} to prevent selecting today's date (which would be in the past by the time the user submits).

Files changed: next_visit/create_service.rb, NextVisitModal.tsx, NextVisitSection.tsx


Bug #2: Resend OTP Not Working (Patient) — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #2
Status✅ Closed (2026-06-23) ✅ VERIFIED

Root cause: RegistrationsController#find_user_for_resend called User.find_by_phone(country_code, phone_number) — a method that doesn't exist. Rails' dynamic find_by_* only works for single columns, not two args. Result: NoMethodError → 500.

Fix: Changed to User.by_phone(...).first — uses the existing scope. Same fix applied to email lookup (find_by_email → by_email(...).first).

Files changed: registrations_controller.rb, passwords_controller.rb


Bug #9: Resend OTP 500 Error (Clinic) — ✅ RESOLVED

FieldValue
Severity🟡 High
Bug #9
Status✅ Closed (2026-06-23) ✅ VERIFIED

Root cause: Same as #2 — User.find_by_phone doesn't exist. Both clinic and patient apps hit the same /identity/registrations/resend_otp endpoint.

Fix: Same as #2.

Files changed: registrations_controller.rb, passwords_controller.rb

Testing: Schedule a next visit with absolute date → should succeed (no more "outside working hours"). Relative mode should still work unchanged.


🧪 Sprint 3.5 Testing Checklist

#Test CaseExpected Result
64Search "mohit goyal" in Add PatientResults found ✅
65Open delete modal, type reason, click outside → reopenReason field is empty ✅

Updating Bug Status

  1. Edit this file
  2. Update status field
  3. Add resolution notes with date

Adding New Bug

  1. Add to appropriate severity section
  2. Include all required fields
  3. Link to session file
  4. Update bug summary table

Document Status: Active Last Updated: 2026-06-25


✅ All Bugs — Verified & Closed Status

StatusDescription
✅ ClosedBug fixed and verified working in QA testing
✅ ResolvedBug fixed, pending verification
⏳ OpenBug confirmed, not yet fixed
🔧 DevOpsInfrastructure/configuration issue
⏸️ DeferredPlanned for future release

🔴 Critical Bugs — ALL CLOSED ✅

Bug #IssueStatusVerified
#10Cross-app auth not enforced✅ Closed2026-06-24
#17Cross-app forgot password✅ Closed2026-06-24
#24Invite sent to registered email✅ Closed2026-06-24
#26Invite to active user✅ Closed2026-06-24
#29Doctor can set other doctor's schedule✅ Closed2026-06-24

🟡 High Priority Bugs — CLOSED ✅

Bug #IssueStatusVerified
#1Error message not user-friendly (Patient signup)✅ Closed2026-06-24
#2Resend OTP not working (Patient)✅ Closed2026-06-24
#8Error message not user-friendly (Clinic signup)✅ Closed2026-06-24
#9Resend OTP 500 error (Clinic)✅ Closed2026-06-24
#10Cross-app auth not enforced✅ Closed2026-06-24
#17Cross-app forgot password✅ Closed2026-06-24
#19Backend validation error not displayed✅ Closed2026-06-24
#21Practitioner invite to existing patient✅ Closed2026-06-24
#31Federated Search - full name works✅ Closed2026-06-24
#32DOB not auto-filled from Kulcare✅ Closed2026-06-24
#36Phone search returns no results✅ Closed2026-06-24
#38Cross-clinic patient null facility IDs✅ Closed2026-06-24
#44Appointment duration/overlap not validated✅ Closed2026-06-24
#45Invite role mismatch✅ Closed2026-06-24
#46Invite role overwritten at signup✅ Closed2026-06-24
#47Registered user gets signup link✅ Closed2026-06-24
#51Next visit absolute date fails✅ Closed2026-06-24
#55Telemedicine follow-ups disappear✅ Closed2026-06-24
#56Patient reports wrong URL✅ Closed2026-06-24
#62Patient name null in services✅ Closed2026-06-24

🟠 Medium Priority Bugs — CLOSED ✅

Bug #IssueStatusVerified
#5DOB allows future dates✅ Closed2026-06-24
#14Duplicate name (exact) not rejected✅ Closed2026-06-25
#15Duplicate name (case-insensitive)✅ Closed2026-06-25
#18Practitioner API missing phone✅ Closed2026-06-24
#20Whitespace-only names allowed✅ Closed2026-06-24
#22Cancelled invites not visible✅ Closed2026-06-24
#23Duplicate invite with same email✅ Closed2026-06-24
#25Invite modal form state not reset✅ Closed2026-06-24
#31Federated search full name✅ Closed2026-06-24
#34No validation for patient form✅ Closed2026-06-25
#48Out-of-queue split inconsistent✅ Closed2026-06-24
#49No couple session indicator✅ Closed2026-06-24
#52Delete dialog reason not cleared✅ Closed2026-06-24
#53Phone not shown in follow-ups✅ Closed2026-06-24
#54✓ icon = edit, not confirm✅ Closed2026-06-24

Patient App Bug Fixes (2026-06-25) — ALL VERIFIED ✅

Bug #IssueStatusVerified
#3OTP paste in reset password✅ Verified Fixed2026-06-25
#4Photo upload preview✅ Verified Fixed2026-06-25
#5DOB allows future dates✅ Verified Fixed2026-06-25
#6Phone/pincode validation✅ Verified Fixed2026-06-25
#6bClear form fields not saved✅ Verified Fixed2026-06-25
#7Special characters in names✅ Verified Fixed2026-06-25
#35Email field missing✅ Verified Fixed2026-06-25

Ready for Testing (Historical - See Above for Verified Status)

SprintBugsCount
Sprint 1#10, #17, #19, #20, #21, #23, #24, #25, #26, #29, #45, #46, #4713
Sprint 2#32, #36, #38, #44, #55, #566
Sprint 3#5, #14, #15, #18, #22, #34, #48, #49, #53, #5410
Sprint 3.5#31, #522
Sprint 4#1, #2, #8, #9, #51, #626
Patient App#3, #4, #5, #6, #6b, #7, #357
Confirmed OK#27, #282

67 test cases across 4 checklists.


🔴 Pending — Needs DevOps (1 bug)

#SeverityDescription
30🟡 HighNew doctors not in search — Sidekiq down on staging

⏭️ Deferred — New Billing Flow (5 bugs)

#SeverityDescription
11, 12, 13🟠 MediumEdit service/procedure/vital PATCH
50🟡 HighGateway payment 500
37🟡 HighExport report EFS permission
57, 60🟡 HighRevenue summary / bill export

🟢 Pending — Architecture (2 bugs)

#SeverityDescription
58🟢 LowCase-sensitive service grouping
59🟠 MediumVisit type breakdown incorrect

✅ Not Bugs (2)

#Description
33Patient visible across clinics — expected
15Fixed by #14

On this page

✅ QA Verification Summary (PR #1735)✨ New Feature Added (2026-06-25)🔧 Bug Fixes (2026-06-25)Bug Summary by Status🔴 Critical Bugs (Block Production)Bug #10: Cross-App Authentication Not EnforcedBug #17: Cross-App Forgot Password Not EnforcedBug #24: Invite Sent to Registered EmailBug #26: Invite to Active UserBug #29: Doctor Can Set Other Doctor's Schedule — ✅ RESOLVED🟡 High Priority BugsBug #2: Resend OTP Not Working (Patient)Bug #9: Resend OTP 500 Error (Clinic)Bug #19: Backend Validation Error Not DisplayedBug #21: Practitioner Invite to Existing PatientBug #27: Set Consultation Fee (PATCH API)Bug #28: Set Telemedicine Fees (PATCH API)Bug #30: Newly Created Doctors/Hospitals Not Appearing in Search🟠 Medium Priority Bugs✅ Not a Bug🆕 New Bugs (Session 08 - Add Patient & Booking)Bug #31: Federated Search - Partial Name Works, Full Name Doesn'tBug #32: DOB Not Auto-filled When Importing from KulcareBug #33: Patient Visible Across Multiple ClinicsBug #34: No Validation for Patient Form (Frontend + Backend)Bug #35: Email Field Missing in Patient App Profile Edit🆕 New Bugs (Session 09 - Patient Management List)Bug #36: Phone Search Returns No Results on Patient ListBug #37: Export Report API Fails - EFS Permission Denied (Staging)Bug #38: Cross-Clinic Patient Flow Incomplete — No Facility Record CreatedBug #44: Appointment Duration Not Validated — Allows Overlapping BookingsBug #48: Out-of-Queue Split Inconsistent — Finished Patients Stay in QueueBug #49: No Couple Session Indicator in Queue RowBug #45: Invite Role Mismatch — Registered User Only Sees Matching Role InvitesBug #46: Invite Role Overwritten at Signup — Always Registers as StaffBug #47: Registered User Receives Signup Link Instead of Accept/Join LinkBug #50: Gateway Payment Method Returns 500 Internal Server ErrorBug #51: Next Visit — Specific Date Fails "Outside Working Hours"Bug #52: Delete/Cancel Dialog — Reason Not Cleared on CloseBug #53: Phone Not Shown in Follow-ups ListBug #54: ✓ Icon = Edit, Not Confirm — Confusing UXBug #55: Telemedicine Follow-ups DisappearBug #56: Patient Reports Row Click — Wrong URL (patientId Used Twice)Bug #57: Revenue Summary — Payments Not Reflected (All Zeros)Bug #58: Revenue Summary — Case-Sensitive Service GroupingBug #59: Revenue Summary — Visit Type Breakdown IncorrectBug #60: Revenue Export — Bill Report API FailsBug #61: Services Tab — Focus Lost on Debounced SearchBug #62: Services Tab — Patient Name Null Causes NA Display + Search 500Bug Status LegendSprint 1 Resolutions (2026-06-23)Bug #10: Cross-App Authentication Not Enforced — ✅ RESOLVEDBug #17: Cross-App Forgot Password — ✅ RESOLVEDBug #24: Invite Sent to Registered Email — ✅ RESOLVEDBug #26: Invite to Active User — ✅ RESOLVEDBug #21: Practitioner Invite to Existing Patient — ✅ RESOLVEDBug #45: Invite Role Mismatch — ✅ RESOLVEDBug #46: Invite Role Overwritten at Signup — ✅ RESOLVEDBug #47: Registered User Gets Signup Link Instead of Accept Link — ✅ RESOLVEDBug #19: Backend Validation Error Not Displayed — ✅ RESOLVEDBug #20: Whitespace-Only Names Allowed — ✅ RESOLVEDBug #25: Invite Modal Form State Not Reset — ✅ RESOLVEDBug #23: Duplicate Invite with Same Email — ✅ RESOLVED🔴 Critical Bugs (Block Production) — 4 Remaining, 1 Resolved🧪 Sprint 1 Testing ChecklistAuth — Cross-App Enforcement (#10, #17)Invite — Backend Validation (#24, #26, #21, #23, #45)Invite — Role Carry-Through (#46)Invite — SMS Links (#47)Frontend — Error Messages (#19)Frontend — Whitespace Names (#20)Frontend — Form Reset (#25)Already Fixed — Verify (#29)Sprint 2 Resolutions (2026-06-23)Bug #36: Phone Search Returns No Results — ✅ RESOLVEDBug #56: Patient Reports Row Click — Wrong URL — ✅ RESOLVEDBug #55: Telemedicine Follow-Ups Disappear — ✅ RESOLVEDBug #32: DOB Not Auto-Filled When Importing from Kulcare — ✅ RESOLVEDBug #38: Cross-Clinic Patient Flow Incomplete — ✅ RESOLVEDBug #44: Appointment Duration/Overlap Not Validated — ✅ RESOLVED🧪 Sprint 2 Testing ChecklistPhone Search (#36)Patient Reports URL (#56)Telemedicine Follow-Ups (#55)DOB Auto-Fill (#32)Cross-Clinic Patient Auto-Registration (#38)Appointment Duration / Overlap (#44)Sprint 3 Resolutions (2026-06-23)Bug #5: DOB Allows Future Dates — ✅ RESOLVEDBug #34: No Backend Validation for Patient Form — ✅ RESOLVEDBug #14+#15: Duplicate Category Names (Case-Insensitive) — ✅ RESOLVEDBug #48: Out-of-Queue Split Inconsistent — ✅ RESOLVEDBug #53: Phone Not Shown in Follow-Ups List — ✅ RESOLVEDBug #18: Practitioner API Missing Phone — ✅ RESOLVEDBug #22: Cancelled Invites Not Visible — ✅ RESOLVEDBug #49: No Couple Session Indicator in Queue — ✅ RESOLVEDBug #54: ✓ Icon = Edit, Not Confirm — ✅ RESOLVED🧪 Sprint 3 Testing ChecklistValidation (#5, #34)Duplicate Categories (#14, #15)Out-of-Queue (#48)Phone in Follow-Ups + Practitioner API (#53, #18)Cancelled Invites (#22)Couple Session Indicator (#49)Edit Icon (#54)Sprint 3.5 — Extra Fixes (2026-06-23)Bug #31: Federated Search — Full Name Now Works — ✅ RESOLVEDBug #52: Delete Dialog — Reason Cleared on Overlay Click — ✅ RESOLVEDBug #1: Error Messages on Signup (Patient) — ✅ RESOLVEDBug #8: Error Messages on Signup (Clinic) — ✅ RESOLVEDBug #51: Next Visit — Absolute Date Now Works — ✅ RESOLVEDBug #2: Resend OTP Not Working (Patient) — ✅ RESOLVEDBug #9: Resend OTP 500 Error (Clinic) — ✅ RESOLVED🧪 Sprint 3.5 Testing ChecklistUpdating Bug StatusAdding New Bug✅ All Bugs — Verified & Closed Status🔴 Critical Bugs — ALL CLOSED ✅🟡 High Priority Bugs — CLOSED ✅🟠 Medium Priority Bugs — CLOSED ✅Patient App Bug Fixes (2026-06-25) — ALL VERIFIED ✅Ready for Testing (Historical - See Above for Verified Status)🔴 Pending — Needs DevOps (1 bug)⏭️ Deferred — New Billing Flow (5 bugs)🟢 Pending — Architecture (2 bugs)✅ Not Bugs (2)