Реестр заказов админа + докладка со склада в окне выдачи + фикс паевого на выдаче (598-50) #136

Closed
claude wants to merge 66 commits from feat/marketplace-admin-orders into feat/marketplace-process-registry
Owner

Стекнут поверх feat/marketplace-process-registry (PR #135).

Что сделано

Стол администратора → новая страница «Реестр заказов» (Order:read:all, видна председателю и совету; ссылок на стол бухгалтера нет):

  • Единый реестр всех заказов кооператива с текущими статусами (серверная пагинация + фильтр по статусу).
  • Раскрытие заказа → состояние заказа (таймлайн вех с датами) + детализация процесса p.mkt.supply по order_hash (документы + операции + проводки).
  • ФИО заказчика/поставщика, статус-бейджи через канон orderStatusDisplay.

Backend: marketplaceListAllOrders (Order:read:all) — переиспользует существующий runListQuery с coopname-only фильтром. SDK-запрос + полный codegen.

DRY: блок «Документы + Операции + Проводки» вынесен в общий виджет ProcessDetailCard и переиспользован на обеих страницах; helper'ы цвета/метки процесса — в shared/lib/ledger2. Навигация к реестрам операций/проводок опциональна (бухгалтер → его реестры; администратор → копирование).

Проверки

  • generate-schema (89 резолверов) + generate-client + sdk build — ок.
  • ESLint изменённых desktop-файлов — чисто.
  • Полный type-check фронта — на CI.
Стекнут поверх feat/marketplace-process-registry (PR #135). ## Что сделано Стол администратора → новая страница «Реестр заказов» (Order:read:all, видна председателю и совету; ссылок на стол бухгалтера нет): - Единый реестр всех заказов кооператива с текущими статусами (серверная пагинация + фильтр по статусу). - Раскрытие заказа → состояние заказа (таймлайн вех с датами) + детализация процесса p.mkt.supply по order_hash (документы + операции + проводки). - ФИО заказчика/поставщика, статус-бейджи через канон orderStatusDisplay. Backend: marketplaceListAllOrders (Order:read:all) — переиспользует существующий runListQuery с coopname-only фильтром. SDK-запрос + полный codegen. DRY: блок «Документы + Операции + Проводки» вынесен в общий виджет ProcessDetailCard и переиспользован на обеих страницах; helper'ы цвета/метки процесса — в shared/lib/ledger2. Навигация к реестрам операций/проводок опциональна (бухгалтер → его реестры; администратор → копирование). ## Проверки - generate-schema (89 резолверов) + generate-client + sdk build — ок. - ESLint изменённых desktop-файлов — чисто. - Полный type-check фронта — на CI.
claude added 2 commits 2026-06-13 09:41:12 +00:00
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Стол администратора: новая страница «Реестр заказов» (Order:read:all) —
все заказы кооператива с текущими статусами, раскрытие в состояние заказа
(таймлайн) и детализацию процесса p.mkt.supply по order_hash. Без ссылок
на стол бухгалтера: № операций/проводок копируются, а не ведут в чужие реестры.

Блок «Документы + Операции + Проводки» вынесен из реестра процессов в общий
виджет ProcessDetailCard (DRY) и переиспользован на обеих страницах; helper'ы
цвета/метки процесса — в shared/lib/ledger2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 10:21:11 +00:00
- состояние заказа рисуем каноническим ActivityTimeline, а не самопальной сеткой;
  причина (last_status_reason) теперь описание события отмены/отказа, а не
  отдельная неподписанная строка «Причина» (было неясно «причина чего»);
- кнопка «Открыть предложение» в детализации заказа → readonly-карточка
  предложения на столе администратора (marketplace-admin-offer-detail);
- гасим подсветку строки при наведении (мигание) в реестре заказов и процессов,
  включая вложенные таблицы операций/проводок.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 10:33:04 +00:00
Новая страница «Реестр предложений» (market-admin) — все предложения всех
поставщиков любого статуса (опубликованные/снятые/отклонённые/на модерации),
отдельно от «Модерации» (там только ждущие решения). Клик по строке → readonly-
карточка предложения (marketplace-admin-offer-detail) — туда же ведёт переход
«Открыть предложение» из реестра заказов.

- backend: marketplaceListAllOffers (Offer:read:all) + offerService.listAll;
  read:all добавлен админу в access-matrix (у совета уже был);
- DRY: логика username→ФИО вынесена из реестра процессов в общий composable
  useFioCache, переиспользована в реестре предложений.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 10:37:41 +00:00
Рядом с названием товара — иконка open_in_new, по клику открывает карточку
предложения (marketplace-admin-offer-detail). Раньше переход был только в
раскрытой детализации заказа и был неочевиден.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 12:02:45 +00:00
Карточка предложения уже читает query from (cart/consolidated); добавлены ветки
orders → «К реестру заказов» и offers → «К реестру предложений». Переходы из
реестра заказов и реестра предложений передают соответствующий from — иначе
кнопка всегда вела «К модерации».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 12:34:16 +00:00
claude added 1 commit 2026-06-13 13:11:08 +00:00
Совет лишь одобряет проект списания; фактическое выбытие со склада инициирует
председатель КУ подписью Служебной записки о списании (registry 1111). Новый
on-chain action marketplace::confirmwroff(coopname, signer, proposal_hash,
braname, memo) закрывает позиции одного КУ (гранулярность по участку), проводит
o.mkt.wroff и якорит записку в реестр документов (package = proposal_hash).
cooptypes: обёртка ConfirmWroff + интерфейс IConfirmWroff + документ 1111.
factory: Action+Template 1111 (подписант — председатель КУ).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 13:32:51 +00:00
Совет больше не запускает списание автоматически: onCouncilAuthorized переводит
проект в PENDING_CONFIRMATION и ждёт подтверждения складов. Председатель КУ
подтверждает фактическое списание своего участка (mutation marketplaceConfirmWriteoff
→ confirmwroff), подписав Служебную записку 1111; когда подтверждены все КУ —
проект EXECUTED. Запросы: marketplaceListWriteoffCandidates (admin — просроченный
скоропорт на складах), marketplaceWriteoffPendingConfirmations (стол ПВЗ, группы
по КУ оператора), marketplaceWriteoffServiceMemoSignablePayload (превью 1111).
Грант operator: Writeoff read/confirm:own-KU. Стандарт p.mkt.wroff приведён к
новому пути (+ фикс дрейфа registry_id 1108/1107). SDK: селекторы, операции, Zeus.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 13:38:49 +00:00
Стол администратора: на странице списаний — выделяемая таблица кандидатов
(просроченный скоропорт на складах), «Новый черновик» активна при выделении и
собирает предзаполненный черновик из выбранного. Новая страница стола ПВЗ
marketplace-pvz-writeoffs: группы одобренных советом списаний по КУ оператора,
просмотр позиций и протокола совета, «Подтвердить списание» — подпись Служебной
записки 1111 (confirmwroff). SDK-обёртки запросов/мутации.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-13 15:31:35 +00:00
- кандидаты и позиции проекта отдают branch_name (резолв с кэшем), в UI больше нет служебного braname
- статус PENDING_CONFIRMATION добавлен в детали проекта
- диалоги пути списания (Submit/Confirm/DraftEditor/Details) переведены на BaseDialog+BaseButton, убран FontAwesome (fa-signature → Material draw)
- протокол совета на столе ПВЗ — канон-контейнер вместо сырого q-card

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 04:52:30 +00:00
Колонка «Гарантия» (warranty_days, «N дн.» / «—») между «Доступно» и «Создано»; поле уже приходит в marketplaceListAllOffers, бэкенд/codegen не трогали.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 05:01:39 +00:00
Добор по акцепту (ACCEPTED вне партии) показываем и принимаем ТОЛЬКО вместе с привезённой партией. Поставщик без партии: добор скрыт, takeAddon=false (нет фантомного акта), в диалоге — empty-state «Нет партии к приёмке». Следствие: самовывоз без сформированной партии этим путём больше не принимается.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 05:06:39 +00:00
Откат прошлого поведения (66c3812): приёмку без партии НЕ убираем.
- Есть партия: чекбокс «Принять добор» показан и по умолчанию ВЫКЛЮЧЕН (не залетает сам).
- Нет партии: чекбокса/обёртки «добор» нет вовсе (путает оператора без контекста партии), имущество показываем как «Имущество поставщика» и принимаем (takeAddon включён скрыто) — «Сформировать акты» работает.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 05:24:10 +00:00
Кандидаты на admin-столе списания теперь показывают всё имущество на складе
(не только просроченное), с флагом is_expired и подсветкой просрочено/годно:
председатель может вручную списать ещё годное (порча, невозврат) и протестировать
флоу — раньше позиции с warranty_days=0 (expiry_date=null) не попадали в список.
Авто-крон не тронут (ежемесячный + grace, null-срок не трогает). Гарантия 0 дней
в реестре предложений и карточке показывается как «Без гарантии», а не «—»/∞.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 05:47:35 +00:00
Гарантия = конечный срок возврата пайщиком или 0 (нет гарантии); бессрочной
гарантии не существует. Три состояния позиции в кандидатах на списание:
«Годен» (в сроке) / «Просрочен» (срок прошёл, авто-кандидат) / «Без гарантии»
(гарантия 0 — ручное списание сразу как испорченное/использованное, авто-крон
не трогает). Колонка «Срок годности» → «Годен до»; null → «Без гарантии» вместо
противоречивого «Без срока»+зелёного «Годно». Подсказка формы создания уточнена:
0 — без гарантии (возврат невозможен). Бэкенд не менялся.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 05:56:13 +00:00
Поток списания свёрнут до одного действия: председатель выделяет имущество на
складах, при необходимости пишет причину (одно поле, по умолчанию пусто →
причина по состоянию позиции) и жмёт «Подписать и отправить в совет» — черновик
собирается под капотом и сразу открывается подпись Заявления. Убраны
промежуточный экран «Открытый черновик», кнопка «Изменить состав» и
DraftEditorDialog. Висящий черновик (прерванная подпись/крон) снимается перед
сборкой свежего. Бэкенд не менялся.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 06:08:18 +00:00
В одношаговом потоке диалог подписи Заявления монтируется уже открытым
(modelValue=true задаётся одновременно с draft), поэтому watch без immediate не
срабатывал и previewDoc оставался null — белый экран без кнопок. Добавлен
immediate:true: загрузка документа идёт и при появлении уже открытого диалога.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 06:30:53 +00:00
Документ 1108: убрана колонка «КУ» (наименования участков в блокчейн не шлём —
юридически достаточно наименование/кол-во/сумма/причина) и строка про транзит
счёта 91; вёрстка переведена на канон без white-space:pre-wrap (убирает большие
отступы), суммы позиций рендерятся с символом валюты как ИТОГО, дата цикла — в
формате ДД.ММ.ГГГГ. Те же правки формата/вёрстки применены к Служебной записке
1111. Причина по умолчанию для просрочки и товара без гарантии — «Истёк срок
годности». Лоадер диалога подписи отцентрован. Требуется перезапуск контроллера
для подхвата нового шаблона (cooptypes/factory dist).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 07:43:20 +00:00
Страница списания переверстана по канону: вкладки PageTabs «Кандидаты / На
повестке / Архив» вместо россыпи карточек и списков; ленты проектов — канон-
таблица .table-wrap с BaseBadge-статусами и EmptyState; CTA только на вкладке
кандидатов. Документ Заявления 1108: сумма в формате «1 020,00 RUB» (2 знака,
разделители), из преамбулы убрано «по итогам цикла», под заголовком добавлен
город «г. {{ coop.city }}». Те же суммы 2-знака применены к Записке 1111.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 07:58:15 +00:00
Рендерер BaseDocument навязывает в Shadow DOM white-space: pre-wrap и
th{width:30% !important}; пятиколоночный thead давал 5×30%=150% и таблица
уезжала вправо («Причина» схлопывалась в столбик), а кастомные margin'ы вместо
канонных переносов давали огромные вертикальные зазоры. Привёл оба документа
1-в-1 к style-блоку и структуре сиблингов (эталон 1106): addressee справа,
заголовок по центру, город под подзаголовком справа; список позиций —
многоколоночная таблица без <th> (шапка через <td><b>), суммы 2 знака.
claude added 1 commit 2026-06-14 08:42:19 +00:00
Путь списания — единственный marketplace-процесс через повестку совета,
поэтому в decisionFactory не было обработчика типа mktwroff: при «Утвердить»
process-decisions не мог сгенерировать документ-Решение и падал. Зарегистрировал
обработчик: собирает Action Протокола совета о списании (registry 1107) из
метаданных подписанного Заявления 1108 (proposal_hash, цикл, сумма, число
позиций) + decision_id и генерит через generic GenerateDocument — фабрика сама
резолвит состав совета, голоса и реквизиты по decision_id.
claude added 1 commit 2026-06-14 10:52:50 +00:00
Проблема 1 (решение совета не отражалось): не было слушателя on-chain
callback'ов совета — onCouncilAuthorized/onCouncilDeclined звались только в
тестах. Добавлен MarketplaceWriteoffSyncService на action::marketplace::
onmktwoauth/onmktwodecl → проект ON_AGENDA → PENDING_CONFIRMATION, Протокол
сохраняется.

Проблема 2 (нельзя создать второй проект пока один в совете): снят гард
findOpenInCouncil в createDraft и частичный unique-индекс
UQ_..._active (несколько проектов в совете допустимы — разные партии
скоропорта независимы). Защита от двойного списания одной позиции перенесена
на уровень кандидатов: findActiveLockedInventoryIds исключает из списка
позиции, уже занятые в незавершённых проектах.
claude added 1 commit 2026-06-14 10:56:25 +00:00
Лента: имя проекта по дате («Списание от ДД.ММ.ГГГГ») + корректное склонение
«N позиция/позиции/позиций» вместо «1 позиций». Детальный диалог: канон-таблица
позиций (.table-wrap + .col-num + BaseBadge статуса) вместо q-markup-table;
журнал решений — человеческие формулировки вместо кодов draft_created/
submitted_to_council; «Решение совета» — итог рассмотрения (Одобрено/Отклонено/
На рассмотрении) вместо служебного номера; on-chain идентификатор укорочен и
вынесен вниз отдельной подписью.
claude added 1 commit 2026-06-14 10:58:27 +00:00
Склонение «позиций» и имя проекта по дате повторялись в AdminWriteoffsPage и
WriteoffProposalDetailsDialog — вынес в ../lib/proposalDisplay по правилу DRY.
claude added 1 commit 2026-06-14 11:46:26 +00:00
Несколько партий (inventory lots) одного товара на одном КУ показывались отдельными
визуально идентичными строками (та же дата годности, тот же КУ) → пайщик видел, как
количество «прыгает» 40↔100, и после списания одной партии вторая оставалась.
Модель позиции переведена с одиночного inventory_id на inventory_ids[]: кандидаты
агрегируются по (braname, asset_title, состояние), одна строка несёт все партии и
суммарное кол-во/сумму; исполнение и блокировка повторного списания идут по всем
партиям агрегата. Сквозь domain→service→dto→mapper→sdk(zeus)→desktop + codegen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 11:46:57 +00:00
claude added 1 commit 2026-06-14 12:56:39 +00:00
Документы 1108/1111: убран white-space:pre-wrap (рендерил переносы строк исходника
и вместе с дефолтными margin'ами <p> удваивал разрывы — документ разъезжался по
вертикали); спейсинг переведён на явные margin'ы по эталону уплотнённого 1110;
'.digital-document { white-space: normal }' перебивает форсированный pre-wrap из
Shadow DOM рендерера. Подписант 1108 — 'от Председателя Совета'. Диалог подписи:
документ рендерится канон-компонентом DocumentHtmlReader в листе фиксированной
ширины (на мобильном — во всю), без 60vh-обрубка. Детальная страница: журнал
решений переведён на канон ActivityTimeline, убран служебный on-chain идентификатор.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 13:19:02 +00:00
Диалог подписи: заявление рендерилось через DocumentHtmlReader, который
форсит h1 line-height 4.5rem и режет <style> документа DOMPurify'ем —
заявление «разлетается» по вертикали. Переведено 1-в-1 на эталон
заявления на вступление (Registrator/SignUp/ReadStatement): .statement +
:deep-нормализатор бекенд-HTML к канон-типографике.

Детальная страница проекта: maximized-диалог рендерил контент full-bleed
без контейнера (поля minmax растянуты на весь экран, всё скучено в углу).
Переверстано по эталону ProfilePage: центрированная колонка max-width 920,
секции в BaseCard, «Основные параметры» через канон-компонент DataRow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 16:21:00 +00:00
В повестке совета документ рендерит BaseDocument: он прогоняет html через
sanitizeHtml (ВЫРЕЗАЕТ <style> документа) и форсит в Shadow DOM
.digital-document{white-space:pre-wrap}. Прежняя вёрстка 1108/1111 полагалась
на <style> с классами (.addressee/.title-block + margin'ы) — всё вырезалось,
оставался pre-wrap → огромные отступы + выравнивание влево.

Переверстано 1-в-1 по канон-документу 1106 (он корректен и в повестке, и в
предпросмотре): выравнивание инлайн (style=text-align), вертикальный ритм —
пустыми строками под pre-wrap, плотные абзацы — инлайн margin:0px,
центр-заголовок — h1.header (shadowStyles центрирует .header).

Добавлена колонка «Ед. изм.» (ед.) — у инвентаря нет поля единицы, склад
считается в дискретных единицах, поэтому константа.

Предпросмотр (SubmitToCouncilDialog): рендер html как есть, без класса
.statement (тянул глобальный h1{line-height:4.5rem}) и без нормализатора,
ломавшего pre-wrap — теперь идентичен повестке.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 16:59:32 +00:00
Колонка marketplace_writeoff_proposal.status была varchar(16), а статус
PENDING_CONFIRMATION = 20 символов: callback совета onmktwoauth отлавливался,
но UPDATE статуса молча падал «value too long» → проект навсегда застревал в
ON_AGENDA (решение совета «не отлавливалось»). Расширил до 32. На колонке индекс
(coopname,status), поэтому synchronize не смог изменить длину сам (recreate →
ADD NOT NULL на непустой таблице) — расширение выполнено ALTER COLUMN TYPE на месте.

Единицы измерения в Заявлении (1108) и Служебной записке (1111): вместо зашитой
«ед.» бэкенд резолвит реальную единицу товара по партиям позиции
(inventory → заказ/published_offer → offer.unit_of_measure → шт./кг/л/упак.),
прокидывает в документ; шаблоны рендерят {{ it.unit }}.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 17:32:07 +00:00
Удалён read-only стол BoardAgendaWriteoff (повестка совета по списаниям) —
страница не нужна: маршрут marketplace-board-writeoff из install.ts, сам пейдж,
ссылки в комментариях.

Протокол совета на столе ПВЗ: вместо инлайн-тоггла со «Протокол совета
недоступен» (в callback'е onmktwoauth html не приходит — хранится только
подпись) — кнопка открывает документ полноэкранным окном, как остальные
документы. Бэкенд регенерит Протокол 1107 фабрикой по decision_id (votes с
цепи) новым query marketplaceWriteoffProtocolDocument — тот же паттерн, что у
Заявления 1108 и Служебной записки 1111. Codegen + SDK-обёртка.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-14 17:51:17 +00:00
Протокол на столе ПВЗ НЕ регенерируем фабрикой: документ уже подписан советом и
лежит в реестре — query marketplaceWriteoffProtocolDocument теперь собирает
DocumentAggregate из подписанного protocol_doc через buildDocumentAggregate
(тело по doc_hash + подписи), как issuance/return-claim. Возврат — DocumentAggregate;
фронт показывает канон-просмотрщиком DocumentViewerDialog. Codegen + SDK-обёртка
на documentAggregateSelector.

ConfirmWriteoffDialog: Служебная записка была обрезана (max-height:60vh + overflow)
— убрал ограничение высоты, документ листом фиксированной ширины (820px), как в
SubmitToCouncilDialog; прокручивается весь диалог.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 05:04:35 +00:00
- DocumentViewerDialog: лист документа центрируется (max-width 900px), а не прижат влево на maximized-диалоге
- Loader (общий) вместо сырого q-spinner в ConfirmWriteoffDialog/SubmitToCouncilDialog и трёх Process*InfoWidget
- 1111 Служебная записка + 1107 Протокол: убраны строки «Идентификатор проекта списания» и бухпроводка Дт86/Кт10 — пользователь не просил этот текст

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 05:46:33 +00:00
- DocumentViewerDialog: лист центрируется блочным margin:0 auto (max-width 900px) — прежний flex+:deep не применялся, протокол оставался прижат
- useFioCache: к ФИО пайщика добавлен fallback на имя КУ из branch-стора (short_name||full_name||full_address); процесс списания пишет на цепочке braname КУ — теперь показывается человеческое имя участка, а не «kaffjpgeznnu»

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 05:53:33 +00:00
- BaseDocument.shadowStyles: .digital-document h1 { text-align:center } — заголовок (ПРОТОКОЛ №, СЛУЖЕБНАЯ ЗАПИСКА и пр.) центрируется на слое рендера, как в других документах; инлайн-стили выживают санитайзер, а блочные правила <style> — нет, поэтому правка шаблона существующий подписанный документ не центрировала
- DocumentViewerDialog: убрал лишнюю обёртку-лист (ширину никто не просил, проблема была только в выравнивании заголовка)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 07:27:03 +00:00
- AccountDomainService.getAccount: распознаёт КУ (branchBlockchainPort.getBranch) и строит private_account из его орг-данных тем же каналом, что и кооператив; getDisplayName/сертификаты/фронтовый getAccount резолвят имя участка автоматически, без ветки у каждого потребителя
- enum AccountKind (participant|branch|cooperative|unknown) + поле account_kind в AccountDTO — дискриминатор субъекта, чтобы UI не путал КУ с организацией-пайщиком
- SDK: account_kind в accountSelector + zeus-клиент
- desktop useFioCache: убран костыль-fallback в branch-стор, опора на getAccount; отдаёт kindCache
- ProcessesPage (стол бухгалтера): имя участка вместо braname + метка «КУ» по account_kind=branch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 08:10:57 +00:00
Поставщик отклонял входящий заказ (decline=erase строки в chain-RAM), но
заказ исчезал и тут же возвращался в «Ждут акцепта», а повторный
decline/accept падал «не найден по хэшу». Причина: парсер на erase шлёт
present=false с последним живым value строки ('active'); у терминального
CANCELLED_BY_SUPPLIER forward-rank=undefined, поэтому updateFromBlockchain
перетирал backend-статус обратно в ACTIVE. Guard: не менять статус, если
заказ уже в терминальной отмене/возврате (mapper выдаёт только живые
on-chain статусы, cancelled — KNOWN_UNMAPPED). +2 регрессионных теста.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 09:28:03 +00:00
Три полировки стола заказов:

1. Уведомление заказчику при отказе поставщика. Раньше decline слал только
   ws-сигнал — push/email заказчику не уходил. Новый Novu-workflow
   marketplace-order-declined-by-supplier (email/in-app/push с причиной +
   названием товара + КУ); событие MARKETPLACE_ORDER_DECLINED_BY_SUPPLIER
   эмитится из declineOrdersBatch по каждому заказу (имя товара батчем по
   offer_id), листенер в MarketplaceNotificationService резолвит имя заказчика
   и КУ и шлёт push. Best-effort, основной flow не блокирует.

2. Тост «Добавлено в корзину» получил CTA «Перейти в корзину» — быстрый переход
   к оформлению прямо из всплывашки, без поиска корзины отдельно.

3. Диалог открытия выдачи: кнопка «Подписать и открыть выдачу» дизейблилась
   без объяснения. Добавлен баннер с причиной (нет на складе / факт больше
   принятого / нулевые кол-во-цена) + отдельный статус строки «Нет на складе»
   (принято 0) в CorrectionTable вместо общей «Недостача».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 09:53:10 +00:00
В диалоге открытия выдачи добавлена колонка-чекбокс «Выдать»: оператор
отмечает позиции, которые пайщик забирает сейчас; снятые остаются на складе и
в выдачу не попадают (acts формируются только по выбранным — openIssuance
per-order, бэк без изменений). Позиции с принято=0 авто-исключены (выдать
нечего) и больше не блокируют всю выдачу. Суммы/возврат/валидность считаются
по выбранным; итоги показывают «к выдаче N из M» и «остаётся на складе».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 11:33:34 +00:00
Граница удержания — акцепт поставщиком. До акцепта отмена бесплатна (полный
возврат), после — cancelorder удерживает 50% тела заказа и членского взноса в
общий кошелёк КУ (w.brn.common), имущество остаётся на складе КУ, вторая
половина возвращается пайщику. Новая ledger-операция o.mkt.penal: транзит
w.mkt.order → w.mkt.fee, далее в КУ существующим Branch::accrue — прямой перевод
между USER_SHARED-кошельками с разным разрезом невозможен (walletop держит один
username на обе стороны). Имя o.mkt.penal (не penalty) — 13-й символ eosio::name
не может быть позже 'j'. Helper retain_refusal_penalty + refund_order_full (DRY),
обновлён стандарт p.mkt.supply и cooptypes-зеркало операции.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 11:52:14 +00:00
Расширил declineorder с ACTIVE на ACCEPTED/SUPPLY_PREPARED: поставщик
подтверждает отмену поставки непринятой позиции (ноль единиц в факт), имущество
ещё не оприходовано (purch на закрывающей подписи) и поставщик не оплачен —
клоубэка нет, полный возврат стоимости и членского взноса заказчику (непринятие
не его вина). Зеркально отказу на выдаче, но инициатор — поставщик и без штрафа.
Обновлён стандарт p.mkt.supply.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 12:04:25 +00:00
Расширил CANCELABLE_STATUSES на ACCEPTED/SUPPLY_PREPARED/ACCEPTED_TO_COOP:
заказчик может отказаться от получения вплоть до открытия акта выдачи. Граница
бесплатно/50% — на контракте (до/после акцепта поставщиком), бэкенд лишь не
закрывает действие раньше. Закрыто на READY_TO_RECEIVE/RECEIVED. Спека: 15/15.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 12:14:44 +00:00
Диалог финализации заказчика принимает refusedOrders (остаток ACCEPTED_TO_COOP
того же пункта — оператор не открыл по ним выдачу = отказ). Пайщик видит две
секции «Получаете / Отказываетесь (удержим 50%)» и подтверждает целиком одной
кнопкой: signiss2 по принятым + cancelOrder по отказным (его сессия, cancel:own).
Не согласен → закрывает, оператор переформировывает. Списание строго в момент
подтверждения. Документы/акт не трогаем — в акт идёт только принятое. ESLint ok.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ant added this to the Marketplace project 2026-06-15 13:13:11 +00:00
claude added 1 commit 2026-06-15 13:22:32 +00:00
Разнос группы приёмки на принятые (факт>0) и отклонённые (факт=0) на шаге
подписи поставщика: signsupp только по принятым, declineorder по нулям
(полный возврат стоимости и членского взноса заказчику без штрафа + erase).
Вся партия некондиция → приёмка CANCELLED + shipment CANCELLED. Председатель
(signchair/ACCEPTED_TO_COOP/склад/выплаты) работает только по принятым.
DRY: declineOrdersAtReception переиспользует runDeclineChain+уведомления.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 13:26:27 +00:00
Поставщик видит два блока: «Принимается» (факт>0, нулевые строки скрыты) и
«Отклоняется (некондиция)» — снятые оператором позиции с пояснением, что
подтверждая, он отменяет их поставку (заказчикам полный возврат, удержания нет).
Метка кнопки «Подтвердить отмену», если принимать нечего. Пустой список актов
(вся партия снята) больше не ошибка — мутация с пустыми документами уводит
приёмку в отмену с полным возвратом.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 14:33:36 +00:00
Поставщик не согласен со снятыми позициями целиком (повезёт замену позже):
до его подписи приёмка — черновик, оператор отменяет акт и пересобирает.
- service.cancelReception: только PENDING_SUPPLIER_SIGN, приёмка → CANCELLED,
  партия → SUPPLY_PREPARED; on-chain ничего не было, заказы не трогаем.
- findByShipmentId исключает CANCELLED → повторный create() по партии проходит.
- мутация marketplaceCancelAplReception (Receiving create, член КУ) + codegen.
- фронт: кнопка «Отменить и пересобрать» на карточке приёмки PENDING_SUPPLIER_SIGN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-15 16:47:17 +00:00
claude added 1 commit 2026-06-15 17:20:51 +00:00
claude added 1 commit 2026-06-15 17:26:58 +00:00
claude added 1 commit 2026-06-15 17:29:11 +00:00
claude added 1 commit 2026-06-15 18:44:01 +00:00
claude added 1 commit 2026-06-16 04:37:32 +00:00
Ветка signiss2 «факт больше заказа» конвертировала паевой в членский (o.mkt.conv)
и добирала довзнос с паевого (o.mkt.fee) автоматически, без Заявления о конвертации.
Это нарушало инвариант «паевой→членский только по заявлению»: на выдаче паевой
трогать нельзя нигде. Теперь доплата тела (o.mkt.lockm) и довзнос (o.mkt.lockmf)
берутся ТОЛЬКО с w.mkt.member; при нехватке — отказ с просьбой сконвертировать
заранее. Backend покажет пайщику разложение (с членского / с паевого по заявлению)
до подписи. Зачем: деньги пайщика на паевом не должны списываться помимо его
явного волеизъявления — конвертация всегда отдельный подписанный документ.
claude added 1 commit 2026-06-16 05:01:24 +00:00
Комментарии называли дособираемую при факте>заказа часть «довзносом с паевого».
По сути это членский взнос (комиссия КУ, идёт в w.mkt.fee → w.brn.common), а
источник средств теперь членский (o.mkt.lockmf), не паевой. Правка только текста
комментариев — логика не меняется; чтобы код самодокументировался корректно.
claude added 1 commit 2026-06-16 05:02:23 +00:00
Стандарт описывал старую модель: при факте больше заказа доплата вносится
дополнительным паевым взносом с авто-конвертацией в членский. Контракт это
уже не делает — паевой на выдаче не списывается и не конвертируется; доплата
и недостающая часть взноса берутся из членских средств, а паевой пайщик
переводит в членский заранее отдельным Заявлением о конвертации. Подровнял
текст под код (дрейф стандарт↔код — прав код).
claude added 1 commit 2026-06-16 05:15:39 +00:00
getAcceptSignablePayloads теперь отдаёт member_amount (сколько стоимости докладки
покроется уже внесёнными членскими «Стола заказов», включая высвобожденные
недосдачей) рядом с convert_amount (дефицит → конвертация с паевого по Заявлению).
Сумма обеих = полная стоимость докладки. Зачем: оператор/пайщик видят в акте
разложение «с членского / с паевого» до подписи — backend считает целочисленно,
фронт не дублирует. Прокинул через DTO, резолвер, SDK-селектор + codegen.
claude added 1 commit 2026-06-16 05:25:56 +00:00
Оператор в окне «Открытие выдачи пайщику» кнопкой «Со склада» открывает выбор
опубликованного остатка КУ (StockPickDialog), набирает позиции — они встают
секцией «Доложено со склада» в том же акте и при «Подписать и открыть выдачу»
создаются предложением пайщику (createStockProposal). Зачем: «это не пришло —
возьмите вот это» оформляется в одном окне выдачи, без отдельного экрана докладки.
Инкремент 1 (сторона оператора); две суммы и слияние подписи у пайщика — следом.
claude changed title from Реестр заказов кооператива на столе администратора (+ виджет детализации процесса) to Реестр заказов админа + докладка со склада в окне выдачи + фикс паевого на выдаче (598-50) 2026-06-16 05:44:23 +00:00
Author
Owner

Докладка со склада в окне выдачи + фикс паевого (598-50)

Поверх реестра заказов в этой же ветке добавлена фича «это не пришло — возьмите вот это» и устранено нарушение инварианта паевого на выдаче.

Контракт (2d01dc1, ef8f8aa, 214a921):

  • signiss2, ветка «факт больше заказа»: убрана авто-конвертация паевого (o.mkt.conv) и довзнос с паевого (o.mkt.fee). Доплата тела (o.mkt.lockm) и членский взнос-комиссия КУ (o.mkt.lockmf) — строго с w.mkt.member; при нехватке отказ. Паевой→членский остаётся только по Заявлению о конвертации (convert).
  • Стандарт p.mkt.supply.standard.yaml подровнян под новую модель.

Backend + SDK (91d5f33):

  • getAcceptSignablePayloads отдаёт member_amount (доплата с членского) рядом с convert_amount (дефицит → конвертация с паевого). Сумма обеих = полная стоимость докладки. Прокинуто через DTO/резолвер/SDK + codegen.

Frontend инкремент 1 (b38773c):

  • Окно «Открытие выдачи пайщику»: кнопка «Со склада» → StockPickDialog (выбор опубликованного остатка КУ) → секция «Доложено со склада» в том же акте + сумма; при «Подписать и открыть выдачу» доложенное уходит пайщику (createStockProposal).

Осталось: инкремент 2 — сторона пайщика в гейте подписи (две суммы «с членского / с паевого» + один экран/подпись), под визуальную проверку.

## Докладка со склада в окне выдачи + фикс паевого (598-50) Поверх реестра заказов в этой же ветке добавлена фича «это не пришло — возьмите вот это» и устранено нарушение инварианта паевого на выдаче. **Контракт** (2d01dc1, ef8f8aa, 214a921): - `signiss2`, ветка «факт больше заказа»: убрана авто-конвертация паевого (`o.mkt.conv`) и довзнос с паевого (`o.mkt.fee`). Доплата тела (`o.mkt.lockm`) и членский взнос-комиссия КУ (`o.mkt.lockmf`) — строго с `w.mkt.member`; при нехватке отказ. Паевой→членский остаётся только по Заявлению о конвертации (`convert`). - Стандарт `p.mkt.supply.standard.yaml` подровнян под новую модель. **Backend + SDK** (91d5f33): - `getAcceptSignablePayloads` отдаёт `member_amount` (доплата с членского) рядом с `convert_amount` (дефицит → конвертация с паевого). Сумма обеих = полная стоимость докладки. Прокинуто через DTO/резолвер/SDK + codegen. **Frontend инкремент 1** (b38773c): - Окно «Открытие выдачи пайщику»: кнопка «Со склада» → `StockPickDialog` (выбор опубликованного остатка КУ) → секция «Доложено со склада» в том же акте + сумма; при «Подписать и открыть выдачу» доложенное уходит пайщику (`createStockProposal`). **Осталось:** инкремент 2 — сторона пайщика в гейте подписи (две суммы «с членского / с паевого» + один экран/подпись), под визуальную проверку.
claude added 1 commit 2026-06-16 05:48:55 +00:00
В гейте подписи на месте карточка предложения со склада теперь показывает
разложение ДО подписи: «спишется с членского «Стола заказов»» (member_amount)
и, при дефиците, «конвертация с паевого (по заявлению)» (convert_amount).
Суммы предзагружаются через getStockProposalSignablePayloads (кэш по proposal_id),
ушедшие предложения чистятся. Убрана устаревшая подпись «Итого (паевой взнос)».
Зачем: пайщик видит, что и откуда спишется, до согласия — как договорено.
claude added 1 commit 2026-06-16 07:37:30 +00:00
Переработка докладки/QR-выдачи со склада кооператива под требование «пайщик видит
готовый акт и одну кнопку Подписать, без отдельного Принять» (вариант Б1).

Оператор при формировании докладки получает АПП-выдачи по строкам корзины
(marketplaceStockIssuancePayloads) и подписывает их первой подписью (signiss1) на
детерминированный order_hash; бандл хранит подписанные акты. Пайщик одной подписью
утверждает докладку (marketplaceFinalizeStockIssuance): при дефиците членских —
конвертация с паевого по Заявлению, затем по каждой строке заказ из остатка
(stockorder) → выдача (signiss1 оператора) → получение (контрподпись signiss2),
заказ сразу RECEIVED. Паевой не трогается без подписанного Заявления.

Убрана двухфазная семантика «Принять предложение» (marketplaceAcceptStockProposal):
принятие = подпись акта получения. SDK/codegen синхронизированы.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-16 07:41:00 +00:00
Оператор в окне выдачи («Со склада») теперь получает АПП-выдачи по строкам
корзины и подписывает их первой подписью (signiss1) сразу при формировании
докладки (getStockIssuancePayloads + createStockProposal с подписанными актами).

Пайщику докладка приходит в гейт готовым актом (пункты имущества, кол-во, цена,
две суммы: с членского / конвертация с паевого). Одна кнопка «Подписать»
(+«Отказаться»): подписывает Заявление о конвертации при дефиците и
контрподписывает signiss2 по строкам — finalizeStockIssuance создаёт заказы и
выдаёт имущество. Кнопка «Принять предложение» убрана: принятие = подпись акта.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
Owner

Докладка со склада — переработка под «акт + одна подпись» (вариант Б1)

Переработан флоу докладки/выдачи со склада кооператива под требование: пайщик видит готовый АКТ (пункты имущества, кол-во, цена) и одну кнопку «Подписать» (+ «Отказаться»), без отдельного «Принять предложение».

Модель подписей (контракт не трогали, кроме ранее закоммиченного фикса паевого):

  • Кооператив только шлёт транзакции (require_auth(coopname)); акты подписывают люди.
  • Оператор КУ при формировании докладки сразу подписывает АПП-выдачи первой подписью (signiss1) на детерминированный order_hash.
  • Пайщик одной подписью: при дефиците членских — Заявление о конвертации (паевой→членский), затем контрподпись получения (signiss2) по строкам. Бэкенд: convert? → stockorder → signiss1 → signiss2, заказ сразу RECEIVED. Паевой не трогается без подписанного Заявления.
  • Отказ — кооператив отменяет (cancelorder).

Слои: контракт — без нового экшена (используется существующий stockorder); backend (issuance/stock-proposal сервисы, DTO, резолвер: новый query marketplaceStockIssuancePayloads, мутация marketplaceFinalizeStockIssuance вместо marketplaceAcceptStockProposal); SDK+codegen; desktop (IssueActOpenDialog подписывает signiss1; гейт — карточка-акт с «Подписать»).

generate-schema/client + SDK typecheck + ESLint — зелёные. Полный e2e — в CI.

## Докладка со склада — переработка под «акт + одна подпись» (вариант Б1) Переработан флоу докладки/выдачи со склада кооператива под требование: пайщик видит готовый АКТ (пункты имущества, кол-во, цена) и **одну кнопку «Подписать»** (+ «Отказаться»), без отдельного «Принять предложение». **Модель подписей** (контракт не трогали, кроме ранее закоммиченного фикса паевого): - Кооператив только шлёт транзакции (require_auth(coopname)); акты подписывают люди. - Оператор КУ при формировании докладки сразу подписывает АПП-выдачи первой подписью (signiss1) на детерминированный order_hash. - Пайщик одной подписью: при дефиците членских — Заявление о конвертации (паевой→членский), затем контрподпись получения (signiss2) по строкам. Бэкенд: convert? → stockorder → signiss1 → signiss2, заказ сразу RECEIVED. Паевой не трогается без подписанного Заявления. - Отказ — кооператив отменяет (cancelorder). **Слои:** контракт — без нового экшена (используется существующий stockorder); backend (issuance/stock-proposal сервисы, DTO, резолвер: новый query `marketplaceStockIssuancePayloads`, мутация `marketplaceFinalizeStockIssuance` вместо `marketplaceAcceptStockProposal`); SDK+codegen; desktop (IssueActOpenDialog подписывает signiss1; гейт — карточка-акт с «Подписать»). generate-schema/client + SDK typecheck + ESLint — зелёные. Полный e2e — в CI.
claude added 1 commit 2026-06-16 07:59:29 +00:00
Пайщику передаётся signiss1-акт оператора на его устройство для контрподписи —
вектор: подменить тело акта (другой товар/количество) и вернуть подписанным.
Перед любыми транзакциями finalizeStockIssuance сверяет каждый контрподписанный
акт с сохранённым signiss1-актом оператора:
 - doc_hash и meta_hash совпадают с выданным к подписи (тело/мета не подменены);
 - подпись оператора сохранена нетронутой (signer+signature+public_key);
 - пайщик подписал своим ключом;
 - DocumentValidationService.validateSignedDocument: крипто + структура (recompute
   signed_hash из doc_hash+meta_hash) + сверка тела с оригиналом в сторе.
На подмене — ForbiddenException до блокировки средств. Defence-in-depth: контракт
signiss2 дополнительно режет подделку on-chain (verify_document_or_fail требует
валидную подпись оператора над телом).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-16 09:24:40 +00:00
Оператор подписывает signiss1 и кладёт всё (существующие заказы + докладку со
склада) в один оффчейн-бандл; на цепи до подписи пайщика ничего нет, поэтому
отмена пайщиком = отказ от бандла без он-чейн отката (никакого reopeniss и
второй ветки немедленного signiss1). Пайщик одной кнопкой контрподписывает
получение — backend проводит convert?→stockorder?→signiss1→signiss2. Снесён
мёртвый member-путь ordererTasks/listMyReadyToReceive в гейте.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-16 09:53:58 +00:00
Унификация сделала немедленный он-чейн-путь выдачи мёртвым: его никто не зовёт.
Удалены GraphQL-эндпоинты marketplaceOpenIssuance / marketplaceFinalizeIssuance /
marketplaceListMyReadyToReceive / marketplaceIssueActOrdererSignablePayload,
сервис-метод getFinalizeIssuanceSignablePayload, repo-метод
listReadyToReceiveByOrderer, мёртвые DTO и SDK-операции/селектор. На фронте убран
OrdererFinalizeIssuanceDialog и подпись получения в «Мои заказы»/детали заказа +
экшен receive в OrderCard (получение оформляется у стойки в гейте «подпись на
месте»). Сервис-методы openIssuance/finalizeIssuance остались — зовутся изнутри
бандла. README расширения: быстрый контекст единого пути выдачи + карта файлов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-16 12:00:34 +00:00
Кошельки на стол пайщика устанавливаются через декларации walletCards в
install.ts расширений + core-набор; реестр дедупит по wallet_name. Состав:
главный паевой (core, w.wal.share), членский стола заказов (market,
w.mkt.member), Благорост (capital, w.cap.blago). Главный членский ЦК
(w.wal.member) и Генератор (w.cap.gen) не показываем; минимальный
неснижаемый остаток — отдельной карточкой как раньше.

Источник балансов — новый core-резолвер getUserWallets (сырой срез
ledger2::userwallets без сворачивания паевого и членского). Зачем: убрать
хардкод трёх программ в WalletProgramWidget и дать расширениям приносить
свои кошельки единым стандартным механизмом.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-16 12:51:34 +00:00
- членский стола заказов: убрана подпись «возврату не подлежит»;
- главный паевой (w.wal.share) опущен вниз — рядом с программными ЦПП-кошельками,
  минимальный неснижаемый остаток остаётся верхней карточкой;
- мини-кошелёк в rail (левый низ): label «Паевой кошелёк» вместо «Доступно»,
  сумма берётся из сырого w.wal.share — членская часть ЦК больше не примешивается.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-16 12:55:47 +00:00
- тост успеха: multiLine=false (заголовок+CTA+крестик в один ряд, без
  прыгающей второй строки), CTA сокращён до «В корзину»;
- главный паевой кошелёк ЦК (w.wal.share) — снова первым в реестре после
  минимального неснижаемого остатка (приоритет), карточка «Главный паевой
  кошелёк» / «Цифровой кошелёк»; мини-кошелёк в rail — тот же заголовок.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
Owner

Содержимое влито в marketplace2 напрямую через git merge (не через merge-кнопку Gitea) — коммиты 4f58871322 и предыдущие в цепочке merge-коммитов marketplace2. Закрываю как поглощённый.

Содержимое влито в marketplace2 напрямую через git merge (не через merge-кнопку Gitea) — коммиты 4f588713229 и предыдущие в цепочке merge-коммитов marketplace2. Закрываю как поглощённый.
claude closed this pull request 2026-07-20 13:05:01 +00:00

Pull request closed

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#136