Skip to content

Contacts & Leads

What this module does

Before someone becomes an active client with a Case, they exist in Orchid as either a Lead (an inquiry) or a Contact (a reviewed applicant who hasn’t been matched yet). This module manages the early pipeline: capturing inquiries, reviewing applicants, screening them, and (if accepted) converting them into Users with active Cases.

Business value

Not everyone who inquires to a fertility agency becomes a client. Agencies need to track who has applied, where they are in the review process, and why some applicants are rejected. This module gives agencies a structured pipeline for managing the top of their funnel.

Key files

  • Directoryorchid/
    • Directorymodels/
      • contact.py 48 KB — Contact, ContactDocument, ContactEmail, ContactLog, ContactNote
      • lead.py ContactLead, ContactLeadRequest
    • Directoryviews/
      • admin_contacts.py 20 KB — contact management admin UI
      • contact_lead.py 11 KB — lead/preview views
      • admin_screening.py 1 KB — screening workflow UI
    • Directoryapi/
      • admin.py — contact API operations (mixed into the 379 KB admin API)

The pipeline

flowchart LR
Inquiry["External inquiry\n(website form, phone, referral)"]
Inquiry --> Lead["ContactLead\n(no login)"]
Lead --> |"Agency reviews"| Contact["Contact\n(no login yet)"]
Contact --> |"Screening passes"| User["User\n(has login, active case)"]
Contact --> |"DQ'd or rejected"| Archived["Contact archived"]
Lead --> |"Spam / not qualified"| Ignored["Lead ignored"]

Contacts vs. Users — a critical distinction

Contact and User are completely different models in different files:

ContactUser
Model fileorchid/models/contact.pyorchid/models/user.py
Has login?NoYes
Has a Case?No (pre-case)Yes
StageApplication / screeningActive journey

A Contact becomes a User when the agency accepts them and creates their account. After that point, the Contact record still exists as a historical reference, but the User record is the primary record.

ContactLead — the very first step

A ContactLead is the lightest-weight record. It is created when:

  • Someone fills out an inquiry form on the agency’s website
  • An agency staff member manually logs a phone inquiry
  • An external referral arrives

ContactLead has only basic info: name, email, phone, inquiry type, and when it arrived. No login, no profile, no case.

ContactLeadRequest is a supplemental record that stores the full data from the lead’s initial inquiry form submission.

Contact records

A Contact is a richer record created after an agency decides a lead is worth pursuing. It includes:

  • Full personal information
  • ContactNote records (staff notes about the contact)
  • ContactEmail records (manually logged emails, separate from EmailSync)
  • ContactLog records (audit trail of status changes)
  • ContactDocument records (uploaded documents)

Screening

The screening workflow is accessible at /admin/screening. It provides an admin UI for:

  • Reviewing pending applications
  • Running DQ checks against AgencyDQSettings
  • Flagging applicants for further review
  • Approving or rejecting contacts

There is no dedicated Screening model — screening state is tracked through Contact status fields and ContactLog entries.

Converting a contact to a user

When a contact is accepted, agency staff:

  1. Create a User account for the contact
  2. Create an initial Case (or CaseParty if matching them to an existing case)
  3. Send the user their login credentials

This is done through the admin UI, not programmatically in the typical flow. The User model has a contact_id field (on some user types) that links back to the originating Contact record.

Gotchas