ClientsFlow Pipeline · EBO Extension
Pipline live-test bug backlog · Scenarios S1–S9 · 2026-06-25 · Sources: bnf-pipelinetest-2026-06-24 + bnf-finish-2026-06-24
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Réka clicks the 'Lemondás' / cancel link in her booking email (GET /cancel?token=… on the booking app) | A confirmation page: the appointment was cancelled — not an error | Copy: "Időpont lemondva" · Look: plain confirmation, no error styling · Where: full-page on booking app | cancel_booking runs on the ZZ deal | No error thrown; no NEW booking confirmation email sent | NEW ENTRY Type: Lemondás · label: "Lemondás · {date}" · icon: 🚫 · timestamp: now (Budapest) |
Critique: The cancel link text in the email is generic ("Lemondás") — no time/date shown in the link itself, so Réka might not be sure which appointment she's cancelling. Suggestion: Include the appointment datetime in the link text: "Lemondás (2026. júl. 3. 10:00)" and on the confirmation page show the cancelled time prominently alongside the ✓. |
| 2 | Card moves OUT of Booked INTO 'Contacted — No Appointment Booked' | ZZ card appears under 'Contacted — No Appointment Booked', GONE from Booked | Copy: card title under 'Contacted — No Appointment Booked' · Look: normal board card in booking_fup column · Where: pipeline board | stage_key set to value mapping to booking_fup; NOT ghost 'contacted' key | Card must NOT stay in Booked; must NOT land in New Lead | No new touchpoint for the column move itself — the cancellation touchpoint from step 1 is the record. History panel now shows the Lemondás entry at the top. | Critique: The column name "Contacted — No Appointment Booked" is long and ambiguous for a cancel scenario — a just-cancelled lead looks identical to a lead who was never booked. Suggestion: Either (a) add a prominent RED "Lemondott" badge on the card face as the main visual signal, or (b) create a dedicated "Lemondott" sub-column / filter view so cancelled leads are visually separated from never-booked ones. |
| 3 | RED 'Lemondás' label + cancellation date appears on the card | RED label reading 'Lemondás' + cancellation date on the ZZ card | Copy: "Lemondás · {date}" · Look: RED label/badge · Where: card label/badge area | Deal stores cancellation flag + date → drives red label render | Label must NOT be neutral/blue; date must be cancellation date, NOT original booking date | History panel already shows the Lemondás entry from step 1. The red label on the card face is the board-level signal; the history entry is the detailed record. | Critique: The red label is correct but sits in the same visual slot as regular tags — easy to miss if the card has several other tags crowding it. Suggestion: Make the Lemondás badge slightly wider/bolder or pin it to the top-right corner of the card (as a ribbon/flag), so it can never be visually buried by other badges. |
| 4 | Card history shows a proper CANCELLATION entry (not 'Call booked' tag) | Newest history entry tagged as a CANCELLATION — 'Lemondva' / 'Cancelled' | Copy: history row tag = cancellation label · Look: visually distinct from booking tag · Where: card's history/touchpoints list | Touchpoint Type is cancellation (not 'booking') → HIST_LABEL renders correctly | History tag must NOT read 'Call booked'; description text stays correct | The Lemondás touchpoint shows: icon 🚫 · label "Lemondás" · "Időpont lemondva" as description · exact timestamp. Clicking the row expands to show the full detail if any note was added. | Critique: The history panel currently has no visual hierarchy — all touchpoint types (booking, cancellation, email, note) use a similar pill badge style, making it hard to scan quickly. Suggestion: Assign a consistent colour-coding per touchpoint type: red = cancellations/negatives, green = bookings, blue = emails, grey = notes/system. This makes the history timeline scannable at a glance without reading every label. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Réka clicks the cancel link | Cancellation completes (column move + red label + history) with NO outbound email queued or sent | Copy: no new outbox/email item for this deal · Look: outbox shows nothing newly armed · Where: absence is the assertion | No email send triggered by the cancel path; AUTOSEND not flipped | NO automatic email sent to lead; AUTOSEND never flipped; safe_click stays armed | No additional touchpoint beyond the Lemondás entry from S1. The Outbox tab should show zero newly armed items for this deal. Confirm by checking the Outbox/send queue in the Control Panel. | Critique: There is no visible confirmation to the operator (Mátyás) that no email was sent — the absence of an email is invisible and could be confused with a system failure. Suggestion: Add a system note touchpoint: "🔇 Auto-email suppressed on cancellation" in the history — low-key, grey styling, so the operator knows the no-send was intentional and not a bug. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Gergő opens the lead-side reschedule link and picks a new slot, then confirms | TODAY (bug): UI throws "időpont közben elkelt" / slot taken — nothing reschedules | Copy: error message "időpont közben elkelt" · Look: red error state · Where: lead-side booking/reschedule page | No appointment time change persisted | After the fix this error must NOT appear — see S4 | No touchpoint is created (the action failed). History is unchanged. | Critique: "időpont közben elkelt" is technically accurate but confusing for a lead rescheduling their OWN appointment — they hold the existing slot, so "it was taken" makes no sense from their perspective. Suggestion: Once fixed (S4), change the error copy to something actionable if it ever fires: "Valami nem sikerült — próbáld újra, vagy hívj minket: +36 70 327 8543". Never expose "slot taken" to a rescheduling lead. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Gergő picks a new valid slot and confirms | Success confirmation: appointment moved to the NEW time, no error | Copy: "Időpont átütemezve {new time}" · Look: plain success, no error · Where: lead-side reschedule page | Deal's appointment datetime updated; old slot cleared | No error shown; no duplicate booking; old slot not still blocked | No touchpoint yet — the reschedule touchpoint is created after the CRM update (step 3). At this point the history is unchanged from the operator side. | Critique: The success page only confirms the new time — but does not show the cancellation of the old appointment, leaving uncertainty about whether the original slot was properly released. Suggestion: Show both: "✓ Régi időpont törölve: júl. 3. 10:00 → Új időpont: júl. 5. 14:00". Two lines, old crossed out, new highlighted. Removes all ambiguity. |
| 2 | Card STAYS in the Booked column, showing the NEW date | ZZ card still under 'Booked / Sales Call Prep', updated date | Copy: new appointment date/time on the card · Look: normal Booked-column card, updated · Where: 'Booked / Sales Call Prep' column | stage_key stays at booked-mapped value; card does NOT leave Booked | Card must NOT move to another column; date must NOT be the old one | No new touchpoint for the column-stay (no column change). History is unchanged at this step. | Critique: The operator (Mátyás) sees the new date on the card but has no immediate indication that this was a lead-initiated reschedule vs. an operator-initiated one. Suggestion: Add a small "🔄 Átütemezve" badge to the card (similar to the Lemondás red badge) that persists until the appointment date, so the operator can spot reschedules at a glance on the board. |
| 3 | History gets a RESCHEDULE entry | New history entry recording the reschedule (old → new time) | Copy: "Átütemezés" · Look: reschedule-type pill · Where: card's history/touchpoints list | Reschedule touchpoint appended | History must NOT drop the reschedule; must not mislabel it as a fresh booking | NEW ENTRY Type: Átütemezés · icon: 🔄 · label: "Átütemezés" · description: "Régi: {old datetime} → Új: {new datetime}" · timestamp: now · initiated_by: lead |
Critique: The reschedule touchpoint currently shows only a single time (the new time). The old time is lost from the history view, making it hard to audit the sequence of changes. Suggestion: Always store and display both old AND new datetime in the reschedule touchpoint: "Régi: júl. 3. 10:00 → júl. 5. 14:00". This is one DB field addition and makes the audit trail complete. |
| 4 | Updated calendar invite sent to lead + rep | Updated Google Calendar invite for the NEW time reaches the lead's email and the rep | Copy: calendar invite with new time · Look: Google Calendar invite email · Where: lead inbox + rep inbox | create_meet_event runs with attendees + sendUpdates='all' for new time; old event deleted | Do NOT fake-green if invite blocked by Workspace / DWD config — FLAG as owner action | NEW ENTRY Type: Meghívó elküldve · icon: 📅 · label: "Naptár meghívó · Átütemezés" · description: "Naptármeghívó kiküldve az új időpontra: {new datetime}" · timestamp: now |
Critique: If the Google Calendar invite fails silently (DWD config issue), neither the operator nor the lead know — the card looks fine but no invite was sent. Suggestion: Add a system touchpoint "⚠️ Naptár meghívó sikertelen — manuális küldés szükséges" if the invite throws an exception. This turns a silent failure into an actionable item. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | On booking, a Google Calendar invite is created with lead + rep as attendees | Invite reaches the lead's inbox AND the rep (matyas@clientsflow.hu) | Copy: Google Calendar invite email · Look: standard GCal invite · Where: lead inbox + rep inbox | create_meet_event called with lead in attendees[] and sendUpdates='all' | Booking must NOT silently succeed with no invite; invite must NOT go only to the rep | NEW ENTRY Type: Foglalás · icon: 📅 · label: "Foglalás · {datetime}" · description: "Időpont foglalva, naptármeghívó kiküldve" · timestamp: now |
Critique: After booking, the lead has no visible "what happens next" context — they land on a generic confirmation page with no instructions about the Google Meet link or how to prepare. Suggestion: Booking confirmation page: add a "Következő lépések" block: (1) nézd meg a naptárba érkező meghívót, (2) a meetinglinkre kattintva csatlakozhatsz, (3) ha kérdésed van: {phone}. Convert a flat confirmation into a short onboarding moment. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Invite delivery fails at the Google Workspace / DWD / config layer | QA run does NOT mark B3 green; raises config blocker as a RESIDUAL HUMAN action | Copy: residual_human TODO: "enable DWD calendar scope / GCAL_DRIVEN_CONFIRMATION" · Look: flagged owner-action row in QA report · Where: QA report residual-human section | Blocker recorded as owner action, not silently passed | NEVER fake-green a blocked invite; never claim delivery succeeded when Workspace/DWD blocks it | SYSTEM ENTRY Type: Rendszerfigyelmeztetés · icon: ⚠️ · label: "Naptár meghívó sikertelen" · description: "A Google Calendar meghívó nem lett elküldve (Workspace konfig szükséges). Manuális link küldés ajánlott." · timestamp: now |
Critique: When the operator opens a card after a failed invite, nothing on the board surface signals a problem — the card looks identical to a successful booking. Suggestion: Surface the failed invite as an orange warning badge on the board card face: "⚠️ Meghívó nem ment ki". This is high-priority because the lead thinks they have a Meet link but doesn't — it directly causes no-shows. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Mátyás looks at a card in the 'Negative Replies' column | The card shows the SAME 'Send Emails' button as a New Leads card; NO stray booking button / datetime-local field | Copy: 'Send Emails' button present; no 'Book + send invite' / datetime-local · Look: button row matches New Leads card · Where: action-button row on the Negative Replies card | Per-stage button logic renders same functions for negative as new_lead | No stray booking button / date-picker on Negative Replies; 'Send Emails' must NOT be missing | No touchpoint created by viewing the card. If the operator clicks 'Send Emails', a new touchpoint is created: Type: Email sorozat indítva · icon: ✉️ · label: "Sorozat újraindítva" — identical to the New Lead path. | Critique: A Negative Replies card looks almost identical to a New Leads card after this fix — an operator who wasn't there for the negative reply has no context for why the lead is negative. Suggestion: Add a collapsible "Előzmény" banner at the top of the card (one line, collapsed by default): "💬 Negatív válasz érkezett: {date} · {truncated reply text}". This gives the operator instant context before sending any follow-up. |
| 2 | Mátyás compares New Leads vs Negative Replies button sets | The function/button SET on Negative Replies is identical to New Leads (same Send Emails, same Log Call; no extra booking control) | Copy: identical button labels across both columns · Look: matching action rows · Where: both card types | Button-set parity holds for both columns | Two columns must NOT expose different booking controls | No touchpoint for visual comparison. Any subsequent action (Send Emails, Log Call) creates its own touchpoint as normal. | Critique: Button parity is correct from a technical standpoint, but from a UX standpoint it may be too identical — there's value in slightly differentiating the negative flow to prompt the operator to consider a different message tone. Suggestion: Keep the same buttons, but change the 'Send Emails' button tooltip/hover text for Negative leads to: "Negatív válasz után – győződj meg róla, hogy a szöveg megfelelő" (a soft reminder, not a blocker). |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Mátyás opens the 'Move to' dropdown and picks '🚫 Negative Replies' | Card visually moves into the Negative Replies column immediately (optimistic UI) | Copy: card now under '🚫 Negative Replies' · Look: card in Negative Replies · Where: pipeline board | api_move runs; neg_reply=true AND stage_key set (the bug: only stage_key was set before) | Move must NOT only set stage_key; must also set neg_reply so deal_col derives negative | NEW ENTRY Type: Státusz változás · icon: 🔀 · label: "Áthelyezve: New Lead → Negative Replies" · description: "Manuális áthelyezés" · timestamp: now · operator: Mátyás |
Critique: The optimistic UI moves the card instantly, but if the Notion write fails (network issue), the card silently snaps back. The operator has no idea why the card "teleported" back. Suggestion: Show a brief "Mentve ✓" confirmation on the card for 2 seconds after a successful move, and a "⚠️ Nem sikerült menteni — próbáld újra" toast on failure. The success case is invisible today; make it explicit. |
| 2 | Mátyás reloads the board | AFTER RELOAD the card is STILL in Negative Replies — does NOT jump back to New Leads | Copy: card stays under '🚫 Negative Replies' after reload · Look: card persists · Where: pipeline board | deal_col(deal)==negative survives reload because neg_reply is persisted | Card must NOT jump back to New Leads after reload | No new touchpoint on reload. The Státusz változás entry from step 1 remains as the record. | Critique: The reload-persistence fix is correct, but the operator has no way to distinguish "this is a genuine Negative Reply" (from an incoming email) vs "I manually moved this here" from the card face. Suggestion: Add a tiny operator-initials badge to manual moves: "🔀 M" (Mátyás) next to the column label on the card. Distinguishes operator-moved from system-routed in the board view. |
| 3 | Mátyás moves the card BACK to New Leads via Move-to, then reloads | After reload, card is back under 'New Lead' — not in Negative Replies | Copy: card under 'New lead' after reload · Look: card in New Leads · Where: pipeline board | deal_col(deal)==new_lead after reload (neg_reply cleared) | Reverse move must NOT silently leave it in Negative Replies; both directions persist | NEW ENTRY Type: Státusz változás · icon: 🔀 · label: "Áthelyezve: Negative Replies → New Lead" · description: "Manuális visszahelyezés" · timestamp: now · operator: Mátyás |
Critique: Moving a lead BACK from Negative to New Lead is a significant operator decision (essentially "re-activating" a negative lead) but there's no confirmation or reason-capture. Suggestion: On back-move to New Lead, show a quick 1-field prompt: "Miért?" with preset options (Tévedés / Kedvező visszajelzés / Egyéb). This adds a 3-second audit step and builds a reason corpus for future analysis. |
| # | You do | You should see | Element that changes copy · look · where |
What changes underneath | Must NOT happen | 🕓 Touchpoint history | 💡 UX critique + suggestion |
|---|---|---|---|---|---|---|---|
| 1 | Mátyás clicks the 'Log Call' button on a card | Log Call panel shows EXACTLY TWO buttons: 'Book appointment' and 'Set FUP date' — nothing else | Copy: 'Book appointment' and 'Set FUP date' — only these two · Look: two buttons, no other fields by default (old redundant datetime-local GONE) · Where: inline Log Call panel under the card | Panel default state renders only the two entry buttons; standalone cs-{id} datetime-local picker is removed | Panel must NOT show the redundant standalone 'Book appointment (optional)' date-picker; no other fields shown until a button is clicked | NEW ENTRY (at click, before choosing an action) Type: Hívás rögzítve · icon: 📞 · label: "Hívás" · description: "Hívás rögzítve" · timestamp: now. Updated/replaced if the operator then books or sets FUP. |
Critique: "Log Call" as a button name is ambiguous — is it logging a past call or initiating a new one? Operators have reported confusion about whether clicking it sends anything. Suggestion: Rename to "📞 Hívás rögzítése" (slightly more explicit). Add a one-line panel header: "Mit szeretnél rögzíteni?" above the two buttons to frame the choice. Cost: 2 string changes. |
| 2 | Mátyás clicks 'Book appointment' | Optional CRM note field AND prefilled, fully-EDITABLE Meet event fields: title, description, outgoing email(s), body text, meeting time, duration | Copy: Title prefilled "ClientsFlow konzultáció — {name}"; body text prefilled; all editable; + note + time + duration · Look: form with prefilled but editable inputs · Where: expanded under 'Book appointment' button in Log Call panel | Event fields prefilled from the deal and remain user-editable before send | Fields must NOT be read-only; editing must NOT be blocked | No additional touchpoint yet — the touchpoint is created only when the operator clicks the blue 'Book appointment' send button (step 3). | Critique: The expanded form has 6 editable fields which can feel overwhelming after a sales call when the operator just wants to quickly log and move on. Suggestion: Collapse the low-frequency fields (description, duration) by default under a "Részletek ▾" toggle. Show only: time, recipient email, and note. Most calls just need those three. Advanced fields expand on demand. |
| 3 | Mátyás edits a field and clicks the single blue 'Book appointment' send button | The edited invite is sent only after the explicit blue 'Book appointment' click (human approve gate); booking created with edited values | Copy: blue 'Book appointment' button is the single send entry · Look: one blue button · Where: Book-appointment sub-form in Log Call panel | schedule_meeting runs with operator-edited event_name/email_body/time/duration; gcal invite sent | NOTHING sent without explicit click; AUTOSEND never flipped; ZZ fixtures only | UPDATED ENTRY Type: Foglalás (manuális) · icon: 📅 · label: "Foglalás · {datetime}" · description: "Időpont rögzítve, meghívó elküldve (manuális). Megjegyzés: {note}" · timestamp: now · initiated_by: operator |
Critique: After clicking the blue button there's no visible success state inside the panel — the panel just closes, leaving the operator wondering "did it go?" Suggestion: After successful send, show a 2-second in-panel confirmation: "✓ Meghívó elküldve · {datetime}" before the panel collapses. Also update the card's date badge optimistically before the backend confirms. |
| 4 | On a separate card, Mátyás clicks 'Log Call' then 'Set FUP date' | 'Set FUP date' reveals a NOTE field + a follow-up DATE picker only — nothing about booking an invite | Copy: note textarea + follow-up date input · Look: small form with note field + date picker · Where: expanded under 'Set FUP date' in Log Call panel | Follow-up date + note captured (logCall path with FUP date) | FUP path must NOT show Meet-event/booking fields; setting FUP must NOT send any invite or email | NEW ENTRY Type: Hívás + Visszahívás · icon: 📞 · label: "Hívás · FUP: {fup_date}" · description: "Visszahívás ütemezve: {fup_date}. Megjegyzés: {note}" · timestamp: now |
Critique: The FUP date picker has no context for what "follow-up" means in practice — is it a reminder for the operator, or does it trigger an automated sequence? Suggestion: Below the date picker, add a one-line grey note: "Emlékeztető neked: {fup_date}-án jelenik meg a Feladatok táblában. Automatikus email NEM megy ki." This sets clear expectations and prevents the operator from thinking they've set up an automated sequence. |