🧭 ClientsFlow — Lead Journeys & Branching Flowchart

Ground truth = the deployed production branch (v103, commit a4403ab) — what real leads hit today. English narrative · Hungarian subject lines quoted verbatim · generated 2026-06-18.

Legend

Two orthogonal things are marked on every message: who triggers the send and whether the code path exists in production.

Who sends / approves

🟢 AUTO-SENT system sends, no human in the loop ✍️→🟡 DRAFT→APPROVE AI drafts, a human must click Jóváhagy / Ready to send before it goes 🔵 GHL-NATIVE GoHighLevel workflow sends it 🟡 MANUAL a human action (call, stage move, set date) — no message

The human-gate invariant: every lead-facing email is DRAFT→APPROVE except the three transactional ones (GHL booking confirmation, the Meet calendar invite, the pre-call reminders), which are AUTO-SENT. Nothing else reaches a lead without an explicit human click.

Backend status (production v103)

[[in backend · dormant]] code exists but is gated off / unreachable in normal use [[not in backend]] described in specs but not built on production [[in backend · no live copy]] wired, but the authored .md isn't what actually sends

How any inbound reply is handled (the stem every scenario shares)

  1. 🟢 Ingest gate (handle_missive_incoming): drop warm-up/DMARC, calendar RSVPs, out-of-office, internal senders, and Layer-0 automated/bulk mail before any AI call. Wise transfer → payment touchpoint.
  2. 🟡-ignore If the mail landed in the main clientsflow.hu inbox, production ignores it entirely — Mátyás handles those by hand. Only the four cold-outreach inboxes feed the pipeline. [[production rule, 2026-06-18]]
  3. 🟢 AI classifier (Gemini 2.5 Flash) sets email_type, sentiment, is_lead, booking_ok, confidence.
  4. 🟢 Route → Notion Activity row + one reply-review task + Slack card (cold inboxes only). Low-confidence cold-inbox replies post a lighter "⚠️ Borderline" flag and are kept, never silently dropped.
  5. ✍️→🟡 The rep works the card on 🌅 Ma: Jóváhagy (send), Elvet (reject + AI learns), Olvasva (close, no reply), Halaszt (snooze), Átadás Daninak (delegate).

Everything below begins at step 3's branch on email_type / sentiment.

Scenarios — every distinct leaf path

Grouped into families A–H by what the lead's reply was. Overlapping steps are repeated so each scenario reads standalone. Each message line shows the send-mode tag and (where it has one) the exact Hungarian subject line; in-thread replies have no new subject.

A — Positive first reply interested / neutral · new_lead_reply

Scenario 1 — The clean win (full prepayment)
  1. 🟢 Gets the cold email — "Beszéljünk a weboldaladról, {keresztnév}?"
  2. Replies positively (classifier: new_lead_reply, interested)
  3. ✍️→🟡 AI drafts a short personalised opener + the fixed booking block (FIRST_REPLY_BLOCK_HU with the lead's prefilled booking link); rep approves → sent in-thread. On send an urgent "📞 Hívd fel" call task is created.
  4. 🟡 Lead books a slot via the link.
  5. 🔵 GHL booking-confirmation email (native) + thank-you page (BOOKING_THANKYOU_HU).
  6. 🟢 Pre-call reminders auto-send: 24h "Holnapi megbeszélés", then ~1h "Megbeszélés".
  7. 🟡 Rep preps, runs the Google Meet call (Fireflies records).
  8. 🟢 Transcript → AI extracts the post-call form fields → pre-filled form emailed to Mátyás.
  9. 🟡 Rep confirms form page 1 (Payment = Full), submits → DocuSeal proposal+contract generated, Stripe link created, stage → Proposal Sent.
  10. ✍️→🟡 AI drafts the proposal email — "Az ajánlatod — {cég} weboldal"; rep checks link/account on form page 2 → sends.
  11. Lead signs the DocuSeal doc and pays in full (within 2h) → stage → Prepayment.
  12. ✍️→🟡 Onboarding/welcome-kit email auto-drafted — "Üdv a fedélzeten, {keresztnév}! 🎉 Indulunk"; rep approves. Drive folder + client-portal credential form.
  13. 🟡 Rep moves stage → Waiting for Dev → 🟢 Slack ping to Dani + Main-Task due today.
  14. 🟡 Dev finishes → Rep → Website Built → (full prepaid) → Fully Paid immediately.
  15. [[dormant]] Handover invite — "Foglaljunk egy átadási hívást, {keresztnév}!" — authored but not auto-sent on production.
  16. 🟡 Rep runs handover → stage → Handed Over.
  17. [[dormant]] +3 days: review request — "Hogy tetszik az új weboldalad, {keresztnév}?" — authored, not auto-sent → mark WON.
Scenario 2 — Win on a deposit + balance (partial payment)
  1. Steps 1–10 identical to Scenario 1, but on form page 1 Payment = Partial (default 70% deposit).
  2. Lead signs + pays the deposit → stage → Prepayment.
  3. Onboarding (drafted), Waiting for Dev (Dani), dev builds → Website Built.
  4. ✍️→🟡 Balance-due email drafted — actual body: "Elkészült a weboldalad 🎉 A fennmaradó {balance}…" (Stripe card link + bank transfer). [[no live copy: the authored email_balance_due.md subject "…utolsó simítások" is not what sends — the config body is]]
  5. Balance paid → stage → Fully Paid → (handover [[dormant]]) → Handed Over → WON.
  6. Branch: balance never paid → 🟡 rep chases manually → or → OFF (Lost).
Scenarios 3–6 — Positive reply, but the lead does NOT book → the nudge ladder

After step 3 of Scenario 1 the lead goes quiet. followup_nudge_sweep (daily cron) drafts a nudge on day 2 / 5 / 9 — each is ✍️→🟡 draft→approve, in-thread (no new subject).

  1. Sc.3 — Day 2: nudge #1 (one new angle, light) → lead books → rejoins Scenario 1 at step 5.
  2. Sc.4 — Day 5: nudge #2 (softer, different angle) → books → rejoin.
  3. Sc.5 — Day 9: nudge #3 (graceful exit, no booking link) → books → rejoin.
  4. Sc.6 — All three sent, still silent → no further auto-nudge → 🟡 rep marks Lezár — nem érdekli or leaves to age out.
Scenario 7 — Positive reply, rep phones instead of emailing
  1. Reply positive → instead of the booking link, 🟡 rep calls the lead (the "📞 Hívd fel" task), agrees a time, and manually sets the Sales Call Date in the 📞 Hívások panel.
  2. → Meet invite + reminders + the call → rejoins Scenario 1 at the post-call step.
Scenarios 8–9 — Booked, then NO-SHOW → 5-step rebook loop

noshow_loop_sweep (daily cron) drafts up to 5 rebook emails, each ✍️→🟡 draft→approve, in-thread, tone gets shorter/looser each step (#5 = polite close). [[the manifest still labels this "authored — not auto-sent"; on production it IS cron-wired as drafts]]

  1. Sc.8 — 🟡 Rep marks No-show — átütemezzük → rebook draft #1 (AI; the authored "Lemaradtunk egymásról, {keresztnév}?" is the reference copy) → lead rebooks at any step → loop stops → rejoins the call flow.
  2. Sc.9 — Steps #1–#5 all sent, no rebook → 🟡 rep → OFF (Lost).
Scenarios 10–11 — Attended the call, but not ready to buy
  1. Sc.10 — Timing objection (still interested): on the post-call form the rep sets a manual follow-up date; lead is parked with Halaszt — X nap (nurture) so the nudge cron skips them until then. [[the spec'd "we'll reach out again on {date}" auto-confirmation email is not built]]
  2. Sc.11 — Second discovery call needed: 🟡 rep sets a new Sales Call Date → new Meet invite + reminders → loops back to the call. [[the post-call form's date-picker that auto-creates the 2nd calendar event is spec'd but not fully built — done manually]] A proposal may or may not be sent alongside the 2nd call.
Scenarios 12–17 — Proposal sent → sign & pay branches
  1. Sc.12 — Happy: signs + pays within 2h → Prepayment → (Scenario 1/2 onboarding tail).
  2. Sc.13 — Abandoned cart (signed, not paid): _abandoned_cart_sweep (10-min cron) arms a 2h timer → drafts a payment reminder (AI, in-thread; authored ref "Már csak egy lépés, {keresztnév} 🙌"), sequence +2h/+1d/+3d, each ✍️→🟡 → lead pays → Prepayment.
  3. Sc.14 — Abandoned, never pays: after the sequence → 🟡 rep manual chase → OFF (Lost).
  4. Sc.15 — Proposal sent, unsigned (FIRM): proposal_chase_sweep drafts a firm nudge (in-thread, CHASE_INSTR_FIRM) ✍️→🟡 → signs → pay.
  5. Sc.16 — Proposal opened, unsigned (SOFT): chase drafts a soft, helpful nudge (CHASE_INSTR_SOFT) ✍️→🟡 → signs → pay.
  6. Sc.17 — Never signs: 🟡 rep → OFF (Lost) → 60-day nurture task.

B — Objection / pushback email_type = objection

Scenarios 18–22 — Objection handling

An objection lands the deal in the 🚫 Negative Replies column (first column) and keeps the AI draft (acknowledge + facts — there may be room to convert). Three one-click actions.

  1. Sc.18 — Converts: 🟡 rep edits/approves the acknowledging draft ✍️→🟡 → lead becomes interested → rejoins Family A.
  2. Sc.19 — Send + Booking FUP → books: reply sent, drops into Booking FUP with a +2-day one-click nudge "Érdekes lehet a lehetőség?" → lead books → rejoin.
  3. Sc.20 — Send + Booking FUP → silence: +2-day nudge, then 1 week of silence → negative_fup_ghost_sweep auto-moves to Ghosted.
  4. Sc.21 — Reply & Mark Lost: 🟡 send + stage → OFF (60-day nurture).
  5. Sc.22 — Archive without replying: 🟡 mark read + archive Missive → Lost.

C — Negative reply "nem érdekel" sentiment = negative

Scenarios 23–26 — Negative reply

Goes to 🚫 Negative Replies with a default polite close draft "Köszönöm a visszajelzést! Sok sikert a továbbiakban!" (not the morning queue). Same three actions as objections.

  1. Sc.23 — Send + Booking FUP → books: polite close sent → +2-day nudge "Érdekes lehet a lehetőség?" → books → rejoin Family A.
  2. Sc.24 — Send + Booking FUP → silence: +2-day nudge → 1 week silence → auto-Ghosted.
  3. Sc.25 — Reply & Mark Lost: 🟡 → OFF (60-day nurture).
  4. Sc.26 — Archive without replying: 🟡 → Lost.

D — Ghosted / Lost lead writes back

Scenario 27 — Reactivation
  1. A Ghosted or Lost lead replies interested → 🟢 auto-cleared of negative markers and moved back to new_lead → rejoins Family A at the first-reply step.
  2. If the re-reply is itself negative/objection → stays in Negative Replies (Family B/C).

E — Re-engaged after a nudge followup_no_reply

Scenario 28 — Lead resurfaces
  1. Lead replies to a nudge → reply-review task → ✍️→🟡 AI draft (booking link if booking_ok) → books → rejoin Family A.

F — Reply on a sent-proposal thread proposal_followup

Scenario 29 — Question on the proposal
  1. Reply on the proposal thread → reply task, no booking link (BOOKING_SKIP_TYPES) → ✍️→🟡 AI draft answers + re-offers the link + next steps → signs → pay.

G — Existing paid client writes in project_update / ongoing

Scenario 30 — Ongoing-client message [[in backend · dormant on production]]
  1. The routing code (_is_paid_client_deal → "Client message" task in the Ongoing build / Ongoing marketing columns) exists, but production ignores the main inbox entirely, so a client emailing clientsflow.hu never reaches it. It only fires if a paid client replies inside a cold-outreach thread — rare. [[effectively dormant]]

H — Non-lead / vendor / system mail other

Scenarios 31–33 — Other
  1. Sc.31 — Other + known CRM contact: 🟢 logged as an Activity row with the CRM relation, no draft.
  2. Sc.32 — Other + cold inbox, no match: 🟢 review row + "⚠️ Borderline" Slack flag (could be a mis-tagged lead) — never silently dropped.
  3. Sc.33 — Other + main inbox: 🟢 ignored entirely (production personal-inbox rule) — stays only in Missive.

Branching flowchart — from the lead's reply onward

Conditions are on the arrows; each box shows the email subject line (or "in-thread" / transactional label) + a short summary. Colours follow the send-mode legend; dashed = dormant/not-built on production.

flowchart TD
  START(["📨 Lead replies
(to cold email or a call)"]):::start CLS{"🤖 AI classifier
email_type · sentiment · booking_ok"}:::ai START --> CLS %% ===== branches by classifier ===== CLS -->|"interested / neutral
(new_lead_reply)"| FR CLS -->|"re-engaged after nudge
(followup_no_reply)"| FR CLS -->|"objection / pushback"| NEGCOL CLS -->|"sentiment = negative"| NEGCOL CLS -->|"reply on proposal thread
(proposal_followup)"| PF CLS -->|"paid client writes in"| ONG CLS -->|"non-lead / vendor (other)"| OTH %% ===== A: positive / first reply ===== FR["✍️→🟡 First reply (in-thread)
opener + fixed booking block
+ '📞 Hívd fel' call task"]:::gate FR -->|"books via link"| BOOKED FR -->|"no booking"| NUDGE FR -->|"rep phones instead"| CALLSET NUDGE["✍️→🟡 Nudge ladder (in-thread)
day 2 · day 5 · day 9 (graceful)"]:::gate NUDGE -->|"books"| BOOKED NUDGE -->|"still silent after #3"| LOST CALLSET["🟡 Rep sets Sales Call Date
manually (phone-agreed)"]:::man CALLSET --> BOOKED BOOKED["🔵 GHL booking confirmation
+ thank-you page"]:::ghl BOOKED --> MEET MEET(["🟢 Meet invite 'Weboldal Bemutató — {név}'
(GCAL-driven = dormant)"]):::dorm MEET --> REMIND REMIND["🟢 Reminders AUTO-SENT
24h 'Holnapi megbeszélés' · 1h 'Megbeszélés'"]:::auto REMIND -->|"attends"| CALL REMIND -->|"no-show"| NOSHOW NOSHOW["✍️→🟡 No-show rebook loop ×5 (in-thread)
ref 'Lemaradtunk egymásról, {név}?'"]:::gate NOSHOW -->|"rebooks"| BOOKED NOSHOW -->|"5 steps, no rebook"| LOST CALL{"🟡 Sales call (Fireflies records)
→ AI post-call form"}:::man CALL -->|"ready to buy"| PROP CALL -->|"timing objection
(still interested)"| NURT CALL -->|"needs 2nd call"| CALL2 CALL2["🟡 New Sales Call Date
(date-picker auto-event = dormant)"]:::dorm CALL2 --> MEET NURT["🟡 Halaszt — nurture until {date}
(auto 'we'll reach out' email = not built)"]:::nobk NURT -->|"date arrives"| FR PROP["✍️→🟡 Proposal email
'Az ajánlatod — {cég} weboldal'
(DocuSeal doc + Stripe link)"]:::gate PROP -->|"signs + pays ≤2h"| PREPAY PROP -->|"signed, not paid"| ABANDON PROP -->|"opened, unsigned"| CHASESOFT PROP -->|"sent, unsigned"| CHASEFIRM ABANDON["✍️→🟡 Abandoned-cart reminders (in-thread)
+2h · +1d · +3d · ref 'Már csak egy lépés 🙌'"]:::gate ABANDON -->|"pays"| PREPAY ABANDON -->|"never pays"| LOST CHASESOFT["✍️→🟡 Proposal chase — soft (in-thread)"]:::gate CHASEFIRM["✍️→🟡 Proposal chase — firm (in-thread)"]:::gate CHASESOFT -->|"signs"| PREPAY CHASEFIRM -->|"signs"| PREPAY CHASESOFT -->|"never signs"| LOST CHASEFIRM -->|"never signs"| LOST %% ===== onboarding tail ===== PREPAY["✍️→🟡 Welcome kit
'Üdv a fedélzeten! 🎉 Indulunk'
+ Drive folder · client portal"]:::gate PREPAY --> DEV DEV["🟡 Waiting for Dev → Dani Slack + task
→ Website Built"]:::man DEV -->|"full prepaid"| FULLPAID DEV -->|"partial"| BALANCE BALANCE["✍️→🟡 Balance due (in-thread)
'Elkészült a weboldalad 🎉 A fennmaradó…'"]:::gate BALANCE -->|"balance paid"| FULLPAID BALANCE -->|"unpaid"| LOST FULLPAID["🟡 Fully Paid → handover"]:::man FULLPAID --> HANDOVER HANDOVER["Handover invite
'Foglaljunk egy átadási hívást'
(authored, not auto-sent)"]:::dorm HANDOVER --> HANDED HANDED["🟡 Handed Over"]:::man HANDED --> REVIEW REVIEW["Review request +3d
'Hogy tetszik az új weboldalad?'
(authored, not auto-sent)"]:::dorm REVIEW --> WON([🏆 WON]):::won %% ===== B/C: negative & objection ===== NEGCOL["🚫 Negative Replies column
objection: keep AI draft ·
negative: 'Köszönöm a visszajelzést!'"]:::neg NEGCOL -->|"Send + Booking FUP"| NEGFUP NEGCOL -->|"engageable objection converts"| FR NEGCOL -->|"Reply & Mark Lost"| LOST NEGCOL -->|"Archive, no reply"| LOST NEGFUP["✍️→🟡 +2-day nudge (in-thread)
'Érdekes lehet a lehetőség?'"]:::gate NEGFUP -->|"books"| BOOKED NEGFUP -->|"1 week silence"| GHOST GHOST([👻 Ghosted]):::term GHOST -->|"writes back interested"| REACT LOST([🪦 Lost — 60-day nurture]):::term LOST -->|"writes back interested"| REACT REACT["🟢 Auto-reactivated → new_lead"]:::auto REACT --> FR %% ===== F/G/H ===== PF["✍️→🟡 Proposal-thread reply (in-thread)
answer + re-offer link · no booking link"]:::gate PF --> PROP ONG["Ongoing-client 'Client message' task
(dormant: main inbox ignored)"]:::dorm OTH["🟢 Logged / borderline-flagged /
ignored (no draft)"]:::auto classDef start fill:#e8f0fe,stroke:#2563eb,stroke-width:2px,color:#1c2230; classDef ai fill:#ffffff,stroke:#5c6675,stroke-width:1.5px,color:#1c2230; classDef auto fill:#e9f7ef,stroke:#1f9d55,color:#13502c; classDef gate fill:#fdf6e3,stroke:#b7791f,color:#6b4a10; classDef ghl fill:#e8f0fe,stroke:#2563eb,color:#15336e; classDef man fill:#eef1f5,stroke:#64748b,color:#33414f; classDef neg fill:#fdecea,stroke:#c0392b,color:#7d1f15; classDef term fill:#eef1f5,stroke:#64748b,stroke-dasharray:4 3,color:#33414f; classDef won fill:#e9f7ef,stroke:#1f9d55,stroke-width:2px,color:#13502c; classDef dorm fill:#f3ecfa,stroke:#8a4baf,stroke-dasharray:5 3,color:#4d2a66;

Copy index — subject line · where it lives · send mode · status

MessageSubject line (HU)SourceSend modeStatus
Cold email (first touch)Beszéljünk a weboldaladról, {keresztnév}?Instantly (read-only)🟢 campaignlive
First replyin-threadAI + FIRST_REPLY_BLOCK_HU✍️→🟡live
Booking confirmationGHL templateGHL workflow🔵live
Booking thank-you pagepage textBOOKING_THANKYOU_HU🔵 pagelive (GHL page)
Meet inviteWeboldal Bemutató — {név}MEET_*🟢dormant (gated)
Reminder 24hHolnapi megbeszélésREMINDER_24H_*🟢 auto-sentlive
Reminder 1hMegbeszélésREMINDER_1H_*🟢 auto-sentlive
Proposal emailAz ajánlatod — {cég} weboldalAI + proposal_followup_email_hu✍️→🟡live
Nudge 1/2/3in-threadNUDGE_INSTR_1/2/3✍️→🟡live (cron-drafted)
Proposal chase soft/firmin-threadCHASE_INSTR_SOFT/FIRM✍️→🟡live (cron-drafted)
Abandoned cartin-thread (ref "Már csak egy lépés 🙌")ABANDONED_CART_INSTR✍️→🟡live (cron-drafted)
No-show rebook ×5in-thread (ref "Lemaradtunk egymásról?")AI loop✍️→🟡live (cron-drafted)
Negative default closein-thread "Köszönöm a visszajelzést!…"NEGATIVE_REPLY_DEFAULT_HU✍️→🟡live
Negative +2-day FUPin-thread "Érdekes lehet a lehetőség?"NEG_FUP_BODY_HU✍️→🟡live
Welcome kit / onboardingÜdv a fedélzeten, {keresztnév}! 🎉 Indulunkcopy:email_welcome_kit✍️→🟡live (auto-drafted)
Balance duein-thread "Elkészült a weboldalad 🎉…"BALANCE_DUE_BODY_HU✍️→🟡live, but the .md subject differs
Handover inviteFoglaljunk egy átadási hívást, {keresztnév}!copy:email_handover_inviteauthored, not auto-sent
Review requestHogy tetszik az új weboldalad, {keresztnév}?copy:email_review_requestauthored, not auto-sent
SMS templatescopy:sms_templatesnot wired (SMS not provisioned)

Sources for the rendering approach: Mermaid flowchart syntax · Mermaid.js guide (Swimm) · Email customer-journey flowchart guide (Omnisend).