Qontak Automation Flow Builder — Discovery + Product Plan
| Document type | Discovery brief + phased product plan (pre-PRD) |
| DRI / PM | Dimas Fauzi Hidayat |
| Date | 17 Jul 2026 (v1.2 — corrects target architecture: replacement, not two coexisting systems) |
| Status | Draft v1.2 — desk validation 🟢 GO; concept test + pricing validation next |
| Likely PRD shape | ANCHOR (multi-phase) |
Sources (grounding):
- Code grounding:
chatbot(BE),chatbot-fe(FE),hub-core/hub-chat,qontak-designerrepos — file paths cited inline, surveyed 17 Jul 2026 product-intelligence-hub/chatbot/ai-agent-configuration/competitive-2025-10-24/— AI Agent Creation Workflow Benchmarking, 10 platformspre-discovery-validation-2026-07-17.md— desk validation + full feature/pricing comparison, all sources accessed 17 Jul 2026- Bifrost:
meta-whatsapp-pricing-oct-2026— WhatsApp service-message pricing change
Changelog v1.1 → v1.2: corrected the core architecture. v1.1 treated the automation builder and the bot tree diagram as two systems that merely share a canvas library (P1 = new Workflow engine; P2 = FE-only reskin of the legacy Path/Intent/Response tree, explicitly "no BE changes"). That undersold the goal. The automation builder replaces the tree diagram — one engine, not two: bot conversation becomes one case of a workflow (trigger = message received; conversational steps = node types in the same catalog as automation actions), so a single flow can span from "customer messages in" through "bot handles it" through "conversation resolves" into post-resolution automation, with no handoff between separate systems. This moves real migration scope (data migration + runtime cutover on a revenue-critical path) into P2, up from a cosmetic reskin — reflected in §2, §3, §4, §9 (P2 rewritten, effort M→L), and §11 (new migration risk).
1. Problem & Opportunity
Qontak's flow builder — the "tree diagram" customers use to design bot conversations — has two compounding problems:
(a) Its value ceiling is bot conversations only. Everything automation-shaped that isn't a bot reply lives as a scattered point feature with its own settings page and no shared mental model:
| Point automation today | Where it lives |
|---|---|
| Agent assignment rules (division routing, round-robin, conditions) | hub settings + hub-core/app/core/domains/interactors/system_assign_agents.rb |
| SLA rules + escalation webhook | hub-core sla_config.rb / sla_condition.rb, send_message_interaction_high_sla_worker.rb |
| Auto-resolve / customer-idle automation | hub-chat CustomerIdlePage + hub-core/app/core/workers/auto_resolve/* |
| Idle-rule reassignment | agent_idle_rule_assignment_queue.rb + workers |
| Recurring campaign scheduling | hub-chat/features/campaign/whatsapp-campaign/recurring/ |
| Bot idle rules, auto-tag, auto-assign, webhook events | flags on Intent inside the bot tree |
A tenant who wants "when a room resolves without CSAT, send a follow-up template 24h later" cannot express it anywhere — even though every ingredient (event, delay, template send) already exists in the platform. Worse: even if it could be expressed, it would live in a second system from the bot conversation that produced it — a separate flow triggered by an event, not a continuation of the same canvas. That's the gap this initiative closes (§2).
(b) The tree-diagram canvas itself is a UX liability. Known complaints: laggy interaction (lemot), zoom in/out doesn't work properly, and latency grows badly when a path has many bot responses/nodes. Root cause is architectural, not tuning: the canvas is a custom renderer — @panzoom/panzoom + CSS-drawn connector lines + recursive DOM components (chatbot-fe/modules/conversation/views/tree-diagram/old-canvas/diagram-bot-response.vue, ~1,450 lines, self-recursing). There is no graph model, no node coordinates, no viewport virtualization — every node is a live DOM subtree, so large flows degrade linearly. Even the existing bot use case underdelivers on this canvas.
Why now. Meta begins charging for WhatsApp service messages on 1 Oct 2026 (no volume discount; corroborated by ≥4 independent BSPs). Every automation that resolves, deflects, or acts without a metered send — or that makes each send count — compounds in value. Tenants will actively shop for automation that reduces message spend; owning a first-party automation layer is the platform-level response.
2. Goals
Headline goal: centralize ALL automation in Qontak into one flow-builder surface.
Target architecture — one engine, not two. The automation builder does not sit next to the bot tree diagram; it replaces it. A "bot conversation" becomes one specific case of a workflow: trigger = message received (keyword/channel/NLP-matched, ported from the legacy
Pathresolution logic), and the conversational steps (ask question, send message, AI agent, reuse response, WhatsApp Flow) become node types in the same NodeRegistry catalog as the automation actions (CRM, HTTP, delay, tag, assign). Because it's one graph, one canvas, one run history, a tenant builds a single continuous flow that starts with a customer message, lets the bot/AI handle it, and — without leaving the canvas or handing off to a second system — continues into post-conversation automation once the room resolves (wait → CSAT → CRM sync → escalate). This is what makes "centralize automation" literal rather than aspirational, and it's why the P2 migration (§9) is the core of this initiative, not a side cleanup or a visual reskin.
Supporting goals:
- Unify bot conversation and automation into one runtime — not two systems sharing a canvas; one engine, one data model, one run history (the correction above).
- Unlock non-conversational value from the flow canvas — flows that start from lifecycle events and schedules, not only inbound messages.
- Fix builder UX/performance — re-platform the canvas on vue-flow under the qontak-designer bot-flow visual language (§7); a side effect of the unification, not its main justification.
- Stay squad-owned — no runtime dependency on Mekari Workflow or any DSAI-style external service (see §5).
- Monetize as an upgrade lever with honest pricing (§8) — the category's pricing is actively resented (WATI silent-stop, Trengo bill shock); simplicity is a differentiator here, not just hygiene.
Non-goals (v1):
- Migrating every existing bot flow on day one. Migration is phased and reversible per §9 P2 (feature-flagged, shadow-run validated, rollback path kept) — not a big-bang cutover.
- External connector marketplace / third-party app directory (groundwork only, in P3).
- Replacing the AI agent's autonomous action-calling — the automation builder is deterministic rails; the AI agent remains the probabilistic layer. They share the same node catalog.
3. Ideation — what "automation builder" means for Qontak
Three solution shapes were considered:
| Shape | Verdict |
|---|---|
| A. Generalize the existing tree builder | ❌ Rejected. The legacy engine (Path → Intent → Response, executed by chatbot/app/core/use_cases/system/hub/process_incoming_message_with_resolve.rb, ~1,240 lines) is hard-bound to Room/Contact/ChannelIntegration/History; the FE canvas has no graph model. Generalizing it in place = rewriting it — better to build the general engine fresh and migrate onto it (below). |
| B. Integrate with Mekari Workflow | ❌ Rejected as the primary path (avoidability assessment in §5). |
| C. Build Qontak-native on the NodeRegistry engine, then migrate bot conversation onto it | ✅ Chosen — with a stronger endpoint than a bolt-on automation module: not "automation builder alongside the legacy tree," but full replacement. ~70% of a general action-execution engine already exists in chatbot BE (§4); what's missing is a trigger layer (incl. porting message-received matching), a room-independent run context, conversational node types, and a canvas. |
Two more shapes surfaced in desk validation (validation report §4): templates-only automation — kept as the activation layer on top of C, not a substitute; AI-authored automation ("describe it, we build the flow") — a later-phase differentiator that needs C's rails first.
Candidate hero use cases (v1-expressible with the §9 P1 scope; #1 becomes a single continuous flow once P2 unification lands, rather than two flows joined by an event):
- Post-resolve follow-up — room resolved → wait → send CSAT / follow-up template → log to Sheets. (Flagship demonstration of unification: pre-P2 this is triggered by a
room_resolvedevent from a separate bot flow; post-P2 it's the tail end of the same flow that handled the conversation.) - CSAT-driven routing — low CSAT score submitted → create CRM ticket + tag room + notify supervisor. (CSAT trigger lands P2+.)
- Scheduled re-engagement — every Monday 09:00 → query/act on a segment (starts as Sheets/HTTP-driven; native segment nodes later).
- SLA-breach escalation — SLA warning event → assign to senior division + create ticket. (Replaces the hard-coded SLA webhook worker over time.)
- CRM sync on room close — room resolved → create/update deal or ticket with room context.
4. Grounding — what exists today (code reality)
4.1 The tree builder is NOT the base — but its capabilities must be ported, not discarded
- BE: legacy engine is conversation-native end-to-end. Trigger resolution = keyword/channel/message-type only (
chatbot/app/core/repositories/paths/find_by_channel_integration.rb); schedules on a Path are eligibility gates, never triggers. State =Historyrows per room. - FE:
chatbot-fe/modules/conversation/views/tree-diagram/renders a parent→child tree via recursive components + CSS lines + panzoom. No node/edge model, no coordinates, no virtualization → the §1(b) performance complaints. - What this means for the corrected plan: "not the base" does not mean discarded — it means
Path/Intent/Response's capabilities (keyword/channel/NLP trigger matching, conversational node behaviors) get re-implemented asWorkflowTrigger/NodeRegistryentries on the new engine, and existing flow data gets migrated across (§9 P2), so the legacy models are eventually retired rather than left running forever alongside the new ones.
4.2 ~70% of a general engine already exists (chatbot BE)
The AI-agent action system is already Zapier-shaped:
- Catalog:
NodeRegistrymodel —node_type,version,categories,inputs/outputsports,propertiesschema,settings.credential,node_type_group. Served to FE viaGET /v1/node_registries+/v1/node-resources/lookup. - Engine:
chatbot/app/core/repositories/node_executions/—ActionExecutorFactory,NodeTypeRegistry::GROUP,CredentialResolver(managed org credentials),ExecutionLogger,{{}}templating (concerns/argument_interpolation.rb). - Executors shipped: generic HTTP
api(arbitrary URL/method/headers/body + interpolation),mekari_qontak_crm(deal/ticket create/update/read),mekari_qontak_chat(room assign/resolve/tag/attachment — room-bound),google_sheets,google_calendar. - The coupling is only at the entry points. The executor contract (
nodes/node_executor_interface.rb) takes keyword args(organization_id:, credential:, parameters:, arguments:, room_id:, node_type:)—room_idis optional context for most executors. What hard-requires a room/AiAgent is the caller (app/api/internal_service/v1/ai_agent/use_cases/node_execution_execute.rb), which a new workflow entry point simply bypasses. - Net-new for unification: conversational node types (
send_message,ask_user_input,ai_agent_step,reuse_response,whatsapp_flow) don't exist asNodeRegistryentries yet — today they'reIntentcolumns/flags, not catalog entries. Porting them is P0/P2 scope (§9).
4.3 The trigger substrate exists (hub-core) — plus message-received must be ported from the legacy engine
- Org-scoped webhook registry:
hub-core/app/core/domains/models/webhook.rb— event enum {room_interaction, message_interaction, agent_responsibility, waba_interaction, available_user_status, custom_agent_allocation}, filterable bychannel_integration_ids. This enum + filter shape is the design template for lifecycleWorkflowTriggers. - Event bus: ~80 publishers in
hub-core/app/core/events/publishers/(RabbitMQ/Sneakers) + Kafka producers/consumers — room created/resolved, message received, agent assigned, CSAT survey, broadcast status, contact created… - Chatbot BE already consumes hub events two ways: HTTP receivers and Karafka (
chatbot/karafka.rb,consumer_group :chatbot, topicchatbot_incoming_message). A Kafka trigger bridge is not new infrastructure. message_receivedas aWorkflowTriggertype: unlike the lifecycle/scheduled triggers, this one isn't sourced from hub-core — it's ported from the legacy Path engine itself (Repositories::Paths::FindByChannelIntegration,PathKeyword,PathChannel), since that's where keyword/channel/NLP-match trigger resolution already lives, tested against production traffic. P0/P2 scope, not a hub-core dependency.
4.4 FE plumbing that carries over
chatbot-fe/modules/ai-agent/constants/ai-agent-actions-constants.ts (ACTION_LIST) already encodes nodes as node_type / inputs / outputs / properties with depends_on visibility and resource_types lookups; the composables beside it render property forms generically. That is ~70% of the node-config-panel work; net-new FE is the canvas, palette (now including conversational node types), edge validation, and run-history views.
5. Positioning vs Mekari Workflow (dependency avoidability assessment)
A Mekari-level workflow product exists, and chatbot BE already emits intent webhook events to it (chatbot/lib/mekari_workflow/workflow.rb + Intent.is_webhook_event → SendIntentWebhookEventWorker).
Decision: build Qontak-native. Dependency avoided.
- Avoidability: fully avoidable — the squad owns the entire critical path (NodeRegistry engine, Karafka consumption, chatbot-fe). Riding Mekari Workflow would put a cross-BU team on the critical path for every trigger, node, and canvas iteration (the DSAI precedent: slow/unreliable cross-team dependency, replaced by squad-owned
Gpt::Completionin spam-gatekeeper). - Squad-owned alternative: exists and is the chosen design (§4.2).
- Interop stance: non-blocking adjacency. Positioning line for stakeholders: Mekari Workflow automates across Mekari products; the Qontak automation builder automates the conversation/CRM domain natively, in-product, on Qontak's own event bus — and now, as one engine, it's also where bot conversations live.
6. Competitive landscape & whitespace (validated 17 Jul 2026)
Full evidence: pre-discovery-validation-2026-07-17.md §2 (capability matrix + pricing table, all source-linked). Headlines:
- Sleekflow is the benchmark and the threat — the only peer with a genuine event-driven canvas: scheduled + webhook + CRM + Shopify triggers, branch/wait/AI nodes, per-enrollment run logs. Gated at Pro (~$149/mo) with per-enrollment credit metering (0.5/1.0 credits by flow size). Notably, even Sleekflow keeps its chatbot builder and its Advanced Flow Builder as two separate products — a fully unified engine (this plan's §2 target) is not something any peer has done, which sharpens the unification as a genuine differentiator, not just parity work.
- Respond.io Workflows is the most general engine (18 step types, 150 workflows × 100 steps) but explicitly does not support scheduled triggers and has no run history — workflow analytics is an open item on their public feature-request board.
- WATI and Gallabox don't really have a workflow canvas — WATI is a rules engine with a hard per-execution quota that silently kills automations at cap (its top G2 complaint); Gallabox workflows are template-shaped and integration-scoped.
- Trengo's real workflow product (AI Journeys) is still beta with unsettled pricing; its conversation-metering + AI wallet model generates documented bill shock.
Qontak's four validated differentiators (adds unification to the original three):
- One engine for conversation and automation — no peer has this; it's the biggest strategic bet in this plan.
- Native CRM objects in the canvas — no peer has deals/tickets as first-class nodes; all bolt on external CRMs. Qontak owns both sides.
- Run history/observability — a market-wide hole (only Sleekflow has it); we designed
WorkflowRun/WorkflowRunStepfor this from P0. - Honest pricing (§8) — the category's metering is actively resented; simple, generous, never-silent-stop pricing is a wedge.
Table stakes confirmed: visual trigger→condition→action canvas, conversation-lifecycle triggers, assign/tag/field/HTTP actions, delay + branch, templates gallery.
7. Design direction — extend the new Bot Flow visual language
The visual baseline exists. The qontak-designer prototype app/pages/bot-automation/bot-flow/[id].vue (Pixel-compliant, builder-canvas + form-panel patterns) defines the look: dotted canvas + Start point node with status warning, Add step palette attached to the node (User input / Bot response / Branch / AI agent / Reuse bot response), right-hand settings drawer (bot type, channels, operational hours, conversation trigger), top bar with search + zoom controls + Discard/Publish, floating Test your bot action, and Trigger text / Bot flow tabs.
Reality check (verified): the prototype is a static visual mock — 613 lines, hardcoded start-point block, non-functional zoom buttons; its own docs list "Add step → actual node insertion" as not implemented. It is the design language, not a working canvas. vue-flow provides the working graph underneath; the prototype provides the skin. This downgrades the design dependency from "net-new pattern, no precedent" to "extend an existing prototype pattern" — significantly less designer lead time.
Extension spec for the automation variant (designer-facing change request, per the read-only-prototype rule) — note the "Start point" and "Add step" extensions below now describe the unified builder, not a separate automation-only tool:
| Bot Flow prototype element | Unified builder extension |
|---|---|
| Start point node (channels + operational hours) | Trigger node — trigger picker spans message received (keyword/channel/NLP — the legacy Path config, ported) and lifecycle events and scheduled (cron + timezone) and (P3: CRM events, inbound webhook); filter config in the same right-drawer pattern |
| Add step palette (5 conversation steps) | Palette driven by /v1/node_registries, grouped: Conversation (send message, ask input, AI agent, reuse response, WA flow — ported from today's palette), Conditions (branch/switch), Timing (delay/wait), Actions (CRM deal/ticket, room tag/assign, HTTP, Sheets, WA template), AI (agent step) |
| Right settings drawer per node | Same drawer, forms rendered from NodeRegistry properties via the existing ai-agent form composables |
| Trigger text / Bot flow tabs | Trigger / Flow / Runs tabs — Runs = the run-history view (per-run status, per-step input/output, retry) |
| "Test your bot" floating action | "Test run" — executes the P0 manual test-run endpoint against sample trigger payload |
| Publish/Discard | Same, plus Active/Paused state |
The reference screenshot is what the unified canvas should look like once P2 lands — not a separate look for automation.
8. Proposed pricing & packaging
Status: proposal for validation — competitor-anchored, but final numbers and tier mapping need pricing/finance sign-off and the §11 pricing-sensitivity check. Qontak's actual plan names/prices to be mapped by PM + pricing team.
8.1 Model choice: plan-gated builder + included run quota + transparent run packs
The market splits three ways (validation report §2B): plan-gate (HubSpot, Respond.io), pure usage metering (Zapier per-task, Make per-credit, Sleekflow per-enrollment, WATI per-trigger), and emerging outcome pricing (Intercom Fin per-resolution). Messaging platforms overwhelmingly plan-gate, and every heavily-metered peer is paying for it in reviews (WATI silent-stop = top complaint; Trengo wallet = bill shock; Sleekflow credits contradict its "unlimited" marketing).
Proposal: hybrid — the builder sells the plan, runs are nearly free, and the meter never silently stops anything.
Important consequence of unification: because bot conversation now runs on the same metered engine, existing bot-serving traffic becomes part of the run count. §8.3's quotas must be sized against current bot-message volume, not just net-new automation volume — flagged as an open question in §12.
8.2 Pricing unit: one workflow run = one full execution
n8n's model (n8n pricing): a run is one execution of the whole workflow regardless of step count. Steps, conditions, delays, branches cost nothing (Zapier itself now excludes utility steps from task counts). This is the simplest unit to explain and directly counters Sleekflow's node-count credit complexity and WATI's chained-trigger double-counting. Explicit rule: WhatsApp message costs stay a separate, pass-through meter — runs ≠ messages, never blended.
8.3 Tier structure (structural — map to actual Qontak plans; run quotas need re-sizing per the §8.1 consequence)
| Entry/Starter tier | Mid/Professional tier | Advanced/Enterprise tier | |
|---|---|---|---|
| Builder access | Templates only — activate up to 2 automations from the gallery (no custom canvas); existing bot flows keep running | Full canvas, up to 15 active flows (conversation + automation) | Up to 50+ active flows |
| Included runs/month | 500 (automation-only baseline — re-size once bot-conversation volume is folded in, §12) | 5,000 (same caveat) | 25,000 (custom above) |
| Triggers | Lifecycle only | Message received + Lifecycle + scheduled | + inbound webhook, CRM events (P3) |
| Nodes | Core actions | + Conversation nodes, HTTP request, Sheets | + credential mgmt, priority queue |
| Run history | 7 days | 30 days | 90 days |
- Run packs (add-on): Rp149.000 per 5.000 runs (≈US$9 →
$0.0018/run). Anchors: Sleekflow $59/1,500 ($0.039/run — 20× more expensive), n8n €20/2,500 (~$0.008/run), Zapier ~$0.013–0.02/task. Deliberately cheap: runs drive habit and stickiness; the plan gate and upgrades carry the revenue. - Templates-on-entry-tier is the funnel: entry tenants taste automation (2 templates), hit the ceiling, and upgrade for the canvas — the Respond.io $79→$159 jump is proof this gate converts, minus their "Starter is a trap" resentment because our entry tier still gets working automation.
- Grandfathering note: existing tenants' live bot flows must not be retroactively metered against a new quota at migration time — P2 migration ships with either unlimited/grandfathered runs for pre-existing flows, or a generous initial allowance, to avoid an unpleasant surprise bill tied to a backend migration the tenant didn't ask for.
- Alternative to test in discovery: "Automation Plus" paid add-on (indicative Rp500.000–750.000/mo) unlocking the full canvas on the mid tier — test add-on vs plan-gate willingness in the §11 pricing check.
8.4 Quota behavior — the anti-WATI guarantee
At 80% quota: in-app + email notification. At 100%: 10% grace buffer, then new runs queue (not drop) for scheduled triggers and degrade to notification-only for lifecycle triggers — with a one-click run-pack purchase. For message-received (bot conversation) triggers, quota must never block a live customer conversation — this is a harder constraint than an automation-only product, since a "silently stop" failure mode here means the bot literally stops replying to customers. Recommend: bot-conversation runs are never quota-gated (unmetered or effectively unlimited), only genuinely new automation-triggered runs count against the quota — protects the revenue-critical path while still monetizing the net-new capability.
8.5 Commercial logic
- Upgrade lever (primary): automation is the proven tier-jump driver in this category — it becomes the reason to move up-plan, same as workflows sell HubSpot Professional.
- Retention: tenants with active automations operationally embed Qontak (harder to churn ahead of Oct-2026 WhatsApp repricing, when they'll be shopping).
- Run packs (secondary revenue): high-volume tenants self-serve packs; margin is high since a run costs fractions of a rupiah in compute.
- Defensive: Sleekflow sells this against Qontak-class platforms in SEA today; parity + the four differentiators (§6) protect the base.
- AI nodes (later): AI-agent steps inside automations can meter through the existing AI pricing path — kept out of the run price to preserve unit simplicity.
9. Phased product plan
Cross-cutting decision — one canvas, one engine. vue-flow (@vue-flow/core, Vue 3-native, fits chatbot-fe's Nuxt 3.12) becomes the single canvas for the unified builder, skinned to the qontak-designer bot-flow visual language (§7) on Mekari Pixel. Unlike earlier drafts, this is not "automation builder + a reskinned legacy tree" — P2 below is a real migration, not a cosmetic pass.
P0 — Engine foundation (BE only, no UI) — effort M
- New org-scoped data model in chatbot BE:
Workflow,WorkflowTrigger(event type + filters; cron + timezone +next_run_atfor scheduled),WorkflowNode(node_type + pinned registry version + parameters + x/y position),WorkflowEdge(source port → target, ports carry branch labels),WorkflowRun(trigger snapshot + accumulated context + dedup_key),WorkflowRunStep(per-node input/output/status, credential-redacted). - Room-independent execution: new entry point
Repositories::Workflows::ExecuteNode+ aWorkflowExecutionContextvalue object; reusesActionExecutorFactory/CredentialResolveruntouched; existing AI-agent entry points untouched. conditionnode (node_type_group: logic, outputs["true","false"]) reusing the 11 tested operators fromResponseRuleCondition#operator_enum(=, <, >, <=, >=, !=, contains, starts_with, ends_with, has_value).- Define the conversational
NodeRegistryentries (send_message,ask_user_input,ai_agent_step,reuse_response,whatsapp_flow) mapped from existingIntent/UserInput/Responsesemantics, and amessage_receivedWorkflowTriggertype portingRepositories::Paths::FindByChannelIntegration's keyword/channel/NLP matching. This is what makes bot-conversation authoring expressible on the new engine — required before P2 can migrate anything. - Manual test-run endpoint = the vertical-slice proof, zero event/scheduler dependencies (also powers the §7 "Test run" UI). Retires the "do executors run with
room_id: nil" risk forapi,mekari_qontak_crm,google_sheets. - Run metering counters per org (for §8 quotas) built into
WorkflowRunfrom day one.
P1 — Thinnest shippable v1 (automation-first, engine de-risking) — effort L
- Triggers (3):
room_created,room_resolved(hub-core adds Kafka producers at the existing publisher call sites → newqontak_automation_eventstopic → new KarafkaAutomationEventConsumerin chatbot BE) + scheduled (single static tick worker advancingnext_run_at— deliberately not per-org dynamic sidekiq-cron; minute granularity, documented). Deliberately notmessage_receivedyet — bot flows keep running on the legacy engine during P1, so the new engine ships and earns production trust on lower-stakes traffic before touching the revenue-critical message-serving path. Scheduled triggers at launch immediately clear Respond.io (explicitly unsupported) and everyone except Sleekflow. - Actions (5) + condition: generic HTTP, CRM create/update deal/ticket, room tag, room assign (chat-group nodes offered only when the trigger provides room context — builder-validated), Google Sheets append.
- FE: vue-flow canvas (shared module) consumed by new
modules/automation/, skinned per §7; node palette from/v1/node_registries(automation groups only at this point); config panels via the extracted ai-agent form composables; workflow CRUD + enable/pause; Runs tab v1 (run list + per-step status — the observability differentiator ships at launch, not later). Surfaced in hub-chat via the existing iframe pattern (hub-chat/features/chatbot/views/ChatbotPage.vue) — S effort there. - Templates gallery at launch (3–5 hero use cases from §3, minus #1's full continuous version until P2) — the activation layer; entry-tier tenants get templates-only access per §8.3.
- Guardrails day one: automation-originated events stamped
triggered_by: automationand skipped/depth-limited by the consumer (loop prevention — HubSpot-style); per-org active-workflow + concurrent-run caps; per-run step cap;dedup_keyunique index (Kafka is at-least-once); §8.4 quota behavior (notify, never silent-stop).
P2 — Unify: bot conversation becomes a workflow (the replacement, not a reskin) — effort L
This is the phase where the tree diagram is actually replaced, not re-skinned:
- Ship the P0 conversational node types +
message_receivedtrigger in the builder UI — palette gains a "Conversation" group alongside the automation groups (§7). - Data migration: script to translate every published
Path/Intent/ResponseintoWorkflow/WorkflowNode/WorkflowEdge— tree → graph, preserving branch semantics viaResponseRule→conditionnode mapping (already designed in P0). - Runtime cutover:
ProcessIncomingMessageWithResolve's tree-walk is replaced by a call into the new Workflow runtime for migrated flows — feature-flagged per organization, with the legacy path kept as fallback/rollback during rollout. - Parity validation: shadow-run migrated flows against the legacy engine on live traffic (compare outputs) before flipping a tenant's flag — given this touches production bot-serving, blast radius is high; this is NOT a "read-only render parity" reskin, it's full behavioral parity on a revenue-critical path.
- The concrete unlock: once migrated, a tenant's flow canvas is literally continuous — the same graph that handles the bot conversation can carry on into post-resolution automation nodes. Hero use case #1 (post-resolve follow-up) ships as one flow, not two joined by an event. This is the flagship demo of the whole initiative.
- Performance fix (the original driver in earlier drafts — lemot/zoom/latency) is a side effect of this migration, not the main justification.
- Also lands:
agent_assigned,csat_submitted,message_from_customer(highest loop risk — gated behind mandatory filters), broadcast status triggers;delay/wait(Sidekiqperform_in+ run re-hydration),switch(multi-branch), WA template send — wrapping existing hub-core broadcast workers only (they own tier throttling) + per-org send budget; per-step retries with backoff (retryable failures only), dead-letter status, run-detail inspector with failed-run replay (Zapier-standard), template gallery expansion.
P3 — Extensibility + convergence — effort L
- CRM triggers: deal/ticket stage changes already arrive in hub-core via
app/apps/crm/repositories/webhook/deal_receiver.rb/ticket_receiver.rb— republish to the automation topic (cross-squad contract, see §10). - Inbound webhook trigger: per-workflow signed URL → Qontak becomes receive-side Zapier for tenant systems.
- Connector groundwork: credential-management UI on the existing
CredentialResolver/settings.credentialrails + 1–2 new executor families (e.g. Slack/email via hub-core) to validate the connector shape. - Convergence roadmap begins (per the §2 headline goal): with conversation and automation already unified in P2, folding in SLA-escalation, auto-resolve, and assignment-rule configurations as workflow templates is the same migration pattern repeated, not new architecture. Assignment rules converge last (highest-volume hot path — needs perf proof first).
- Candidate: AI-authored automation ("describe the automation, get a draft flow") — differentiator identified in validation; needs P1/P2 rails.
10. Dependency register (per standing dependency rule)
| Dependency | Team | Phase | Avoidability | Status |
|---|---|---|---|---|
| Kafka producers for room lifecycle events at existing publisher call sites in hub-core | Hub squad | P1 | Additive, small, well-understood pattern (app/core/events/kafka_producers/ already exists). Fallback if blocked: consume the existing HTTP webhook receivers chatbot BE already has — worse (per-tier throttling semantics) but workable. | To flag before PRD |
| CRM deal/ticket webhook contract republish | CRM team | P3 | Deferred by design; not on v1 critical path. | Deferred |
| Mekari Workflow | Mekari platform | — | Avoided (§5). Interop-only adjacency. | Closed |
| notification-service push (supervisor notify action + quota alerts) | Broadcast squad | P2+ | Reuses the ai_agent_alert category path already being established by Live Monitoring — shared, not net-new. | Watch |
| Design: unified builder extension of the bot-flow prototype (§7) | Design (Wulan) | P1–P2 | Visual language + canvas/drawer patterns exist in qontak-designer bot-automation/bot-flow/; net-new = trigger picker spanning message-received + lifecycle + scheduled, conversation-node-group palette, Runs tab. Deliver as change-request spec (read-only prototype rule). | To brief |
| Pricing/finance validation of §8 | Pricing team | pre-PRD | Numbers are competitor-anchored proposals; needs run-quota re-sizing against real bot-message volume (§8.1). | To flag |
| Internal engineering sign-off on live-traffic cutover | Chatbot BE eng lead / SRE | P2 | Not cross-team in the standing-rule sense, but P2's runtime cutover touches production bot-serving — treat as a required internal safety review before any org's feature flag flips, same rigor as a payments-adjacent migration. | To schedule ahead of P2 |
No DSAI dependency anywhere in the plan.
11. Risks
- Runaway loops (workflow's own action re-triggers it) — event envelope carries
triggered_by: automationfrom day one; consumer skips or depth-limits ≤1; per-workflow rate limit + step cap. Designed into P1, not retrofitted. (HubSpot-validated pattern: hard-block re-enrollment loops.) - Multi-tenancy on the shared bus — consumer filters by
organization_idbefore any work; covered index(organization_id, trigger_type, enabled)onWorkflowTrigger; per-org concurrent-run cap at enqueue (noisy neighbor). - WA rate limits / pricing — WA sends only through existing hub-core broadcast workers + per-org automation send budget; also keeps automation from silently inflating the Oct-2026 bill. Runs ≠ messages billing separation (§8.2).
- Idempotency — at-least-once delivery →
WorkflowRun.dedup_key = hash(workflow_id, event_id)unique index; retries only on declared-retryable failures. - Registry version drift —
WorkflowNodepinsnode_registry_versionat save; builder prompts upgrades instead of silently re-resolving latest. - Live bot-conversation migration risk (elevated from earlier drafts — was scoped as FE-only): P2 now includes a real BE runtime cutover for a revenue-critical path serving live customer conversations. Mitigations: per-org feature flag, shadow-run parity validation against the legacy engine before any cutover, migration dry-runs on copied data, and a fast rollback path (keep legacy engine + data live as fallback for N weeks post-cutover per org). This is the single highest-risk item in the plan and should gate the P2 go/no-go, not be treated as routine.
- Node-type parity gaps — some legacy
Intentbehaviors (specific content-type rendering, idle-rule side effects,IntentAPIEntityfield-saving) may not map 1:1 toNodeRegistrynode types. Audit needed during P0 design, before committing to the P2 migration scope, so gaps are known rather than discovered mid-cutover. - Quota blocking live conversations — addressed in §8.4: bot-conversation runs must never be quota-gated the way automation runs are; a metering bug here has a categorically worse failure mode (bot stops replying) than in any peer's automation-only product.
- Scope gravity — "centralize all automation" invites boiling the ocean; the convergence roadmap (§9 P3) is deliberately behind three phases of proof.
- Pricing misfire — quota sizing must account for real bot-message volume (§8.1), not just net-new automation.
- Sleekflow velocity — the one peer with the full package; monitor their Advanced Flow Builder releases quarterly, noting they haven't unified conversation+automation either (§6), which is Qontak's opening.
12. Open questions & next steps
Open questions
- Tier mapping + run-quota sizing against real bot-message volume (§8.1/§8.3) — needs a volume pull from production before any pricing commitment.
- Migration sequencing: which tenant segment migrates first in P2 (new tenants only vs. opt-in existing vs. forced timeline)?
- Who is the v1 persona — org admin only, or supervisor-level authoring too? (Affects permissions model.)
- Scheduled trigger: timezone-per-workflow or org-timezone default in v1?
- Naming/IA: "Automation" as a new nav item vs. the bot-flow builder simply gaining new capabilities in place — with design.
- Run-history retention (
WorkflowRunStepvolume) vs. the §8.3 retention tiers — needs a volume estimate from Hub event rates. - What is the rollback SLA if a migrated org's flow misbehaves in production — how long does the legacy engine stay warm as a fallback?
Next steps
Pre-discovery desk validation— DONE 17 Jul 2026, verdict 🟢 GO (pre-discovery-validation-2026-07-17.md).Feature + pricing comparison— DONE 17 Jul 2026 (validation report §2; re-verify freshness before PRD sign-off).- Engineering feasibility spike on P2 migration (elevated priority given §11 risk #6) — before committing this to a PRD, get chatbot BE eng to sanity-check the
Path/Intent/Response→Workflowdata-migration mapping and the shadow-run parity approach on a sample of real production flows. - Concept test — extend the bot-flow prototype with the unified trigger picker + a continuous flow spanning conversation → automation (hero use case #1), test with 6–8 tenant admins; includes the pricing-sensitivity check (plan-gate vs add-on, quota sufficiency).
- Design change-request brief to Wulan — §7 extension spec (net-new: trigger picker, palette grouping, Runs tab).
- Pricing/finance review of §8 — map structural tiers to actual plans, including the run-quota re-sizing question.
- write-prd — ANCHOR PRD (multi-phase, §9 mapping to PRD phases), grounded per the standard chatbot + chatbot-fe + hub-core flow, with this document + the validation report + the P2 feasibility spike as discovery sources.