feat: выход из кооператива (выход пайщика, возврат паевого взноса) #137
Reference in New Issue
Block a user
Delete Branch "feat/membership-exit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Реализация выхода пайщика из кооператива по аналогии с вступлением. Umbrella-PR, наполняется по фазам.
Фаза 1 — Документы (этот коммит)
Следующие фазы
- PaymentTypeEnum.MEMBERSHIP_EXIT (исходящий) + лейблы; - document-DTO заявления (200) и решения совета (201) — зеркало join-документов; - ParticipantInteractor.generateMembershipExit{Application,Decision} (registry 200/201); - AccountBlockchainPort/adapter.exitCoop — push registrator::exitcoop с подписанным заявлением (прямой transact кооперативным ключом, как reguser); - модуль membership-exit: resolver+service с мутациями generateMembershipExitApplication / generateMembershipExitDecision / createMembershipExit и query membershipExitReturnPreview (сумма возврата по L3-балансам w.wal.share + w.reg.minshr; итог фиксирует контракт на confirmexit); self-service для пайщика + операторские роли (chairman/member); - cooptypes Ledger2.SHARE_WALLET_NAME / MIN_SHARE_WALLET_NAME — именованные константы кошельков вместо магических строк. tsc --noEmit контроллера — чисто. Codegen Zeus-клиента — отдельным коммитом. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>- query membershipExit(coopname, username) → {exit_hash, status, quantity, created_at} или null; читает chain-таблицу registrator::exits; enum MembershipExitStatus (PENDING/AUTHORIZED); self-/operator-доступ; - AccountBlockchainPort/adapter.getExit — чтение exits по username; - SDK: Queries.MembershipExit.GetMembershipExit + селектор. Нужен фронту для глобального gate: пока есть активный выход — кабинет блокируется, показывается только статус заявления и сумма возврата. tsc контроллера + SDK чисто. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Заявление о выходе из кооператива подписывается цифровой подписью (signatures[]), поэтому из документа убрано поле собственноручной подписи (рукописная картинка): - cooptypes 200: убраны Action.signature/Model.signature, <img src="{{ signature }}">, signature из exampleData; - factory Actions/200: убрана логика поиска/сохранения подписи в mongo; Templates/200: убрано свойство signature из AJV-схемы; - controller DTO: убрано поле signature (@IsString) из меты заявления. Это и вызывало "signature must be a string" — ValidationPipe (422, не логируется) рубил генерацию, т.к. фронт картинку не передаёт. Также откат самодуманной шапки "ФОРМА УТВЕРЖДЕНА решением Собрания Совета (Протокол №)": исходная форма заявления её не содержит. Убраны vars.participant_exit_application (cooptypes IVars + factory VarsSchema + фикстура теста), проверка протокола в фабрике и переводы APPROVED/approved_by_council/protocol. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>- Суммы к возврату форматируются канонной formatAsset2Digits ("300.0000 RUB" → "300,00 RUB") в диалоге заявления и в оверлее — вместо сырого asset. - Убрана разбивка "целевой + минимальный" (оба паевые, суммируются): показываем одну строку "Сумма к возврату". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>'text-h*/inline' досрочно закрывал блочный комментарий → expected '{'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>