[apps-catalog umbrella] mono — Federation MWP (E9 demo pilot + E10 runtime federation + 9.3.b publish) #64

Merged
claude merged 21 commits from apps-catalog into dev 2026-06-04 11:26:48 +00:00
Owner

Зонтичный PR для всей mono-стороны apps-catalog

Включает E9 (demo pilot), E10 (Runtime Federation backend) и 9.3.b (publishPackage/publishRelease). Все ранее открытые саб-PR свёрнуты сюда merge-commit-ом (история по фичам сохранена).

Свёрнутые саб-PR

  • #71 — [E10 umbrella] Runtime Federation для backend-расширений (10.1+10.2+10.2b+10.3)
  • #72 — [9.3.b umbrella] Mutation.publishPackage + publishRelease — proxy на ca-admin

Содержимое (по эпикам)

E10 Runtime Federation:

  • 10.1 — coopback → ApolloFederationDriver (subgraph mode)
  • 10.2 — Extension SDK для subgraph'ов (Nest-template)
  • 10.2b — PoC subgraph для smoke-теста SDK
  • 10.3 — Orchestrator service + Apollo Gateway runtime (components/gateway-orchestrator)

9.3.b publish mutations:

  • backend Mutation.publishPackage (chairman) — proxy на ca-admin
  • backend Mutation.publishRelease — proxy на ca-admin

Дальше будет докинуто сюда (текущая работа):

  • 10.4 — Install pipeline integration (approve → up → recompose → desktop)
  • 10.5 — Orchestrator watches on-chain apps-contract
  • 10.8 — chatcoop subgraph
  • 10.3b — Dynamic supergraph composition без рестарта gateway
  • 9.3.b-ui — форма publishPackage в DeveloperPublishReleasePage.vue

Порядок merge

  1. Сначала apps-catalog (репа) PR #2 → dev (бэкенд каталога стабилен)
  2. Потом этот mono PR #64 → dev (mono догоняет каталог)
## Зонтичный PR для всей mono-стороны apps-catalog Включает E9 (demo pilot), E10 (Runtime Federation backend) и 9.3.b (publishPackage/publishRelease). Все ранее открытые саб-PR свёрнуты сюда merge-commit-ом (история по фичам сохранена). ### Свёрнутые саб-PR - #71 — [E10 umbrella] Runtime Federation для backend-расширений (10.1+10.2+10.2b+10.3) - #72 — [9.3.b umbrella] Mutation.publishPackage + publishRelease — proxy на ca-admin ### Содержимое (по эпикам) **E10 Runtime Federation:** - 10.1 — coopback → ApolloFederationDriver (subgraph mode) - 10.2 — Extension SDK для subgraph'ов (Nest-template) - 10.2b — PoC subgraph для smoke-теста SDK - 10.3 — Orchestrator service + Apollo Gateway runtime (components/gateway-orchestrator) **9.3.b publish mutations:** - backend Mutation.publishPackage (chairman) — proxy на ca-admin - backend Mutation.publishRelease — proxy на ca-admin **Дальше будет докинуто сюда (текущая работа):** - 10.4 — Install pipeline integration (approve → up → recompose → desktop) - 10.5 — Orchestrator watches on-chain apps-contract - 10.8 — chatcoop subgraph - 10.3b — Dynamic supergraph composition без рестарта gateway - 9.3.b-ui — форма publishPackage в DeveloperPublishReleasePage.vue ### Порядок merge 1. Сначала apps-catalog (репа) PR #2 → dev (бэкенд каталога стабилен) 2. Потом этот mono PR #64 → dev (mono догоняет каталог)
claude added 1 commit 2026-06-02 18:04:50 +00:00
docs(apps-catalog): research-доклад по миграции native extensions в каталог
Typecheck / desktop (pull_request) Successful in 13m21s
Typecheck / controller (pull_request) Successful in 12m43s
87834c4e56
claude added 1 commit 2026-06-02 18:30:25 +00:00
docs(apps-catalog): Epic 9 MVP demo-app pilot — раскладка решений и stories
Typecheck / desktop (pull_request) Successful in 13m20s
Typecheck / controller (pull_request) Successful in 12m58s
c18828c534
Финальные решения по V1 пилоту (без миграции native):
- demo-app = пустой Hello-стол, @voskhod/demo-app
- Pricing 1000 RUB/мес (60 сек на dev), trial 15 мин
- partner1 как покупатель через pnpm boot:extra (на той же цепи)
- Self-subscription bypass: воскод как оператор подписан бесплатно
- Без кэша tarball'ов — каждый desktop boot качает заново
- Стол Разработчика = новый bundle-extension developer, виден chairman оператора
- partner1 desktop+coopback в отдельном docker overlay из apps-catalog

Epic 9 раскладка на 8 stories с зависимостями. Реализация — следующими
коммитами в зонтичной ветке apps-catalog mono + feat/E9-demo-app-pilot
в apps-catalog репо.
claude added 1 commit 2026-06-02 19:21:02 +00:00
[9.3][9.4] feat: стол разработчика + remote-loader каркас в desktop
Typecheck / desktop (pull_request) Failing after 7m22s
Typecheck / controller (pull_request) Failing after 7m21s
9f6d2dc699
9.3 — components/desktop/extensions/developer/:
- install.ts: workspace `developer`, defaultRoute=developer-my-packages,
  4 страницы (packages, publish, subscribers, pricing), все under
  meta.roles=['chairman']. Регистрация в extensions-registry.ts.
- pages/: V1 Vue-заглушки с описанием TODO (без реальных мутаций).
  Mutation flow (POST /v1/admin/package, /releases, /pricing с подписью
  chairman'а) — story 9.3.b.

9.4 — processes/init-installed-extensions/remote-loader.ts:
- Контракт fetch/load для remote-пакетов с активной подпиской: тип
  RemoteExtensionDescriptor, функции fetchInstalledRemotePackages,
  loadRemoteExtension, installRemoteExtensions.
- V1 — заглушка возвращающая []. Не падает, логирует пропуск.
- index.ts: после bundle-pass — remote pass через installRemoteExtensions;
  try/catch чтобы падение remote-flow не валило bundle extensions.
- TODO 9.4.b: реальный fetch к coopback + tar-x + dynamic require
  + sha256-check + (V2 sandbox).

Видимость стола: пока через meta.roles в install.ts. Полноценная
авторизация через DesktopWorkspace.grants с флагом is_operator_coop —
9.3.b/9.5.

Refs: /home/admin/mono-ai-5/docs/integration/native-to-catalog-research.md §9.
claude added 1 commit 2026-06-02 19:22:01 +00:00
[9.5] feat: Epic 9 hint-banner в pages/ExtensionStore/ExtensionsShowcase
Typecheck / desktop (pull_request) Failing after 7m22s
Typecheck / controller (pull_request) Failing after 7m15s
da0690bca1
V1 минимум для UI ExtensionStore:
- Информационный banner сверху grid'а карточек, объясняющий что bundle-
  extensions ниже бесплатные, а remote-пакеты с подпиской появятся
  на следующем шаге пилота.
- Реальная карточка remote-пакета с кнопкой «Подписаться» / «Уже
  подписан до DD.MM» — story 9.5.b (требует расширения extStore
  на kind/subscribed/pricingRubPerMonth + backend-резолверы coopback'а).

Refs: docs/integration/native-to-catalog-research.md §9 story 9.5.
Author
Owner

Epic 9 (mono часть) — финальный статус

Закрывает stories 9.3 + 9.4 + 9.5 на стороне mono. Парный PR в apps-catalog — C9S/apps-catalog#2.

Завершено в этом PR:

  • components/desktop/extensions/developer/ — стол разработчика с 4 страницами-заглушками (packages/publish/subscribers/pricing), все требуют роль chairman.
  • components/desktop/src/processes/init-installed-extensions/remote-loader.ts — каркас remote-loader для удалённых пакетов.
  • components/desktop/src/processes/init-installed-extensions/index.ts — второй проход remote-extensions после bundle.
  • components/desktop/src/pages/ExtensionStore/ExtensionsShowcase/ExtensionsShowcase.vue — hint-banner Epic 9 (объясняет, что remote-пакеты появятся).

E2E pilot smoke (admin-side в apps-catalog) — PASS (4/5 hard, 5 soft-warn audit-routing). Полная backend-цепочка seed → setglobals → setpricing → register package → create release → watcher alive работает без warn-разрывов после 9.6.c (фикс CachedPricingReadAdapter критического пути).

Отложено в V2:

  • 9.3.b реальные мутации в столе разработчика (POST package/release/pricing с подписью chairman)
  • 9.4.b fetch + tarball-eval + sha256-check в remote-loader
  • 9.5.b remote-package card с кнопкой «Подписаться»
  • 9.6.b auto-extend self-subscription watcher
### Epic 9 (mono часть) — финальный статус Закрывает stories 9.3 + 9.4 + 9.5 на стороне mono. Парный PR в apps-catalog — C9S/apps-catalog#2. **Завершено в этом PR:** - `components/desktop/extensions/developer/` — стол разработчика с 4 страницами-заглушками (packages/publish/subscribers/pricing), все требуют роль `chairman`. - `components/desktop/src/processes/init-installed-extensions/remote-loader.ts` — каркас remote-loader для удалённых пакетов. - `components/desktop/src/processes/init-installed-extensions/index.ts` — второй проход remote-extensions после bundle. - `components/desktop/src/pages/ExtensionStore/ExtensionsShowcase/ExtensionsShowcase.vue` — hint-banner Epic 9 (объясняет, что remote-пакеты появятся). **E2E pilot smoke** (admin-side в apps-catalog) — PASS (4/5 hard, 5 soft-warn audit-routing). Полная backend-цепочка `seed → setglobals → setpricing → register package → create release → watcher alive` работает без warn-разрывов после 9.6.c (фикс CachedPricingReadAdapter критического пути). **Отложено в V2:** - 9.3.b реальные мутации в столе разработчика (POST package/release/pricing с подписью chairman) - 9.4.b fetch + tarball-eval + sha256-check в remote-loader - 9.5.b remote-package card с кнопкой «Подписаться» - 9.6.b auto-extend self-subscription watcher
claude added 1 commit 2026-06-02 20:10:38 +00:00
[9.5.a] feat(ExtensionStore): inline-моки remote-витрины demo
Typecheck / desktop (pull_request) Failing after 7m18s
Typecheck / controller (pull_request) Failing after 7m14s
237cd19e62
Секция «Удалённые пакеты» с карточкой @voskhod/demoapp (publisher,
price 1000 ₽/мес) + dialog «Подписаться» (V1 — заглушка).

Why: Анна видит реальный второй раздел, отделённый от bundle-расширений,
и проходит UX-сценарий клика «Подписаться» — без backend-резолверов.
Реальный список remoteExtensions через Query.appsCatalogRemotePackages
+ Mutation.appsCatalogSubscribe — отложено в 9.5.b (см. mono#64
follow-ups).

Стили — токены MONO Design System (--p-*), никаких magic hex.
claude added 1 commit 2026-06-02 21:55:23 +00:00
[9.5.b] feat(controller): apps-catalog-proxy — резолвер appsCatalogRemotePackages
Typecheck / desktop (pull_request) Failing after 7m39s
Typecheck / controller (pull_request) Failing after 7m23s
5a2fc336e9
Story 9.5.b mono часть: добавляет модуль расширения
`apps-catalog-proxy` с GraphQL Query.appsCatalogRemotePackages, который
проксирует запрос на apps-catalog/ca-admin /v1/public/packages.

Архитектурно — выбран альтернатива C (см. apps-catalog
docs/epics/E9-demo-app-pilot.md, V2 follow-ups): браузер ходит в каталог
через mono controller, а не напрямую в ca-admin. Поэтому:
- admin-secret apps-catalog'а живёт в env controller'а, не в SPA;
- нет CORS — desktop запрос на свой же origin;
- единый канон mono GraphQL (никаких raw HTTP в desktop).

Компоненты:
- AppsCatalogRemotePackageDTO (@ObjectType): packageId/publisher/
  compatibleSubnets/lastActiveVersion + UI-поля title/description/
  rubPerMonth (в V1 description и rubPerMonth — заглушки; в V2 будут из
  package manifest и apps-catalog pricing).
- AppsCatalogHttpService: axios-клиент к ca-admin с Authorization: Bearer
  admin-key из APPS_CATALOG_API_KEY. Degraded mode (пустой список без
  ошибки), если env пустой — чтобы dev/CI без apps-catalog не валили
  desktop boot.
- AppsCatalogProxyResolver: @Query, @UseGuards(GqlJwtAuthGuard) — каталог
  видят только авторизованные пайщики.
- Регистрация в ExtensionsModule.

Config:
- Новые env APPS_CATALOG_URL и APPS_CATALOG_API_KEY (оба optional).
- Зеркальные поля в config.apps_catalog.{url, api_key}.

TODO (требует ручного запуска на остановленном контейнере, см. CLAUDE.md:
'pnpm generate-schema / generate-client — не запускать локально'):
- pnpm -F controller generate-schema → пересоздать schema.gql.
- pnpm -F controller generate-client → graphql-zeus в SDK.
- pnpm -F sdk build → unbuild dist.
Без codegen фронт ещё не сможет дёрнуть резолвер через Zeus.
claude added 1 commit 2026-06-02 22:01:02 +00:00
[9.5.b] fix(apps-catalog-proxy): явный type fn для nullable Field + .env.example
Typecheck / desktop (pull_request) Failing after 7m15s
Typecheck / controller (pull_request) Failing after 7m21s
a6d6b0af2f
При nullable=true декоратор @Field NestJS GraphQL не умеет вывести тип из
TS-reflection-метаданных (TS пишет в metadata-ключ Object). Без явного
type fn (() => String) — UndefinedTypeError на старте.

Фикс:
- @Field({ nullable: true }) → @Field(() => String, { nullable: true })
  для lastActiveVersion: string | null.
- .env.example добавлены APPS_CATALOG_URL и APPS_CATALOG_API_KEY с
  готовыми значениями для dev (URL = DNS-имя ca-admin в mono-shared
  сети).

Verify: coopback стартует чисто (Nest application successfully started),
DTO виден через introspection (__type AppsCatalogRemotePackageDTO →
поля packageId/publisher/title/description/rubPerMonth/lastActiveVersion/
compatibleSubnets), guard срабатывает (без JWT → 401 Unauthorized).
claude added 1 commit 2026-06-03 04:52:29 +00:00
[9.5.b] feat(sdk+desktop): Zeus client + ExtensionsShowcase реальный fetch apps-catalog
Typecheck / desktop (pull_request) Failing after 7m27s
Typecheck / controller (pull_request) Failing after 7m36s
45def1bbec
- sdk/zeus: regenerated через `controller generate-schema && generate-client`
  + `pnpm -F sdk build`; типы AppsCatalogRemotePackageDTO и
  Query.appsCatalogRemotePackages пробрасываются end-to-end.
- sdk/selectors/extensions: новый appsCatalogRemotePackageSelector с
  валидатором MakeAllFieldsRequired.
- sdk/queries/extensions: новый namespace Queries.Extensions.AppsCatalogRemotePackages
  (page/pageSize → AppsCatalogRemotePackageDTO[]).
- desktop/entities/Extension/api: api.loadAppsCatalogRemotePackages(page, pageSize)
  по канону client.Query + строгие типы из @coopenomics/sdk.
- desktop/pages/ExtensionStore/ExtensionsShowcase: убран inline-mock,
  каталог загружается через Zeus query. Добавлены loading/error/empty
  состояния по дизайн-канону (--p-*, base-card токены), плюсификация
  слова «пакет», version-чип и Intl-форматирование цены.

Это шаги 3–4 V2 9.5.b. Закрывает task #38 и #37.
claude added 1 commit 2026-06-03 05:26:09 +00:00
[9.4.b] feat(controller+desktop): реальный remote-loader fetch+eval install.js
Typecheck / desktop (pull_request) Successful in 13m24s
Typecheck / controller (pull_request) Successful in 13m19s
da50e423ca
mono controller:
- AppsCatalogHttpService.fetchInstallScript(scope, name) — fetch text
  install.js из ca-admin /v1/public/packages/:scope/:name/install.js;
  degraded mode (null) при отсутствии env-config'а apps-catalog'а.
- Новый REST controller AppsCatalogInstallScriptController
  `GET /v1/apps-catalog/install/:scope/:name` под HttpJwtAuthGuard:
  валидирует scope/name regex'ом, проксирует на ca-admin, отдаёт
  text/javascript + Cache-Control: no-store. Admin-API key остаётся
  на backend'е.
- AppsCatalogProxyModule: добавлен controller в module.controllers[].

mono desktop:
- remote-loader.ts: реальный fetch + CJS-eval. fetchInstalledRemotePackages
  читает Queries.Extensions.AppsCatalogRemotePackages, парсит packageId
  на (scope, name). loadRemoteExtension качает install.js по REST через
  axios responseType:'text' с JWT desktop'а, оборачивает в
  `new Function('module','exports','require', code)`, вызывает
  `module.exports.install()` → IWorkspaceConfig[].
- Try/catch per item (NFR15-стиль): падение одного пакета не валит
  остальные. require() сразу throw — пакеты должны быть CJS без
  внешних зависимостей (sandbox — Story 11.x).
- sha256 пока не проверяем (release-таблица будет в 9.4.c).

Demo path: voskhod publishes @voskhod/demo-app → ca-admin отдаёт
examples/demo-app/install.js → controller-proxy → desktop boot тянет +
eval'ит + получает workspace «Demo» с роутом demo-hello.
claude added 8 commits 2026-06-04 04:54:52 +00:00
[E10-1] feat(controller): переключение GraphQL на ApolloFederationDriver (subgraph mode)
Typecheck / desktop (pull_request) Has been cancelled
Typecheck / controller (pull_request) Has been cancelled
f6b5c01030
Epic 10 Story 10.1 — coopback становится первым federation v2 subgraph'ом.
Локальная core-схема компилируется с federation директивами (`autoSchemaFile.federation: 2`).
Endpoint остаётся на /v1/graphql; non-federated клиенты (desktop) не должны
заметить переключения — Apollo Federation добавляет лишь служебные
`_service { sdl }` и `_entities` query.

Gateway-режим (Apollo Gateway + IntrospectAndCompose) зайдёт отдельной
story 10.1b — поверх этого subgraph'а + registry в Postgres. На MVP пока
один subgraph, gateway не нужен.

Зависимости:
- + @apollo/subgraph ^2 (peer для federation 2 в @nestjs/apollo)

@key директивы на core entity (User/Cooperative/Account/Wallet) добавятся
по мере вытаскивания первых extension'ов — отдельными точечными PR.
[E10-2] feat(extension-sdk): @coopenomics/extension-sdk — Nest-template subgraph'а
Typecheck / controller (pull_request) Has been cancelled
Typecheck / desktop (pull_request) Has been cancelled
883e597d40
Epic 10 Story 10.2 — SDK для разработки backend-расширений Apollo Federation v2
subgraph'ов экосистемы кооператива.

Что внутри:
- ExtensionFederationModule.forRoot() — готовый GraphQL модуль с
  ApolloFederationDriver + autoSchemaFile.federation: 2
- ExtensionAuthModule.forRoot({ secret }) — passport-jwt стратегия,
  валидирует токен который Apollo Gateway forward'ит в Authorization-header.
- ExtensionJwtAuthGuard — guard для GraphQL resolver'ов
- SharedCooperator/SharedCooperative/SharedAccount — federation v2 stub'ы
  на core-entity для cross-extension references (@key + @external)
- HealthController GET /_health — обязательный для orchestrator'а
- loadExtensionConfig() — fail-fast загрузчик env'ов

Templates:
- Dockerfile multi-stage (builder + runtime + wget healthcheck)
- docker-compose.snippet.yaml — шаблон service'а для orchestrator'а

Контракт фиксирован Epic 10 PRD (apps-catalog/docs/epics/E10-federation-runtime.md)
и Architecture v3 (blago req 8b-architecture-v3-runtime-federation).
[E10-2b] feat(extension-hello-subgraph): PoC smoke-тест @coopenomics/extension-sdk
Typecheck / desktop (pull_request) Has been cancelled
Typecheck / controller (pull_request) Has been cancelled
68b91566ad
Epic 10 Story 10.2b — минимальный subgraph на extension-sdk доказывает что
Federation v2 driver + JWT module + healthcheck реально работают вместе.

Smoke результат (SUBGRAPH_PORT=33001 JWT_SECRET=test-secret COOPNAME=voskhod):
- GET /_health → {"status":"ok","version":"unknown","uptimeSeconds":N}
- POST /v1/graphql { helloFromExtension(name:"мир") { greeting fromExtension } }
  → {"greeting":"Здравствуй, мир!","fromExtension":"hello-subgraph@0.1.0"}
- POST /v1/graphql { _service { sdl } } → returns federation v2 SDL с
  @key/@external/@requires/@shareable директивами

Также в этом коммите:
- extension-sdk переключён с unbuild на обычный tsc (unbuild esbuild не
  поддерживает декораторы для target ES2020). main: dist/index.js, CommonJS.
- @types/passport-jwt в devDeps.

Cross-extension entity references (SharedCooperator @key + ResolveField)
живут в chatcoop subgraph'е (story 10.8) — там есть локальная сущность
ChatThread которая ссылается на пайщика. Этот PoC только доказывает
базовую механику.
[E10-3] feat(gateway-orchestrator): Apollo Gateway + subgraph registry skeleton
Typecheck / desktop (pull_request) Successful in 13m48s
Typecheck / controller (pull_request) Successful in 13m40s
8ea8bceea9
Epic 10 Story 10.3 — отдельный per-tenant Nest-сервис, объединяющий:
1. Apollo Federation Gateway (ApolloGatewayDriver) на /v1/graphql.
2. REST orchestrator API на /v1/internal/{extensions,composition}/*.
3. Subgraph registry в Postgres (TypeORM entity SubgraphRegistryEntity).

Что работает:
- Bootstrap seed'ит запись core-subgraph'а (coopback) → IntrospectAndCompose
  стартует с одним subgraph'ом → gateway проксирует все queries в core.
- JWT forwarding: Authorization-header forward'ится в каждый subgraph
  через RemoteGraphQLDataSource.willSendRequest.
- POST /v1/internal/extensions/install { packageId, version, url } —
  upsert в registry.
- DELETE /v1/internal/extensions/uninstall/:packageId — deactivate.
- POST /v1/internal/composition/refresh — 202 Accepted (реальный recompose
  по polling'у IntrospectAndCompose, ≤10 сек).
- GET /v1/internal/composition/status — текущие subgraph'ы.

Trade-off MVP:
- subgraphs читаются ОДИН раз на bootstrap (Apollo 2.9 IntrospectAndCompose
  ожидает статичный массив). Добавление НОВОГО subgraph'а → требует
  рестарта контейнера gateway-orchestrator. Warmup ~5 сек, делается
  orchestrator-pipeline при install'е (Story 10.4).
- Реальный docker pull/up/healthcheck — Story 10.4 (Install pipeline).
- Динамическая supergraph composition без рестарта — Story 10.3b
  (custom SupergraphManager).
- On-chain auto-update watcher — Story 10.5.

ENV: GATEWAY_PORT, DATABASE_URL, CORE_SUBGRAPH_URL, COOPNAME, JWT_SECRET.
Story 9.3.b-pub стола разработчика — мутация для воскходовского
chairman'а: координаты пакета (@scope/name + owner + compatible_subnets)
прокидываются на ca-admin POST /v1/admin/package, который сам
подписывает on-chain action apps::regpkg от имени chairman'а
кооператива-оператора каталога.

Backend (apps-catalog-proxy):
- PublishPackageInputDTO / PublishPackageResultDTO — GraphQL InputType +
  ObjectType (camelCase для Zeus, без snake-case утечек).
- AppsCatalogHttpService.registerPackage(): POST на /v1/admin/package;
  discriminated outcome (applied | conflict | failed) — мапит 409 в
  conflict, прочие axios-ошибки в failed; degraded-mode (без
  APPS_CATALOG_API_KEY) возвращает failed с явным сообщением, чтобы UI
  не вводился в заблуждение «опубликовано».
- AppsCatalogProxyResolver.publishPackage(): @UseGuards(GqlJwtAuthGuard,
  RolesGuard) + @AuthRoles(['chairman']) — мутация доступна только
  председателю кооператива.

Multipart upload install.js под архитектуру E10 НЕ делаем: расширения
теперь публикуются как npm-package + docker-image в Nexus отдельной
процедурой (`npm publish` / `docker push`) через scoped JWT от
CA-auth. Эта мутация — только on-chain маркер «такой пакет
существует»; релизы с manifest'ом — story 9.3.b-rel.

schema.gql / Zeus client — codegen за пределами этого PR (mono-каноном
pnpm generate-schema + generate-client + sdk build делается отдельным
коммитом, чтобы PR с backend changes не зависел от пересборки SDK
артефактов).

Frontend — отдельной story 9.3.b-ui: DeveloperPublishReleasePage.vue
сейчас заглушка, форму подключим после codegen'а Zeus.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Story 9.3.b-rel — мутация выкладки нового релиза ранее зарегистрированного
пакета. Прокидывает manifest + версию + tarball_sha256 на ca-admin
POST /v1/admin/releases, который сам валидирует manifest Zod-схемой
(PackageManifestSchema) и подписывает on-chain apps::setrelease от
имени chairman'а кооператива-оператора каталога.

Backend (apps-catalog-proxy):
- PublishReleaseInputDTO / PublishReleaseResultDTO — GraphQL Input/Object;
  manifest как GraphQLJSON (произвольная структура валидируется на
  ca-admin'е).
- AppsCatalogHttpService.createRelease(): POST /v1/admin/releases;
  discriminated outcome — applied (с опциональным transaction_id) |
  invalidManifest (HTTP 422 INVALID_MANIFEST мапится явно, чтобы UI
  показывал валидационную ошибку отдельно от network/auth) | failed
  для прочих.
- AppsCatalogProxyResolver.publishRelease(): @AuthRoles(['chairman']).

Под архитектуру E10 manifest содержит ссылки на артефакты в Nexus:
- coopenomics.backend.image — docker-image (subgraph расширения);
- coopenomics.frontend.tarball — npm tarball (desktop-bundle).

Сам manifest НЕ валидируется на стороне controller'а — это делает
ca-admin (там Zod-схема и она же будет расширена для package.json
полей в story 10.7).

Frontend (форма Опубликовать релиз) — отдельной story 9.3.b-ui после
codegen'а Zeus.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
[9.3.b umbrella-merge] Mutation.publishPackage + publishRelease — proxy на ca-admin — closes #72
Typecheck / desktop (pull_request) Successful in 13m38s
Typecheck / controller (pull_request) Successful in 13m17s
4e64637823
claude changed title from apps-catalog: integration research + bundle/remote coexistence plan to [apps-catalog umbrella] mono — Federation MWP (E9 demo pilot + E10 runtime federation + 9.3.b publish) 2026-06-04 04:55:24 +00:00
claude added 2 commits 2026-06-04 11:22:41 +00:00
Story 10.4 — pipeline установки subgraph-расширения:
1. (опц.) OCI token у CA-auth → docker pull образа;
2. (опц.) docker compose up сервиса;
3. healthcheck poll по url subgraph'а до 200 OK;
4. upsert в subgraph_registry (Apollo Gateway за ≤10с подхватит);
5. на failure — composeDown rollback + discriminated outcome {applied|failed}.

InstallController стал тонкой обёрткой над InstallOrchestratorService.
Внешние зависимости (docker shell / fetch / CA-auth) изолированы за
портами; тесты (7/7 green) гоняют сценарий через ин-мемори моки без
реального docker daemon'а и сети.

Что ОСТАЁТСЯ для отдельной ветки под этим зонтиком:
- wiring approve→install REST из mono controller (mutation approvePackage);
- desktop notification после успешного install'а;
- E2E на реальном compose + chatcoop subgraph (Story 10.8).
claude added 2 commits 2026-06-04 11:23:14 +00:00
Story 9.9 «Стол восхода: approve pending packages» — backend-сторона.

GraphQL contract:
- Query.appsCatalogPendingModerations(status?: ModerationStatusEnum, limit?: Int)
  → [ModerationRequestDTO]. По умолчанию SUBMITTED. Chairman-only.
- Mutation.approveModeration(data: ApproveModerationInputDTO!)
  → ApproveModerationResultDTO. Discriminated outcome:
    applied / pendingChain (423) / conflict (409) / requiresOverride (403) / failed.
- Mutation.rejectModeration(data: RejectModerationInputDTO!)
  → RejectModerationResultDTO. Discriminated outcome: applied / conflict / failed.

HTTP-service: 3 новых метода (listSubmittedModerations / approveModeration /
rejectModeration) на ca-admin endpoints, добавленных параллельным
apps-catalog PR #7. Mapping snake_case → camelCase; degraded mode на
list — пустой массив, на mutations — failed с явной причиной (чтобы UI
не вводился в заблуждение «approved»).

ReleaseScope передаётся как InputType с union-style полями
(type + subnets?/coopnames?); резолвер валидирует соответствие type →
непустой массив перед отправкой на ca-admin.

Зависимость: apps-catalog PR #7 (GET /v1/admin/moderation) должен быть
смёрджен в feat/E9-demo-app-pilot до того, как этот endpoint можно
использовать в e2e.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
claude merged commit 9df3bfe4a9 into dev 2026-06-04 11:26:48 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: C9S/mono#64