feat(dialer): volunteer caller backend - #205
Conversation
Backend for the volunteer dialer, stacked on dialer-campaign-type:
- GraphQL schema, resolvers, and Telnyx WebRTC token route
- dialer lib: shift assignment, contact-hours-aware serving, atomic
call_status claim, disposition + attempt tracking
- forward migrations (campaign-type's create migrations left untouched):
- 000009: drop call_campaigns_no_autoassign (call campaigns use autoassign
for shifts)
- 000010: add call_status/attempt_count/last_attempted_at to
dialer_campaign_contact and disposition to dialer_call
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ajohn25
left a comment
There was a problem hiding this comment.
Just flagging the 1 down migration, otherwise all suggestions! Review workout 😆
| table.integer("attempt_count").notNullable().defaultTo(0); | ||
| table.timestamp("last_attempted_at").nullable(); |
There was a problem hiding this comment.
Question: Intentional choice to put these back in?
| await trx.query( | ||
| `update campaign set external_system_id = null, landlines_filtered = false where id = $1`, | ||
| [campaignId] | ||
| ); |
There was a problem hiding this comment.
Question: See question above about this happening for dialer too
There was a problem hiding this comment.
Question: do filtered out contacts make it to filtered_contact ?
| optOutCount | ||
| }); | ||
|
|
||
| // Always set a result message to mark the job as complete |
There was a problem hiding this comment.
Question: Intentional delete?
| DIALER_SHIFT_SIZE: num({ | ||
| desc: | ||
| "Number of contacts assigned to a volunteer per call shift when they request calls.", | ||
| default: 10 | ||
| }), |
There was a problem hiding this comment.
Suggestion: Think we should just make a follow up issue for doing something similar to the texting flow to give admins greater control over this
| r | ||
| .reader("dialer_campaign_contact") | ||
| .where({ campaign_id: campaign.id }) | ||
| .where("attempt_count", ">", 0) |
There was a problem hiding this comment.
Suggestion: I think a join to dialer_call with an EXISTS would be faster since this isn't indexed. Or we could index the column (but that might be overkill if this is the only place its used)
* chore(tool-versions): update node version (#195) * feat(dialer): volunteer caller frontend (Telnyx WebRTC UI) Frontend for the volunteer dialer, stacked on dialer-backend: - VolunteerDialer container: WebRTC call controls, timer, status bar, disposition form, contact flow - TexterTodoList: call-shift request entry point (CallRequest) and call-aware assignment summary - AdminCampaignStats: call-campaign stat tweaks - dialer GraphQL operations (hooks) and @telnyx/webrtc dependency Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(dialer): add canned responses + tags to calling (#208) * feat(dialer): add canned responses + tags to calling * feat(dialer): allow releasing calls (#209) * feat(dialer): allow releasing calls * feat(dialer): add texting history to call screen (#210) * feat(dialer): add texting history to call screen * chore: update seeds to not use logger.info * chore(dialer): fix variable interpolation in script --------- Co-authored-by: Aashish John <aashishjohn25@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(campaigns): add campaign type (SMS/Call) to campaign editor * feat(admin): add campaign type to admin UI * feat(admin): add new dialer tables * chore(admin): address feedback * chore(dialer): address new table feedback * chore(dialer): address feedback * chore(dialer): regenerate schema dump * chore(dialer): address feedback * feat(dialer): volunteer caller backend (#205) * feat(dialer): volunteer caller backend (Design-B call tracking) Backend for the volunteer dialer, stacked on dialer-campaign-type: - GraphQL schema, resolvers, and Telnyx WebRTC token route - dialer lib: shift assignment, contact-hours-aware serving, atomic call_status claim, disposition + attempt tracking - forward migrations (campaign-type's create migrations left untouched): - 000009: drop call_campaigns_no_autoassign (call campaigns use autoassign for shifts) - 000010: add call_status/attempt_count/last_attempted_at to dialer_campaign_contact and disposition to dialer_call Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(dialer): address feedback * feat(dialer): volunteer caller frontend (Telnyx WebRTC UI) (#207) * chore(tool-versions): update node version (#195) * feat(dialer): volunteer caller frontend (Telnyx WebRTC UI) Frontend for the volunteer dialer, stacked on dialer-backend: - VolunteerDialer container: WebRTC call controls, timer, status bar, disposition form, contact flow - TexterTodoList: call-shift request entry point (CallRequest) and call-aware assignment summary - AdminCampaignStats: call-campaign stat tweaks - dialer GraphQL operations (hooks) and @telnyx/webrtc dependency Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(dialer): add canned responses + tags to calling (#208) * feat(dialer): add canned responses + tags to calling * feat(dialer): allow releasing calls (#209) * feat(dialer): allow releasing calls * feat(dialer): add texting history to call screen (#210) * feat(dialer): add texting history to call screen * chore: update seeds to not use logger.info * chore(dialer): fix variable interpolation in script --------- Co-authored-by: Aashish John <aashishjohn25@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Aashish John <aashishjohn25@gmail.com> * chore(dialer): fix down migration for campaign type campaign view --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Aashish John <aashishjohn25@gmail.com>
Backend for the volunteer dialer, stacked on dialer-campaign-type: