DocsAutoResponderProcess

Hodor (SQL Server — dmorders_thompson)#

Purpose: Prospect / order-side contact data (IPv4). Reads for identity; update intents are emitted as a Prospect Import deliverable, and in live mode the action engine also applies a targeted AutoRenewal SQL update for INACTIVE determinations.

Code: src/auto_responder/services/databases/hodor.py

Configuration#

SettingNotes
HODOR_CONNECTION_STRINGFull ODBC/SQL connection string (preferred when you already have one).
HODOR_DB_HOST, HODOR_DB_DATABASE, HODOR_DB_USER, HODOR_DB_PASSWORD, HODOR_DB_PORTBuilt into a connection string when HODOR_CONNECTION_STRING is unset. Default database name in config is dmorders_thompson.
HODOR_* column/table overridesOptional: hodor_contact_table, hodor_id_column, hodor_email_column, etc. — for schema differences (see config.py).
HODOR_AUTOMATIC_UPDATESWhen true (default) and writes are enabled, INACTIVE handling also applies the AutoRenewal SQL (IsNoLongerWithFirm = 1, LastUpdatedDate = getdate(), UpdatedReason = 'Updated based on AutoRenewal Program') by email in addition to queuing Prospect Import rows. When false, only Prospect Import rows are queued.
NOTIFICATION_EMAIL_VENURecipient for Hodor Prospect Import digest emails. If unset, NOTIFICATION_EMAIL_VENU is used.

If no Hodor SQL configuration is present, the connector runs in graceful-unavailable mode (available=False): lookups return empty, writes no-op.

Contact lookup#

CallPurpose
lookup_by_emailPer-email lookup
lookup_batchOptional batch path in ContactLookup.lookup_batch when available and the method exists

Action engine touches#

The action engine queues Prospect Import rows and sends notify_hodor_prospect_import (catalog N01) at batch flush with hodor_prospect_import_verification.csv (InboxSource, Action, RequestedStatus, and full SAC columns). See NOTIFICATIONS_CATALOG — N01.

In live mode with HODOR_AUTOMATIC_UPDATES=true, INACTIVE determinations may also call mark_inactive_by_email_for_autorenewal(email) to set AutoRenewal flags directly in Hodor.

Hodor email/title updates follow the same CUPOLA active-only gate as other systems: if the preferred CUPOLA row is missing or inactive, updates are not queued and the case goes to Human Review.

INACTIVE (_handle_inactive)#

Call / behaviorPurpose
Prospect Import row (Action=status, RequestedStatus=INACTIVE)Queue inactive request for Hodor ingestion
mark_inactive_by_email_for_autorenewal(email) (live mode, HODOR_AUTOMATIC_UPDATES=true)Apply AutoRenewal update: IsNoLongerWithFirm = 1, LastUpdatedDate = getdate(), UpdatedReason = 'Updated based on AutoRenewal Program' for the sender email
check_active_subscription(id)If true, include Hodor in "systems with subscription" notification list (read-only; always runs when Hodor is available)

ACTIVE (_handle_active)#

After Cupola / Salesforce branches, remaining systems (including Hodor) use:

Call / behaviorPurpose
Prospect Import row (Action=status, RequestedStatus=ACTIVE)Queue active request when Hodor row is inactive. Note: this does not auto-reactivate CUPOLA; CUPOLA reactivation remains manual-review only.

OUT_OF_OFFICE#

OOO determinations are routed to _handle_out_of_office and add a Human Review row (HUMAN_REVIEW_REASON_OUT_OF_OFFICE). No Hodor calls fire — neither live SQL nor the manual-mode pending-actions queue.

Changed email / title (shared handler)#

Runs only when the CUPOLA active-only gate in _handle_title_update passes. After the gate:

REPLACEMENT (_handle_replacement)#

Does not insert a new Hodor row in code (add_contact returns None in the connector).
Uses read helpers for deliverable lists when implemented:

CallPurpose
get_library_for_account(account)Alternate-contact output — library hint
generate_import_record(...)Alternate-contact output — suggested import payload

Connector capabilities worth knowing#

Read-only / dry-run behavior#

Application behavior: ActionEngine always emits Prospect Import rows and emails them to Venu (NOTIFICATION_EMAIL_VENU, catalog N01). In live mode (writes enabled, HODOR_AUTOMATIC_UPDATES=true), INACTIVE handling also issues a targeted Hodor UPDATE by email via mark_inactive_by_email_for_autorenewal.

Simulation — no writes (WRITE_OPERATIONS_ENABLED=false): When Hodor SQL is configured and hodor_real.available, main.py wraps the connector with ReadOnlyDatabaseWrapper like Cupola/Multipub/Salesforce — writes are logged and not executed. If Hodor is not configured, the connector stays graceful-unavailable (no wrapper needed).

Dev mock-all (MOCK_ALL_SERVICES_FOR_DEV=true): main.py constructs a real HodorDatabase while Cupola/Multipub/Salesforce use mocks. Step 4c contact lookup is skipped in dry-run (main.py uses a minimal stub Contact), so routine per-email Hodor lookups do not run; the Hodor instance is still present for any code paths that reference it. If SQL credentials are set, be aware of the connector’s behavior vs mocks for other systems. If SQL is not configured, Hodor stays graceful-unavailable.

Output artifacts#

Hodor ProsNums appear on inactive, alternate, undeliverable deliverables via OutputDocumentCollector.