# NDC Module Foundry

Текущий living catalog эволюционирует в **NDC Module Foundry** без создания второго визуального приложения. Существующие разделы остаются `Visual Library`; рядом живут `Page Library` и `Applications`. Foundry — модульный контур для создания экземпляров готовых приложений, а `Design Guideline` остаётся каноническим языком и каталогом компонентов.

## Page Template contract v0.1

Канонические TypeScript-контракты и manifests находятся в `@nodedc/page-patterns`, машинно-читаемый реестр — в `registry/pages.json`.

Первый шаблон `Map Page 0.1.0` формально фиксирует:

- template identity и pinned version;
- стартовую страницу и navigation defaults;
- разрешённые feature flags `Inspector`, `Toolbar`, `Assistant`;
- runtime-neutral slots `points`, `traces`, `routes`, `zones`, `selection`, `commands`, `assistant`;
- template-owned actions.

Шаблон не содержит Cesium token, Engine workflow, React component tree или свободные координаты элементов. Renderer/Cesium adapter и Capability Bindings являются отдельными следующими слоями.

## Map Scene Fixture v0.1

Каноническая JSON Schema: `registry/schemas/map-scene-fixture-v0.1.schema.json`. Проверочные сцены перечислены прямо в контракте `map@0.1.0` и лежат в `registry/fixtures/map`.

`map-empty-offline-v0.1.json` проверяет, что shell и системные действия остаются работоспособными без live-данных. Operational demo fixture удалён: Visual Library, Page Library и Applications не поставляют города, движущиеся объекты, станции, маршруты, пути, зоны или selection. Domain entities появляются только из declared Application bindings.

LOD вынесен в отдельный контракт `registry/schemas/map-lod-policy-v0.1.schema.json` и policy set `registry/fixtures/map/map-lod-policies-v0.1.json`. Он использует расстояние камеры в метрах, полуоткрытые диапазоны и hysteresis, поэтому не зависит от Cesium `DistanceDisplayCondition`. Дальнейшая калибровка bands выполняется на живом Map shell, а не в отрыве от визуального результата.

## Application Manifest v0.1

Каноническая JSON Schema: `registry/schemas/application-manifest-v0.1.schema.json`.

Manifest фиксирует:

- identity, slug, draft status и версию;
- ссылку на конкретный Design Profile release (`id + version + status + theme`);
- хотя бы одну страницу и pinned page-template version;
- navigation visibility;
- только заранее разрешённые feature flags;
- favicon source;
- server-controlled timestamps.

Manifest не хранит runtime credentials, arbitrary component tree или deployment secrets. Map page instance хранит provider-neutral capability bindings и контролируемый view state: camera, base settings, exact facet selection и геометрию canonical binding windows, keyed by stable `bindingId`.

## Draft lifecycle

Catalog server предоставляет минимальный временный API:

- `GET /api/applications` — список drafts;
- `GET /api/page-templates` — получить канонический page registry;
- `POST /api/applications` — создать draft из явно выбранных `templateId` и `templateVersion`;
- `GET /api/applications/:id` — открыть draft;
- `PUT /api/applications/:id` — атомарно сохранить draft.

Файлы находятся в `runtime-data/applications` и исключены из Git. Этот store доказывает lifecycle `create → save → reload → open`; целевой production store позже принадлежит Platform `application-core`.

## Согласованный UX Application Projects

- круглая кнопка `+` в заголовке Applications открывает модалку создания модуля;
- текущий модуль выбирается через Hub-style searchable selector, а не через плоский список проектов;
- root модуля содержит metadata, ссылку на один pinned Design Profile и Application Composition;
- Dark/Light, favicon, Glass и прочие визуальные параметры не настраиваются внутри модуля;
- две равные колонки `Доступные страницы / Конфигурация приложения` работают только с готовыми Page Templates;
- drag-and-drop меняет состав и порядок ссылок на шаблоны, но не создаёт свободный canvas;
- после сохранения страницы появляются в левой навигации и открывают визуальный preview;
- режимы `Настройка / Предпросмотр` разделяют Studio controls и поведение будущего приложения;
- удаление draft выполняется только через destructive confirmation modal.

## Design Profile lifecycle

Каноническая JSON Schema: `registry/schemas/design-profile-v0.1.schema.json`.

Visual Library использует отдельный Hub-style selector профилей. Общая кнопка Save открывает каноническую модалку `Сохранить / Сохранить как новый / Опубликовать`. Приложение хранит pinned `profile id + version + status + theme`; media, favicon и material settings принадлежат Design Profile.

Design Profile также хранит независимые design-only фрагменты по зарегистрированному типу страницы (`pageTypes["map@0.1.0"]`). Для Map в такой фрагмент входят только `settings` и provider-neutral `presentationProfiles`. Camera, высота рабочего окна, pin/data-product bindings, subjects, endpoints и credentials остаются состоянием Application/runtime и никогда не попадают в профиль.

Кнопка Save в Page Library не изменяет канонический Page Template: она открывает ту же модалку Design Profile и обновляет только фрагмент текущего типа страницы. Сохранение следующего типа страницы сливает его фрагмент в тот же профиль, не перезаписывая глобальные поля и ранее сохранённые типы. Application разрешает визуальное состояние в порядке `canonical page defaults → pinned Design Profile page fragment → Application designOverrides`; runtime bindings при этом сохраняются отдельно.

`Draft` — изменяемая рабочая голова профиля. Каждое сохранение увеличивает patch-версию. `Published` — неизменяемый снимок конкретной версии: повторная публикация той же версии запрещена. Application Manifest может ссылаться на draft для внутренней разработки, но стабильный модуль должен фиксировать published release. Изменение будущего draft или публикация следующей версии не меняют уже закреплённое приложение.

Временный catalog server предоставляет:

- `GET /api/design-profiles`;
- `GET /api/design-profiles/:id`;
- `POST /api/design-profiles`;
- `PUT /api/design-profiles/:id`;
- `GET /api/design-profiles/:id/versions`;
- `GET /api/design-profiles/:id/versions/:version`;
- `POST /api/design-profiles/:id/publish`;
- `DELETE /api/applications/:id` с переносом draft в локальное deleted-storage.

Catalog server проверяет полный layout-контракт Design Profile и существование выбранной Application Manifest ссылки при создании и сохранении модуля. Опубликованные снимки лежат отдельно от draft-head в `runtime-data/design-profile-releases` и исключены из Git; в production этот lifecycle должен перейти в Platform `design-profile-core` без изменения публичного контракта.

Все save/update/publish операции показывают канонический `ToastStack` снизу справа. Loading-state обновляется в success/error в том же toast; blocking confirmation остаётся отдельной modal-механикой.

## Baseline MCP

Foundry предоставляет базовый MCP-контур для уже существующего сквозного AI Workspace Assistant. Он не создаёт отдельную оркестрацию: штатный entitlement adapter выдаёт доступ к Foundry только авторизованному пользователю, после чего ассистент получает ограниченный набор инструментов.

- `Page Library` и канонические шаблоны доступны только на чтение;
- изменяются только экземпляры в `Applications`;
- доступны создание модуля, изменение его 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.

Полная конфигурация, endpoint и границы MCP описаны в [MCP контуре Module Foundry](MODULE_FOUNDRY_MCP.md).
