Trigger action flows from field changes

Objective

  • Enable Action Flows to trigger when a watched field changes to a matching value — not only when a job or quote is created, reaches a fixed lifecycle milestone, or hits a scheduled time offset.
  • Support immediate automations tied to data changes that matter, such as required info becoming known, becoming empty, or changing to a specific value.
  • Start with required info fields as the first supported watched-field surface, while keeping the model extensible to broader inspection and quote fields later.
  • Reuse the existing conditions system for field values instead of inventing a separate filtering model.

Background

  • Product ask: changing a field should immediately send an email or notification — for example when radon results are marked high, or when required payload information is missing or updated.
  • Today those workflows are approximated with scheduled actions or unrelated lifecycle events, so the message is not tied to the field change that actually matters.
  • Workaround-heavy setups create duplicate-send risk, extra custom fields, and brittle automation logic.
  • Triggers that exist today (fixed events and schedules — not field watches):
  • Flow start: unconfirmed_job (inspection) / new_quote (quote) when a flow is assigned to a job or quote
  • Job lifecycle: confirmed_job, job_cancelled, job_rescheduled, services_updated (charges), payment_created
  • Reports: job_completed (first report), report_completed (additional reports)
  • Quote lifecycle: quote_updated, quote_accepted, quote_rejected
  • Time-based: reminders, follow_up (job); quote_follow_up (quote)
  • Backend review confirms this is a feature gap, not a bug:
  • Action Flows use a closed event model in attik-backend/src/models/flowSchema.ts.
  • Inspection updates trigger flows only for specific hard-coded changes in attik-backend/src/events/streamHandlers/inspectionStream.ts, such as status confirm/cancel, datetime change, charges change, and payments change.
  • requiredInfoValues and other arbitrary field edits do not emit a flow event today.
  • attik-backend/src/util/functions/actionFlows/flowEventTriggerer.ts matches flows by named _flowEventId; there is no generic field-change dispatch path.
  • Frontend review adds an important constraint:
  • The current Action Flows builder exposes only fixed trigger types, not a configurable field-change trigger.
  • The shared conditions UI already fetches required info definitions and exposes them as typed conditionable attributes, so required info fields are already available for filtering.
  • The gap is therefore on the trigger side, not the conditions side.
  • Product direction for v1:
  • Start with required info fields for simplicity, even though the long-term ideal is to support broader inspection and quote fields.
  • Support quote parity in v1 rather than shipping inspection-only behavior.
  • The trigger should fire on any change to the watched field.
  • Flows should evaluate on every qualifying change by default, while actions can optionally support only send once behavior.
  • The builder should expose a Field changed trigger, with the specific watched field selected separately in trigger configuration rather than encoded as many hard-coded trigger types.
  • This means the main product/design work is deciding the exact field-watch model and action-level send-once behavior, while the existing conditions system can likely be reused for post-trigger filtering.

Done

  • Users can configure Action Flows that run when a watched field changes.
  • v1 supports required info fields on both inspections and quotes.
  • The field-change trigger fires on any change to the selected watched field.
  • Actions evaluate on each qualifying change unless an only send once option is enabled for that action.
  • Field-change triggers fire without relying on unrelated lifecycle events or time offsets.
  • Existing lifecycle and time-based flows continue to work unchanged.
  • Existing required info conditions continue to be reused rather than replaced.

Scope

Backend (attik-backend)

  • src/models/flowSchema.ts — extend the current closed trigger model with a configurable field-change trigger rather than adding many narrow hard-coded events.
  • src/events/streamHandlers/inspectionStream.ts — detect updates to watched fields such as requiredInfoValues.* and emit the new trigger.
  • Add equivalent quote-side trigger support so quote required info field changes can also start flows in v1.
  • src/util/functions/actionFlows/flowEventTriggerer.ts — support dispatch for the new trigger path.
  • src/util/functions/actionFlows/handleEventTriggerdByBull.ts — continue loading the job/quote and evaluating conditions after the trigger fires.
  • src/util/functions/actionFlows/conditionsResolver.ts and attributePathResolver.ts — existing field-value resolution is already the right foundation for post-trigger filtering.
  • Add or extend action execution behavior so actions can optionally support an only send once mode while still allowing default re-fire behavior on later edits.

Frontend (attik-frontend)

  • src/app/tools/action-flow/[flow_id]/components/TriggerContent.tsx — add a Field changed trigger type to the builder.
  • Add trigger configuration UI so users can select the watched field separately from the trigger type.
  • Scope v1 field selection to required info fields while keeping the model extensible to broader inspection and quote fields later.
  • Reuse the existing required info metadata and typed conditions plumbing instead of creating a new filtering system.
  • src/components/conditions/Conditions.tsx already exposes required info fields as conditionable attributes and should remain the source of truth for conditionable required info values.
  • Add action-level UI for an optional only send once behavior where applicable.

Product framing

  • This is primarily a new trigger capability.
  • It is not a conditions-system rewrite.
  • It is not a bug in existing lifecycle, reminder, or payment-triggered flows.
  • v1 is intentionally narrower in watched-field coverage (required info first) while still requiring inspection and quote parity.

Decision needed

  • Whether the v1 watched field picker should show:
  • all required info fields for the current entity type only
  • all required info fields across both inspections and quotes with type-appropriate filtering
  • Whether the action-level only send once option applies to:
  • all communication actions
  • only email / SMS
  • other action types too
  • What identity should define “once” for send-once behavior:
  • once per action per job/quote
  • once per action per watched field
  • once per action per watched field/value combination
  • Whether future expansion beyond required info should use the same field picker model without changing trigger semantics.

Diagram

flowchart LR
  subgraph today [Today]
    E[Fixed trigger event\njob or quote lifecycle]
    T[Time offset\nreminders / follow-up]
    C[Existing conditions\nincluding required info]
    S[Send action]
    E --> C --> S
    T --> C --> S
    F[Field edit\nrequired info / radon / payload] -.->|no trigger| X[Nothing]
  end

  subgraph desired [Desired]
    FC[Field changed trigger\nselected watched field]
    C2[Existing conditions reused]
    O[Optional only-send-once\naction behavior]
    S2[Send action]
    FC --> C2 --> O --> S2
  end

References

  • Backend trigger model: attik-backend/src/models/flowSchema.ts
  • Backend inspection event mapping: attik-backend/src/events/streamHandlers/inspectionStream.ts
  • Backend trigger dispatch: attik-backend/src/util/functions/actionFlows/flowEventTriggerer.ts
  • Backend conditions: attik-backend/src/util/functions/actionFlows/attributePathResolver.ts, attik-backend/src/util/functions/actionFlows/conditionsResolver.ts
  • Frontend trigger builder: attik-frontend/src/app/tools/action-flow/[flow_id]/components/TriggerContent.tsx
  • Frontend conditions UI: attik-frontend/src/components/conditions/Conditions.tsx
  • Core conclusion: required info already works as a condition; the missing capability is a field-change trigger

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

2 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.