# Шаг 12. Двусторонняя доска внешних контуров ## Главная продуктовая задача Во `Внешних контурах` пользователь должен видеть не только прилетевшие или уже принятые задачи, но и те запросы, которые его проект сам отправил в другие контуры. Без этого теряется управляемость: - пользователь отправляет запрос - но не может нормально наблюдать его как отдельную рабочую сущность - и не получает полноценный рабочий экран для исходящих запросов Поэтому следующий обязательный этап — двусторонняя доска. ## Обязательный состав первой версии В первой версии должны быть только две системные зоны: - `Исходящие` - `Входящие` Это фиксированные рабочие представления, а не свободный конструктор колонок. ## Что означает каждая зона ### Исходящие Запросы, которые текущий проект отправил в другие контуры. Для них пользователь должен видеть: - текущий статус исполнения - целевой контур - назначенного - последнее изменение - признаки новых изменений ### Входящие Запросы, которые пришли в текущий проект из других контуров. Они должны оставаться видимыми во `Внешних контурах` как отдельный контекст межконтурной работы, даже если фактическая работа по исполнению идет во `Внутреннем контуре`. Это не отменяет текущий lifecycle появления задачи во `Внутреннем контуре`. Наоборот, это добавляет отдельный рабочий слой наблюдения и управления межконтурным потоком. ## Обязательное ограничение Во `Внешних контурах` нельзя реализовывать перетаскивание карточек между блоками. Причина: - блоки здесь не равны стадиям workflow - это не kanban статусов - это представления по направлению и фильтрам Следовательно: - никаких drag-and-drop переходов между `Исходящими` и `Входящими` - никаких попыток “перетащить” запрос в другой блок как способ смены состояния Смена состояния остается доменной операцией, а не визуальным переносом. ## Требования к фильтрации Обе системные зоны должны поддерживать гибкую фильтрацию по аналогии с `Внутренним контуром`. Минимально нужно уметь фильтровать: - по пользователям - по назначенным - по автору - по статусам - по связанным контурам или проектам - по приоритету - по срокам и датам Если часть фильтров недоступна на первой итерации из-за backend-модели, это нужно закрывать адаптером или агрегированным endpoint, а не урезать целевой продуктовый контракт. ## Текущее архитектурное препятствие На сегодня `Исходящие` и `Входящие` живут в разных подсистемах: - source-side отправленные запросы приходят из модуля `external-contours` - входящие рабочие объекты и bridge-история живут вокруг `intake` и связанной target issue Поэтому полноценная двусторонняя доска не собирается простым склеиванием текущего UI. Нужен единый слой представления данных. ## Рекомендуемое архитектурное решение ### 1. Не собирать эту доску фронтовыми хаками Можно временно склеить две разные выдачи на frontend, но это быстро упрется в: - сортировки - пагинацию - счетчики - консистентность фильтров - unread-индикаторы Поэтому базовый путь должен вести к агрегированному data contract. ### 2. Ввести единый board-level view model Нужна единая проекция, условно: - `direction` - `source_project` - `target_project` - `status` - `assignee` - `created_by` - `updated_at` - `unread` - `target_issue_id` - `external_request_id` Этот view model не обязан ломать существующие доменные сущности. Он нужен как стабильный контракт уровня доски. Детализация этого контракта вынесена отдельно в: - [13_STEP_external-contours-board-data-contract.md](/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/docs_prod/1_STEP_cross-project-task-routing/13_STEP_external-contours-board-data-contract.md) ### 3. Сделать board как фиксированные системные представления Первая версия не должна строиться как свободный пользовательский конструктор. Нужны два системных блока: - блок `Исходящие` - блок `Входящие` И только поверх этого позже можно добавлять дополнительные пользовательские представления. ## Как не уйти в крайности ### Плохой путь 1 Сделать поверх текущего экрана несколько разрозненных переоберток и локальных фильтров. Результат: - быстрое накопление технического долга - отсутствие общего контракта - трудная интеграция следующих board-type модулей ### Плохой путь 2 Остановить проект и начать строить универсальную платформу на все будущие доски сразу. Результат: - высокий срок поставки - риск поломать текущий runtime - потеря фокуса на реальной продуктовой потребности ### Рабочий путь Сделать ограниченный, но расширяемый board contract именно для межконтурных задач: - фиксированные системные зоны - единый тип board item - единый фильтровый слой - переиспользуемый detail-shell из шага 11 ## Связь с будущими пользовательскими колонками Пользовательские представления нужны, но не должны быть частью первой двусторонней доски. Их нужно проектировать как следующий слой поверх уже введенного board contract: - пользователь создает свой блок - задает имя - задает фильтр - получает еще одно представление рядом с системными блоками Но это именно представление. Это не новая стадия исполнения и не область для drag-and-drop. ## Связь с будущими типами досок Архитектура этого шага должна допускать расширение на: - агентные доски - специализированные operational boards - гибридные наблюдательные представления по нескольким контурам Из этого следуют два правила: - доска должна собираться вокруг контракта представления, а не вокруг одной конкретной сущности `Issue` - колонка должна означать выборку или представление, а не обязательно статус workflow ## Критерий приемки - пользователь видит во `Внешних контурах` две системные зоны: `Исходящие` и `Входящие` - отправленные запросы не теряются после отправки и остаются видимыми как рабочие объекты - обе зоны фильтруются через единый механизм - открытие карточки из любой зоны ведет в единый shell шага 11 - между зонами нет drag-and-drop ## Что идет следующим шагом после этого После стабилизации двусторонней доски можно переходить к пользовательским представлениям поверх того же контракта. Но только после того, как: - подтверждена стабильность системных зон - подтверждена консистентность фильтров - подтверждена работа detail-shell в обоих направлениях Связанный документ: - [11_STEP_external-contours-detail-shell.md](/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/docs_prod/1_STEP_cross-project-task-routing/11_STEP_external-contours-detail-shell.md) - [13_STEP_external-contours-board-data-contract.md](/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/docs_prod/1_STEP_cross-project-task-routing/13_STEP_external-contours-board-data-contract.md)