feat(foundry): add composable subject detail profiles

This commit is contained in:
Codex
2026-07-22 19:06:33 +03:00
parent dd2febe7cf
commit dc82ae4c07
21 changed files with 1007 additions and 140 deletions
+20 -2
View File
@@ -43,6 +43,22 @@ profile; renderer не содержит provider-specific условий.
Кнопка `Объекты` открывает вверх текстовый dropdown из Application bindings. Выбор строки открывает или фокусирует отдельное canonical `WorkspaceWindow`, а его универсальное содержимое строится из presentation profile/facets. Несколько binding-окон могут быть открыты одновременно; stable identity всегда `bindingId`, поэтому пользовательское переименование не ломает сохранённый layout.
Клик по pin или его label открывает второе canonical `WorkspaceWindow` — карточку
выбранного объекта. Её вкладки и поля задаёт versioned provider-neutral
`subjectDetailProfile`, а не renderer и не provider payload. Базовый профиль
находится в `registry/map-subject-detail-profiles.json`. Он разделяет обзор,
позицию, телеметрию, счётчики, оборудование, настройки, ТО и происхождение
данных. Неизвестные поля не получают автоматическую вкладку `Other`: UI
показывает только явно классифицированную проекцию. Динамические показания
сенсоров требуют отдельного `allowedReadingIds`; пустой список означает явный
запрет вывода.
Несколько Data Product могут собираться в одну карточку без смешивания
контрактов. Primary binding владеет `subjectDetailProfileId`, а
`subject-aspect-stream` bindings указывают `joinToBindingId` и уникальный
`aspectId`. Соединение выполняется по стабильному `sourceId`; provider endpoint,
credentials и raw payload в Application Manifest не попадают.
Facet-фильтры поддерживают мультивыбор: OR внутри одного facet и AND между facets. Missing facet означает отсутствие ограничения, а явно пустой список — ноль совпадений. Отжатие последнего chip не включает `Все`; `Все` включается и выключается только явным кликом. Переключение фильтра не двигает камеру, обзор выполняется отдельным действием.
## Acceptance fixtures
@@ -98,8 +114,10 @@ Runtime tile cache не является исходным кодом и не х
## Live data-product runtime
`Map Page` хранит только provider-neutral binding: `dataProductId`, approved
semantic types, field projection, `presentationProfileId` и `slotId`: `points`
для live point entities или `zones` для polygon/multipolygon `map.zone`.
semantic types, field projection, `presentationProfileId`, optional
`subjectDetailProfileId`, `aspectId`/`joinToBindingId` и `slotId`: `points`
для live point entities, `zones` для polygon/multipolygon `map.zone` или
`subject-details` для non-spatial current aspects выбранного объекта.
При открытии Application page browser делает same-origin запрос к Foundry:
```text
+1 -1
View File
@@ -97,7 +97,7 @@ Foundry предоставляет базовый MCP-контур для уже
- `Page Library` и канонические шаблоны доступны только на чтение;
- изменяются только экземпляры в `Applications`;
- доступны создание модуля, изменение его metadata, добавление экземпляра готовой страницы, upsert provider-neutral map pin bindings, versioned Map presentation profiles и data-product bindings;
- доступны создание модуля, изменение его metadata, добавление экземпляра готовой страницы, upsert provider-neutral map pin bindings, versioned Map presentation profiles, versioned subject-detail profiles и data-product bindings;
- удаление модуля через MCP намеренно отсутствует;
- каждая write-операция требует idempotency key и сохраняет аудит операции в persistent runtime store.