Goal
Доработать §4 Access чтобы закрыть 3 пробела из CONV-22 What's Next:
- Internal/External Sales Agent split — сейчас оба упомянуты только в §1 entity glossary; в §4 (permissions matrix + scoping + stock allocation) различие не surface'ится явно.
- «Actions column» — оказалось это новые строки в §4.2 permissions matrix для invite/remove Sales Agent action'ов которых сейчас нет (Sales Manager должен мочь добавлять internal SA в свою команду; Admin — приглашать external SA через guest org).
- View-as-Agent — admin debug tool «посмотреть как видит Иван». Отдельная фича от «Preview as Buyer» (последняя — в presentation builder, не входит в §4).
ADR 0009 (Tenancy) остаётся placeholder — Chunk 3 уточняет surface, не пишет ADR.
Locked Decisions (CONV-24 interview)
| # | Тема | Решение |
|---|---|---|
| Q1 | «Actions column» что это | Новые строки в §4.2 permissions matrix для invite/remove SA actions, которых сейчас нет: «Invite/remove internal Sales Agents» (Owner ✅, Admin ✅, Sales Manager ✅) + «Invite/remove External Sales Agents (через guest org)» (Owner ✅, Admin ✅). |
| Q2 | View-as-Agent сценарий | Доступно: Owner / Admin / Sales Manager. Sales Agent — нет (their own view = normal login, viewer state #4). Use cases: manager debug + onboarding/training. UX: persistent toggle с баннером «Viewing as Иван — Exit». Read-only (никаких действий «от имени» — это не impersonation). |
| Q2.5 | Preview as Buyer (related but separate) | Отдельная фича в presentation builder (кнопка «Preview» перед «Send»). Не часть §4. Упоминается одной строкой как cross-reference в §4 View-as-Agent subsection. |
| Q3 | Internal vs External SA — что отличается | Базовые permissions в §4.2 — одинаковые. Различия на 5 других осях: stock pool default (§4.4), cross-team visibility, invitation source, removal authority, reports/analytics scope. Закрепляется в новой comparison table в §4. |
Strategic insight: Internal vs External SA — это не «разные роли», а одна роль с разным operational context. Базовый rule «Sales Agent» одинаков; разница в orbital concerns (откуда пришёл, что видит по дефолту, кто им управляет).
Approach
Surgical правки + 1 новая subsection в §4. Все изменения внутри launch-plan-stage-1.html + changelog v4.7 + workstream update. ADR 0009 placeholder сохраняется.
Pattern Chunk 2 (CONV-24): анchor IDs, cross-links, comparison table, callout style.
Steps
A. §4.2 Permissions matrix — добавить 2 новых action rows
A1. Add 2 строки после «Add/remove team members» (line 875), перед «Invite guest organisations» (line 876):
Invite/remove internal Sales Agents (own team)— Owner ✅, Admin ✅, Sales Manager ✅, Content Editor —, Sales Agent —Invite/remove External Sales Agents (via guest organisation)— Owner ✅, Admin ✅, Sales Manager —, Content Editor —, Sales Agent —
A2. Update header line (line 870) — добавить small note: «Sales Agent column применяется к обоим Internal и External — базовые permissions идентичны (различия — в §4.5 ниже).»
B. §4.2 → renumber subsections (§4.5/§4.6 будут добавлены)
Текущая структура §4: 4.1 Invitations, 4.2 Permissions matrix, 4.3 Scoping, 4.4 Stock allocation. План добавляет 4.5 (Internal/External SA split) + 4.6 (View-as-Agent).
C. New §4.5 — Internal vs External Sales Agent split
C1. Insert new subsection после §4.4 Stock allocation (после line 928 закрывающего </details>):
<h4 style="color:var(--navy); margin:20px 0 10px;">4.5 — Internal vs External Sales Agent</h4>
<p>Sales Agent — одна role с двумя operational контекстами: <strong>Internal</strong> (Client из team самой Organisation) и <strong>External</strong> (Client из guest organisation, приглашённой через guest-org invite). Базовые permissions в §4.2 одинаковы; различия — на orbital осях:</p>
<table>
<thead><tr><th>Ось</th><th>Internal SA</th><th>External SA</th></tr></thead>
<tbody>
<tr><td>Stock pool default (Closed mode, см. §4.4)</td><td>Видит Internal pool</td><td>Не видит Internal pool — только assigned</td></tr>
<tr><td>Cross-team visibility</td><td>Видит коллег-Internal SA в своей Organisation</td><td>Видит только своих в guest organisation</td></tr>
<tr><td>Invitation source</td><td>Personal invite (см. §4.1) от Owner / Admin / Sales Manager</td><td>Член guest organisation, добавлен через org-invite от Owner / Admin</td></tr>
<tr><td>Removal authority</td><td>Owner / Admin / Sales Manager (revoke personal invite)</td><td>Admin (revoke guest-org membership) или Admin своей guest org удаляет user'а</td></tr>
<tr><td>Reports / analytics</td><td>Видит aggregate Organisation-level (own performance + team performance, без других guest orgs)</td><td>Видит только свои продажи + own guest organisation aggregate</td></tr>
</tbody>
</table>
<p>Cross-link: §1 Sales Agent definition + §4.4 Stock allocation Closed pool table.</p>
D. New §4.6 — View-as-Agent (admin debug tool)
D1. Insert new subsection после §4.5:
<h4 style="color:var(--navy); margin:20px 0 10px;">4.6 — View-as-Agent (admin debug + training)</h4>
<p><strong>Use cases:</strong> Sales Manager хочет проверить что Иван видит правильно после assignment'ов; Admin отлаживает permissions setup перед onboarding; obвучение нового Sales Manager'а («давайте посмотрим как видит работу новый коллега»).</p>
<ul>
<li><strong>Кому доступен:</strong> Owner / Admin / Sales Manager. Sales Agent — нет (свой view = normal login, см. viewer state #4 в §5).</li>
<li><strong>UI:</strong> в шапке админки toggle/dropdown «View as...» → выбрать Sales Agent / другого Sales Manager. После выбора — admin panel перерисовывается с perspective этого user'а; вверху страницы фиксированный banner: «Viewing as Иван (Sales Agent) · Exit view-as-mode →».</li>
<li><strong>Read-only mode:</strong> в view-as-режиме все действия залочены (Save / Edit / Delete / Send / Assign — все disabled с тултипом «Disabled in view-as mode»). Это explicit decision — НЕ impersonation. Для actual impersonation (login as user) — отдельный operator flow в Phase 1.4, deferred to Stage 4.</li>
<li><strong>Что показывается:</strong> stock filtered как для target user, list юнитов с их visibility/availability, buyer profiles target user'а, его сейлз-метрики. Permissions matrix фильтрует UI элементы.</li>
<li><strong>Audit log:</strong> entry «User X viewed as User Y at TIMESTAMP, duration N min». Compliance — important чтобы знать кто и когда смотрел чужие views.</li>
<li><strong>Cross-link:</strong> Preview-as-Buyer (отдельная фича в presentation builder, не часть §4) — для проверки как выглядит email-презентация для конкретного buyer'а перед отправкой. Cм. <a href="#phase-1-11">Phase 1.11</a>.</li>
</ul>
E. §1 Sales Agent definition — minor update
E1. Update existing line (line 619) для добавления cross-link на §4.5:
<tr><td><strong>Sales Agent</strong></td><td>Buyer / presentation flow. Меняет status assigned units через verification form (см. <a href="#phase-1-10">Phase 1.10</a>). Не редактирует контент. Делится на <strong>Internal</strong> (Client из команды самой Organisation) и <strong>External</strong> (Client из другой Organisation, приглашён через guest-organisation invite) — operational различия в <a href="#fd-access">§4.5</a>.</td></tr>
F. Phase callouts touchpoints (audit + light updates)
F1. Phase 1.3 (Tenancy) — RBAC engineering brief должен учитывать Internal/External SA differentiation в данных (e.g., membership_type field или derived через organisation_id link). Add bullet в существующий v4.4 callout: «Internal/External Sales Agent operational split formalised in §4.5 — RBAC должен exposing both via API + UI permissions filter».
F2. Phase 1.4 (Operator Dashboard) — View-as-Agent НЕ путать с operator impersonation (последний deferred Stage 4). Add note: «View-as-Agent (§4.6) — это team-level admin tool, ≠ Stage 4 operator impersonation».
F3. Phase 1.10 (Sales App) — view-as-state в sales-app UI должен respect View-as-Agent toggle. Add bullet: «Sales Agent unit list view rendering должен поддерживать "view-as" mode когда Sales Manager инспектирует team-member view (§4.6)».
F4. Phase 1.11 (Presentation Layer) — Preview-as-Buyer placeholder. Add bullet: «Preview-as-Buyer feature (отдельный от §4.6 View-as-Agent) — кнопка в presentation builder перед Send. Render buyer-tokenised view с тестовым token'ом для preview only».
G. Changelog v4.7 entry
G1. Append v4.7 entry в launch-plan-changelog.html:
- Date: 2026-05-08
- Source: CONV-24 / Wave 2 Chunk 3
- Summary: «§4 Access additions — 2 new permissions matrix rows (Invite/remove internal SA + External SA), new §4.5 Internal/External Sales Agent split (5-row comparison table), new §4.6 View-as-Agent (read-only admin debug tool с persistent toggle + audit log). Phase callouts updated в 1.3/1.4/1.10/1.11. Cross-link patches §1 SA definition.»
H. Workstream update
H1. workstreams/stage1-roman-integration.md:
- Add CONV-24 Chunk 3 entry в Session Log
- Update What's Next → Chunk 4 (§5 Visibility — PIN-protected preset + Custom preset cleanup)
I. Preview repo sync
I1. Sync 2 файла в ~/code/offplan-online/preview/plan/:
launch-plan-stage-1.htmllaunch-plan-changelog.html
Commit + push в preview (analogous Chunk 2 sync).
Files
- Primary edit:
docs/rendered/launch-plan-stage-1.html(~50-70 lines added — 2 matrix rows + §4.5 + §4.6 + 4 phase callouts + 1 §1 cross-link) - Secondary edit:
docs/rendered/launch-plan-changelog.html(v4.7 entry, ~30 lines) - Workstream update:
workstreams/stage1-roman-integration.md - Optional sync:
~/code/offplan-online/preview/
Dependencies
- Blocked by: nothing (Chunks 1+2 commit'нуты в production, sync'нуты в preview).
- Blocks: nothing (последующие Chunks 4-8 могут идти в любом порядке, кроме общих anchor cross-links).
Testing
- Visual sanity check: открыть
launch-plan-stage-1.html, проверить:- §4.2 matrix имеет 2 новые строки (invite/remove internal/external SA)
- §4.5 + §4.6 рендерятся как distinct subsections
- Cross-links работают: §1 SA → #fd-access (§4.5), §4.6 mention Phase 1.11
- Phase callouts видны в 1.3/1.4/1.10/1.11
- Cross-doc consistency: grep по «Internal Sales Agent» и «External Sales Agent» в плане — должны cross-reference §4.5 везде кроме §1 definition
- Preview sync (если выполнили): проверить
https://offplan-online.github.io/preview/plan/launch-plan-stage-1.html
Risks
- §4.6 View-as-Agent vs Stage 4 operator impersonation — terminologically близко, легко смешать. Mitigate: explicit «НЕ impersonation» note в §4.6 + cross-link в Phase 1.4.
- Audit log requirement в §4.6 — может перетянуть scope в Phase 1.8 (Security & Infrastructure). Mitigate: упомянуть в §4.6 как requirement, без deep dive в схему таблицы — это уровень Phase 1.3 implementation.
- Reports/analytics row в §4.5 — самая мутная (заочно подтверждено пользователем но детали не зафиксированы). Mitigate: формулировка осторожная, точная имплементация → Phase 1.4 Operator Dashboard или ADR 0009.
- Phase callouts могут разрастаться при /build, особенно 1.10 + 1.11 (где view-as логика может pull в UX тесты). Mitigate: surgical bullets, не глубокий rewrite — глубокие phase callouts отдельно в Wave 2 Chunk 7.
Workstreams
- Updates
workstreams/stage1-roman-integration.md:- Mark Chunk 3 done в Session Log (CONV-24 entry, append к existing)
- Update What's Next → Chunk 4 (§5 Visibility)
Evaluation
Done when:
- §4.2 matrix имеет 2 новые invite/remove rows для internal + external SA
- §4.5 (Internal/External SA split) — comparison table с 5 осями
- §4.6 (View-as-Agent) — описание UX + read-only + audit log requirement + cross-link на Preview-as-Buyer
- §1 SA definition имеет cross-link на §4.5
- Phase 1.3/1.4/1.10/1.11 — light callouts добавлены
- Changelog v4.7 entry
- Workstream Session Log + What's Next обновлены
- Cross-link sanity check passed (grep по new концептам)
- (optional) Preview synced + pushed
Definition of NOT done (deferred):
- ADR 0009 (Tenancy) — placeholder remains
- Preview-as-Buyer detailed spec — Phase 1.11 build / отдельный sub-plan
- View-as-Agent UI mockup —
docs/mockups/admin-panel-atelier.htmladd later - Wave 2 Chunks 4-8
- View-as-Agent backend (audit log table schema, etc.) — Phase 1.3 implementation level