Commit Graph

2967 Commits

Author SHA1 Message Date
coopops 9d9cb7f5cf fix(controller): UInt128 из antelope + from(string) — конфликт инстанций wharfkit после обновления lock
Typecheck / desktop (pull_request) Successful in 14m20s
Typecheck / controller (pull_request) Successful in 13m28s
UInt128 из re-export'а @wharfkit/session перестал совпадать по типам с
API.v1.TableIndexType, а UInt128.from не имеет перегрузки под bigint
(возврат unknown) — dev-запуск controller падал TS2345.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 10:39:57 +00:00
coopops 5d88d8c655 fix(controller): BigInt(BN) не компилируется с @types/bn.js из lock-файла
Typecheck / controller (pull_request) Has been cancelled
Typecheck / desktop (pull_request) Has been cancelled
После обновления pnpm-lock (типы для orchestrator) приехал @types/bn.js,
и UInt64.value стал типизированным BN — BigInt(BN) перестал собираться,
dev-запуск controller падал TS2345. Конвертация через десятичную строку.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 10:35:09 +00:00
coopops b5a22d04ab fix(apps-catalog-proxy): авто-выпуск tenant JWT по COOPERATIVE_WIF вместо статического env-токена
Typecheck / controller (pull_request) Has been cancelled
Typecheck / desktop (pull_request) Has been cancelled
Tenant JWT ca-auth живёт 30 минут — статический APPS_CATALOG_TENANT_JWT
умирал через полчаса после деплоя, и subscribe mutation навсегда падала
401. Теперь coopback сам выпускает токен (challenge → подпись
coopname@active → verify), кэширует до exp с минутным запасом и
обновляет автоматически. Статический env-токен остаётся как
отладочный override.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 10:26:41 +00:00
coopops b267ee2d24 [E2E][@ant] fix(orchestrator): экспортировать InstallOrchestratorService из OrchestratorModule
Typecheck / desktop (pull_request) Successful in 13m58s
Typecheck / controller (pull_request) Failing after 8m7s
WatcherModule инжектит install-pipeline в OnChainWatcherService, но
модуль провайдера его не экспортировал — boot падал DI-резолвом
(скрытый баг E10-5b: с полным federation-профилем orchestrator ни разу
не стартовал).
2026-06-11 08:16:14 +00:00
coopops e7697c82d8 [E2E][@ant] fix: объявить директиву @auth в субграф-схеме + типы elliptic/bs58 для orchestrator
Typecheck / controller (pull_request) Has been cancelled
Typecheck / desktop (pull_request) Has been cancelled
- buildSubgraphSchema (federation v2) строго валидирует SDL: @auth из
  AuthRoles-декоратора без объявления валит boot coopback'а
  ('Unknown directive "@auth"' x100). Объявление через
  buildSchemaOptions.directives — transformSchema продолжает работать.
- orchestrator не компилился ts-node-dev'ом: elliptic/bs58 без типов
  (TS7016). @types/bs58 строго ^4 — v5-пакет это deprecation-пустышка
  под bs58@5, который шипит собственные типы.
2026-06-11 08:14:14 +00:00
coopops 8448d6fc73 [E12-3][@ant] feat(coopback+desktop): доставка фронтов из кэша orchestrator'а — установленные пакеты вместо публичного каталога
Typecheck / desktop (pull_request) Successful in 13m42s
Typecheck / controller (pull_request) Has been cancelled
coopback: ORCHESTRATOR_URL + методы listInstalledFrontends /
fetchInstalledInstallScript; GET /v1/apps-catalog/installed-frontends
(JWT); install/:scope/:name переключён на volume-кэш orchestrator'а с
проброской X-Install-Script-Sha256/X-Package-Version (fallback на прямой
ca-admin только без ORCHESTRATOR_URL — degraded dev). desktop
remote-loader: список remote-расширений — installed-frontends (реально
установленные по подписке), sha256 install.js сверяется через
crypto.subtle перед eval.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:21:31 +00:00
coopops 071525f2a2 [E12-2][@ant] feat(orchestrator): volume-кэш фронт-частей расширений — JWT-gated доставка вместо публичного каталога
Typecheck / desktop (pull_request) Has been cancelled
Typecheck / controller (pull_request) Has been cancelled
install.js активного релиза качается с ca-admin при установке/обновлении
пакета (watcher-события подписки/релиза), проверяется по sha256
(заголовок ca-admin + независимая сверка с coopenomics.frontend.installSha256
из манифеста в ca-auth registry, fail-closed) и складывается в volume.
Endpoints /v1/internal/extensions/frontend{,/:scope/:name/install.js} —
источник для coopback-прокси (E12-3): desktop получает только фронты
реально установленных у кооператива пакетов.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:16:05 +00:00
coopops 27220c8572 [E10-5b] feat(orchestrator): реальный on-chain watcher — авто-установка расширений без ручных вызовов
Typecheck / desktop (pull_request) Successful in 13m36s
Typecheck / controller (pull_request) Successful in 13m13s
- ChainRpcAppsEventStream: поллинг таблиц apps-контракта (releases/subs/
  packages) через nodeos get_table_rows, синтез событий из диффа снапшотов;
  маппинг on-chain package_id (eosio::name) → npm @scope/name через
  packages.package_name; initial-снапшот доводит стенд до chain-состояния;
- CaAuthReleaseMetadata: install-spec из npm-манифеста CA-auth registry —
  signed-request (канон X-Signature k1: + canonicalize) → per-package JWT
  (выдаётся только при активной подписке) → coopenomics.backend секция;
  тот же JWT идёт в docker login (подписка = единственный источник доступа);
- docker run-путь install pipeline'а: контейнер расширения поднимается
  прямым docker run (имя/сеть/env из spec'а), без заранее описанного
  compose-сервиса; rollback снимает контейнер;
- DI-проводка по env: CHAIN_RPC_URL / COOPERATIVE_WIF включают реальные
  impl'ы, без них — Noop (dev-стенд стартует как раньше);
- compose: env-переменные watcher'а у сервиса orchestrator;
- 41 юнит-тест зелёный (8 новых на поллер, 6 на metadata/подпись)
2026-06-10 19:17:47 +00:00
coopops a401065246 [E9-UI] feat(desktop): канон стола разработчика, живая подписка, модерация, авто-подхват пакетов
- ExtensionsShowcase: Material-иконки вместо FontAwesome, BaseBanner/
  BaseButton/BaseDialog/BaseBadge/EmptyState вместо сырых q-*, скелетон
  вместо спиннера; «Подписаться» вызывает Mutation.subscribePackage
  с разбором статусов (trial/active/clientNotRegistered/...);
- Опубликовать релиз: добавлен шаг 2 — Mutation.publishRelease (версия +
  manifest с coopenomics-секцией + sha256), раньше мутация не вызывалась;
- новая страница «Модерация» (операторский approve/reject восхода) по
  канону .table-wrap + BaseBadge + TableSkeleton + EmptyState;
- «Мои пакеты»/«Pricing»: реальные данные каталога вместо хардкод-карточек;
- init-installed-extensions: периодический идемпотентный re-pass — новый
  пакет появляется в drawer'е без F5 (Architecture v3 шаг 18, вместо WS);
- иконки воркспейса разработчика переведены на Material
2026-06-09 20:59:41 +00:00
coopops 65e1cb23dc [E9-3b] feat(controller+sdk): enum-статусы publish* + SDK-обёртки подписки и модерации + regen ZEUS
- PublishPackageStatus/PublishReleaseStatus через registerEnumType вместо
  строковых литералов (канон: статусы — всегда enum);
- SDK: Mutations SubscribePackage/ApproveModeration/RejectModeration,
  Query AppsCatalogPendingModerations, селектор moderationRequestSelector;
- ZEUS перегенерирован от полного merged-dev состояния схемы (закрывает
  заявленный в PR долг: sdk на ветке не компилировался — schema отставала
  от dev на registration/notifications/voteagainst)
2026-06-09 20:59:41 +00:00
coopops f48205e461 [E9-3b-sub] chore(env): APPS_CATALOG_AUTH_URL + APPS_CATALOG_TENANT_JWT в .env.example
Без них Mutation.subscribePackage всегда в degraded-режиме (status=failed)
2026-06-09 20:59:40 +00:00
coopops 4208004ae6 [E10-4] feat(orchestrator): Dockerfile + compose-сервис (profile federation)
Обычный docker compose up -d сервис НЕ поднимает — только явный
--profile federation. Socket-mount для shell-out docker pull/compose;
порт 4000 на localhost; doc-фикс примера CORE_SUBGRAPH_URL (2998)
2026-06-09 20:59:21 +00:00
coopops 8bcfb77c57 [E10-4] fix(orchestrator): healthcheck /_health + docker pull по OCI token flow
- health-probe бьёт в <origin>/_health (канон extension-sdk), а не в GraphQL
  endpoint, который на GET отвечает 400/405 — install всегда падал;
- oci-token-client выровнен с реальным контрактом ca-auth (Story 10.6):
  GET /v2/auth/token?service=ca-auth&scope=repository:<scope>/<name>:pull,
  Basic-auth с per-package JWT в password;
- docker pull через изолированный DOCKER_CONFIG + docker login (стандартный
  WWW-Authenticate token flow) вместо несуществующего credential helper'а;
- watcher передаёт coopname в install pipeline (username для docker login)
2026-06-09 20:59:21 +00:00
coopops a56d14e349 [E10-3b] fix(orchestrator): boot DI + реальный dynamic supergraph
- GraphQLModule.forRootAsync не видел SubgraphRegistryService из родительского
  модуля (boot-crash Nest DI) — провайдеры вынесены в SubgraphRegistryModule;
- supergraph-manager подключён к gateway через supergraphSdl-hook: появление
  нового subgraph'а в registry подхватывается без рестарта orchestrator'а;
- composer-impl: _service{sdl}-introspection + @apollo/composition;
- POST /v1/internal/composition/refresh теперь форсит немедленный recompose
  (SupergraphRefreshService), а не no-op;
- имена subgraph'ов санитизируются для join__Graph enum'а
2026-06-09 20:59:21 +00:00
coopops 29ab3ad00f [E10-3b] feat(orchestrator): dynamic supergraph manager — recompose без рестарта
Typecheck / desktop (pull_request) Failing after 6m29s
Typecheck / controller (pull_request) Failing after 6m36s
Story 10.3b — custom SupergraphManager, который на каждый poll-tick
re-читает subgraph registry и если список изменился — пересобирает
supergraph и вызывает gateway update(newSdl).

Раньше Apollo Gateway получал статический список subgraph'ов на
bootstrap'е через IntrospectAndCompose — добавление нового
расширения (Story 10.4 install pipeline) требовало рестарта контейнера.
Теперь watcher install pipeline → registry upsert → manager на
следующий tick видит новую запись → recompose → gateway swap'ает
supergraph in-memory. Без рестарта.

Идемпотентность через fingerprint (`name:url` sorted join):
- список не изменился → composer НЕ зовётся, ничего не делаем;
- список изменился → composer.compose() → update().

Скрытая ловушка: fingerprint обновляем только ПОСЛЕ успешного
compose'а — иначе exception в composer'е навсегда залипает в
устаревшем состоянии (следующий tick думает что состояние актуально).
Покрыто continuity-тестом.

7/7 unit-тестов покрывают: initial, idempotent tick, add/remove/url-change,
continuity на ошибке composer'а, cleanup. Используют jest fake timers.

Интеграция с Apollo Gateway (gateway.module.ts) — отдельный follow-up
(`feat/E10-3b-apollo-integration`), требует @apollo/composition impl
для SupergraphComposerPort.

(cherry picked from commit 6ac6a0319b)
2026-06-09 11:54:42 +00:00
coopops ad2de42fdc [E10-5] feat(orchestrator): on-chain watcher для apps-contract
Story 10.5 — orchestrator слушает события apps-contract и автоматически
синхронизирует установленные расширения с тем, что в блокчейне.

Обрабатываемые события (discriminated union по `kind`):
- `release-published` → scope check → fetch metadata → install pipeline;
- `subscription-activated` → fetch active release → install pipeline;
- `release-withdrawn` → registry.deactivate;
- `subscription-expired` → registry.deactivate (для нашего coopname).

Все три триггера install'а идут через единый InstallOrchestratorService
(idempotent, upsert в registry). Apollo Gateway за ≤10с подхватит
изменения polling'ом — supergraph рекомпозируется без рестарта.

Порты (AppsContractEventStreamPort, ReleaseMetadataPort) изолируют
watcher от реального chain-чтения. В этом PR — Noop-импленты в
WatcherModule + контракт; реальный parser2/RPC-impl поедет в
follow-up'е (`feat/E10-5b-chain-rpc-impl`).

11/11 unit-тестов покрывают все 4 типа событий + scope-фильтрацию
(all/cooperatives/subnets/empty) + coopname-фильтрацию по своему
кооперативу. Тесты гоняют сценарий через ин-мемори фейки портов
без реальной chain-ноды и Postgres.

(cherry picked from commit b926dc2a15)
2026-06-09 11:54:42 +00:00
coopops a79eb49954 [E9-3b-ui] feat(desktop+sdk): форма publishPackage в Столе разработчика
Story 9.3.b-ui. Закрывает UI-петлю Эпика 9 «MVP demo-app pilot».

SDK (@coopenomics/sdk):
- mutations/extensions/publishPackage.ts — wrapper над Mutation.publishPackage,
  селектор {status, requestId, error}.
- mutations/extensions/publishRelease.ts — wrapper над Mutation.publishRelease,
  селектор {status, requestId, transactionId, error}. Готов для отдельной
  страницы публикации релизов (следующая story 9.3.b-rel-ui).
- mutations/extensions/index.ts: добавлены PublishPackage / PublishRelease.
- Codegen (controller/sdk): pnpm generate-schema + generate-client + sdk build —
  zeus подхватил PublishPackageInputDTO / PublishReleaseInputDTO.

Desktop:
- features/PublishPackage/{api,model}/index.ts — каноническая пара по mono-ai-N
  FSD-конвенции: api тонко оборачивает client.Mutation, model задаёт
  IPublishPackageInput = Mutations.Extensions.PublishPackage.IInput['data'] и
  composable usePublishPackage (isSubmitting / lastResult / lastError / submit).
- pages/DeveloperPublishReleasePage.vue: форма из BaseForm + BaseInput
  (packageId @scope/name + ownerUsername Antelope-name + compatibleSubnets
  textarea с chain_id). Валидация регуляркой ДО отправки. BaseBanner с
  warning если роль текущей сессии не chairman; кнопка submit disabled.
  Зелёный banner при applied, оранжевый — при conflict. Канон BaseBanner
  variant='warn|pos', BaseCard variant='default'. Session-данные читаются
  через useSessionStore (pinia auto-unwrap, без .value).

Что не делалось:
- Форма publishRelease (manifest + sha256) — отдельная страница; mutation
  в SDK уже готова под неё.
- Реальная привязка к списку «Мои пакеты» — пока кнопка отдельной страницы;
  список и интеграция (post-success refresh) — последующая итерация.

(cherry picked from commit 1a0ac54f88)
2026-06-09 11:54:31 +00:00
coopops 00e07163e4 [E9-3b-sub] feat(controller): Mutation.subscribePackage — chairman активирует подписку через ca-auth
Story 9.3.b-sub: пайщик в десктопе нажимает Подписаться в ExtensionsShowcase.
Backend проксирует это в ca-auth POST /v1/subscriptions/activate с tenant
JWT кооператива-партнёра. ca-auth активирует подписку (trial → active по
free_trial_period_seconds; pay-period после expired); on-chain
apps::regsub подписывает ca-auth от имени каталога-оператора. После
активации pricing-watcher на coopback партнёра подхватит подписку
(Story 9.6).

GraphQL:
- Mutation.subscribePackage(data: SubscribePackageInputDTO!)
  → SubscribePackageResultDTO. Discriminated outcome:
    activated / alreadyActive (409) / clientNotRegistered (403) /
    unavailable (423) / failed.

Защита: chairman кооператива-партнёра (GqlJwtAuthGuard + RolesGuard +
AuthRoles).

Config:
- APPS_CATALOG_AUTH_URL — base URL ca-auth (отдельный от admin).
- APPS_CATALOG_TENANT_JWT — JWT кооператива-партнёра.

Tenant читается ca-auth'ом ТОЛЬКО из JWT — body НЕ может его
переопределить (закрывает «активировать от имени другого tenant'а»).

На degraded-mode (нет AUTH_URL/TENANT_JWT) — mutation возвращает failed
с явной причиной, а не silent no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
(cherry picked from commit dbe349f742)
2026-06-09 11:54:05 +00:00
coopops 28f8d1f581 Revert "Revert "Merge pull request '[apps-catalog umbrella] mono — Federation MWP (E9 demo pilot + E10 runtime federation + 9.3.b publish)' (#64) from apps-catalog into dev""
This reverts commit 96e16ee6ab.
2026-06-09 11:53:56 +00:00
coopops 9ae811dae3 [@ant] fix(desktop/push): device-aware подписка + кнопка переподписки в колокольчике
Корень бага «push приходит только на одно устройство»: autoSubscribe
гейтился store.isSubscribed (= у аккаунта есть подписка на ЛЮБОМ устройстве),
поэтому второе устройство никогда не подписывалось. Введён endpoint текущего
браузера + computed isThisDeviceSubscribed; autoSubscribe теперь идемпотентно
регистрирует каждое устройство. Добавлены resubscribe()/refreshDeviceState()
и строка статуса push с кнопкой «Включить/Переподписать» в виджете колокольчика.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 11:51:26 +00:00
coopops a77fa945a6 [C28-28][@ant] chore(email-relay): вынести релей из mono в C9S/email-relay
Релей переехал в отдельный репозиторий C9S/email-relay, собирается локально
плейбуком (playbooks/email-relay) — релиз mono его больше не пересобирает.
Прод-образ mono-base (prune --prod) не подходил для standalone-сервиса.

Удалено: components/email-relay, build_service в release.yaml, dev-сервис в
docker-compose. Контроллерный relay-режим (EMAIL_RELAY_URL/TOKEN в
email-channel.adapter + config) ОСТАЁТСЯ — он и активирует отправку через релей.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:47:59 +00:00
coopops be7e1585b0 [C28-28][@ant] fix(email-relay): ts-node+typescript в dependencies (переживают prune --prod)
Прод-образ mono-base делает `pnpm prune --prod` (Dockerfile:74) — devDeps
вырезаются. ts-node был в devDependencies → в проде `sh: ts-node: not found`,
контейнер в restart-loop, /health не отвечал. controller держит ts-node в
dependencies — повторяем паттерн. (Коммит из закрытого PR #115 не попал в dev,
вношу прямо.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:47:15 +00:00
Alex Ant f37605b343 migrations 2026-06-09 14:10:09 +05:00
ant f728563bdb Merge pull request '[C28-28] feat(email-relay): HTTP→SMTP релей для коопов с закрытым SMTP' (#115) from feature/C28-28-email-relay into dev
Reviewed-on: #115
Reviewed-by: Алексей Муравьев <chairman.voskhod@gmail.com>
2026-06-09 07:54:56 +00:00
coopops 468c946610 [C28-28][@ant] fix(email-relay): убрать mailpit из compose, env_file как coopback
Typecheck / desktop (pull_request) Successful in 13m51s
Typecheck / controller (pull_request) Has been cancelled
mailpit был только локальным SMTP-перехватчиком для теста — в поставке не нужен.
email-relay сам ходит в реальный SMTP через nodemailer; конфиг (RELAY_TOKEN,
SMTP_*) выносим в components/email-relay/.env по образцу coopback, без отдельного
контейнера и inline-параметров.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 07:51:58 +00:00
coopops 7e2b26a02e [C28-28][@ant] feat(email-relay): HTTP→SMTP релей для коопов с закрытым SMTP
Typecheck / desktop (pull_request) Has been cancelled
Typecheck / controller (pull_request) Has been cancelled
Хостинги коопов режут исходящий SMTP → письма controller'а уходят в timeout
(раньше хабом был Novu, его убрали). Новый компонент @coopenomics/email-relay
принимает письма по HTTPS с Bearer-токеном и форвардит по SMTP. Ставится на
сервер с открытыми портами (плейбук в playbooks/email-relay).

- components/email-relay: express + nodemailer, POST /send + GET /health,
  Bearer-токен (constant-time), опц. IP-allowlist, конфиг из ENV
- controller: email-channel.adapter получил relay-режим — если задан
  EMAIL_RELAY_URL, письмо уходит POST'ом на релей; иначе прямой SMTP как
  раньше (opt-in, без регрессии)
- docker-compose: дев-сервисы email-relay + mailpit (SMTP-перехватчик для E2E)
- release.yaml: сборка образа dicoop/email-relay

E2E проверен локально: controller-формат письма → релей → SMTP → mailpit,
тело с <br> и заголовки целы; 401 на отсутствие/неверный токен, 400 на пустое тело.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 07:42:15 +00:00
coopops a76f875725 [C28-27][@ant] fix(desktop): in-app уведомления видны на тёмной теме
Build bootstrap container / build (push) Successful in 3m2s
В колоколе уведомлений на тёмной теме элементы сливались с фоном панели:
разделители на --p-line (0.06 white) почти невидимы, а непрочитанные
отличались лишь цветом текста + точкой — всё тонуло в --p-surface. На светлой
контраст тёмного текста на белом спасал.

Канон-токенами (обе темы, светлую не ухудшает): панели — рамка --p-line-1
для контура; разделители между уведомлениями — --p-line-1 (заметнее); у
непрочитанных подложка --p-primary-soft + левый акцент-бар --p-primary,
hover/focus — --p-primary-line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 07:22:39 +00:00
coopops 1d235e5caf chore(release): publish
Build bootstrap container / build (push) Successful in 3m5s
Release / release (push) Successful in 24m54s
Release / publish-packages (push) Failing after 8m23s
Release / trigger-coopenomics-docs (push) Successful in 2s
Release / trigger-mono-docs (push) Successful in 2s
v2026.6.9-2
2026-06-09 07:18:39 +00:00
coopops 98b9c03977 chore(release): publish
Build bootstrap container / build (push) Successful in 3m5s
Release / release (push) Successful in 26m40s
Release / publish-packages (push) Has been skipped
Release / trigger-coopenomics-docs (push) Has been skipped
Release / trigger-mono-docs (push) Has been skipped
v2026.6.9-alpha-1
2026-06-09 07:09:56 +00:00
ant c05daad8fd Merge pull request 'feat(pwa): надёжное оповещение об обновлении через version-watch' (#114) from feat/pwa-version-watch into dev
Reviewed-on: #114
2026-06-09 07:06:53 +00:00
ant c3ff628dac Merge pull request 'feat(desktop): статусы пайщиков бейджами + удаление непринятых аккаунтов из реестра' (#112) from fix/participants-registry-status-badges into dev
Build bootstrap container / build (push) Successful in 3m7s
Reviewed-on: #112
Reviewed-by: Алексей Муравьев <chairman.voskhod@gmail.com>
2026-06-09 06:52:52 +00:00
coopops 3ba3a867ad feat(pwa): надёжное оповещение об обновлении через version-watch
Typecheck / desktop (pull_request) Successful in 15m5s
Typecheck / controller (pull_request) Successful in 13m12s
Заменяет ненадёжный триггер от lifecycle service worker'а (не срабатывал
на iOS standalone PWA, при первой установке и когда бинарь SW не менялся)
на сравнение версий: запечённая в бандл package-версия (process.env.APP_VERSION)
сверяется с self-report SSR-ноды (/version). При расхождении — существующий тост.

- quasar.config: APP_VERSION из package.json в build.env; middleware 'version'
- src-ssr/middlewares/version.ts: self-report /version (JSON, no-store)
- entities/AppVersion: стор useUpdateWatch (реестр компонентов, сейчас shell),
  опрос /version раз в 5 мин + при возврате на вкладку; SPA-safe (нет ноды -> no-op)
- init-app: старт version-watch рядом с systemMonitoring
- register-service-worker: убран SW-триггер; applyUpdate устойчив (waiting -> SKIP_WAITING, иначе reload)
- LeftDrawerMenu: версия приложения в футере рейла

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 06:46:04 +00:00
coopops 15813d91ef [@ant] fix(desktop): правка текста предупреждения при удалении registered-аккаунта
Typecheck / desktop (pull_request) Successful in 15m1s
Typecheck / controller (pull_request) Successful in 13m41s
«исчезнет» → «исчезает»; убрано предложение про отзыв заявки на повестке —
кнопка доступна только когда аккаунт уже в цепи (after оплаты), решение совета
тут неприменимо.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 06:44:31 +00:00
coopops 955142cf84 [@ant] feat: удаление любого непринятого аккаунта из реестра (гард только participant_account)
Typecheck / controller (pull_request) Has been cancelled
Typecheck / desktop (pull_request) Has been cancelled
Прежний allow-list статусов исключал Registered — но именно туда попадают
отклонённые советом и оплаченные брошенные регистрации (отказ/возврат
оставляют статус registered; failed/refunded users.status никем не
выставляются). То есть чистка не работала для своей же цели «убрать
незавершённые/отклонённые регистрации (тестеры)».

- backend deleteAccount: убран allow-list по статусу, остаётся единственный
  гард — НЕ принят в кооператив (нет participant_account).
- frontend isDeletable: !participant_account. Кнопка удаления теперь и у
  Registered (оплачен/на рассмотрении совета/отклонён/возврат).
- confirm-диалог: для blockchain-registered (Registered) предупреждение, что
  on-chain аккаунт неудаляем (имя в цепи занято навсегда) + про отзыв заявки
  на повестке, если ещё на рассмотрении совета.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 06:32:10 +00:00
coopops 7efbf90c9b [C28-27][@ant] fix(desktop): таблицы переносят содержимое, не скроллят по горизонтали
На мобиле (и в узком окне десктопа) canon-таблицы выходили за ширину: левая
колонка обрезалась, появлялся внутренний горизонтальный скролл — из-за
фиксированной min-width (780–1000px), которую виджеты ставят локально, а
скелетон inline-стилем.

Централизовал в каноне components.css: `.table { min-width: 0 !important }`
снимает форс-ширину на всех экранах (!important — иначе scoped/inline
перебивают канон), таблица всегда влезает (width:100%) и переносит содержимое
на следующую строку вместо скролла. На узких экранах (≤599px) дополнительно
table-layout:auto + перенос в ячейках + плотнее паддинги, чтобы многоколоночная
таблица читалась переносом, а не клиппингом.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 06:29:07 +00:00
coopops 0e9542fff4 [@ant] feat(desktop): статусы пайщиков бейджами в реестре + enrich registration_payment
Typecheck / desktop (pull_request) Successful in 13m49s
Typecheck / controller (pull_request) Has been cancelled
- ParticipantsTable/ParticipantCard: галочка «Активен» → BaseBadge с
  человекочитаемым статусом; колонка «Активен» → «Статус».
- entities/Account/lib/accountStatus.ts: getAccountStatusBadge — сводит
  participant_account (accepted|blocked) + provider_account.status +
  отказ совета (Registered + возврат взноса) → «Отклонён советом».
- controller getAccounts: enrich registration_payment через this.getAccount,
  иначе на списке реестра отказ совета неотличим от «ожидает совет».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 06:14:46 +00:00
ant 8ffe4bea94 Merge pull request 'feat: Центр уведомлений DC v3 (замена Novu) [C28-22…27] — код-комплит, 6/6 эпиков' (#60) from feat/notification-center-dc-v3 into dev
Reviewed-on: #60
Reviewed-by: Алексей Муравьев <chairman.voskhod@gmail.com>
2026-06-08 08:37:29 +00:00
coopops 70bd1323c7 chore(release): publish
Build bootstrap container / build (push) Successful in 3m8s
Release / release (push) Successful in 25m6s
Release / publish-packages (push) Failing after 8m25s
Release / trigger-coopenomics-docs (push) Successful in 2s
Release / trigger-mono-docs (push) Successful in 1s
v2026.6.8-6
2026-06-08 07:03:58 +00:00
coopops 765af3cbef chore(release): publish
Build bootstrap container / build (push) Successful in 2m57s
Release / release (push) Successful in 25m7s
Release / publish-packages (push) Has been skipped
Release / trigger-coopenomics-docs (push) Has been skipped
Release / trigger-mono-docs (push) Has been skipped
v2026.6.8-alpha-5
2026-06-08 07:03:41 +00:00
ant 9cdee035b9 Merge pull request 'fix(controller): приложения-оферты ЦПП к заявлению на повестке (wallet::signagree)' (#108) from fix/agenda-program-offer-links into dev
Reviewed-on: #108
2026-06-08 07:03:13 +00:00
ant 9553697f2b Merge pull request 'fix(desktop): чистить технические детали ассертов цепи в тостах ошибок' (#110) from fix/sanitize-blockchain-error-toast into dev
Reviewed-on: #110
2026-06-08 07:02:47 +00:00
ant 124782a8d9 Merge pull request 'fix(controller): не фиксировать возврат паевого взноса в БД при ошибке блокчейна' (#109) from fix/wallet-withdraw-no-phantom-payment into dev
Reviewed-on: #109
2026-06-08 07:02:39 +00:00
coopops f10b49ac8f [@ant] fix(desktop): чистить технические детали ассертов цепи в тостах ошибок
Typecheck / desktop (pull_request) Successful in 13m28s
Typecheck / controller (pull_request) Successful in 12m29s
Пользователю в тост летел сырой ассерт контракта, напр.
`walletop TRANSFER: недостаточно средств на кошельке w.wal.share`.
Ему не нужны ни scope-префикс операции, ни служебное имя кошелька — он
нажал конкретную кнопку и так понимает, о каком кошельке речь.

Добавлен универсальный санитайзер sanitizeBlockchainError, встроенный в
единую точку показа ошибок FailAlert:
- снимает ведущий технический scope-префикс (`walletop TRANSFER:`,
  `ledger2::apply:`, `o.mkt.supply:`) — распознаёт идентификатор с
  `.`/`::` либо слово+ALLCAPS-опкод, кириллицу не трогает;
- убирает служебные имена ledger2-кошельков (`w.wal.share` и т.п.);
- нормализует пробелы и ставит заглавную первую букву.

Результат для примера выше — «Недостаточно средств на кошельке».
Обычные (нетехнические) сообщения проходят без изменений.

Полный технический текст остаётся разработчикам: FailAlert дублирует
сырой message в console.error, бэкенд пишет его в логи контроллера.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 06:42:22 +00:00
coopops 75548036f4 chore(release): publish
Release / release (push) Successful in 24m41s
Build bootstrap container / build (push) Successful in 38s
Release / publish-packages (push) Failing after 8m22s
Release / trigger-coopenomics-docs (push) Successful in 2s
Release / trigger-mono-docs (push) Successful in 1s
v2026.6.8-4
2026-06-08 06:27:19 +00:00
coopops ec0427c778 chore(release): publish
Build bootstrap container / build (push) Successful in 3m8s
Release / release (push) Failing after 14m44s
Release / publish-packages (push) Has been skipped
Release / trigger-coopenomics-docs (push) Has been skipped
Release / trigger-mono-docs (push) Has been skipped
v2026.6.8-alpha-3
2026-06-08 06:27:02 +00:00
coopops 29417dd425 [@ant] fix(controller): не фиксировать возврат паевого взноса в БД при ошибке блокчейна
Typecheck / desktop (pull_request) Successful in 13m22s
Typecheck / controller (pull_request) Successful in 15m49s
Баг: при «Получить возврат» с суммой больше L3-баланса платёж писался в
gateway-БД (AWAITING_AUTHORIZATION) ДО on-chain транзакции. Контракт wallet
отклонял заявку (недостаточно L3-средств), а в разделе «Платежи» оставался
висеть фантомный исходящий платёж со статусом FAILED.

Фикс — порядок операций в WalletInteractor.createWithdraw:
1. prepareWithdraw — все валидации (символ, дубликат hash, платёжный метод)
   и сборка записи, БЕЗ записи в БД;
2. on-chain wallet::createwthd — при недостатке средств падает здесь,
   ни одной записи о платеже не создаётся;
3. persistWithdraw — фиксация платежа в БД только после успешной заявки.

GatewayInteractor.createWithdraw разбит на prepareWithdraw/persistWithdraw
(старый combined-метод сохранён как обёртка). Порт и оба адаптера обновлены.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 06:00:02 +00:00
coopops ca1d1ec1a2 [@ant] fix(controller): приложения-оферты ЦПП к заявлению на повестке (wallet::signagree)
Typecheck / desktop (pull_request) Successful in 14m13s
Typecheck / controller (pull_request) Successful in 13m2s
Программные оферты (program_id > 0) с Эпика 2 уходят на цепь через
wallet::signagree (commit 21e94ce0ed), а не soviet::sndagreement —
soviet::newagreement по ним не создаётся. Агрегатор пакета документов
(document-package-v1) искал приложения к заявлению только по
soviet::newagreement, поэтому подписанная оферта молча выпадала из links
и не отображалась как приложение к заявлению на повестке совета (при этом
сам документ виден в реестре).

Резолв каждого linkHash вынесен в общий хелпер buildLinkedAggregate;
носитель подписи ищется сначала в soviet::newagreement, затем фолбэком в
wallet::signagree. Унифицированы три дублировавшихся цикла (statement /
decision / acts). Добавлен регрессионный unit-тест.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 05:49:07 +00:00
coopops c28bb81c25 [C28-27][@ant] fix: in-app уведомления — перенос строки вместо литерального <br>
In-app тело инбокса рендерится как текст ({{ n.description }}, без v-html —
payload несёт ФИО/заголовки, v-html = XSS-вектор), поэтому HTML-тег <br> из
шаблона показывался строкой «№C53E<br>От: …». Перевёл 2 in-app шаблона
(new-agenda-item, approval-request) с <br> на \n и добавил white-space:
pre-line на .notification-center__item-desc (line-clamp:2 сохранён).

Push не трогаю — его тела уже plain-text без тегов, отображается верно.
Email оставлен на HTML (<br>/<strong>) — рендерится почтовым клиентом.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 05:28:04 +00:00
coopops 4df811d40f chore(desktop): пометить stripLegacyBankKpp на удаление после 01.09.2026
Build bootstrap container / build (push) Successful in 2m18s
Временный shim очистки persisted-localStorage от устаревшего «КПП банка».
К 01.09.2026 старые незавершённые черновики регистрации истекут — утилиту
и оба вызова (CreateUser/AddUser model) можно удалить.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 05:23:53 +00:00
coopops 54e27df7f8 chore(release): publish
Build bootstrap container / build (push) Successful in 3m27s
Release / release (push) Successful in 26m49s
Release / publish-packages (push) Failing after 28m24s
Release / trigger-coopenomics-docs (push) Successful in 2s
Release / trigger-mono-docs (push) Successful in 1s
v2026.6.8-2
2026-06-08 05:13:30 +00:00