Enumerations

All enumerations are StrEnum, so a member is its string value. That means a member can be passed straight into a SQL comparison, a JSON payload, or an f-string without .value, and json.dumps() serialises it without a custom encoder.

The database enums live in libs/morpheus-data-layer/morpheus_data_layer/enums.py. The ORM builds its PostgreSQL ENUM types from these classes with create_type=False (see ORM models), so the Python members and the database type cannot drift in their values — but they can drift in their membership.

Adding a value is a three-step change in a fixed order: change the web application’s Prisma schema, migrate the database, then add the member here. Adding it here first produces a runtime error on insert, because PostgreSQL rejects a value its type does not know.

Seller

Enum Members

SellerPlatform

amazon, walmart

SellerDatasource

smartscout, manual

SellerLifeCycleStage

new, raw_lead, enriched, in_sequence, engaged, qualified, bdr_handoff, demo_scheduled, opportunity, customer, disqualified

SellerLifeCycleStage is the ladder a business climbs from discovery to close. Only the first few transitions are automated: enrichment-scraper creates rows at new, and enrichment-scorer advances them to enriched. Everything from engaged onward is set by human activity in HubSpot and mirrored back. See Outbound funnel.

The Prisma schema declares a different set for this enum — new, enriched, qualified, opportunity, closed_won, closed_lost. SellerPlatform also carries a shopify member in Prisma that is absent here. This is real drift; see schema drift.

Contact

Enum Members

ContactHubspotSyncStatus

synced, pending, failed, skipped

ContactSource

campaign, hubspot, import, manual

ContactHeatStatus

hot, warm, warming, idle

ContactLifecycleStage

subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other

ContactLeadStatus

new, open, in_progress, open_deal, unqualified, attempted_to_contact, connected, bad_timing

ContactLifecycleStage values are unpunctuated on purpose — marketingqualifiedlead, not marketing_qualified_lead. They are HubSpot’s own internal values, copied verbatim so the mirror needs no translation table. ContactLeadStatus, by contrast, is snake_case and is mapped when written to the CRM.

ContactHeatStatus is Morpheus’s own engagement temperature, not a HubSpot concept. What earns each level is described in CRM sync.

Contact.source is mapped as a plain String with a default of "manual", not as this ContactSource enum. The values still come from ContactSource, but nothing enforces it at the database level.

Email

Enum Members

EmailTargetStatus

pending, requested, sent, opened, bounced, unsubscribed, blocked, failed

EmailTargetCategory

interested, not_interested, question, out_of_office, unsubscribe, wrong_person, other

EmailDirection

sent, received

EmailInboxCategory

campaign, reply, transactional, other

EmailVariationStatus

pending_generation, active, archived

EmailTargetCategory is the output schema of the reply classifier — it is the structured_output_model the Bedrock call is constrained to, which is why the agent can never invent a category. other is the fallback that keeps an unrecognised reply from failing the message. See Email engagement.

bounced, unsubscribed, and blocked in EmailTargetStatus are terminal suppression states — see suppression.

Telephony

Enum Members

LineTypes

mobile, landline, fixedVoip, nonFixedVoip, tollFree, sharedCost, premium, voicemail, pager, voip, uan, unknown, other

RiskLevel

low, medium, high, critical

CallStatus

created, dialing, answered, ended

TargetState

pending, in_progress, dialing, completed, failed, canceled, skipped, DNC, WN, MAX, DT_PENDING, VOICEMAIL

LineTypes members are camelCase because they are Twilio Lookup’s own line-type strings, stored unmodified. A mobile result is what makes a number SMS-eligible and worth a dial; see Phone line intelligence.

TargetState mixes lowercase workflow states with uppercase dialer outcomes. The uppercase ones are terminal and carry specific meanings: DNC do-not-call, WN wrong number, MAX maximum attempts reached, DT_PENDING awaiting a dial-tone retry. The mixed casing is the upstream dialer’s convention, preserved rather than normalised. The state machine is described in Daily call lists.

Tasks and activity

Enum Members

FollowUpTaskType

call, email, sequence_enrollment

FollowUpTaskStatus

pending, in_progress, completed, skipped, failed

ActivityType

sms, email, call, task, meeting, note, reminder

FollowUpTaskStatus distinguishes skipped from failed: skipped is a deliberate decision (suppressed, already covered by another task), failed is an error worth retrying. Only pending and failed tasks are picked up by the HubSpot poll.

Activity.status (default "sent") and Activity.direction (default "outbound") are plain String columns with no enum type behind them, as are the various hubspotSyncStatus fields and Call.direction. Treat their values as conventions, not constraints.

Enums outside the data layer

These are not database enums, but they are shared vocabulary across deployment units.

AgentModelIds

libs/morpheus-llm/morpheus_llm/utils/enums.py. The only sanctioned source of Bedrock model identifiers.

Member Model id

CLAUDE_OPUS_4_6

us.anthropic.claude-opus-4-6-v1

CLAUDE_SONNET_4

us.anthropic.claude-sonnet-4-20250514-v1:0

CLAUDE_HAIKU_4_5

us.anthropic.claude-haiku-4-5-20251001-v1:0

CLAUDE_HAIKU_3_5

us.anthropic.claude-3-5-haiku-20241022-v1:0

CLAUDE_HAIKU_3

us.anthropic.claude-3-haiku-20240307-v1:0

NOVA_MICRO

us.amazon.nova-micro-v1:0

NOVA_LITE

us.amazon.nova-lite-v1:0

NOVA_2_LITE

us.amazon.nova-2-lite-v1:0

The us. prefix selects a cross-region inference profile. Removing it produces a model id that does not resolve in us-east-1. Never strip it to "clean up" an identifier.

Call dispositions

libs/pyb-hubspot/pyb_hubspot/disposition_outcomes.py.

Enum Members

Disposition

Qualified_Lead, Amazon_Seller, Sales_Handoff, Callback_Requested, Not_Qualified, Not_Interested, Wrong_Number, Do_Not_Call, Not_a_Seller, Hangup_Early, AI_Issue, Busy, AI_Screening, Gatekeeper, Voicemail_Detected, Undetermined

NextAction

None, Retarget_Later, Sales_Handoff

Disposition members are Title_Case_With_Underscores — the labels the dialer emits. HubSpot does not accept them directly; it wants an opaque outcome GUID, and the mapping lives in FIVE9_DISPOSITION_TO_HUBSPOT_GUID in lambdas/morpheus_hubspot/utils/constants.py. That mapping is environment-specific: the GUIDs differ between the production and preview portals, which is what HUBSPOT_ENVIRONMENT selects. See Call logging and dispositions.

NextAction is what turns a disposition into work — Retarget_Later schedules re-engagement, Sales_Handoff creates a task for a human.

Other

Enum Location Members

HubSpotApiEndpoint

libs/pyb-hubspot/pyb_hubspot/utils/enums/endpoints.py

COMMUNICATION_PREFERENCES_STATUSES_V2026_03 = /communication-preferences/2026-03/statuses

CustomEventKind

libs/morpheus-common/morpheus_common/events/custom_events.py

agent_email

Marketplace

lambdas/enrichment_scorer/models/seller.py (duplicated in the scraper)

amazon, walmart

DataSource

same

smartscout, jungle_scout, walmart_scraper

Marketplace and DataSource duplicate SellerPlatform and SellerDatasource, and DataSource carries two extra members with no data-layer equivalent. The duplication is deliberate: a Lambda’s Pydantic event models must be importable without the data-layer attached, so a queue payload can be validated by a function that does not touch the database. The cost is that the two sets must be kept aligned by hand.

Where enums are enforced

Layer Enforcement

PostgreSQL

A real ENUM type rejects an unknown value on write — for every enum mapped in the ORM with a matching type name.

SQLAlchemy

Coerces to the Python member on read. create_type=False means it never creates or alters the type.

Pydantic

Event models validate incoming payload values against the enum and reject the message before a handler runs — see Publishing events.

Bedrock structured output

structured_output_model constrains generation, so a model literally cannot return a value outside the enum. See morpheus-llm.