CRM · Automation Builder Spec — grounded in Phase 1 schema

Set Property — Property & value reference

Every property in this dropdown is a field that already exists on a contact in PracticeEHR's Phase 1 CRM. The canonical source is the Smart Filter table in crm.html (Phase 1 doc) — if a field is not in that table, it is not in this dropdown. Out: HubSpot-flavored stages that don't map to PracticeEHR (e.g., "MQL", "SQL", "Evangelist"); clinical writes (ICD/CPT/Medication); free-form taxonomy that doesn't yet exist (tags, scores, custom personas).

Sourcing rule

  • Every property maps to a row in the Phase 1 Smart Filter table at crm.html:1331
  • Or to an existing Phase 1 contact-detail surface, such as the Notes tab
  • No external taxonomy invented

Mix of the 7

  • 3 live in the builder — two kept as-is, one renamed
  • 3 net-new from Phase 1 schema — pulled directly from Smart Filter rows
  • 1 collaboration action — mapped to the Phase 1 Notes tab

Excluded on purpose

  • Clinical writes (ICD / CPT / Medication) — filterable, not settable
  • Identity / demographic (Age, Gender, DOB, Phone, Email) — user-entered, not automation-flipped
  • Tags / scores / personas — do not exist in Phase 1; defer until added to schema

All 7 properties at a glance

Each row maps to an existing Phase 1 field. Click a name to jump to its detail card.

# Property Phase 1 field Value control Source
1 Status Status (Lead / Patient) Enum dropdown Rename of "Lifecycle stage"
2 Contact Owner Contact Owner (user list) User picker Already in dropdown
3 Provider Provider (user list) Provider picker Net-new from Phase 1
4 Lead Source Lead Source (string) Text input Already in dropdown
5 Patient Enter Date Patient Enter Date (date) Date picker Net-new from Phase 1
6 Contact Enter Date Contact Enter Date (date) Date picker Net-new from Phase 1
7 Note (system note) Phase 1 Notes tab on Contact Detail Rich text + @mention Net-new from Phase 1
Lifecycle

1. Status Enum dropdown Rename of "Lifecycle stage"

Lifecycle
The single binary lifecycle field in PracticeEHR. The product UI displays this as a status badge with two values: Lead (no appointment booked yet) and Patient (booked at least one appointment). The current Phase 2 dropdown calls this field "Lifecycle stage" with HubSpot values — that doesn't match the schema. Rename and align to the live Lead / Patient values.
Allowed values2
Lead
No appointment booked yet.
Patient
Has at least one booked appointment. Demographics & Documents tabs become live in PracticeEHR.
Example: Trigger = Appointment booked → Set property Status = Patient. Removes the contact from new-lead nurture, unblocks the Visits tab on Contact Detail.
Phase 1 source: Smart Filter row "Status" with values Lead / Patient at crm.html:1342; lifecycle copy at crm.html:500-501.
Set property

Just two values. No HubSpot ladder.

Ownership

2. Contact Owner User picker Already in dropdown

Ownership
Which staff user owns this contact. Already exists end-to-end in Phase 1 — drives the My Contacts / Unassigned Contacts filter views, the Owner assignee shortcut on Create-task, and the From: Contact owner sender on Send-email.
Allowed values2
Specific user
Pick a named staff member from the practice's user list.
Clear / Unassigned
Sets owner to none; contact appears in the Unassigned Contacts view.
Example: Trigger = New web form submission → Set property Contact Owner = Sarah Ahmed. Sarah's My Contacts view now shows the new lead.
Phase 1 source: Smart Filter row "Contact Owner" at crm.html:1331; Contacts views at crm.html:530, 532.
Set property
SA Sarah Ahmed

Reference picker with avatar — not free-text.

3. Provider Provider picker Net-new from Phase 1

Ownership
The clinical staff member assigned to this contact. Distinct from Contact Owner (who is the front-desk / CRM owner). Phase 1 carries it as a Smart Filter field, so list segments already segment by provider; the automation builder should be able to set it.
Allowed values2
Specific provider
Pick from the practice's provider list.
Clear
Removes the provider assignment.
Example: Trigger = Form answer "Which provider?" = Dr. Patel → Set property Provider = Dr. Patel. Later list segments and recall automations honor it.
Phase 1 source: Smart Filter row "Provider" with multi-select user list at crm.html:1332.
Set property
PP Dr. Priya Patel

Reuses the same provider picker that already exists in scheduling.

Attribution

4. Lead Source Text input Already in dropdown

Attribution
Where the contact came from. Phase 1 stores it as a free string — not a controlled enum — so the value control should remain a text input (with token support), not a locked dropdown. Locking values would break Phase 1's existing data.
Value type1
String
Free text. Common practice values: Web, Referral, Walk-in, Paid, Organic, Event, Partner, Dr. <name>. The practice owns the taxonomy.
Example: Trigger = Form submitted on /landing/google-ads → Set property Lead Source = "Paid - Google Ads Q2 2026".
Phase 1 source: Smart Filter row "Lead Source" with value type String at crm.html:1344.
Set property

Token-aware: {{trigger.utm_source}} can drive the value at runtime.

Date fields

5. Patient Enter Date Date picker Net-new from Phase 1

Date fields
The date the contact converted to a Patient. Usually set automatically when Status = Patient, but the automation builder should be able to set it explicitly — e.g., for back-fill or for branch-on-anniversary recall flows.
Modes3
Specific date
Pick a date from the calendar.
Date of step
Sets to the moment this step runs (most common).
Clear
Removes the date.
Example: Trigger = First appointment booked → Set Status = Patient → Set Patient Enter Date = Date of step. A year later, anniversary recall fires off this date.
Phase 1 source: Smart Filter row "Patient Enter Date" with value type Date picker at crm.html:1339.
Set property

Date of step is the safe default — sets the timestamp at the moment the automation runs.

6. Contact Enter Date Date picker Net-new from Phase 1

Date fields
The date the contact was first created. Set automatically on contact creation in Phase 1, but exposing it as a settable property handles import / migration scenarios where the original date needs to be preserved (or back-dated).
Modes3
Specific date
Pick a date from the calendar.
Date of step
Sets to the moment this step runs.
Clear
Removes the date.
Example: Trigger = CSV import job ran → Set Contact Enter Date = trigger.row.created_at. Preserves true acquisition dates so cohort reports stay honest.
Phase 1 source: Smart Filter row "Contact Enter Date" with value type Date picker at crm.html:1340; Contacts list "Create Date" filter at crm.html:533.
Set property

Use Specific date for back-fill / migration. Use Date of step for new-contact triggers.

Collaboration

7. Note (system note) Rich text + @mention Net-new from Phase 1

Collaboration
Adds an internal note to the contact's Notes tab. Phase 1's Notes tab already supports rich text, @mentions, threaded comments, and is keyword-searchable. Letting an automation drop a note is the cheapest way to leave a trail when the system flips other properties — e.g., "Auto-set Status = Patient after first appointment booked on 2026-05-07".
Fields2
Note text
Rich text (bold, italic, lists, links). Supports tokens like {{firstname}}, {{trigger.event}}.
Mention (optional)
@-pick one or more staff users; they get notified per Phase 1's @mention logic.
Example: Trigger = Appointment booked → in parallel, Set Status = Patient AND Add Note: "Converted after appointment booked at {{trigger.timestamp}}. @{{contact.owner}} please confirm first-visit prep is complete."
Phase 1 source: Notes tab on Contact Detail at crm.html:643-691; behavior — "Internal notes track call summaries... @mentions notify tagged teammates... Notes are indexed and searchable by keyword".
Set property

Rich text + @mention. Notification follows Phase 1 @mention rules. The note is searchable from the Notes tab.

Phase 1 fields intentionally NOT in this dropdown

These rows exist in Phase 1's Smart Filter table (so they're filterable for list segmentation), but they shouldn't be settable from a marketing-automation step. Different categories, different reasons.

Clinical — never write

Filterable for segmentation, but writing them from a marketing automation creates a PHI surface where one shouldn't exist. The chart owns these.

  • ICD — diagnoses
  • CPT — procedures
  • Medication — meds list

Demographic / identity — user-entered, not flipped

These come from form intake or staff entry. An automation flipping them is almost always a bug, not a feature.

  • Age, Gender, DOB
  • Phone, Email

Implementation status

Shipped. The live Set-property options below are available in the builder. The remaining properties on this page (Provider, Patient/Contact Enter Date, Note) are spec only for now; they appear here as the recommended next round.

What's currently in the builder ([source.html: case 'property']):

Property Value control Allowed values Status
Status Single-select dropdown Lead / Patient Live
Lead source Free-text input String Live
Contact owner Free-text input String Live

How the type-aware control works:

  • The Property dropdown's onchange calls updateConfigAndRefresh('property', this.value, true) (vs. the regular updateConfig).
  • That helper updates the property, clears the stale value (third arg true), and re-renders the config panel so the value control swaps to the right shape.
  • The value control itself stays on the regular updateConfig path — no re-render needed when only the value changes within the same property.