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