Indexer Contract

April 8, 2026 · View on GitHub

This document is the authoritative reference for all data the voting service sends to the indexer service, which makes resources searchable via the query service.

The voting service is a wrapper service — it ingests data from the legacy ITX system via NATS KV bucket events and republishes index messages to the LFX indexer. It does not own data directly.

Update this document in the same PR as any change to indexer message construction.


Resource Types


Vote (Poll)

Object type: vote

Source struct: internal/domain/event_models.goVoteData

Publisher: internal/infrastructure/eventing/nats_publisher.gosendVoteIndexerMessage

NATS subject: lfx.index.vote

Indexed on: create, update, delete events from the ITX NATS KV bucket (poll data).

Data Schema

These fields are indexed and queryable via filters or cel_filter in the query service.

FieldTypeDescription
vote_uidstringVote unique identifier (v2 primary key; same value as poll_id)
poll_idstringITX poll identifier (v1 primary key)
namestringVote/poll display name
descriptionstringVote description
creation_timestringCreation timestamp from ITX
last_modified_timestringLast modified timestamp from ITX
end_timestringVote end time
statusstringVote status (e.g., Open, Closed)
project_idstringITX project identifier (v1 SFID)
project_uidstringLFX project UID (v2)
project_namestringProject display name
committee_idstringITX committee identifier (v1 SFID)
committee_uidstringLFX committee UID (v2)
committee_namestringCommittee display name
committee_typestringCommittee type
committee_voting_statusboolWhether the committee has voting enabled
committee_filters[]stringCommittee filter values applied to this vote
total_voting_request_invitationsintTotal number of voting invitations sent
poll_questions[]objectPoll questions (see Poll Question schema)
num_response_receivedintNumber of responses received
poll_typestringPoll type (e.g., election, general)
pseudo_anonymityboolWhether responses are pseudo-anonymous
num_winnersintNumber of winners for election-type polls
allow_abstainboolWhether abstaining is allowed

Poll Question Schema

Each element in poll_questions has:

FieldTypeDescription
question_idstringQuestion identifier
promptstringQuestion text
typestringQuestion type (e.g., single_choice, multiple_choice, ranked_choice)
choices[]objectAvailable choices (each has choice_id string and choice_text string)

Tags

Tag FormatExamplePurpose
committee_uid:{value}committee_uid:061a110a-7c38-4cd3-bfcf-fc8511a37f35Find votes for a committee
project_uid:{value}project_uid:cbef1ed5-17dc-4a50-84e2-6cddd70f6878Find votes for a project

Tags are only emitted when the corresponding UID is non-empty.

Access Control (IndexingConfig)

FieldValue
access_check_objectvote:{vote_uid}
access_check_relationviewer
history_check_objectvote:{vote_uid}
history_check_relationauditor

Search Behavior

FieldValue
fulltextname, description (space-joined)
name_and_aliasesname (when non-empty)
sort_namename
publicfalse (always)

Parent References

RefCondition
project:{project_uid}Only when project_uid is non-empty
committee:{committee_uid}Only when committee_uid is non-empty

Vote Response

Object type: vote_response

Source struct: internal/domain/event_models.goVoteResponseData

Publisher: internal/infrastructure/eventing/nats_publisher.gosendVoteResponseIndexerMessage

NATS subject: lfx.index.vote_response

Indexed on: create, update, delete events from the ITX NATS KV bucket (vote response data).

Data Schema

FieldTypeDescription
uidstringVote response unique identifier (v2 primary key; same value as vote_id)
vote_idstringITX vote identifier (v1 primary key)
vote_uidstringUID of the parent vote/poll (v2)
poll_idstringITX poll identifier (v1)
project_idstringITX project identifier (v1 SFID)
project_uidstringLFX project UID (v2)
vote_creation_timestringTime the vote response was created
user_idstringAuth0 user identifier
user_emailstringUser's email address
user_rolestringUser's role at time of voting
user_namestringUser's display name
usernamestringUser's Auth0 username
profile_picturestringURL to user's profile picture
user_voting_statusstringUser's voting eligibility status
user_org_idstringUser's organization identifier
user_org_namestringUser's organization name
poll_answers[]objectUser's answers to poll questions (see Poll Answer schema)
vote_statusstringVote response status
abstainedboolWhether the user abstained
voter_removedboolWhether the voter was removed
ses_message_idstringAWS SES message identifier
ses_message_last_sent_timestringTimestamp of last SES email send
ses_bounce_typestringSES bounce type (if any)
ses_bounce_subtypestringSES bounce subtype (if any)
ses_delivery_successfulboolWhether SES delivery succeeded
ses_complaint_existsboolWhether an SES complaint was filed
ses_complaint_typestringSES complaint type (if any)
ses_complaint_datestringDate of SES complaint (if any)
ses_email_openedboolWhether the email was opened
ses_email_opened_first_timestringFirst time the email was opened
ses_email_opened_last_timestringLast time the email was opened
ses_link_clickedboolWhether a link in the email was clicked
ses_link_clicked_first_timestringFirst time a link was clicked
ses_link_clicked_last_timestringLast time a link was clicked

Poll Answer Schema

Each element in poll_answers has:

FieldTypeDescription
question_idstringQuestion identifier
promptstringQuestion text
typestringQuestion type
user_choice[]object (optional)Selected choices for non-ranked questions (each has choice_id and choice_text)
ranked_user_choice[]object (optional)Ranked choices for ranked questions (each has choice_id, choice_text, choice_rank int)

Tags

Tag FormatExamplePurpose
vote_uid:{value}vote_uid:abc123-...Find responses for a vote
project_uid:{value}project_uid:cbef1ed5-...Find responses for a project

Tags are only emitted when the corresponding UID is non-empty.

Access Control (IndexingConfig)

FieldValue
access_check_objectvote:{vote_uid}
access_check_relationviewer
history_check_objectvote_response:{uid}
history_check_relationauditor

Note: access checks are scoped to the parent vote object, not the response itself.

Search Behavior

FieldValue
fulltextusername
name_and_aliasesusername (when non-empty)
sort_nameusername
publicfalse (always)

Parent References

RefCondition
project:{project_uid}Only when project_uid is non-empty
vote:{vote_uid}Only when vote_uid is non-empty