Goal
Закрыть 4 пункта из CONV-22 What's Next по §6 User Journeys (Sales Agent ↔ Buyer flow):
- D — status protection (unit status flip Available→Reserved/Sold) + E — buyer↔unit linkage — unified mechanism (decision локальное в CONV-22 line 42, deep spec потерян, нужна reconstrucция)
- F — request-more (buyer запрашивает additional units / unit pages) — wholly new design space, deferred Open Question
- G — channels (Email + WhatsApp + Copy link для отправки tokenised presentation links) — wholly new
Pattern Chunks 3/4: surgical правки + 2 новые subsections в §6 + light phase callouts (1.10, 1.4) + small §4.2 Permissions matrix touch. Все изменения внутри launch-plan-stage-1.html + changelog v4.9 + workstream update.
Locked Decisions (CONV-25 interview)
D + E — Status-change form + buyer↔unit linkage (unified)
| # | Тема | Решение |
|---|---|---|
| D1 | Form shape | (i') Augmented single-click verification form. Sales Agent в админке открывает unit card → нажимает «Mark as Reserved» / «Mark as Sold» (status implicit from button) → modal с полями. Roman'у соответствует «verification form» semantics из §1 SA definition cross-link. Frictionless когда buyer уже в системе. |
| D2 | Required fields | Email buyer'а — единственное всегда-required поле. Если email matches existing buyer-record для этого Sales Agent'а → name + phone displayed read-only (не дублируется ввод). Если email НЕ matches existing record → name + phone становятся required (создаётся новый buyer-record). |
| D3 | Optional fields | Notes (free text, в неё можно вписать deal value, conditions, комментарий) + File upload (PDF / JPG — signed booking letter, deposit receipt, etc.). |
| D4 | Status mechanic | Status выбирается кликом по кнопке («Mark as Reserved» / «Mark as Sold»), не отдельным dropdown'ом в форме. Reduces clicks, mistake-proof кнопки чётко разделены. |
| D5 | Auto-fill после email match | Из existing buyer-record: name + phone (read-only display, not editable inline), token history (для smart-match attribution). Sales Agent видит «<strong>Buyer found:</strong> Иван Петров, +971 50 123 45 67 — ваш buyer от 12 апреля». |
| D6 | Reverse direction policy | (a) Симметричная. Same permissions per <a href="#fd-access">§4.2</a> «Change unit status» row — Owner ✅, Admin ✅, SM ✅, CE —, SA ✅ (own assigned). Reverse-flip = Sold→Reserved, Sold→Available, Reserved→Available. Sales Agent fixes own mistakes без эскалации. Audit log catches abuse. |
| D7 | Reverse-flip notification | Каждый reverse-flip → audit log entry + email notification к Sales Manager'у (если SA откатывает); reverse-flip от Sales Manager'а → notification к Owner / Admin. Forward-flip не требует notification (стандартный workflow); reverse — «interesting event», visible by default. |
| D8 | Buyer-record fate при reverse | Buyer-record остаётся в DB (history preserved, attribution для commission). Unit↔buyer link воидится (audit log: «User X reverted Sold → Reserved at TIMESTAMP, voided link to Buyer Y»). Re-flip forward (Reserved→Sold) re-fills the form — если same email, auto-link recreates от existing buyer-record; никаких stale link'ов в DB. |
Smart-match logic (E side)
Когда Sales Agent вводит email в форме:
- Lookup в buyer-records этого Sales Agent'а (org-scope) — если email matches existing buyer для этого SA → display banner «Buyer found: <name>, <phone>» + auto-link.
- Если match не найден в SA's buyer-records, lookup в Organisation-wide buyer-records — если найден → display warning «Buyer <name> existing, attributed to <other Sales Agent>. Continue?» (UX decision: повторно использовать запись или новый record per SA — gut feeling per CONV-22 «разные buyer-records под одним email, разная attribution» — создаём новый record для текущего SA).
- Если ни там, ни там → name + phone становятся required, создаётся новый buyer-record, attribution = текущий SA.
G — Channels (Sales Agent отправляет presentation link)
| # | Тема | Решение | ||
|---|---|---|---|---|
| G1 | Channels в scope Stage 1 | Email + WhatsApp + Copy link (3 канала). SMS dropped — низкий ROI vs vendor pain (Twilio account, carrier compliance for int'l). Deferred Stage 2 если попросят. | ||
| G2 | Implementation approach | Light deep-link approach. Email = native через Phase 1.8 backend (SES / Mailgun, как уже в plan'е). WhatsApp = https://wa.me/<phone>?text=<encoded message> — открывает SA's own WhatsApp с предзаполненным message; SA жмёт «Send». Copy link = clipboard. Ноль vendor integrations, ноль compliance overhead. |
||
| G3 | Tracking | URL parameter — `?ch=email | wa | link` добавляется к buyer-token URL'у когда SA выбирает channel. Backend увеличивает counter «N opens per channel per project». В analytics видно «WhatsApp converts лучше для UAE buyer'ов» — для product decisions. |
| G4 | Default message text | Pre-filled на Org locale (fall-back English): «Hi <buyer_name>, here's the presentation we discussed: <link>». SA редактирует inline в admin'е перед клик'ом «Send». Отдельные templates per channel — Stage 2 (если попросят). | ||
| G5 | Edge cases | (a) Phone не заполнен для WhatsApp → button disabled с tooltip «Phone required for WhatsApp». (b) Multiple channels одновременно — same buyer-token URL, разный ?ch= параметр; одна buyer-record, multi-channel attribution counter. SA может send via Email + WA одновременно («не уверен какой buyer чаще проверяет»). (c) Buyer открывает link не из того канала где SA отправил (forwarded email → buyer открывает в WhatsApp web) — ?ch= parameter preserved, attribution unchanged, но channel counter показывает «opened via Email channel» по URL parameter, не по browser context. Это intentionally simple — не отслеживаем cross-channel migration. |
F — Request-more (DEFERRED)
F-A: Какой scope доступа у buyer'а с валидным token'ом помимо самой ссылки в email'е — Open Question, 2 candidate variants для Roman ratification:
- Variant (i) — Token = elevated visitor для всего project'а. Buyer гуляет по проекту с эффективным Full sales preset (видит все units, цены, availability badges, рендеры, 360° tours) — независимо от Public Visibility setting. Hearts ANY unit → notification к Sales Agent'у. Mental model: «Sales Agent привёл buyer'а в офис показывать проект — buyer видит всё». Self-serve discovery — buyer находит дополнительные интересные units и сам hearts'ит без необходимости звонить SA. Explicit «Request more options» CTA становится опциональным — heart-based discovery покрывает 80% use case'ов. CTA опционально живёт на unit-page как small «Show me similar» — notify'ит SA с контекстом «buyer wants something close to unit X».
- Variant (iii) — Token = elevated до Discovery preset, but не Full sales. Buyer видит project с renders + 360° + floorplate + counter «N units», но без цен и individual unit pages — только token'd unit pages открыты в Full sales. Owner'у даётся Stage 1 toggle «Allow buyer-token full project access» (per-project) который elevates до Variant (i). Default = mid-conservative. Plus: explicit «Request more options» CTA на unit-page обязательна (notify SA → SA sends new email с new tokenised links).
Решение по F-A влияет на:
- Phase 1.10 sales-app routing (token state filter)
- Buyer experience UX (passive vs active discovery)
- Owner control (locked-down vs elevated default)
Decision deferred до Roman call / next /plan iteration на §6 (post-Wave 2). В этом chunk'е F-A документирован обоими candidate'ами в Open Questions section с UX implications для каждого; mini-patch после ratification обновит §6.
Approach
Approach B (New §6.1 + §6.2 subsections):
- §6 lead — light intro mention про §6.1 / §6.2 (no major rewrite)
- Новая §6.1 — Sales Agent status-change form (D+E unified mechanism) — full spec (form fields, smart-match logic, triggers, reverse-direction policy, buyer-record fate, audit, edge cases)
- Новая §6.2 — Channels (G) — Email + WhatsApp + Copy link — 3-channel deep-link spec, default message,
?ch=tracking - F-A — Open Questions section внутри plan (две candidate variants spec'ed для Roman ratification); content в плане НЕ добавляется до решения
- §4.2 Permissions matrix — sub-bullet под «Change unit status» row про reverse-flip email notification
- Phase callouts: 1.10 (verification form UI + WhatsApp / Copy link buttons + buyer-token routing F-related light note про deferred F-A), 1.4 (operator dashboard sees status flip audit + reverse-flip notifications), §1 SA definition — refresh cross-link с
#phase-1-10на#fd-buyer-status(более precise) - Changelog v4.9
- Workstream update + preview sync
Pattern Chunks 3/4 (CONV-25 build): anchor IDs (fd-buyer-status, fd-buyer-channels), cross-links, callout style.
Steps
A. §6 lead — light intro update
A1. Insert one paragraph после existing lead в §6 (after line 1062), кратко flagging что §6.1 / §6.2 ниже describe Sales Agent ↔ Buyer mechanics in detail.
<p style="margin-bottom:14px; font-size:13.5px; color:var(--text-mid);"><strong>Внутри §6:</strong> существующие <code><details></code> блоки покрывают buyer entity model и token mechanics. Подробные subsections ниже: <a href="#fd-buyer-status" style="color:var(--text-mid);">§6.1 — Sales Agent status-change form (D+E unified mechanism)</a> + <a href="#fd-buyer-channels" style="color:var(--text-mid);">§6.2 — Channels (Email + WhatsApp + Copy link)</a>.</p>
B. New §6.1 — Sales Agent status-change form (D+E unified)
B1. Insert new subsection after existing 3rd <details> («Forward email / shared token») on line 1090, before closing </div> на 1091.
<h4 id="fd-buyer-status" style="color:var(--navy); margin:24px 0 10px;">6.1 — Sales Agent status-change form (D + E unified mechanism)</h4>
<p style="margin-bottom:10px;"><strong>Use case:</strong> Sales Agent проводит встречу с buyer'ом, договорился о reservation / sold deal'е, нужно поставить unit в Reserved / Sold + связать buyer'а с unit'ом для attribution / commission. Decision (CONV-22): D (status protection) и E (buyer↔unit linkage) <strong>объединены в один mechanism</strong> — заполнение status-change form auto-links buyer-record by email lookup (smart-match). Альтернатива (2 separate UI: status form + manual unit-buyer link в карточке) отвергнута как излишняя ручная работа.</p>
<div style="margin:12px 0; padding:14px 18px; background:var(--sand-50); border-left:3px solid var(--gold); border-radius:0 6px 6px 0;">
<strong style="color:var(--navy); font-size:14px;">Form shape (augmented single-click verification)</strong>
<ul style="margin:8px 0 0 20px; font-size:13.5px; color:var(--text-mid);">
<li><strong>Trigger:</strong> Sales Agent в админке Project → unit card → нажимает кнопку «Mark as Reserved» (амбер) или «Mark as Sold» (red). Status выбирается кликом, не dropdown'ом — reduces clicks, кнопки чётко разделены.</li>
<li><strong>Required field:</strong> <code>buyer email</code> (с autocomplete'ом из buyer-records этого Sales Agent'а — recent first).</li>
<li><strong>Conditional required:</strong> если email НЕ matches existing buyer-record → <code>buyer name</code> + <code>phone</code> становятся required (создаётся новый record). Если email matches existing record → name + phone displayed read-only (auto-fill из existing).</li>
<li><strong>Optional:</strong> <code>notes</code> (free text — deal value, conditions, comment) + <code>file upload</code> (PDF / JPG: signed booking letter, deposit receipt, photo подписанного контракта, etc.).</li>
<li><strong>Submit:</strong> server validates → создаёт/links buyer-record → flips unit status → audit log entry → email notification (см. ниже).</li>
</ul>
</div>
<div style="margin:12px 0; padding:14px 18px; background:var(--sand-50); border-left:3px solid var(--gold); border-radius:0 6px 6px 0;">
<strong style="color:var(--navy); font-size:14px;">Smart-match logic (email lookup, E side)</strong>
<ol style="margin:8px 0 0 20px; font-size:13.5px; color:var(--text-mid);">
<li><strong>Lookup в buyer-records этого Sales Agent'а</strong> (org-scope, recent first) — если email match → display banner «<em>Buyer found: <strong>Иван Петров</strong>, +971 50 123 45 67 — ваш buyer от 12 апреля</em>» + auto-link к существующему record'у.</li>
<li><strong>Lookup в Organisation-wide buyer-records</strong> (если в (1) match не найден) — если match → display warning «<em>Buyer <strong>Иван Петров</strong> existing, attributed to <strong>Алексей Иванов</strong>. New buyer-record will be created для вашей attribution. Continue?</em>». Решение per CONV-22: разные buyer-records под одним email = разная attribution; новый record создаётся для текущего SA.</li>
<li><strong>Если match не найден ни там, ни там</strong> → form требует name + phone, создаётся new buyer-record (attribution = текущий SA), unit↔buyer link создаётся.</li>
</ol>
</div>
<div style="margin:12px 0; padding:14px 18px; background:#fff; border:1px solid var(--border); border-radius:6px;">
<strong style="color:var(--navy); font-size:14px;">Triggers + reverse direction policy</strong>
<ul style="margin:8px 0 0 20px; font-size:13.5px; color:var(--text-mid);">
<li><strong>Forward triggers:</strong> Available → Reserved · Available → Sold · Reserved → Sold (с pre-fill «same buyer?» — если в Reserved уже есть linked buyer-record, форма pre-fill'ит email).</li>
<li><strong>Reverse triggers:</strong> Sold → Reserved · Sold → Available · Reserved → Available. Симметричная policy — same permissions per <a href="#fd-access">§4.2 «Change unit status»</a> row (Owner / Admin / SM / SA own-assigned). Sales Agent fixes own mistakes без эскалации к manager'у. Audit log + email notification catches abuse.</li>
<li><strong>Email notification на reverse-flip:</strong> к Sales Manager'у (если SA откатывает); к Admin / Owner (если SM откатывает). Forward-flip — без notification (standard workflow); reverse — «interesting event» worth surfacing.</li>
<li><strong>Buyer-record fate при reverse:</strong> buyer-record <strong>остаётся в DB</strong> (history + attribution preserved для commission). Unit↔buyer link <strong>воидится</strong> (audit log entry: «<em>User X reverted Sold → Reserved at TIMESTAMP, voided link to Buyer Y</em>»). Re-flip forward (Reserved → Sold снова) — SA re-fills форму; если same email — auto-link recreates от existing buyer-record. Никаких stale link'ов в DB.</li>
</ul>
</div>
<div style="margin:12px 0; padding:14px 18px; background:#fff; border:1px solid var(--border); border-radius:6px;">
<strong style="color:var(--navy); font-size:14px;">Audit log</strong>
<ul style="margin:8px 0 0 20px; font-size:13.5px; color:var(--text-mid);">
<li><strong>Forward-flip:</strong> «<em>User X marked unit Y as Reserved/Sold; linked to Buyer Z (existing | new) at TIMESTAMP. Notes: «...». File: foo.pdf (если приложен)</em>».</li>
<li><strong>Reverse-flip:</strong> «<em>User X reverted unit Y from Sold → Reserved at TIMESTAMP. Voided link to Buyer Z. Reason: «...» (notes если заполнено)</em>».</li>
<li><strong>Visible to:</strong> Owner / Admin / Sales Manager (full audit trail per Project в Project Settings → Activity log). Sales Agent — own actions only (own assigned units history).</li>
<li><strong>Schema-level дизайн</strong> — Phase 1.3 implementation level (consistent с pattern <a href="#fd-access">§4.6 View-as-Agent</a> + <a href="#fd-visibility-pin">§5.1 PIN-protected</a> audit).</li>
</ul>
</div>
<p style="font-size:13px; color:var(--text-mid); margin-top:14px;"><strong>Cross-link:</strong> <a href="#phase-1-10" style="color:var(--text-mid);">Phase 1.10</a> — verification form UI build + WhatsApp button (см. §6.2) · <a href="#phase-1-4" style="color:var(--text-mid);">Phase 1.4</a> — operator dashboard sees flip audit + reverse-flip emails · <a href="#fd-access">§4.2</a> — permission row для status changes (forward + reverse symmetric).</p>
C. New §6.2 — Channels (G) — Email + WhatsApp + Copy link
C1. Insert after §6.1 (after Step B1 closing </p>).
<h4 id="fd-buyer-channels" style="color:var(--navy); margin:24px 0 10px;">6.2 — Channels — Email + WhatsApp + Copy link</h4>
<p style="margin-bottom:10px;"><strong>Use case:</strong> Sales Agent после встречи / звонка отправляет buyer'у tokenised presentation link через подходящий канал. UAE / MENA reality — WhatsApp dominant (~80% delivery), Email — деловой / formal, SMS — устаревает. Stage 1 covers 3 channels через <strong>light deep-link approach</strong> (zero vendor integrations).</p>
<div style="margin:12px 0; padding:14px 18px; background:var(--sand-50); border-left:3px solid var(--gold); border-radius:0 6px 6px 0;">
<strong style="color:var(--navy); font-size:14px;">3 channels (Stage 1)</strong>
<table style="margin:8px 0 0; font-size:13px;">
<thead><tr><th style="width:140px;">Channel</th><th>Mechanic</th><th>Tracking</th></tr></thead>
<tbody>
<tr><td><strong>Email</strong></td><td>Native send из platform'ы через Phase 1.8 infra (SES / Mailgun). Default sender = Organisation's verified email; subject = «<em>Presentation: <Project name></em>»; body = composed message + tokenised links. Phase 1.8 handles delivery, bounces, opens.</td><td>URL: <code>?ch=email</code>. Opens counted в analytics.</td></tr>
<tr><td><strong>WhatsApp</strong></td><td>Deep-link to SA's own WhatsApp client: <code>https://wa.me/<phone>?text=<encoded message></code>. SA жмёт кнопку «Send via WhatsApp» в admin'е → browser открывает <code>web.whatsapp.com</code> (или native app если на mobile) с предзаполненным message; SA жмёт «Send» уже там. <strong>Никаких vendor integrations</strong> — никакого WhatsApp Business API, никакой compliance approval, никаких monthly fees.</td><td>URL: <code>?ch=wa</code>. Opens counted.</td></tr>
<tr><td><strong>Copy link</strong></td><td>Кнопка «Copy buyer link» в admin'е → clipboard'у копируется tokenised URL с <code>?ch=link</code>. SA pastes куда хочет — Telegram / iMessage / LinkedIn DM / SMS / etc. Универсальный fallback.</td><td>URL: <code>?ch=link</code>. Opens counted (без знания target channel).</td></tr>
</tbody>
</table>
</div>
<div style="margin:12px 0; padding:14px 18px; background:#fff; border:1px solid var(--border); border-radius:6px;">
<strong style="color:var(--navy); font-size:14px;">UI flow в Sales Agent admin'е</strong>
<ol style="margin:8px 0 0 20px; font-size:13.5px; color:var(--text-mid);">
<li>SA в Project admin'е → buyer-record card (или после Object Builder при создании презентации) → «<strong>Send to buyer</strong>» button.</li>
<li>Modal: <em>compose message</em> (default text editable: «Hi <buyer_name>, here's the presentation we discussed: <link>») + selected units (chips, removable) + 3 channel buttons:
<ul style="margin:4px 0 0 16px;">
<li><strong>📧 Send via Email</strong> — disabled if buyer email is empty.</li>
<li><strong>💬 Send via WhatsApp</strong> — disabled if buyer phone is empty (tooltip «Phone required for WhatsApp»).</li>
<li><strong>🔗 Copy link</strong> — always enabled.</li>
</ul>
</li>
<li>Click → action: Email отправляется с backend'а; WhatsApp / Copy открывают browser handlers.</li>
<li><strong>Multi-channel в одну операцию</strong> — SA может click Email AND WhatsApp одновременно («не уверен какой канал buyer чаще проверяет»). Same buyer-token URL, разный <code>?ch=</code> param на каждой версии — multi-channel attribution counter в analytics.</li>
</ol>
</div>
<div style="margin:12px 0; padding:14px 18px; background:#fff; border:1px solid var(--border); border-radius:6px;">
<strong style="color:var(--navy); font-size:14px;">Default message text + locale</strong>
<ul style="margin:8px 0 0 20px; font-size:13.5px; color:var(--text-mid);">
<li>Pre-filled на Org locale (Stage 1 supports English + Russian per ADR 0007 i18n; Arabic Stage 2 если рынок попросит).</li>
<li>Template (English): <em>«Hi <buyer_name>, here's the presentation we discussed: <link>»</em>. Russian: <em>«Привет <buyer_name>, вот презентация о которой мы говорили: <link>»</em>.</li>
<li>SA редактирует inline в admin'е перед клик'ом «Send» — full freedom для personalisation.</li>
<li><strong>Per-channel templates</strong> (different text для Email vs WhatsApp) — Stage 2 если попросят. В Stage 1 — same text для всех channels (SA может вручную подкорректировать перед каждым send'ом).</li>
</ul>
</div>
<p style="font-size:13px; color:var(--text-mid); margin-top:14px;"><strong>Cross-link:</strong> <a href="#phase-1-10" style="color:var(--text-mid);">Phase 1.10</a> — UI flow build + 3 channel buttons · <a href="#phase-1-8" style="color:var(--text-mid);">Phase 1.8</a> — Email infra (already in plan) · <a href="#phase-1-4" style="color:var(--text-mid);">Phase 1.4</a> — operator dashboard channel analytics aggregate.</p>
<p style="font-size:13px; color:var(--text-mid); margin-top:8px;"><strong>Stage 2 channels backlog:</strong> SMS via Twilio (carrier compliance, monthly fee), centralised WhatsApp via Business API (от platform'ы send not from SA's phone — pretty UX, audit log, opt-in flows; vendor onboarding required).</p>
D. §4.2 Permissions matrix — sub-bullet про reverse-flip notification
D1. Update existing «Change unit status» row (line ~882) — same row label / permissions, но добавить short note под таблицей про reverse-flip email notification.
Альтернатива (если row note inline получается ugly) — add as a paragraph after matrix table ends (post line ~887).
<p style="font-size:13px; color:var(--text-mid); margin-top:8px;"><strong>Reverse-flip note (CONV-25):</strong> reverse направление status change (Sold → Reserved/Available, Reserved → Available) — same permissions как forward (Owner / Admin / SM / SA own assigned). Каждый reverse-flip → audit log + email notification к одному уровню выше (SA → SM, SM → Admin/Owner). Forward-flip — audit only, без notification (standard workflow). См. <a href="#fd-buyer-status">§6.1 — reverse direction policy</a>.</p>
E. §1 Sales Agent definition — cross-link refresh
E1. Update existing line 619 — change cross-link from #phase-1-10 to #fd-buyer-status (более precise — SA verification form lives в §6.1, не в Phase 1.10 implementation level).
<tr><td><strong>Sales Agent</strong></td><td>Buyer / presentation flow. Меняет status assigned units через verification form (см. <a href="#fd-buyer-status" style="color:var(--navy);">§6.1</a>). Не редактирует контент. Делится на <strong>Internal</strong> (Client из команды самой Organisation) и <strong>External</strong> (Client из другой Organisation, приглашён через guest-organisation invite) — operational различия в <a href="#fd-access" style="color:var(--navy);">§4.5</a>.</td></tr>
F. Phase 1.10 callout — verification form UI + channel buttons
F1. Add new bullet в существующий v4.7 / v4.8 callout (где живут recent CONV-25 entries):
<li><em>v4.9 (CONV-25):</em> <strong>Status-change verification form UI (D+E unified) + 3-channel buyer-link send.</strong> Form: button-driven status select + email-required field with smart-match autocomplete + auto-fill from existing buyer-record + optional notes/file upload. Reverse-direction symmetric per <a href="#fd-access">§4.2</a> with email notification одну ступень выше. Buyer-link send modal: 3 channel buttons (Email native via Phase 1.8 / WhatsApp via <code>https://wa.me/...</code> deep-link / Copy link clipboard) + <code>?ch=</code> URL parameter tracking. F-A (buyer browse scope from token) — deferred Open Question, two candidate variants documented в <code>plans/stage1-chunk-5-journeys.md</code>. См. <a href="#fd-buyer-status">§6.1</a> + <a href="#fd-buyer-channels">§6.2</a>.</li>
G. Phase 1.4 callout — operator dashboard sees status flip audit
G1. Add new bullet в существующий v4.7 / v4.8 callout:
<li><em>v4.9 (CONV-25):</em> <strong>Status-flip audit visibility + reverse-flip email pipeline.</strong> Operator dashboard читает audit log entries для status flips (forward + reverse) per Organisation — для support troubleshooting (e.g., «client claims refund but unit Sold» → operator смотрит timeline). Reverse-flip emails (SA → SM, SM → Admin/Owner) идут через Phase 1.8 transactional email infra; operator video log this как separate event class «status-reverse-notification-sent». Anti-abuse aggregate: «Organisation X had >20 reverse-flips в 30 дней» highlighted в overview (фрод-индикатор: фейковые reservations и тут же откаты для commission games). Channel analytics aggregate (Email / WhatsApp / Copy opens по проектам) — standalone widget в operator overview. См. <a href="#fd-buyer-status">§6.1 audit log</a> + <a href="#fd-buyer-channels">§6.2 tracking</a>.</li>
H. Changelog v4.9 entry
H1. Append v4.9 entry в launch-plan-changelog.html поверх v4.8.
- Date: 2026-05-08
- Source: CONV-25 / Wave 2 Chunk 5
- Sections: §6 lead update (intro to §6.1/§6.2), new §6.1 D+E status-change form (form spec, smart-match, triggers + reverse, buyer-record fate, audit), new §6.2 G channels (3 channels, light deep-link, default message, tracking), §4.2 reverse-flip note, §1 SA cross-link refresh, phase callouts 1.10 + 1.4, F-A deferred Open Question.
I. Workstream update
I1. workstreams/stage1-roman-integration.md:
- Add CONV-25 Chunk 5 entry в Session Log
- Update What's Next → Chunk 6 (§7 Edge cases)
J. Preview repo sync
J1. Sync 2 файла в ~/code/offplan-online/preview/plan/: launch-plan-stage-1.html + launch-plan-changelog.html. Commit + push.
Files
- Primary edit:
docs/rendered/launch-plan-stage-1.html(~180 lines added — §6 lead intro + §6.1 (D+E spec — 4 boxes) + §6.2 (G channels — 3 boxes) + §4.2 reverse-flip note + §1 SA cross-link refresh + 2 phase callouts) - Secondary edit:
docs/rendered/launch-plan-changelog.html(v4.9 entry, ~50 lines) - Workstream update:
workstreams/stage1-roman-integration.md - Optional sync:
~/code/offplan-online/preview/
Dependencies
- Blocked by: nothing (Chunks 1-4 commit'нуты в production, sync'нуты в preview)
- Blocks: nothing (Chunks 6-8 могут идти параллельно)
Testing
- Visual sanity check: открыть
launch-plan-stage-1.html, проверить:- §6 lead intro paragraph упоминает §6.1 + §6.2
- §6.1 — 4 boxes (form shape / smart-match / triggers+reverse / audit) рендерятся с styling
- §6.2 — 3 boxes (3 channels table / UI flow / default message) + Stage 2 backlog note
- §4.2 reverse-flip note под matrix
- §1 SA cross-link →
#fd-buyer-status(был#phase-1-10) - Phase callouts видны в 1.10 + 1.4 (v4.9 entries)
- Cross-link sanity: anchors
fd-buyer-status+fd-buyer-channelsработают; cross-refs из §1 SA, §4.2, phase callouts остались valid - Cross-doc consistency: grep по «verification form» — 2 mentions (§1 SA + §6.1 lead). Grep по «WhatsApp» — должен match только в §6.2 + Phase 1.10 callout (не trespass'ит в Stage 2/3/4 sections)
- Preview sync (если выполнили): проверить
https://offplan-online.github.io/preview/plan/launch-plan-stage-1.html
Risks
- §6.1 размер — может вырасти больше 200 lines если все 4 boxes (form / smart-match / triggers / audit) детально расписаны. Mitigate: использовать compact bullet style, не embedded sub-tables (кроме triggers row table). Если в /build выходит >250 lines — split на §6.1 (form + smart-match) и §6.2 промотать в §6.3 (channels), переnumber'я.
- F-A deferred — может понадобиться mini-patch после Roman ratification. Mitigate: Open Question section детально документирует обе variants (UX implications, Phase 1.10 routing impact). После ratification — short patch в §6 (1 paragraph + Phase 1.10 callout update). Не block'ит Chunk 5.
- Smart-match logic ambiguity — gut feeling per CONV-22 «разные buyer-records под одним email = разная attribution» применён, но Roman может не подтвердить если он имел в виду другое. Mitigate: spec'ed как assumption; Open Question fallback в plan.
- Reverse-flip notification может перетянуть в Phase 1.8 (Email infra) — schema schema design каких events emails отправлять, какие шаблоны, opt-out controls. Mitigate: упомянуть как requirement без deep dive в Phase 1.8 spec — это уровень build implementation.
- WhatsApp deep-link — phone format edge cases. International phones (+971...) versus locale-specific.
wa.meпринимает E.164 без + (e.g.,971501234567). Mitigate: phone normalization at validate-time в form input (Stage 1 = simple regex; libphonenumber Stage 2 если ошибки). - Channel tracking может drift —
?ch=parameter может потеряться если buyer forwards link (некоторые messengers strip query strings). Mitigate: document как «known limitation» в §6.2 — channel analytics показывает «opens by intended channel», не «opens by actual channel». OK для MVP.
Workstreams
- Updates
workstreams/stage1-roman-integration.md:- Mark Chunk 5 done в Session Log (CONV-25 entry, append к existing)
- Update What's Next → Chunk 6 (§7 Edge cases)
Evaluation
Done when:
- §6 lead — intro paragraph упоминает §6.1 + §6.2
- §6.1 — full spec (form shape + smart-match + triggers/reverse + audit) — 4 boxes
- §6.2 — full spec (3 channels + UI flow + default message) — 3 boxes + Stage 2 backlog note
- §4.2 — reverse-flip notification note under matrix
- §1 SA definition — cross-link refresh
#phase-1-10→#fd-buyer-status - Phase 1.10 + 1.4 — v4.9 callouts
- Changelog v4.9 entry
- Workstream Session Log + What's Next обновлены
- F-A documented as Open Question с двумя candidate variants для Roman ratification
- Cross-link sanity check passed
- (optional) Preview synced + pushed
Definition of NOT done (deferred):
- F-A decision (buyer browse scope) — Open Question awaiting Roman
- «Request more options» CTA spec — depends on F-A
- SMS channel — Stage 2
- Centralised WhatsApp via Business API — Stage 2
- Per-channel templates — Stage 2
- Arabic locale — Stage 2 (per ADR 0007)
- Status-change form audit table schema — Phase 1.3 implementation
- Reverse-flip email templates — Phase 1.8 implementation
- Wave 2 Chunks 6-8 (§7 Edges, deep Phase callouts, ADRs)
Open Questions
F-A — Buyer browse scope from valid token (deferred for Roman ratification)
Context. Currently §6 line 1071 says «buyer возвращается к другим ссылкам в email'е или гуляет по сайту с сохранённой attribution» — implies project-level browsing OK, но уровень доступа не специфицирован. Если project на Discovery preset (default — anonymous не видит цены), buyer открывает unit-X по token'у, нажимает «Back to Project» → попадает на main project page → что показано там? Два candidate variants:
Variant (i) — Token = elevated visitor для всего project'а. Buyer гуляет по проекту с эффективным Full sales preset (видит все units, цены, availability badges, рендеры, 360° tours) — независимо от Public Visibility setting. Hearts ANY unit → notification к Sales Agent'у. Mental model: «SA привёл buyer'а в офис показывать проект — buyer видит всё». Self-serve discovery — buyer находит дополнительные интересные units и сам hearts'ит без необходимости звонить SA. Explicit «Request more options» CTA становится опциональным (small «Show me similar» on unit-page → notify SA).
- Phase 1.10 routing impact: middleware checks valid
?b=<token>→ render все project pages с Full sales preset, attribute all interactions к token'у. - Pro: simpler routing logic (один elevated state for any token); frictionless UX; matches real-world sales-agent behavior.
- Con: Owner теряет control over price visibility — любой token holder видит все цены. Studios могут не хотеть этого для VIP-only price reveal scenarios.
Variant (iii) — Token = elevated до Discovery preset, но не Full sales. Buyer видит project с renders + 360° + floorplate + counter «N units», но без цен и individual unit pages — только token'd unit pages открыты в Full sales (т.е. buyer видит цены только на тех units которые SA explicitly link'нул в email). Owner'у даётся Stage 1 toggle «Allow buyer-token full project access» (per-project) который elevates до Variant (i). Default = mid-conservative, opt-in elevation. Plus: explicit «Request more options» CTA на unit-page обязательна (notify SA → SA sends new email с new tokenised links).
- Phase 1.10 routing impact: middleware checks valid
?b=<token>AND requested URL — token'd unit URL → Full sales render; project page или non-token'd unit URL → Discovery preset render. Toggle per project elevates все pages в Full sales. - Pro: Owner-controlled price visibility — fits VIP-only price reveal use case; Sales Agent decides what buyer sees.
- Con: more complex routing; «Request more options» CTA необходима что добавляет roundtrip (buyer → SA → new email → buyer); может frustrate buyer'а который хочет self-serve discovery.
Decision criteria:
- UAE / MENA off-plan property sales reality — how much price visibility control do studios actually want? If "Sales Agent must show prices personally" is real norm → (iii). If "buyer expects self-serve browsing once authed" is closer → (i).
- Roman call sentiment — он упомянул что buyer не должен «вертеть носом» через open project but не сказал точно где cutoff. Need explicit ask.
- Implementation cost — (i) simpler по routing; (iii) добавляет toggle UI + per-page filter logic в Phase 1.10. (i) ships faster.
Resolution path:
- Send Roman ссылку на этот plan section после Wave 2 close (per CONV-22 next steps line 71)
- Roman picks (i) или (iii)
- Mini-patch на §6 + Phase 1.10 callout update + § footer note про toggle (если (iii))
- Mini-patch не block'ит Chunk 5 ratification — F-A deliberate deferred.