# Шаг 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)
