fix: contact form creates Lead only, not Patient
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

Widget contact + chat-start were creating Patient records for new
visitors. Patient should only be created during appointment booking.
Added createPatient flag to findOrCreateLeadByPhone — defaults to
false, only bookAppointment passes true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-21 16:41:11 +05:30
parent ac76ef5487
commit a837c95d8c

View File

@@ -17,6 +17,7 @@ export type FindOrCreateLeadOpts = {
source?: string; source?: string;
status?: string; status?: string;
interestedService?: string; interestedService?: string;
createPatient?: boolean; // default false — only booking creates patients
}; };
@Injectable() @Injectable()
@@ -60,26 +61,27 @@ export class WidgetService {
const lastName = name.split(' ').slice(1).join(' ') || ''; const lastName = name.split(' ').slice(1).join(' ') || '';
if (resolved.isNew) { if (resolved.isNew) {
// Net-new visitor — create Patient + Lead with the widget- // Net-new visitor — create Lead. Patient is only created
// collected name. Both records get the real name from the // when explicitly requested (e.g., booking an appointment).
// first moment they exist.
let patientId: string | undefined; let patientId: string | undefined;
try { if (opts.createPatient) {
const p = await this.platform.queryWithAuth<any>( try {
`mutation($data: PatientCreateInput!) { createPatient(data: $data) { id } }`, const p = await this.platform.queryWithAuth<any>(
{ `mutation($data: PatientCreateInput!) { createPatient(data: $data) { id } }`,
data: { {
name: `${firstName} ${lastName}`.trim() || 'Unknown', data: {
fullName: { firstName, lastName }, name: `${firstName} ${lastName}`.trim() || 'Unknown',
phones: { primaryPhoneNumber: `+91${phone}` }, fullName: { firstName, lastName },
patientType: 'NEW', phones: { primaryPhoneNumber: `+91${phone}` },
patientType: 'NEW',
},
}, },
}, this.auth,
this.auth, );
); patientId = p?.createPatient?.id;
patientId = p?.createPatient?.id; } catch (err) {
} catch (err) { this.logger.warn(`Widget patient create failed (${phone}): ${err}`);
this.logger.warn(`Widget patient create failed (${phone}): ${err}`); }
} }
const created = await this.platform.queryWithAuth<any>( const created = await this.platform.queryWithAuth<any>(
`mutation($data: LeadCreateInput!) { createLead(data: $data) { id } }`, `mutation($data: LeadCreateInput!) { createLead(data: $data) { id } }`,
@@ -263,6 +265,7 @@ export class WidgetService {
source: 'WEBSITE', source: 'WEBSITE',
status: 'APPOINTMENT_SET', status: 'APPOINTMENT_SET',
interestedService: req.chiefComplaint ?? 'Appointment Booking', interestedService: req.chiefComplaint ?? 'Appointment Booking',
createPatient: true,
}); });
// Idempotent upgrade: if the lead was reused from an earlier chat/ // Idempotent upgrade: if the lead was reused from an earlier chat/
// contact, promote its status and reflect the new interest. // contact, promote its status and reflect the new interest.