Combined EBO · ClientsFlow Pipeline · Whole-Journey QA
55 deduped rows / 12 journey stages · synthesized from 6 prior EBOs · plus the visual-QA screenshots
The final visual QA was driven mostly via the live API + DOM reads (full-page CDP captures timed out, so we switched to Playwright per-card shots). Below is the genuine pixel evidence for the Studio card.
A single ordered master of every behavior the ClientsFlow Pipeline system must exhibit across the entire sales journey, deduped and asserted once at its strongest seam. It was synthesized by unioning six prior Expected-Behavior Oracles:
| Source slug | Rows in | Description |
|---|---|---|
studio-pipeline-integration | 13 | Studio↔Pipeline integration (S1–S12 + INV) |
extended-ebo-2026-06-25 | 9 scenarios (B1–B6) | Touchpoint history + UX critique extension |
bnf-2026-06-24-r3 | 12 | Round-3 pipeline fixes (I1–I14) |
bnf-2026-06-23-duo2 | 14 | DUO-2 live-test bugs BUG-01..11 + features |
board-card-redesign | 17 | Board/stage/card behaviors |
live-test-bug-fixes | 11 | Post-call → sign → pay journey |
Pre-dedup source total: ~76 scenarios/rows across all sources Master rows after dedup: 55 rows (WJ-01 … WJ-55) Dedup principle: Many sources assert the same behavior (e.g. the red ❗ badge appears in both studio-S1 and bnf-2026-06-24-r3-S8). Each behavior is merged into ONE master row, asserted at the strongest observable seam, with all originating sources cited. No behavior appears twice.
Deployment state (correction 2026-06-25): the Studio↔Pipeline integration is BUILT and DEPLOYED — pipeline live at v110 (3cab5fa+v110), STUDIO_BASE_URL → the live Studio -rebuild instance (https://matyas--clientsflow-studio-rebuild-web.modal.run, all 8 API endpoints verified). The seam functions (studio_create_and_kick, studio_resume_on_url_save, studio_draft_send_message, studio_send_to_client, poll_studio_stages) and all dash UI (chip, badge, send modal, approval overlay, live-URL) are merged to main and deployed. The Studio rows (WJ-41..WJ-48) and WJ-26 are therefore drivable, not blocked.
QA buckets: live (driven by clicking the live dashboard / a ZZ sentinel deal in Chrome) · live-sim (drivable live but via API-injected state rather than a real external client action) · test (covered at a pytest seam) · blocked (needs a real external event / live infra not drivable with a sentinel).
---
_New lead arrives, website_url enrichment, name parser, cold-inbox "other" capture_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-01 | Enrichment fires automatically on new-lead entry and populates website_url, business fields, and legal info (entity type, tax number) — visible in Details panel before any booking | Details panel → Legal Information shows filled fields immediately after ingestion | — | No visual progress indicator shows enrichment is running — a blank card on arrival could be confused with a bug | blocked | bnf-2026-06-24-r3-S8, bnf-2026-06-23-duo2-S14, studio-S1 |
| WJ-02 | De-dup matches only on email address or unambiguous phone number — never website domain or company name; two people at the same company always get separate CRM cards | Board shows two separate cards when same website appears in two different sender emails | — | Dedup logic is invisible to the operator; a 'Új lead (nincs egyezés)' tag would build trust | live | bnf-2026-06-24-r3-S1 |
| WJ-03 | Cold-inbox "other" replies enter the pipeline as new cards; email touchpoints classified as 'Email' (icon/badge), NOT 'Note' (grey badge); none dropped | Board card present; history shows Email icon on both Outgoing and Incoming entries | Two 'Email' entries (Outgoing + Incoming) with email icon, full body text | Intermittent bug means first cold-email touchpoint sometimes renders as a grey 'Note' badge — unreliable classification signal | live | bnf-2026-06-23-duo2-S08, bnf-2026-06-23-duo2-S11 |
| WJ-04 | AI first-reply draft on new-lead arrival ends with the standard Mátyás signature block; nothing is auto-sent — draft waits for human approval in Outbox tab | Outbox tab shows draft with complete signature; ZZ lead's inbox has no email until approved | — | No badge or nudge on the board card indicating 'draft waiting for approval' | live | bnf-2026-06-23-duo2-S11 |
---
_Card render, red ❗ website-missing badge, sort toggles, "Move to" dropdown, pinned-to-top_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-05 | New-lead card renders with: lead name + company (Row 1), no sequence pill (Row 2), website + county (Row 3), email + phone chip (Row 4), HTML-stripped plain-text 'Their last message' (full body, no truncation), action row = exactly 'Log Call' + 'Send Emails'; card pulses red when unread | Board card in 'New Lead' column: pulse-red, no seq pill, clean plain-text message block, two-button action row | — | 'Their last message' includes signature block noise — a trim-signature heuristic would improve signal/noise ratio | live | board-card-redesign-S1, board-card-redesign-S3 |
| WJ-06 | If enrichment found no website URL, card shows a prominent red ❗ badge — the only thing blocking Studio booking auto-kick; saving a valid URL clears the badge without re-booking | Card face: red ❗ badge visible; saving a URL removes it | — | ❗ badge has no inline tooltip explaining what to do — first-time operator won't know to add a website URL | live | studio-S1, studio-S3, bnf-2026-06-24-r3-S8 |
| WJ-07 | Phone chip click copies the number to clipboard and shows 'Másolva ✓' tooltip that auto-dismisses after ~1.5 s | Card phone chip: click → clipboard holds number + tooltip appears and fades | — | Clean and correct; could add tel: link on mobile but desktop-first is appropriate here | live | board-card-redesign-S2 |
| WJ-08 | Status dropdown moves any card to any column instantly (optimistic UI); Notion syncs in background; real save failure shows error toast and returns card — never a silent snap-back | Card stays in target column after ≥2 reload cycles; error toast visible on simulated failure | Státusz változás touchpoint: icon 🔀, label 'Áthelyezve: {from} → {to}', Budapest timestamp | 'Áthelyezve' toast is ephemeral — no persistent indicator the move was manually vs system-initiated | live | board-card-redesign-S6, bnf-2026-06-23-duo2-S02, live-test-bug-fixes-S1 |
| WJ-09 | Negative Replies column cards show same 'Log Call' + 'Send Emails' button set as New Lead (no stray booking button or datetime-local picker); card stays in Negative Replies after reload (neg_reply flag persisted) | ZZ card in Negative Replies: stays after reload; action row shows only Log Call + Send Emails | Státusz változás entry on move; subsequent 'Send Emails' creates 'Sorozat újraindítva' touchpoint | Negative Replies card looks identical to New Lead — an operator without context of the negative reply has no quick indicator | live | extended-ebo-2026-06-25-S7, extended-ebo-2026-06-25-S8 |
---
_AI reply draft, human-gate approve→send, follow-up sequences, neg-reply handling_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-10 | 'Send Emails' opens sequence modal with pre-loaded copies; 'Send & schedule emails' button disables immediately on click (spinner) and is idempotent — rapid multi-click creates exactly ONE 'Szekvencia élesítve' touchpoint; intervals shorter than 5 min are blocked with a validation error | History after rapid multi-click: exactly one 'Szekvencia élesítve' entry; sequence modal shows validation error on <5 min input | Email 1: 'Sent' (green tag); Email 2: 'Scheduled' (yellow tag) with correct future date; one 'Szekvencia élesítve' system note | No preview of the 06:12–18:00 Mon–Fri send window in the modal — operators must remember from training | live | live-test-bug-fixes-S2, bnf-2026-06-23-duo2-S01, board-card-redesign-S7 |
| WJ-11 | After arming, card moves to 'Contacted — No Appointment Booked' with dim overlay + blue dashed animated border; hovering lifts the overlay, making the card fully readable without un-dimming the whole board | Card in Contacted: dimmed + blue dashed border visible; hover lifts overlay | Email 1 and Email 2 (scheduled) visible in history from WJ-10; no new touchpoint for column move | The hover-to-reveal interaction is not discoverable — no affordance on the dimmed card indicates hovering reveals content | live | board-card-redesign-S7, board-card-redesign-S10, bnf-2026-06-24-r3-S2 |
| WJ-12 | Sequence cron dispatches Email 2 at its due time (next cron tick after due timestamp); Email 2 flips from yellow 'Scheduled' to green 'Sent' in history — does not remain stuck 'Scheduled' indefinitely | History panel: Email 2 tag changes from yellow to green at/after due time | Email 2 entry updates from yellow 'Scheduled' to green 'Sent' | 'Scheduled' tag shows date but not time — operator can't tell if Email 2 fires at midnight or midday | live | bnf-2026-06-23-duo2-S01 |
| WJ-13 | Lead reply mid-sequence: sequence cancelled immediately; card resurfaces to TOP of 'New Lead' column with pulsing-red unread state; blue dashed border gone | Card leaves Contacted, appears at top of New Lead, pulse-red, seq armed=false | Incoming email touchpoint ('Email · Incoming') at top of history; 'Sorozat leállítva' system note below | Resurfaced card carries no indicator of prior sequence state — how many follow-ups went out before this reply is not visible on the card face | live | board-card-redesign-S11 |
| WJ-14 | Manual action (log call, book appointment) on an armed-sequence lead calls sequences.stop(), clears the blue dashed border, dim lifts after board reconciliation | After logging call/booking on dimmed-sequence card: blue dashed border disappears, dim lifted, seq_armed_at=null | Hívás rögzítve or Foglalás touchpoint + 'Sorozat leállítva' system note | Sequence-stop is silent — no toast confirming 'Szekvencia leállítva' when operator takes manual action | live | live-test-bug-fixes-S8, bnf-2026-06-23-duo2-S03 |
| WJ-15 | Reschedule and cancel confirmation emails show 'kattints ide' as an inline hyperlinked phrase — never a raw https:// URL as the visible link text; cancel link is working (not dead) | ZZ lead's inbox: reschedule/cancel email shows 'kattints ide' as clickable link, not raw URL; clicking cancel link actually works | — | Even with 'kattints ide' there's no appointment datetime in the link text — leads could accidentally cancel the wrong appointment | live | bnf-2026-06-24-r3-S3 |
---
_Own-booking, manual-booking parity → Sales-Call Prep + Booking-FUP arm, reschedule, Fireflies recording_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-16 | Unique per-contact booking link shows ONLY date+time picker + read-only email confirmation; no input fields; exactly 1 email sent (Meet invite, not two); card moves to 'Booked / Sales Call Prep' instantly; booking attaches to existing CRM contact (no duplicate created) | Booking page: no input fields; ZZ inbox: 1 email received; board: card moves to Booked instantly with 'New booking' toast | Foglalás touchpoint: icon 📅, label 'Foglalás · {datetime}', description 'Időpont foglalva, naptármeghívó kiküldve', Budapest timestamp | Booking confirmation page lacks a 'Következő lépések' block — missed onboarding moment for the lead | live | bnf-2026-06-23-duo2-S04, bnf-2026-06-23-duo2-S10, bnf-2026-06-24-r3-S4 |
| WJ-17 | Booked card stays DIMMED while appointment is >1 day away; dim lifts at 00:00 on the calendar day BEFORE the appointment; booking-follow-up sequence is disarmed on booking and its scheduled email entries disappear from history | Booked card: dim overlay present when >1 day away; history shows no 'Scheduled email' rows from booking-fup sequence | Booking touchpoint at top of history; no queued 'Scheduled email' rows | Booked card shows appointment date but no countdown — a '3 nap múlva' label would give glanceable urgency | live | bnf-2026-06-24-r3-S4, board-card-redesign-S12, board-card-redesign-S15 |
| WJ-18 | Booking slot grid shows only 30-min slots on weekdays 08:30–18:30 Europe/Budapest; GCal busy blocks excluded; 15-min buffer after each existing booked call enforced (no back-to-back) | Booking page slot grid: no weekend slots, no out-of-hours, no slots within 15 min after a booked call | — | No timezone label visible on the slot grid — international leads may assume their local timezone | blocked | bnf-2026-06-24-r3-S5 |
| WJ-19 | GCal invite created with lead + rep (matyas@clientsflow.hu) as attendees and sendUpdates='all'; on DWD/config failure: warning touchpoint + orange badge on card face; QA does NOT mark step green on failure | ZZ lead's inbox: receives GCal invite; on failure: card shows orange warning badge + system warning in history | Foglalás touchpoint + optional 'Rendszerfigyelmeztetés: Naptár meghívó sikertelen' system entry (grey) on failure | Failed invite is invisible on the card today — a failed invite directly causes no-shows, making the orange badge high-priority | blocked | extended-ebo-2026-06-25-S5, extended-ebo-2026-06-25-S6 |
| WJ-20 | Manual booking via Log Call → 'Book appointment': form shows prefilled-but-editable fields; invite sent only on explicit blue 'Book appointment' click; Foglalás touchpoint logged even if GCal fails (fail-open with warning toast) | Log Call → Book appointment: form with prefilled+editable fields; after submit: Foglalás (manuális) touchpoint in history; GCal fail: warning toast + touchpoint still logged | Foglalás (manuális) touchpoint: icon 📅, label 'Foglalás · {datetime}', description 'Időpont rögzítve, meghívó elküldve (manuális). Megjegyzés: {note}' | After blue 'Book appointment' click the panel just closes — operator unsure if invite was sent; a 2-second in-panel confirmation would close this feedback gap | live | extended-ebo-2026-06-25-S9, live-test-bug-fixes-S7, board-card-redesign-S8 |
| WJ-21 | Lead-side reschedule succeeds: original GCal event deleted, new event created; card stays in 'Booked' showing NEW date; reschedule touchpoint (old → new datetime) appended; 'időpont közben elkelt' error must NOT appear | Lead-side reschedule page: success message, not error; card in Booked column shows new date; history has 'Átütemezés' entry with both old and new datetime | Átütemezés touchpoint: icon 🔄, label 'Átütemezés', description 'Régi: {old datetime} → Új: {new datetime}', initiated_by: lead | Reschedule success page confirms new time but not deletion of old — lead might wonder if they have two appointments | blocked | extended-ebo-2026-06-25-S3, extended-ebo-2026-06-25-S4, bnf-2026-06-23-duo2-S06 |
| WJ-22 | Manual GCal reschedule (operator moves event in Google Calendar) logged as 'reschedule' touchpoint with source=manual (old_time → new_time, via gcal_watch); card meeting time updated; no duplicate booking touchpoint created | Move a GCal event manually: board card shows updated datetime; history shows reschedule (source=manual) touchpoint with both old and new times | Reschedule touchpoint (source=manual): icon 🔁, description 'Manuális átütemezés: {old_time} → {new_time}' | Card face doesn't distinguish rep-initiated from lead-initiated reschedule — a 'Manuális' label on the date badge would clarify | blocked | studio-S12, studio-pipeline-integration-EBO-11 |
| WJ-23 | Booking widget gives instant feedback: confirm click → button disables + spinner immediately; optimistic success state ('Booking… → Confirmed ✓') within ~2 s independent of backend completion | Booking widget: button disables + spinner immediately after click; success state within 2 s; no frozen UI | — | Optimistic success before backend confirm means a late backend failure delivers a confusing success-then-error experience | live | bnf-2026-06-23-duo2-S05 |
---
_Transcript ingest, AI extract, call summary, log-call touchpoints_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-24 | Fireflies transcription: bot-free Meet recording used if confirmed available; otherwise Fireflies Note Taker bot auto-joins at ≥2 real participants, named 'Note Taker' with plain/boring avatar; bot must NOT join 1-person call | 2-participant ZZ call: 'Note Taker' appears in participant list (not 'Fireflies AI Notetaker'); transcript lands in CRM | — | Bot appearing as a participant might confuse the lead into thinking a third person joined their private call | blocked | bnf-2026-06-24-r3-S6 |
| WJ-25 | Sales Call/Proposal card shows: (1) 'Sales call megvolt · {X} perc' status pill and (2) transcript-status tag cycling 'Transcript: betöltés…' → 'Transcript: hiányzik' → 'Transcript: megvan'; 'megvan' must not appear when no transcript exists in CRM | Sales Call card: both pills present; 'megvan' appears only after transcript confirmed in CRM | Sales call touchpoint: icon ☎, label 'Hívás', description with duration | 'hiányzik' tag gives no next step — operator doesn't know if they should wait, upload manually, or re-trigger | live | bnf-2026-06-24-r3-S7 |
| WJ-26 | Call transcript saved into CRM AND auto-pushed into Studio intake; summary generated alongside full transcript; both stored in collapsible toggles in BOTH touchpoint-history panel AND Details panel; only real call transcript pushed — never warmup/no-show noise | After transcript ingest: history panel and Details panel both show collapsible toggles with full transcript + summary; Studio intake received the push | Transcript touchpoint with collapsible toggle containing full transcript + summary; same in Details panel | Two different panels show the same transcript — a 'Ugyanaz a forrás' note or cross-link between the two would clarify which is canonical | live | studio-S6, studio-pipeline-integration-EBO-5 |
| WJ-27 | Manual log-call timestamps render in Budapest local time in the History feed (14:15 Budapest → displayed '14:15', not '12:15' UTC) | History touchpoint timestamp: logged at 14:15 Budapest; displayed timestamp reads '14:15' | Hívás rögzítve touchpoint with correct 14:15 Budapest timestamp | Table-stakes correctness; no UX critique needed | live | bnf-2026-06-23-duo2-S07 |
| WJ-28 | Logged call touchpoint header reads 'Phone call' (human-readable label) with operator notes below — not a raw backend string/UUID | History feed header: reads 'Phone call' with notes below, not 'event_type_sales_call_init' or similar | Hívás rögzítve entry: header 'Phone call', body = operator notes | 'Phone call' is English in an otherwise Hungarian dashboard — consistent with the ENGLISH Control Panel UI rule | live | bnf-2026-06-23-duo2-S09 |
---
_Proposal generation, discount/promo copy line, DocuSeal 3-part sign, proposal page_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-29 | Post-call wizard Step 1 sets agreed_price, price_expiry_date, proposal_due_date, and price_after_expiry (price × 1.25); Step 2 proposal preview always includes the deterministic price box: discounted price + struck-through anchor price + 'érvényes {exp}-ig aláírva — 20% kedvezmény' | Proposal preview and DocuSeal doc part 1 both contain price box with struck-through anchor price and expiry date | — | Post-expiry price (× 1.25) is stored but not shown in Step 1 — displaying the calculated value makes the consequence explicit | live | live-test-bug-fixes-S1, live-test-bug-fixes-S9 |
| WJ-30 | Proposal creation + schedule emails moves card to 'Sign-Follow-Up' column INSTANTLY (optimistic UI) — no ~1-minute poll/cron wait | Card appears in Sign-Follow-Up immediately after action (< 2 s); no page refresh required | Proposal sent (OUT) touchpoint at send time; proposal_chase sequence DEFINED un-armed | Instant move is correct but operator may miss the column change if looking away; brief highlight animation on arrival would draw the eye | live | bnf-2026-06-24-r3-S9, live-test-bug-fixes-S1 |
| WJ-31 | 'Route for approval' button shows spinner and disables while request runs — double-click is a no-op; /review page opens in a new tab | Click 'Route for approval': button disables + spinner immediately; second click is no-op; /review tab opens | — | /review tab opening in a new tab can be blocked by pop-up blockers silently; a fallback inline toast with the URL would prevent silent failure | live | live-test-bug-fixes-S1 |
| WJ-32 | New lead entry triggers scraper + AI legal/CRM extraction; generated contract is pre-populated with legal entity type and tax number from CRM; enrichment must not silently no-op | Generated contract (DocuSeal part 1): legal entity type and tax number pre-filled; no blank legal fields when CRM has them | — | If enrichment ran but found no legal data, blank contract fields only surface at generation time — too late; an early 'Legal info: nem található' badge would surface the gap sooner | blocked | bnf-2026-06-24-r3-S8 |
| WJ-33 | Self-sent proposal email re-ingested by Missive is recognized as outbound and dropped — NOT logged as 'Incoming reply', does NOT cancel proposal-chase sequence, does NOT resurface card to New Lead | After proposal send: Missive re-delivers to webhook; history gains NO 'Incoming reply' touchpoint; card stays in Sign-Follow-Up; sequence stays armed | No touchpoint created for self-sent mail re-ingestion; existing 'Proposal sent (OUT)' is the only record | Guard firing is invisible — if it malfunctions, there's no audit trail of what was dropped; a grey 'Saját levél kiszűrve' system note would help | live | live-test-bug-fixes-S6 |
---
_Contract signed stage, sign-follow-up sequence_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-34 | Sign-Follow-Up card shows three tags: (1) next-call-date, (2) 'Ajánlat érvényes: {date}' offer-validity, (3) 'Emlékeztető {n}/{m}' reminder index | Sign-Follow-Up card face: three status pills visible | Reminder emails logged as outbound 'Email (OUT)' touchpoints as they send | Three pills may crowd the card if lead name is long; offer-validity date is most decision-critical and should be most visually prominent | live | bnf-2026-06-24-r3-S10 |
| WJ-35 | Signed deal with stage_key=contract_signed and days_in_stage > PAYMENT_OVERDUE_DAYS (default 3) shows a red overdue border; a freshly-signed card has no red border | Board card in 'Proposal Signed / Fizetés FUP': red border when overdue; no border on fresh-signed card | — | Red border is passive — overdue-payment cards should also surface as task cards in the 'Today' tab to make the prompt active | live | live-test-bug-fixes-S5 |
---
_Deposit→WON, balance/végszámla, Stripe, onboarding email draft + task_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-36 | On DocuSeal both-signed, payment reminder sequence self-arms automatically (owner-approved exception); first payment email sends immediately with Stripe pay link + bank-transfer details + exact amount; ~5 reminder emails drip at 1–2 day gaps; sequence stops as soon as payment is detected | DocuSeal webhook fires: card enters contract_signed, payment seq armed without manual click; ZZ inbox receives email #1 with Stripe link + utalási adatok + pontos összeg | Contract signed touchpoint; Email #1 outbound touchpoint immediately after; reminder emails as outbound touchpoints until seq stops | No acknowledgment to the operator that self-arm happened; a system note 'Fizetési emlékeztető szekvencia automatikusan élesítve' would document the exception | live | bnf-2026-06-24-r3-S11, live-test-bug-fixes-S3 |
| WJ-37 | Stripe checkout opens with lead's email pre-filled (prefilled_email on session); no billing address requested (already on contract) | Stripe TEST checkout: email field pre-filled with lead's email; no billing address form | — | Checkout has no reference to the contract or project — a description line 'ClientsFlow honlap csomag — {deal_name}' would reduce checkout drop-off | blocked | bnf-2026-06-24-r3-S11 |
| WJ-38 | Stripe TEST payment completes → card moves to 'Payment Arrived / Adatbekérő FUP'; payment reminder sequence stops; DocuSeal auto-emails signed PDF to both parties (no manual DocuSeal click required) | After Stripe TEST checkout.session.completed: card in 'Payment Arrived / Adatbekérő FUP'; seq_armed_at=null; signed PDF arrives by email | deposit_paid touchpoint; 'Fizetési emlékeztető szekvencia leállítva' system note; 'Szerződés aláírva (PDF)' document touchpoint | 'Payment Arrived' column name is English in an otherwise Hungarian-mixed UI — standardizing to Hungarian would improve visual coherence | blocked | live-test-bug-fixes-S4, bnf-2026-06-24-r3-S12 |
| WJ-39 | DocuSeal contract signature-date field is labelled 'Aláírás dátuma' (renamed from 'Megbízó dátum') | DocuSeal contract: client signature date field label reads 'Aláírás dátuma' | — | 'Aláírás dátuma' is unambiguous; old label was confusing about whether it meant contract date vs company founding date | live | live-test-bug-fixes-S11 |
---
_Portal row, onboarding task_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-40 | After deposit_paid, card is in 'Payment Arrived / Adatbekérő FUP'; onboarding email draft generated for human review in Outbox; onboarding task appears in Feladatok tab; later stages (waiting_dev+) map to ongoing_build column | Board: card in 'Payment Arrived / Adatbekérő FUP' after Stripe payment; Feladatok tab: onboarding task visible; Outbox: draft pending human approval | deposit_paid touchpoint; onboarding task creation note in history | Onboarding email draft in Outbox but no task card in 'Today' tab nudging the operator — draft can age unnoticed | blocked | live-test-bug-fixes-S4 |
---
_S1–S12: auto-create project on booking, Lab kick, status chip, transcript→Studio, send-to-client human-gated, comment/approve overlay, won→live URL, lost→archive, waiting_dev soft-removal_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-41 | Booking of URL-present deal: Studio project auto-created (crm_ref=deal_id, idempotent), Lab auto-kicked (home-page design + SEO audit + structure), single Studio chip walks 🎨 Dizájn készül → ✅ Dizájn kész; booking not blocked if Studio is slow (fail-open) | Card in Booked: chip shows '🎨 Dizájn készül'; after Lab completes: '✅ Dizájn kész'; re-triggering creates no duplicate project | studio_created (🎨) + studio_generating (⚙️) at booking; studio_ready (✅) when Lab completes | Chip gives no ETA for when design will be ready — an estimated time or progress % would reduce uncertainty before a sales call | live | studio-S2, studio-pipeline-integration-EBO-1 |
| WJ-42 | Booking on red-❗ deal: no Studio project, no Lab kick; URL-prompt shown (studio_deferred=true); saving a valid URL clears ❗ and auto-kicks Studio — no re-booking, no manual project creation | Book a card with ❗: no Studio chip appears; save a URL: ❗ clears and Studio chip appears without re-booking | No Studio touchpoints until URL saved; then studio_created + studio_generating at URL-save time | URL prompt competes with other card elements — should be the most prominent visual element when it's the only blocker, ideally a full-width orange banner | live | studio-S3, studio-pipeline-integration-EBO-2 |
| WJ-43 | 'Open in Studio' button deep-links to the deal's Phase-1 project; Phase-1 is sales-aid only — nothing emailed to the prospect | Click 'Open in Studio' on Booked card: Studio opens on the correct deal's project; no outbound email triggered | — | Deep-link depends on Studio being in the correct state; a fallback Studio project URL in the history panel would handle failures | live | studio-S4 |
| WJ-44 | Exactly ONE Studio status chip on the card face, cycling: 🎨 Dizájn készül / 📤 Elküldve / 💬 Ügyfél véleményez / ✅ Jóváhagyva; read-only (Studio owns it); does not go permanently stale | Card face: exactly one chip; chip state matches Studio's actual state; chip updates within one board refresh cycle | Each chip state change → Studio milestone touchpoint in history | Chip is purely reflective — operator cannot force a Studio state refresh; a rate-limited 'Refresh Studio state' button would help when chip appears stale | live | studio-S5, studio-pipeline-integration-EBO-4 |
| WJ-45 | 'Send to client' button on BOTH pipeline card and Studio opens same modal (AI-drafted message + review link); nothing sends on click — human clicks 'Küldés'; chip flips to 📤 Elküldve; both surfaces reflect 'sent' immediately to prevent double-send | Click 'Send to client' on card: modal opens with AI draft + review link; click 'Küldés': chip → 📤 Elküldve on card and in Studio; no second send possible | studio_sent touchpoint: icon 📤, label 'Design elküldve az ügyfélnek', includes review link, initiated_by: operator | Dual send paths (card + Studio) require both surfaces to reflect 'sent' simultaneously — failure to sync would allow a double-send. QA: confirm AI draft + review link in the modal; do NOT click 'Küldés' against anything but a ZZ sentinel (human gate) | live | studio-S7, studio-pipeline-integration-EBO-6 |
| WJ-46 | On client approval in Studio: card gains pulsing green overlay ('✅ Dizájn jóváhagyva'); hover shows two buttons ('Move to next stage' and 'Move to next stage + open in Studio'); pipeline does NOT auto-advance; stage moves only on explicit human click | Client approves in Studio: pipeline card gains pulsing green overlay; hover shows two buttons; clicking one advances stage | studio_approved touchpoint: icon ✅, label 'Design jóváhagyva', initiated_by: client | Two hover buttons are almost identical in action — making their icons clearly distinct would prevent clicks under time pressure. QA: set the Studio project approved via the -rebuild API, then confirm the pipeline card reflects the overlay after a poll/refresh | live-sim | studio-S9, studio-pipeline-integration-EBO-8 |
| WJ-47 | Won deal: NO separate 'Dev handoff' pipeline state; won project published live via Cloudflare API from Studio; live URL reflected back on deal card; Dani sees the same single pipeline view — no separate handoff board | Won deal card: live URL link to published site; no separate handoff column visible; Dani's view is the same board | studio_won touchpoint (🎯); studio_published touchpoint (🌐) with live URL | Collapsing dev handoff into Studio simplifies the workflow; main risk is Dani needing a documented SOP for which stage = his work. QA: drive trigger_won; live URL reflects on the card (Cloudflare publish is real Studio-side — tag any real-publish dependency as a residual) | live-sim | studio-S11, studio-pipeline-integration-EBO-10 |
| WJ-48 | Marking deal 'Lost' auto-archives (never deletes) the linked Studio project; chip reflects '🗄️ Studio archiválva'; no orphan active Studio project left | Mark booked ZZ deal as Lost: Studio project archived (not deleted); card chip reads '🗄️ Studio archiválva'; project recoverable from Studio | studio_archived touchpoint: icon 🗄️, label 'Studio projekt archiválva', initiated_by: system | Archive-not-delete is correct, but no 'Restore' link on the chip tooltip to recover from the pipeline side | live | studio-S10, studio-pipeline-integration-EBO-9 |
---
_Cancel success page polish + cancel logged as touchpoint_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-49 | Lead clicks cancel link: full-page 'Időpont lemondva' confirmation (no error); card moves Booked → 'Contacted — No Appointment Booked'; RED 'Lemondás · {date}' badge on card face (cancellation date, not original booking date); Lemondás touchpoint (🚫) logged; NO automatic email sent; AUTOSEND stays OFF | Cancel link → confirmation page; board card moves to Contacted; red badge 'Lemondás · {date}' on card face; history: Lemondás touchpoint; ZZ inbox: zero new emails | Lemondás touchpoint: icon 🚫, label 'Lemondás · {date}', description 'Időpont lemondva', Budapest timestamp; NO email outbound touchpoint | Cancel link text is generic ('Lemondás') with no datetime — lead might not know which appointment they're cancelling if they have multiple interactions | live | extended-ebo-2026-06-25-S1, extended-ebo-2026-06-25-S2 |
| WJ-50 | Cancellation history touchpoint renders with 'Lemondás' label (not 'Call booked') and a visually distinct badge; colour-coding principle: red = cancellations/negatives; green = bookings; blue = emails; grey = system notes | History panel after cancellation: top entry shows 🚫 Lemondás pill, NOT 'Call booked' pill; badge colour is red, distinct from booking entries | See WJ-49 | Consistent colour-coding would make history scannable at a glance — single highest-value history UX improvement | live | extended-ebo-2026-06-25-S1 |
---
_Human gate; AUTOSEND stays as-is; ZZ sentinel only; Notion archive-not-delete; touchpoint colour-coding_
| ID | Behavior | Strongest seam | 🕓 Touchpoint history | 💡 UX critique | QA bucket | Sources |
|---|---|---|---|---|---|---|
| WJ-51 | Human gate: nothing sent to a lead/client without explicit human action (Jóváhagy / Küldés click); sole approved exception is payment-reminder sequence self-arm on DocuSeal both-signed (owner-authorized, documented); AUTOSEND never flipped during testing | Any test: ZZ lead's inbox receives no email unless operator explicitly approved; AUTOSEND=false verified before each test run | — | AUTOSEND flag is invisible on the dashboard until navigating to a specific settings area; a persistent header badge 'AUTOSEND: OFF' (green) would prevent accidental sends | live | board-card-redesign-S7, live-test-bug-fixes-S2, bnf-2026-06-24-r3-S11, studio-S7, CLAUDE.md-invariants |
| WJ-52 | ZZ sentinel rule: all test deals use ZZ-prefix names; after each test run, ZZ deals are purged via Test Drive → ZZ purge; no live lead data used in QA | After test run: Test Drive ZZ purge completes; no ZZ-prefixed cards remain on the board | — | ZZ purge is a manual step that could be forgotten — a post-test 'teardown' endpoint would make the test lifecycle self-cleaning | live | board-card-redesign-S7, CLAUDE.md-invariants |
| WJ-53 | Notion destructive ops use archive (PATCH /pages/{id} {'archived': true}), never permanent DELETE; lost-deal Studio project archived (never deleted); all manual stage overrides are allowed (no locked stages) | Any delete/archive action: Notion API call is PATCH with archived:true; Studio project on lost deal shows archived status but is recoverable | — | Archive-not-delete is completely invisible to the operator — an 'Archívum' read-only tab would make the safety net discoverable | test | studio-S10, bnf-2026-06-23-duo2-S02, CLAUDE.md-invariants |
| WJ-54 | Instantly warmup mail (campaign IDs 8ZP8HWG, i-am-happy, DMARC-related) is never logged to Notion and never appears on the pipeline board; auto-archived in Missive (not deleted) | Warmup emails: not in any deal's touchpoint history; not in Notion; auto-archived in Missive inbox | — | If the warmup filter ever breaks, warmup mail will flood pipeline history — a daily health check counting dropped warmup messages would catch regressions early | test | CLAUDE.md-invariants |
| WJ-55 | Dim logic: card DIMMED when deadline is in the future OR on automated sequence; ACTIVE (no overlay) when due date is today or overdue; booked call on appointment day is ACTIVE even if on a sequence (due≤today wins over sequence-dim); overdue cards must never be wrongly dimmed | Board: overdue card is undimmed; future-deadline card is dimmed; today's appointment card is undimmed even if on a sequence | — | All dimmed states use the same dark grey overlay — a card dimmed by a sequence looks identical to one with a future deadline; different border styles per reason would help triage | live | board-card-redesign-S15, bnf-2026-06-24-r3-S4 |
---
_Updated for the v110 Studio-integration deployment (2026-06-25). New live-sim bucket = drivable live but via API-injected state rather than a real external client action._
| Stage | Row count | live | live-sim | test | blocked |
|---|---|---|---|---|---|
| 1 — Ingestion & enrichment | 4 | 3 | 0 | 0 | 1 |
| 2 — New lead on the board | 5 | 5 | 0 | 0 | 0 |
| 3 — Contacted / sequence | 6 | 6 | 0 | 0 | 0 |
| 4 — Booked | 8 | 4 | 0 | 0 | 4 |
| 5 — Sales call & transcript | 5 | 4 | 0 | 0 | 1 |
| 6 — Proposal | 5 | 4 | 0 | 0 | 1 |
| 7 — Sign / follow-up | 2 | 2 | 0 | 0 | 0 |
| 8 — Payment | 4 | 2 | 0 | 0 | 2 |
| 9 — Onboarding | 1 | 0 | 0 | 0 | 1 |
| 10 — Studio design loop | 8 | 6 | 2 | 0 | 0 |
| 11 — Cancellation | 2 | 2 | 0 | 0 | 0 |
| 12 — Cross-cutting invariants | 5 | 3 | 0 | 2 | 0 |
| TOTAL | 55 | 41 | 2 | 2 | 10 |
---
These rows CANNOT be driven with a ZZ sentinel in the live QA. Each is listed with its reason; the orchestrator must flag these as human-action residuals in the QA report.
| ID | Reason blocked |
|---|---|
| WJ-01 | Needs real new lead entering from zero via Missive/webhook; enrichment silently no-ops on manually-moved deals |
| WJ-18 | Requires Google Calendar with pre-populated busy blocks and DWD configured |
| WJ-19 | Requires DWD / GCAL_DRIVEN_CONFIRMATION enabled on Google Workspace; owner action: 'enable DWD calendar scope / GCAL_DRIVEN_CONFIRMATION' |
| WJ-21 | Lead-side reschedule requires a ZZ lead with a real booking; GCal event replace cannot be faked without real GCal access |
| WJ-22 | Requires Google Calendar domain-wide delegation (gcal_watch) live and configured |
| WJ-24 | Requires a real 2-person Google Meet call; Fireflies bot-free criteria must be verified via research; DWD config needed |
| WJ-32 | Needs a real new lead entering from zero (not manually moved) for enrichment to trigger |
| WJ-37 | Real card charge not drivable with a ZZ sentinel; the prefilled-email checkout PAGE rendering needs a real Stripe checkout. PARTIAL live-sim: the Test Drive tab simulates checkout.session.completed via handle_stripe_event (covers the downstream WON/onboarding effects, not the checkout page itself). Stripe still in TEST mode |
| WJ-38 | Real card charge not drivable with a ZZ sentinel. PARTIAL live-sim: Test Drive tab simulates checkout.session.completed via handle_stripe_event, so the card-move to 'Payment Arrived' + sequence-stop CAN be exercised; DocuSeal signed-PDF auto-email still needs config verification |
| WJ-40 | Downstream of Stripe payment. PARTIAL live-sim: Test Drive tab simulates checkout.session.completed via handle_stripe_event, so the onboarding email draft + task generation CAN be exercised (draft stays human-gated in Outbox); no real card charge drivable |
Summary: 10 blocked rows (down from 17 after the v110 Studio-integration correction). Of these: 4 are blocked by real GCal/DWD configuration (WJ-18, WJ-19, WJ-22, WJ-24); 3 are blocked by Stripe real-charge state but have a PARTIAL live-sim path via the Test Drive handle_stripe_event simulator (WJ-37, WJ-38, WJ-40); 2 are blocked by needing a real new-lead entry (WJ-01, WJ-32); 1 is blocked by lead-side GCal event deletion (WJ-21).
Reclassified out of blocked (v110 correction): WJ-26, WJ-41, WJ-42, WJ-43, WJ-44, WJ-45, WJ-48 → live (Studio integration deployed at v110, STUDIO_BASE_URL → -rebuild, 8 endpoints verified); WJ-46, WJ-47 → live-sim (drivable via the -rebuild API to inject the approved / won state, then verify the pipeline card reflects it after a poll/refresh).