feat: инвестирование средств кооператива-партнёра в ЦПП «Благорост» оператора (hub-spoke) #121

Open
claude wants to merge 7 commits from feat/coop-invest-blagorost into dev
Owner

Что делает

Кооператив-партнёр («спица», свой инстанс ЦК), подключённый к ПК «ВОСХОД» как пайщик-юрлицо, получает стандартный флоу инвестирования средств кооператива в ЦПП «Благорост» оператора через решение совета:

  1. Председатель на столе совета (новая страница «Инвестиции») нажимает «Инвестировать», подписывает заявление (registry 1200) — в текст бэкенд подставляет данные оператора, извлечённые из бэкенда ВОСХОДа.
  2. Вопрос идёт по стандартной фабрике решений: wallet::createinvsoviet::createagenda → голосование → авторизация председателем (решение registry 1201) → callback wallet::authinv.
  3. authinv создаёт исходящий платёж в gateway (createoutpay); листенер бэкенда переводит платёж кассиру в PENDING и логинится в бэкенд ВОСХОДа (SDK, email+WIF кооператива из vault), создаёт там deposit-счёт на пополнение главного кошелька организации и кладёт его реквизиты + назначение платежа в payment_details/memo кассиру. Счёт создаётся после решения совета (а не при предложении) — счета оператора живут 24 часа, совет может думать дольше.
  4. Кассир в реестре платежей оплачивает по реквизитам ВОСХОДа и жмёт «оплачено» → gateway::outcompletewallet::completeinv → ledger2 o.wal.invcpl: проводка Дт 58 / Кт 51, зачисление на новый кошелёк w.wal.invest («Финансовые вложения в ЦПП оператора», COOPERATIVE, счёт 58 — прецедент o.cap.lend).
  5. На ВОСХОДе деньги приходят как паевой взнос организации (существующий deposit-флоу). Финальное размещение в Благоросте делает председатель вручную в ЛК оператора (в решении: «поручить председателю произвести необходимые действия»).

Резервирования на этапе заявки нет: источник — расчётный счёт (51), не имеющий wallet-зеркала в ledger2.

Слои

  • Контракты: wallet::{createinv,authinv,declineinv,completeinv}, таблица investments, agenda-тип createinv; ledger2: w.wal.invest + o.wal.invcpl + p.wal.invest. Все 4 контракта (wallet/ledger2/gateway/soviet) собраны в CDT-docker, static_assert'ы реестров прошли.
  • cooptypes: registry 1200/1201, зеркала ledger2, интерфейсы и обёртки actions/tables.
  • factory: шаблоны и фабрики 1200/1201 (resolveParallel по канону).
  • controller: HubClientService (hub-spoke связь, конфиг HUB_BACKEND_URL/HUB_COOPNAME/HUB_LOGIN_EMAIL/HUB_PROGRAM_NAME; graceful при недоступности), mutations generateCooperativeInvest{Statement,Decision}Document + createCooperativeInvestment (prepare→on-chain→persist по образцу withdraw), query getOperatorWallets (балансы организации на хабе), PaymentTypeEnum.COOPERATIVE_INVESTMENT, InvestmentAuthorizationListener, запись в process-hash-locator.
  • sdk: codegen (schema→zeus→build) + обёртки мутаций/запроса.
  • desktop: страница «Инвестиции» в workspace совета (балансы: локальный счёт 58 / кошелёк и Благорост у оператора; таблица платежей-инвестиций; канон MONO Platform v2), кнопка «Инвестировать» с диалогом и подписью, DecisionFactory-handler createinv.
  • стандарт: p.wal.invest.standard.yaml бизнес-языком.
  • тест: boot/src/tests/wallet-invest.test.ts — полный цикл с проверкой проводки Дт 58 / Кт 51 + ветка отказа (запуск против локального стенда).

Попутные фиксы

  • WithdrawAuthorizationListener читал action.data.withdraw_hash, но в ABI authwthd поле называется hash (AUTHORIZE_CALLBACK_SIGNATURE) — листенер молча не срабатывал. Теперь читает оба.

Заметки для ревью

  • Нейминг (канон, на утверждение): actions createinv/authinv/declineinv/completeinv, операция o.wal.invcpl, кошелёк w.wal.invest, процесс p.wal.invest, registry 1200/1201 (1100–1108 заняты marketplace-ветками).
  • boot/src/tests/ledger2-wallets-registry.test.ts уже устарел до этого PR (ждёт 11 кошельков при 16 в dev) — не трогал, в дефолтный pnpm test не входит.
  • Email организации на хабе может отличаться от локального — override HUB_LOGIN_EMAIL.

🤖 Generated with Claude Code

## Что делает Кооператив-партнёр («спица», свой инстанс ЦК), подключённый к ПК «ВОСХОД» как пайщик-юрлицо, получает стандартный флоу инвестирования средств кооператива в ЦПП «Благорост» оператора через решение совета: 1. **Председатель** на столе совета (новая страница «Инвестиции») нажимает «Инвестировать», подписывает заявление (**registry 1200**) — в текст бэкенд подставляет данные оператора, извлечённые из бэкенда ВОСХОДа. 2. Вопрос идёт по **стандартной фабрике решений**: `wallet::createinv` → `soviet::createagenda` → голосование → авторизация председателем (решение **registry 1201**) → callback `wallet::authinv`. 3. `authinv` создаёт исходящий платёж в **gateway** (`createoutpay`); листенер бэкенда переводит платёж кассиру в PENDING и **логинится в бэкенд ВОСХОДа** (SDK, email+WIF кооператива из vault), создаёт там **deposit-счёт** на пополнение главного кошелька организации и кладёт его реквизиты + назначение платежа в `payment_details`/`memo` кассиру. Счёт создаётся после решения совета (а не при предложении) — счета оператора живут 24 часа, совет может думать дольше. 4. **Кассир** в реестре платежей оплачивает по реквизитам ВОСХОДа и жмёт «оплачено» → `gateway::outcomplete` → `wallet::completeinv` → ledger2 **`o.wal.invcpl`: проводка Дт 58 / Кт 51**, зачисление на новый кошелёк `w.wal.invest` («Финансовые вложения в ЦПП оператора», COOPERATIVE, счёт 58 — прецедент `o.cap.lend`). 5. На ВОСХОДе деньги приходят как паевой взнос организации (существующий deposit-флоу). Финальное размещение в Благоросте делает председатель вручную в ЛК оператора (в решении: «поручить председателю произвести необходимые действия»). Резервирования на этапе заявки нет: источник — расчётный счёт (51), не имеющий wallet-зеркала в ledger2. ## Слои - **Контракты**: `wallet::{createinv,authinv,declineinv,completeinv}`, таблица `investments`, agenda-тип `createinv`; ledger2: `w.wal.invest` + `o.wal.invcpl` + `p.wal.invest`. Все 4 контракта (wallet/ledger2/gateway/soviet) собраны в CDT-docker, static_assert'ы реестров прошли. - **cooptypes**: registry 1200/1201, зеркала ledger2, интерфейсы и обёртки actions/tables. - **factory**: шаблоны и фабрики 1200/1201 (resolveParallel по канону). - **controller**: `HubClientService` (hub-spoke связь, конфиг `HUB_BACKEND_URL`/`HUB_COOPNAME`/`HUB_LOGIN_EMAIL`/`HUB_PROGRAM_NAME`; graceful при недоступности), mutations `generateCooperativeInvest{Statement,Decision}Document` + `createCooperativeInvestment` (prepare→on-chain→persist по образцу withdraw), query `getOperatorWallets` (балансы организации на хабе), `PaymentTypeEnum.COOPERATIVE_INVESTMENT`, `InvestmentAuthorizationListener`, запись в process-hash-locator. - **sdk**: codegen (schema→zeus→build) + обёртки мутаций/запроса. - **desktop**: страница «Инвестиции» в workspace совета (балансы: локальный счёт 58 / кошелёк и Благорост у оператора; таблица платежей-инвестиций; канон MONO Platform v2), кнопка «Инвестировать» с диалогом и подписью, DecisionFactory-handler `createinv`. - **стандарт**: `p.wal.invest.standard.yaml` бизнес-языком. - **тест**: `boot/src/tests/wallet-invest.test.ts` — полный цикл с проверкой проводки Дт 58 / Кт 51 + ветка отказа (запуск против локального стенда). ## Попутные фиксы - `WithdrawAuthorizationListener` читал `action.data.withdraw_hash`, но в ABI `authwthd` поле называется `hash` (AUTHORIZE_CALLBACK_SIGNATURE) — листенер молча не срабатывал. Теперь читает оба. ## Заметки для ревью - Нейминг (канон, на утверждение): actions `createinv/authinv/declineinv/completeinv`, операция `o.wal.invcpl`, кошелёк `w.wal.invest`, процесс `p.wal.invest`, registry **1200/1201** (1100–1108 заняты marketplace-ветками). - `boot/src/tests/ledger2-wallets-registry.test.ts` уже устарел до этого PR (ждёт 11 кошельков при 16 в dev) — не трогал, в дефолтный `pnpm test` не входит. - Email организации на хабе может отличаться от локального — override `HUB_LOGIN_EMAIL`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude added 3 commits 2026-06-09 20:35:02 +00:00
- wallet: createinv/authinv/declineinv/completeinv по паттерну withdraw, таблица investments, agenda-тип createinv
- ledger2: кошелёк w.wal.invest (счёт 58), операция o.wal.invcpl (Дт 58 / Кт 51, ISSUE), процесс p.wal.invest; без резервирования — источник банк (51) без wallet-зеркала
- документы 1200 CooperativeInvestStatement + 1201 CooperativeInvestDecision (cooptypes registry + factory)
- controller: HubClientService (логин на бэкенде оператора email+WIF из vault, публичные данные, deposit-счёт, балансы организации), mutations generateCooperativeInvest*/createCooperativeInvestment, query getOperatorWallets, PaymentTypeEnum.COOPERATIVE_INVESTMENT, InvestmentAuthorizationListener (PENDING + обогащение платежа счётом оператора после решения совета)
- fix: WithdrawAuthorizationListener читает hash из AUTHORIZE_CALLBACK_SIGNATURE (в ABI поле hash, не withdraw_hash)
- codegen: schema.gql → zeus → sdk build; SDK-обёртки мутаций/запроса

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- страница Investments: балансы (локальный счёт 58, кошелёк и Благорост у оператора), таблица платежей-инвестиций, канон MONO Platform v2 (WalletCard/BaseBadge/EmptyState/TableSkeleton, Material-иконки)
- кнопка «Инвестировать» (председатель, useHeaderActions): диалог BaseDialog/BaseForm → генерация заявления 1200 → подпись DigitalDocument → createCooperativeInvestment
- DecisionFactory-handler типа createinv → генерация решения 1201
- роут investments в workspace soviet (chairman/member)
- стандарт процесса p.wal.invest бизнес-языком

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
test(coop-invest): интеграционный тест p.wal.invest — полный цикл и отказ совета
Typecheck / desktop (pull_request) Failing after 8m44s
Typecheck / controller (pull_request) Failing after 7m53s
a35d58f318
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
claude closed this pull request 2026-06-10 03:56:05 +00:00
claude reopened this pull request 2026-06-10 03:56:09 +00:00
Some checks are pending
Typecheck / desktop (pull_request) Successful in 13m32s
Typecheck / controller (pull_request) Successful in 13m11s
Checking for merge conflicts…
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/coop-invest-blagorost:feat/coop-invest-blagorost
git checkout feat/coop-invest-blagorost
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#121