Hypertext Rails
Documentation
Getting Started
Communication Center
- Automation Workflow Flow
- Trigger Events and Cadence Rules
- Fallback Channel Implementation
- Fallback Channel Testing (dev)
- Twilio SMS Integration Guide
- Email Tracking Setup (sent, delivered, failed, open, click)
- SMS Tracking & Twilio Free Tier
- AWS SES Delivery Tracking (console setup for delivery webhook)
- Compiled Template Guide (layout, components, variables)
- Workflow & Template Features (project-driven recipients, multi-project format)
Procore / Project Groups
- Procore Integration — Complete Guide (installation single/grouped, project groups, token storage, why no migration)
Other Features
- Heartbeats Dashboard (kiosk connectivity, queries, sample data)
Communication Center: Workflow & Template Features
This document covers two related features: project-driven workflow recipients and multi-project template format. Both affect how deliveries are created and what content they contain.
Implementation date: January 27, 2026
Part 1: Project-Driven Workflow (Recipients)
Overview
Workflows now use a project-driven recipient configuration: projects and personas are chosen independently, and only stakeholders who watch the selected projects and have the selected personas receive deliveries. Previously, selecting a persona auto-selected projects and all stakeholders with that persona received deliveries.
Before (Persona-Driven)
- User selects persona → projects auto-selected.
- Workflow runs → all stakeholders with that persona receive deliveries.
- Projects enriched content but did not filter recipients.
After (Project-Driven)
- User selects projects and personas independently.
- Workflow runs → only stakeholders who watch the selected projects and have the selected personas receive deliveries.
- Projects filter recipients and define delivery context (intersection with stakeholder’s watched projects).
Changes Made (Project-Driven Flow)
1. Backend: app/services/delivery_schedule_service.rb
resolve_audience (lines 151–185)
- Before: Filter by persona first; projects only used for exclusion when in exclude mode.
- After: Filter by projects first (include: only stakeholders watching selected projects; exclude: exclude those watching selected projects), then filter by personas.
- Effect: Recipients are limited to stakeholders watching the chosen projects (and matching personas).
determine_project_contexts (lines 519–534)
- Before: With include mode, delivery context = union of stakeholder’s projects and workflow’s selected projects.
- After: With include mode, delivery context = intersection of stakeholder’s projects and workflow’s selected projects.
- Effect: Each delivery only includes data for projects that are both watched by the stakeholder and selected in the workflow.
2. Model: app/models/automation_workflow.rb
recipient_count
- Uses the same project-first filtering as resolve_audience so the UI shows the correct number of recipients.
3. Frontend: app/views/communication_center/automation/_workflow_form.html.erb
- Removed: HTMX on persona checkboxes that called
communication_center_projects_for_personas_pathand auto-filled projects. - Now: Personas and projects are independent; no auto-selection.
4. Controller: app/controllers/concerns/communication_center/workflows_concern.rb
- Removed:
projects_for_personasaction (no longer used after HTMX removal).
5. Routes
- Removed: Route for
/workflows/projects_for_personas.
Example Scenarios (Project-Driven)
- Projects 1, 2 + Persona Executive: Only executives who watch Project 1 or 2 get a delivery; delivery context is only those projects they watch among {1, 2}.
- Include mode: Recipients = stakeholders watching selected projects with selected personas; context = intersection of their projects and workflow projects.
- Exclude mode: Recipients = stakeholders who do not watch the selected projects (and match personas); context = their projects minus the excluded ones.
Testing (Project-Driven)
- Recipient count: Create workflow with projects + personas; confirm count matches stakeholders who watch those projects and have those personas.
- Context: For a stakeholder watching P1, P2, P3 and workflow selecting P1, P2, delivery should only contain P1 and P2.
- Exclude mode: Select P1, P2 as exclude; only stakeholders not watching P1 or P2 (and matching personas) receive deliveries.
Files modified: delivery_schedule_service.rb, automation_workflow.rb, _workflow_form.html.erb, workflows_concern.rb, config/routes.rb.
Part 2: Multi-Project Template Format
Overview
Templates can be single-project (one delivery per project per stakeholder) or multi-project (one delivery per stakeholder containing all their watched projects from the workflow). Multi-project is for stakeholders who watch several projects and should get one combined email/SMS.
Current vs desired (for multi-project)
- Before: One delivery per stakeholder per project → multiple emails/SMS.
- After (multi-project format): One delivery per stakeholder → one email/SMS with sections/cards for each project (ordered by
project_idascending).
Implementation Summary (Multi-Project Format)
- Database:
communication_templates.format_type('single_project'|'multi_project'), default'single_project'. - Model:
CommunicationTemplate—FORMAT_TYPES,multi_project?,single_project?, validation (seeapp/models/communication_template.rb). - UI: Template form has Format dropdown: "Single Project" | "Multi-Project" (see
_template_form.html.erb). - Delivery creation (
delivery_schedule_service.rb):
- If template is
multi_project, one delivery per stakeholder withproject_idsin payload; otherwise unchanged (one delivery per project).
- If template is
- Variable resolution (
template_variable_resolver_service.rb):
- If payload has
multi_projectandproject_ids,resolve_and_render_multi_projectruns: resolve for each project, then: - Email:
build_multi_project_email_html— project cards, color cycling (#F4B54E, #E1563B, #4498E2), grid layout. - SMS:
build_multi_project_sms_text— one section per project, blank lines between.
- If payload has
- Email view:
delivery_email.html.erbfooter can show all projects for multi-project; body comes from resolver (raw @body_content). - SMS: Body already comes from resolver; no extra change in send job.
How It Works (Multi-Project)
- Single-project:
format_type = 'single_project'→ one delivery per project per stakeholder; each delivery resolved for that project. - Multi-project:
format_type = 'multi_project'→ one delivery per stakeholder; payload hasmulti_project: true,project_ids: [72, 73, 74](ascending). Resolver runs per project and combines into one HTML or SMS body.
Multi-Project Email / SMS Structure
- Email:
<div class="multi-project-email">with<div class="project-card">per project (background color from the three-color cycle). - SMS: Plain text blocks, one per project, separated by blank lines.
Files Modified (Multi-Project)
db/migrate/..._add_format_type_to_communication_templates.rbapp/models/communication_template.rbapp/views/communication_center/communications/_template_form.html.erbapp/controllers/concerns/communication_center/templates_concern.rbapp/services/delivery_schedule_service.rbapp/services/template_variable_resolver_service.rbapp/views/application_mailer/delivery_email.html.erb
Backward Compatibility
- Project-driven: Existing workflows with personas but no projects now filter by persona only (no project filter). Recommend auditing workflows and adding project selection where needed.
- Multi-project: Existing templates default to
single_project; no change until format is set to Multi-Project.
Summary
| Feature | What changed |
|---|---|
| Project-driven workflow | Recipients = stakeholders watching selected projects with selected personas. Delivery context = intersection of stakeholder projects and workflow projects. Persona/project selection in UI is independent; no HTMX auto-selection. |
| Multi-project format | Template can be single- or multi-project. Multi-project creates one delivery per stakeholder with combined content for all relevant projects (email cards, SMS sections). |