[ledger2][@ant] refactor(ledger2): wallet IDs uint64_t → eosio::name
Сквозная замена числовых идентификаторов кошельков ledger2 (1001/2001/9001/...)
на eosio::name с префиксом w.<contract>.<waltype> по аналогии с операциями
(o.<contract>.<verb>) и процессами (p.<contract>.<noun>).
Маппинг:
2001 → w.wal.share (паевые деньгами)
2002 → w.reg.minshr (минимальный паевой)
2003 → w.wal.sharid (паевой фонд РИД)
3001 → w.reg.entry (вступительные)
3002 → w.sov.member (членские)
3003 → w.sov.delgte (делегатские)
4001 → w.wal.wthdrw (возвраты пайщикам)
4002 → w.mkt.payout (выплаты поставщикам)
4051 → w.cap.loan (займы)
5001 → w.led.adjust (ручные корректировки)
9001 → w.cap.bginv (Благорост — деньги)
9002 → w.cap.bgrid (Благорост — РИД)
9003 → w.cap.bgprop (Благорост — имущество)
9004 → w.cap.bgmem (Благорост — членские)
10001 → w.cap.gncom (Генератор — коммит)
10002 → w.cap.gnmem (Генератор — членские)
11001 → w.mkt.fund (Стол Заказов)
0 → eosio::name{} (sentinel «вне системы» для ISSUE/REVOKE)
Затронуто:
• C++ контракты: wallets.hpp, operations.hpp, table_ledger2_wallet.hpp
(id: uint64_t → eosio::name, primary_key() = id.value), actions
walletop/walmove/revert.
• cooptypes: WalletMeta { name: IName, human_name }, OperationMeta
wallet_from/to: IName | null, IWallet2.id, IWalmove, IRevert.
• controller: DTO Int → String, getLedger2History разделён на accountId
(число) + walletName (строка), repository без ::bigint для wallet полей.
• SDK zeus/index.ts: 4 секции типов под String + walletName поле.
• desktop: WalletIdCell prop wallet-name, store getWalletByName, query
param wallet_name=, OperationsPage filter walletName.
• YAML стандарты: 10 файлов processes capital/marketplace/registrator/
soviet/wallet — wallet_from/wallet_to ('' для sentinel).
• boot tests: walmove/migrate/read-layer на eosio::name.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,8 +23,8 @@ export async function walmove(
|
||||
login: LoginResult,
|
||||
coopname: string,
|
||||
username: string,
|
||||
fromWallet: number,
|
||||
toWallet: number,
|
||||
fromWallet: string,
|
||||
toWallet: string,
|
||||
quantity: string,
|
||||
memo: string,
|
||||
): Promise<{ processHash: string; transactionId: string }> {
|
||||
|
||||
@@ -8,15 +8,16 @@ import { LedgerAccountType } from './wallet/walletUtils'
|
||||
|
||||
// =============================================================================
|
||||
// Epic 1 addendum (пересмотр 2026-04-20): миграция переведена на 6 прямых
|
||||
// TRANSIT_* проводок без транзитного счёта 99 и без кошелька CASH_MAIN (1001).
|
||||
// TRANSIT_* проводок без транзитного счёта 99 и без кошелька CASH_MAIN.
|
||||
// 2026-04-27: numeric wallet id → eosio::name w.<contract>.<waltype>.
|
||||
//
|
||||
// Семантика:
|
||||
// TRANSIT_MIN_SHARE → Dr 51 / Cr 80, ISSUE MIN_SHARE_FUND 2002 (N × min_share)
|
||||
// TRANSIT_BLAGOROST → Dr 51 / Cr 80, ISSUE BLAGOROST_INVEST 9001
|
||||
// TRANSIT_SHARE → Dr 51 / Cr 80, ISSUE SHARE_FUND_PAY 2001 (остаток money)
|
||||
// TRANSIT_ENTRY → Dr 51 / Cr 86, ISSUE ENTRANCE_FEES 3001
|
||||
// TRANSIT_COMMITMENT → Dr 08 / Cr 80, ISSUE GENERATOR_COMMIT 10001
|
||||
// TRANSIT_RID → Dr 04 / Cr 80, ISSUE SHARE_FUND_RID 2003
|
||||
// TRANSIT_MIN_SHARE → Dr 51 / Cr 80, ISSUE MIN_SHARE_FUND (w.reg.minshr)
|
||||
// TRANSIT_BLAGOROST → Dr 51 / Cr 80, ISSUE BLAGOROST_INVEST (w.cap.bginv)
|
||||
// TRANSIT_SHARE → Dr 51 / Cr 80, ISSUE SHARE_FUND_PAY (w.wal.share)
|
||||
// TRANSIT_ENTRY → Dr 51 / Cr 86, ISSUE ENTRANCE_FEES (w.reg.entry)
|
||||
// TRANSIT_COMMITMENT → Dr 08 / Cr 80, ISSUE GENERATOR_COMMIT (w.cap.gncom)
|
||||
// TRANSIT_RID → Dr 04 / Cr 80, ISSUE SHARE_FUND_RID (w.wal.sharid)
|
||||
//
|
||||
// План счетов: 04, 08, 51, 58, 80, 86 (99 удалён как лишний транзит).
|
||||
// =============================================================================
|
||||
@@ -32,10 +33,10 @@ const LEGACY_ACCOUNTS = {
|
||||
} as const
|
||||
|
||||
const LEDGER2_WALLETS = {
|
||||
SHARE_FUND_PAY: 2001,
|
||||
MIN_SHARE_FUND: 2002,
|
||||
SHARE_FUND_RID: 2003,
|
||||
ENTRANCE_FEES: 3001,
|
||||
SHARE_FUND_PAY: 'w.wal.share',
|
||||
MIN_SHARE_FUND: 'w.reg.minshr',
|
||||
SHARE_FUND_RID: 'w.wal.sharid',
|
||||
ENTRANCE_FEES: 'w.reg.entry',
|
||||
} as const
|
||||
|
||||
const LEDGER2_ACCOUNTS = {
|
||||
@@ -70,9 +71,9 @@ async function getLegacyLaccount(accountId: number) {
|
||||
return rows.find((row: any) => Number(row.id) === accountId)
|
||||
}
|
||||
|
||||
async function getLedger2Wallet(walletId: number) {
|
||||
async function getLedger2Wallet(walletName: string) {
|
||||
const rows = await blockchain.getTableRows(LEDGER2, COOP, 'wallets', 200)
|
||||
return rows.find((row: any) => Number(row.id) === walletId)
|
||||
return rows.find((row: any) => String(row.id) === walletName)
|
||||
}
|
||||
|
||||
async function getLedger2Account(accountId: number) {
|
||||
@@ -150,7 +151,7 @@ describe('ledger2::migrate (пересмотр 2026-04-20: 6 TRANSIT_* без 99
|
||||
baselineShareAcc = parseAssetAmount((await getLedger2Account(LEDGER2_ACCOUNTS.SHARE_FUND))?.credit_balance)
|
||||
baselineEntryAcc = parseAssetAmount((await getLedger2Account(LEDGER2_ACCOUNTS.TARGET_RECEIPTS))?.credit_balance)
|
||||
|
||||
// Baseline Σ wallets (2001+2002+3001+2003): testnet-boot мог создать
|
||||
// Baseline Σ wallets (w.wal.share + w.reg.minshr + w.reg.entry + w.wal.sharid): testnet-boot мог создать
|
||||
// начальные балансы для пайщиков. AC8 проверяет что seed добавил ровно
|
||||
// seedCash сверху baseline.
|
||||
const sharePayW = await getLedger2Wallet(LEDGER2_WALLETS.SHARE_FUND_PAY)
|
||||
@@ -241,15 +242,15 @@ describe('ledger2::migrate (пересмотр 2026-04-20: 6 TRANSIT_* без 99
|
||||
expect(parseAssetAmount(entryAcc.balance)).toBeCloseTo(parseAssetAmount(entryAcc.credit_balance) - parseAssetAmount(entryAcc.debit_balance), 4)
|
||||
})
|
||||
|
||||
it('AC7: wallet CASH_MAIN (1001) больше НЕ существует — убран из плана кошельков', async () => {
|
||||
it('AC7: wallet CASH_MAIN больше НЕ существует — убран из плана кошельков', async () => {
|
||||
// Пересмотр 2026-04-20: CASH_MAIN удалён, счёт 51 ведётся только в accounts2.
|
||||
// Никаких wallet-записей под id=1001 быть не должно.
|
||||
// Никаких wallet-записей под устаревшим именем быть не должно.
|
||||
const rows = await blockchain.getTableRows(LEDGER2, COOP, 'wallets', 200)
|
||||
const legacyCashMain = rows.find((row: any) => Number(row.id) === 1001)
|
||||
expect(legacyCashMain, 'wallet 1001 (CASH_MAIN) не должен существовать после migrate').toBeUndefined()
|
||||
const legacyCashMain = rows.find((row: any) => String(row.id) === 'w.wal.cash')
|
||||
expect(legacyCashMain, 'wallet CASH_MAIN не должен существовать после migrate').toBeUndefined()
|
||||
})
|
||||
|
||||
it('AC8: Σ wallets (2001 + 2002 + 3001 + 2003) == baseline + seedCash (инвариант миграции)', async () => {
|
||||
it('AC8: Σ wallets (w.wal.share + w.reg.minshr + w.reg.entry + w.wal.sharid) == baseline + seedCash (инвариант миграции)', async () => {
|
||||
if (migrateWasAlreadyDone) {
|
||||
console.log('⏩ migrate был ранее — AC8 проверка Σ wallets пропущена (неизвестен baseline)')
|
||||
return
|
||||
@@ -267,8 +268,8 @@ describe('ledger2::migrate (пересмотр 2026-04-20: 6 TRANSIT_* без 99
|
||||
|
||||
// Инвариант: seed добавил ровно seedCash в Σ money-кошельков над baseline.
|
||||
// Baseline снимался ДО seed (в первом it) — теперь baseline + seedCash.
|
||||
// Благорост (9001) и Генератор (10001) в эту сумму не входят — они emplace-ятся
|
||||
// отдельно из soviet::progwallets без участия в бух-проводках.
|
||||
// Благорост (w.cap.bginv) и Генератор (w.cap.gncom) в эту сумму не входят — они
|
||||
// emplace-ятся отдельно из soviet::progwallets без участия в бух-проводках.
|
||||
expect(totalWallets).toBeCloseTo(baselineWalletsTotal + seedCash, 4)
|
||||
})
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@ const ACCOUNT_TARGET = 86_000
|
||||
const ACCOUNT_TYPE_ACTIVE = 0
|
||||
const ACCOUNT_TYPE_PASSIVE = 1
|
||||
|
||||
// Кошельки кооператива после миграции (пересмотр 2026-04-20: CASH_MAIN удалён).
|
||||
const WALLET_SHARE_FUND_PAY = 2001
|
||||
const WALLET_ENTRANCE_FEES = 3001
|
||||
// Кошельки кооператива после миграции (пересмотр 2026-04-20: CASH_MAIN удалён;
|
||||
// 2026-04-27: numeric id → eosio::name w.<contract>.<waltype>).
|
||||
const WALLET_SHARE_FUND_PAY = 'w.wal.share'
|
||||
const WALLET_ENTRANCE_FEES = 'w.reg.entry'
|
||||
|
||||
const ACCOUNTS_QUERY = `query($c:String!){
|
||||
getLedger2Accounts(coopname:$c){ id name balance debitBalance creditBalance accountType }
|
||||
@@ -125,15 +126,15 @@ describe('Ledger2 read-layer (Story 1.23)', () => {
|
||||
expect(Array.isArray(wallets)).toBe(true)
|
||||
expect(wallets.length).toBeGreaterThanOrEqual(3)
|
||||
|
||||
const byId = new Map<number, any>(wallets.map((w) => [Number(w.id), w]))
|
||||
expect(byId.get(WALLET_SHARE_FUND_PAY), 'кошелёк паевых взносов 2001').toBeDefined()
|
||||
expect(byId.get(WALLET_ENTRANCE_FEES), 'кошелёк вступ.взносов 3001').toBeDefined()
|
||||
// CASH_MAIN (1001) удалён пересмотром 2026-04-20 — счёт 51 ведётся только в accounts2.
|
||||
expect(byId.get(1001), 'wallet 1001 (CASH_MAIN) удалён, проверка на отсутствие').toBeUndefined()
|
||||
const byId = new Map<string, any>(wallets.map((w) => [String(w.id), w]))
|
||||
expect(byId.get(WALLET_SHARE_FUND_PAY), 'кошелёк паевых взносов w.wal.share').toBeDefined()
|
||||
expect(byId.get(WALLET_ENTRANCE_FEES), 'кошелёк вступ.взносов w.reg.entry').toBeDefined()
|
||||
// CASH_MAIN удалён пересмотром 2026-04-20 — счёт 51 ведётся только в accounts2.
|
||||
expect(byId.get('w.wal.cash'), 'устаревший CASH_MAIN отсутствует в реестре').toBeUndefined()
|
||||
|
||||
const onchain = await bc.getTableRows('ledger2', COOP, 'wallets', 500)
|
||||
for (const w of onchain) {
|
||||
const match = byId.get(Number(w.id))
|
||||
const match = byId.get(String(w.id))
|
||||
if (!match) continue
|
||||
expect(parseAssetAmount(match.available)).toBeCloseTo(parseAssetAmount(w.available), 4)
|
||||
expect(parseAssetAmount(match.blocked)).toBeCloseTo(parseAssetAmount(w.blocked), 4)
|
||||
@@ -148,9 +149,10 @@ describe('Ledger2 read-layer (Story 1.23)', () => {
|
||||
expect(resp.totalCount).toBeGreaterThan(0)
|
||||
expect(resp.items.length).toBeGreaterThan(0)
|
||||
|
||||
// Каждая операция — одного из 4 типов blockchain-actions ledger2.
|
||||
// Каждая операция — одного из типов blockchain-actions ledger2:
|
||||
// штатное трио apply/walletop/debit/credit + adjustment-actions walmove/revert.
|
||||
for (const op of resp.items) {
|
||||
expect(['apply', 'walletop', 'debit', 'credit']).toContain(op.action)
|
||||
expect(['apply', 'walletop', 'debit', 'credit', 'walmove', 'revert']).toContain(op.action)
|
||||
}
|
||||
|
||||
// Фильтр по operationCodes: если есть o.mig.share (транзит паевого фонда), то
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
* Integration: walmove (operation `o.adj.walmove`) — перевод между кошельками
|
||||
* одного бух.счёта (без Dr/Cr). Кейс: после регистрации пайщика на 2002
|
||||
* (MIN_SHARE_FUND) и 2001 (SHARE_FUND_PAY) лежит вместе X RUB на 80-м счёте,
|
||||
* нам нужно перенести часть с 2002 на 2001 (например, реструктуризация
|
||||
* минимального паевого взноса в обычный после criteria-аудита).
|
||||
* одного бух.счёта (без Dr/Cr). Кейс: после регистрации пайщика на
|
||||
* `w.reg.minshr` (MIN_SHARE_FUND) и `w.wal.share` (SHARE_FUND_PAY) лежит
|
||||
* вместе X RUB на 80-м счёте, нам нужно перенести часть с MIN_SHARE_FUND на
|
||||
* SHARE_FUND_PAY (например, реструктуризация минимального паевого взноса
|
||||
* в обычный после criteria-аудита).
|
||||
*
|
||||
* Проверяет:
|
||||
* - mutation walmoveWallets отрабатывает успешно
|
||||
* - balance кошельков 2002 (источник) и 2001 (получатель) изменился на amount
|
||||
* - balance кошельков `w.reg.minshr` и `w.wal.share` изменился на amount
|
||||
* - account 80 (Cr SHARE_FUND) ≡ не изменился (WALLET_ONLY не трогает счета)
|
||||
* - в getLedger2History появилась запись с operation_code='o.adj.walmove'
|
||||
* - попытка перевода между кошельками разных счетов отбивается на backend
|
||||
@@ -24,9 +25,9 @@ import { generateRandomUsername } from '../utils/randomUsername'
|
||||
|
||||
const COOP = 'voskhod'
|
||||
|
||||
const WALLET_MIN_SHARE_FUND = 2002
|
||||
const WALLET_SHARE_FUND_PAY = 2001
|
||||
const WALLET_ENTRANCE_FEES = 3001
|
||||
const WALLET_MIN_SHARE_FUND = 'w.reg.minshr'
|
||||
const WALLET_SHARE_FUND_PAY = 'w.wal.share'
|
||||
const WALLET_ENTRANCE_FEES = 'w.reg.entry'
|
||||
|
||||
const ACCOUNT_SHARE_FUND = 80_000
|
||||
|
||||
@@ -60,15 +61,15 @@ function parseAsset(raw: string | null | undefined): number {
|
||||
* Читаем балансы кошельков напрямую с блокчейна — parser отстаёт от head_block
|
||||
* на минуты, GraphQL-снимок ненадёжен для проверок «сразу после транзакции».
|
||||
*/
|
||||
async function getWalletAvailable(walletId: number): Promise<number> {
|
||||
async function getWalletAvailable(walletName: string): Promise<number> {
|
||||
const rows = await bc.getTableRows('ledger2', COOP, 'wallets', 200)
|
||||
const w = rows.find((r: { id: number | string }) => Number(r.id) === walletId)
|
||||
const w = rows.find((r: { id: string }) => String(r.id) === walletName)
|
||||
return w ? parseAsset((w as { available: string }).available) : 0
|
||||
}
|
||||
|
||||
describe('walmove (operation o.adj.walmove) — корректировка между кошельками одного бух.счёта', () => {
|
||||
it('переводит сумму между двумя кошельками счёта 80 без изменения balance счёта', async () => {
|
||||
// 1. Регистрируем нового пайщика — пополняет 2002 (MIN_SHARE_FUND) и 3001 (ENTRANCE_FEES)
|
||||
// 1. Регистрируем нового пайщика — пополняет w.reg.minshr (MIN_SHARE_FUND) и w.reg.entry (ENTRANCE_FEES)
|
||||
const username = generateRandomUsername()
|
||||
const participant = await registerUser(bc, COOP, username)
|
||||
expect(participant).toBeDefined()
|
||||
@@ -85,7 +86,7 @@ describe('walmove (operation o.adj.walmove) — корректировка ме
|
||||
expect(moveAmount).toBeGreaterThan(0)
|
||||
expect(fromBefore).toBeGreaterThanOrEqual(moveAmount)
|
||||
|
||||
// 3. Перевод 2002 → 2001 (оба кошелька на счёте 80)
|
||||
// 3. Перевод w.reg.minshr → w.wal.share (оба кошелька на счёте 80)
|
||||
const memo = `walmove test: ${username}`
|
||||
const { processHash } = await walmove(
|
||||
login, COOP, COOP,
|
||||
@@ -122,7 +123,7 @@ describe('walmove (operation o.adj.walmove) — корректировка ме
|
||||
}, 240_000)
|
||||
|
||||
it('отказывает в переводе между кошельками разных бух.счетов (валидация в backend)', async () => {
|
||||
// 2002 (MIN_SHARE_FUND, на счёте 80) → 3001 (ENTRANCE_FEES, на счёте 86) — разные счета.
|
||||
// w.reg.minshr (MIN_SHARE_FUND, на счёте 80) → w.reg.entry (ENTRANCE_FEES, на счёте 86) — разные счета.
|
||||
let errMessage = ''
|
||||
try {
|
||||
await walmove(
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# фонда кооператива и его возврат через акт приёма-передачи проекта.
|
||||
#
|
||||
# Многоактовый процесс с авторизацией советом. Две операции:
|
||||
# • o.cap.lend — выдача займа на момент авторизации (ISSUE → 4051, Дт 58 / Кт 51)
|
||||
# • o.cap.repay — возврат займа из акта-2 (TRANSFER 4051 → 2001, Дт 80 / Кт 58)
|
||||
# • o.cap.lend — выдача займа на момент авторизации (ISSUE → w.cap.loan, Дт 58 / Кт 51)
|
||||
# • o.cap.repay — возврат займа из акта-2 (TRANSFER w.cap.loan → w.wal.share, Дт 80 / Кт 58)
|
||||
#
|
||||
# Источники правды в коде:
|
||||
# • cpp/capital/capital.hpp — actions
|
||||
@@ -29,8 +29,8 @@ purpose: >
|
||||
Gateway выплачивает деньги пайщику — в этот момент применяется операция
|
||||
o.cap.lend (выдача займа со счёта 51 в счёт 58). Возврат займа происходит
|
||||
на этапе сдачи акта-2 проекта: операция o.cap.repay переводит средства
|
||||
с кошелька «Выданные займы» (4051) на «ЦПП Цифровой Кошелёк» пайщика
|
||||
(2001) с проводкой Дт 80 / Кт 58 — паевой фонд закрывает заём.
|
||||
с кошелька «Выданные займы» (w.cap.loan) на «ЦПП Цифровой Кошелёк» пайщика
|
||||
(w.wal.share) с проводкой Дт 80 / Кт 58 — паевой фонд закрывает заём.
|
||||
roles:
|
||||
- contributor
|
||||
- chairman
|
||||
@@ -204,7 +204,7 @@ scenario:
|
||||
action: capital::debtauthcnfr
|
||||
description: >
|
||||
Совет авторизует выплату. В ledger2 применяется операция o.cap.lend
|
||||
(ISSUE → 4051, Дт 58 / Кт 51), Gateway получает поручение на
|
||||
(ISSUE → w.cap.loan, Дт 58 / Кт 51), Gateway получает поручение на
|
||||
исходящий платёж. Статус → `authorized`.
|
||||
|
||||
- step: 4
|
||||
@@ -262,8 +262,8 @@ operations:
|
||||
- ledger_code: o.cap.lend
|
||||
human_name: Выдача пайщику беспроцентного займа
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 4051 # Выданные пайщикам беспроцентные займы
|
||||
wallet_from: ''
|
||||
wallet_to: w.cap.loan # Выданные пайщикам беспроцентные займы
|
||||
debit: 58 # Финансовые вложения
|
||||
credit: 51 # Расчётный счёт
|
||||
amount_ref: debt.amount
|
||||
@@ -271,14 +271,14 @@ operations:
|
||||
description: >
|
||||
Выдача беспроцентного займа пайщику. Деньги уходят с расчётного счёта
|
||||
кооператива (Кт 51) и появляются как финансовое вложение Дт 58.
|
||||
Кошелёк «Выданные пайщикам беспроцентные займы» (4051) фиксирует
|
||||
Кошелёк «Выданные пайщикам беспроцентные займы» (w.cap.loan) фиксирует
|
||||
обязательство пайщика перед кооперативом.
|
||||
|
||||
- ledger_code: o.cap.repay
|
||||
human_name: Возврат беспроцентного займа пайщика по акту-2
|
||||
wallet_op: TRANSFER
|
||||
wallet_from: 4051 # Выданные пайщикам беспроцентные займы
|
||||
wallet_to: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_from: w.cap.loan # Выданные пайщикам беспроцентные займы
|
||||
wallet_to: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
debit: 80 # Паевой фонд (складочный капитал)
|
||||
credit: 58 # Финансовые вложения
|
||||
amount_ref: debt.amount
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Стандарт «Инвестиция в ЦПП «Благорост»» — перенос ранее внесённого паевого
|
||||
# взноса с кошелька SHARE_FUND_PAY (2001) на инвестиционный кошелёк программы
|
||||
# «Благорост» (9001) без бухгалтерских проводок.
|
||||
# взноса с кошелька SHARE_FUND_PAY (w.wal.share) на инвестиционный кошелёк программы
|
||||
# «Благорост» (w.cap.bginv) без бухгалтерских проводок.
|
||||
#
|
||||
# Одноактовый процесс. В ledger2 — одна операция o.cap.invest c wallet_op =
|
||||
# WALLET_ONLY: средства переходят между двумя аналитическими кошельками
|
||||
@@ -27,8 +27,8 @@ summary: >
|
||||
своими кошельками.
|
||||
purpose: >
|
||||
Одноактовый процесс. Пайщик подписывает заявление об инвестировании,
|
||||
контракт переносит сумму с его кошелька SHARE_FUND_PAY (2001, паевые
|
||||
взносы деньгами) на BLAGOROST_INVEST (9001, инвестиции в «Благорост»).
|
||||
контракт переносит сумму с его кошелька SHARE_FUND_PAY (w.wal.share, паевые
|
||||
взносы деньгами) на BLAGOROST_INVEST (w.cap.bginv, инвестиции в «Благорост»).
|
||||
Бухгалтерские проводки не делаются: это аналитическое перемещение в рамках
|
||||
одной общей суммы паевого фонда. Денежные средства фактически остаются на
|
||||
расчётном счёте кооператива, но в учёте пайщика они теперь считаются
|
||||
@@ -45,8 +45,8 @@ actions:
|
||||
purpose: >
|
||||
Закрывающее одношаговое действие: пайщик подписывает заявление об
|
||||
инвестировании в «Благорост», контракт применяет ledger2-операцию
|
||||
o.cap.invest и средства аналитически переходят с SHARE_FUND_PAY (2001)
|
||||
на BLAGOROST_INVEST (9001).
|
||||
o.cap.invest и средства аналитически переходят с SHARE_FUND_PAY (w.wal.share)
|
||||
на BLAGOROST_INVEST (w.cap.bginv).
|
||||
|
||||
# ── Секция 3. Граф состояний ────────────────────────────────────────────────
|
||||
entity: capital::invest
|
||||
@@ -57,8 +57,8 @@ states:
|
||||
- name: invested
|
||||
human: Инвестировано
|
||||
description: >
|
||||
Сумма перенесена с кошелька SHARE_FUND_PAY (2001) пайщика на
|
||||
BLAGOROST_INVEST (9001). Бухгалтерия не затронута — это аналитический
|
||||
Сумма перенесена с кошелька SHARE_FUND_PAY (w.wal.share) пайщика на
|
||||
BLAGOROST_INVEST (w.cap.bginv). Бухгалтерия не затронута — это аналитический
|
||||
сдвиг внутри паевого фонда.
|
||||
kind: final
|
||||
|
||||
@@ -72,7 +72,7 @@ transitions:
|
||||
- o.cap.invest
|
||||
guards:
|
||||
- Пайщик имеет статус active.
|
||||
- Сумма ≤ доступного остатка на SHARE_FUND_PAY (2001).
|
||||
- Сумма ≤ доступного остатка на SHARE_FUND_PAY (w.wal.share).
|
||||
- invest_hash уникален.
|
||||
- Заявление об инвестировании подписано пайщиком.
|
||||
|
||||
@@ -86,7 +86,7 @@ scenario:
|
||||
description: >
|
||||
Пайщик подписывает заявление об инвестировании и вызывает
|
||||
capital::createpinv. Контракт переводит указанную сумму с кошелька
|
||||
SHARE_FUND_PAY (2001) на BLAGOROST_INVEST (9001) — операция
|
||||
SHARE_FUND_PAY (w.wal.share) на BLAGOROST_INVEST (w.cap.bginv) — операция
|
||||
o.cap.invest, wallet_op WALLET_ONLY (без проводок). Запись в
|
||||
реестре фиксирует факт инвестиции.
|
||||
pre:
|
||||
@@ -94,7 +94,7 @@ scenario:
|
||||
- Достаточный остаток на SHARE_FUND_PAY.
|
||||
- Заявление подписано ЭЦП.
|
||||
post:
|
||||
- Сумма переведена 2001 → 9001 (аналитический сдвиг).
|
||||
- Сумма переведена w.wal.share → w.cap.bginv (аналитический сдвиг).
|
||||
- В ledger2 применена операция o.cap.invest.
|
||||
- Создана запись инвестиции в таблице.
|
||||
|
||||
@@ -115,8 +115,8 @@ operations:
|
||||
- ledger_code: o.cap.invest
|
||||
human_name: Инвестиция в ЦПП «Благорост» (перенос между кошельками)
|
||||
wallet_op: WALLET_ONLY
|
||||
wallet_from: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_to: 9001 # ЦПП «Благорост» — инвестиции деньгами
|
||||
wallet_from: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_to: w.cap.bginv # ЦПП «Благорост» — инвестиции деньгами
|
||||
debit: null
|
||||
credit: null
|
||||
amount_ref: invest.quantity
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# Шестиактовый процесс с двумя последовательными актами и одной операцией.
|
||||
# В ledger2 — одна операция o.cap.actprp на закрывающем действии акта-2
|
||||
# (ISSUE → 9003, Дт 51 / Кт 80).
|
||||
# (ISSUE → w.cap.bgprop, Дт 51 / Кт 80).
|
||||
#
|
||||
# Источники правды в коде:
|
||||
# • cpp/capital/capital.hpp — actions
|
||||
@@ -29,7 +29,7 @@ purpose: >
|
||||
его одобряет, совет авторизует. Передача оформляется двумя актами:
|
||||
пайщик ставит первую подпись на акте приёма-передачи, председатель —
|
||||
вторую (закрывающее действие). На второй подписи применяется ledger2-операция
|
||||
o.cap.actprp (ISSUE → 9003, Дт 51 / Кт 80) — имущество учитывается
|
||||
o.cap.actprp (ISSUE → w.cap.bgprop, Дт 51 / Кт 80) — имущество учитывается
|
||||
как паевой взнос на кошельке «Благорост — имущественные паевые взносы».
|
||||
roles:
|
||||
- contributor
|
||||
@@ -71,7 +71,7 @@ actions:
|
||||
role: closer
|
||||
purpose: >
|
||||
Председатель ставит вторую подпись на акте приёма-передачи — закрывающее
|
||||
действие. Применяется ledger2-операция o.cap.actprp (ISSUE → 9003, Дт 51 / Кт 80).
|
||||
действие. Применяется ledger2-операция o.cap.actprp (ISSUE → w.cap.bgprop, Дт 51 / Кт 80).
|
||||
- name: capital::declinepgprp
|
||||
human: Отклонить
|
||||
actor: chairman
|
||||
@@ -108,7 +108,7 @@ states:
|
||||
human: Имущество принято
|
||||
description: >
|
||||
Председатель поставил вторую подпись на акте приёма-передачи: имущество учтено как паевой взнос на
|
||||
кошельке «Благорост — имущественные паевые взносы» (9003) с проводкой
|
||||
кошельке «Благорост — имущественные паевые взносы» (w.cap.bgprop) с проводкой
|
||||
Дт 51 / Кт 80.
|
||||
kind: final
|
||||
- name: removed
|
||||
@@ -212,7 +212,7 @@ scenario:
|
||||
description: >
|
||||
Председатель ставит вторую подпись на акте приёма-передачи —
|
||||
закрывающее действие. Применяется
|
||||
ledger2-операция o.cap.actprp (ISSUE → 9003, Дт 51 / Кт 80) — имущество
|
||||
ledger2-операция o.cap.actprp (ISSUE → w.cap.bgprop, Дт 51 / Кт 80) — имущество
|
||||
учтено как паевой взнос.
|
||||
|
||||
alternatives:
|
||||
@@ -263,15 +263,15 @@ operations:
|
||||
- ledger_code: o.cap.actprp
|
||||
human_name: Паевой взнос (имущественный) по программе «Благорост»
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 9003 # ЦПП «Благорост» — имущественные паевые взносы
|
||||
wallet_from: ''
|
||||
wallet_to: w.cap.bgprop # ЦПП «Благорост» — имущественные паевые взносы
|
||||
debit: 51 # Расчётный счёт
|
||||
credit: 80 # Паевой фонд (складочный капитал)
|
||||
amount_ref: property.amount
|
||||
triggered_by: capital::act2pgprp
|
||||
description: >
|
||||
Зачисление имущества (по сумме оценки) на кошелёк «Благорост —
|
||||
имущественные паевые взносы» (9003). Двойная запись Дт 51 / Кт 80 —
|
||||
имущественные паевые взносы» (w.cap.bgprop). Двойная запись Дт 51 / Кт 80 —
|
||||
кооператив принял имущество и оно учтено как часть паевого фонда.
|
||||
|
||||
# ── Секция 7. Связи ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# паевого взноса.
|
||||
#
|
||||
# Многоэтапный процесс. Три ledger2-операции:
|
||||
# • o.cap.commit — коммит РИД при одобрении (Дт 8 / Кт 80, кошелёк 10001)
|
||||
# • o.cap.accept — приём РИД в паевой фонд по акту-2 (TRANSFER 10001 → 9002, Дт 4 / Кт 8)
|
||||
# • o.cap.commit — коммит РИД при одобрении (Дт 8 / Кт 80, кошелёк w.cap.gncom)
|
||||
# • o.cap.accept — приём РИД в паевой фонд по акту-2 (TRANSFER w.cap.gncom → w.cap.bgrid, Дт 4 / Кт 8)
|
||||
# • o.cap.repay — опционально, если у участника есть заём (см. p.cap.debt)
|
||||
#
|
||||
# Источники правды в коде:
|
||||
@@ -35,7 +35,7 @@ purpose: >
|
||||
(Дт 8 / Кт 80, кошелёк «Генератор — принятый коммит»). Затем РИД
|
||||
передаётся через акт приёма-передачи: первую подпись ставит участник,
|
||||
вторую — председатель; на второй подписи применяется o.cap.accept
|
||||
(TRANSFER 10001 → 9002, Дт 4 / Кт 8) —
|
||||
(TRANSFER w.cap.gncom → w.cap.bgrid, Дт 4 / Кт 8) —
|
||||
РИД переходит в паевой фонд «Благорост — принятые РИД». Если у участника
|
||||
был заём проекта (см. p.cap.debt), на акте-2 дополнительно срабатывает
|
||||
o.cap.repay (зачёт займа в паевой фонд).
|
||||
@@ -62,7 +62,7 @@ actions:
|
||||
purpose: >
|
||||
Мастер проекта одобряет коммит. На этом этапе применяется ledger2-
|
||||
операция o.cap.commit — РИД зачисляется на «Генератор — принятый
|
||||
коммит» (10001) с проводкой Дт 8 / Кт 80.
|
||||
коммит» (w.cap.gncom) с проводкой Дт 8 / Кт 80.
|
||||
- name: capital::declinecmmt
|
||||
human: Отклонить коммит
|
||||
actor: master
|
||||
@@ -110,7 +110,7 @@ states:
|
||||
human: Коммит одобрен
|
||||
description: >
|
||||
Мастер одобрил коммит. РИД зачислен на кошелёк «Генератор — принятый
|
||||
коммит» (10001) с проводкой Дт 8 / Кт 80. Ожидается сдача актами.
|
||||
коммит» (w.cap.gncom) с проводкой Дт 8 / Кт 80. Ожидается сдача актами.
|
||||
kind: normal
|
||||
- name: pushed
|
||||
human: Результат сдан
|
||||
@@ -127,8 +127,8 @@ states:
|
||||
- name: accepted
|
||||
human: РИД принят в паевой фонд
|
||||
description: >
|
||||
Председатель поставил вторую подпись на акте приёма-передачи: РИД переведён с «Генератора» (10001)
|
||||
на «Благорост — принятые РИД» (9002), Дт 4 / Кт 8. Если у участника
|
||||
Председатель поставил вторую подпись на акте приёма-передачи: РИД переведён с «Генератора» (w.cap.gncom)
|
||||
на «Благорост — принятые РИД» (w.cap.bgrid), Дт 4 / Кт 8. Если у участника
|
||||
был заём проекта — он закрылся (o.cap.repay). РИД считается
|
||||
имущественным паевым взносом.
|
||||
kind: final
|
||||
@@ -210,7 +210,7 @@ scenario:
|
||||
description: >
|
||||
Мастер проекта одобряет коммит. Применяется ledger2-операция
|
||||
o.cap.commit — РИД зачисляется на «Генератор — принятый коммит»
|
||||
(10001) с проводкой Дт 8 / Кт 80.
|
||||
(w.cap.gncom) с проводкой Дт 8 / Кт 80.
|
||||
|
||||
- step: 3
|
||||
title: Сдача результата
|
||||
@@ -236,9 +236,9 @@ scenario:
|
||||
действие. Применяются
|
||||
две ledger2-операции:
|
||||
(1) o.cap.accept — РИД переходит с «Генератор — принятый коммит»
|
||||
(10001) на «Благорост — принятые РИД» (9002), Дт 4 / Кт 8;
|
||||
(w.cap.gncom) на «Благорост — принятые РИД» (w.cap.bgrid), Дт 4 / Кт 8;
|
||||
(2) опционально o.cap.repay — если у участника был заём проекта,
|
||||
заём закрывается (4051 → 2001, Дт 80 / Кт 58).
|
||||
заём закрывается (w.cap.loan → w.wal.share, Дт 80 / Кт 58).
|
||||
|
||||
alternatives:
|
||||
- branch: Отказ мастера
|
||||
@@ -280,22 +280,22 @@ operations:
|
||||
- ledger_code: o.cap.commit
|
||||
human_name: Коммит РИД по программе «Благорост»
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 10001 # ЦПП «Генератор» — принятый коммит (имущество)
|
||||
wallet_from: ''
|
||||
wallet_to: w.cap.gncom # ЦПП «Генератор» — принятый коммит (имущество)
|
||||
debit: 8 # Вложения во внеоборотные активы
|
||||
credit: 80 # Паевой фонд (складочный капитал)
|
||||
amount_ref: commit.delta_amount
|
||||
triggered_by: capital::approvecmmt
|
||||
description: >
|
||||
Зачисление РИД-коммита на кошелёк «Генератор — принятый коммит» (10001)
|
||||
Зачисление РИД-коммита на кошелёк «Генератор — принятый коммит» (w.cap.gncom)
|
||||
при одобрении мастером. Двойная запись Дт 8 / Кт 80 — РИД учитывается
|
||||
как вложение во внеоборотные активы и формирует паевой фонд.
|
||||
|
||||
- ledger_code: o.cap.accept
|
||||
human_name: Приём РИД в паевой фонд
|
||||
wallet_op: TRANSFER
|
||||
wallet_from: 10001 # ЦПП «Генератор» — принятый коммит
|
||||
wallet_to: 9002 # ЦПП «Благорост» — принятые РИД
|
||||
wallet_from: w.cap.gncom # ЦПП «Генератор» — принятый коммит
|
||||
wallet_to: w.cap.bgrid # ЦПП «Благорост» — принятые РИД
|
||||
debit: 4 # Нематериальные активы
|
||||
credit: 8 # Вложения во внеоборотные активы
|
||||
amount_ref: result.amount
|
||||
@@ -308,8 +308,8 @@ operations:
|
||||
- ledger_code: o.cap.repay
|
||||
human_name: Возврат беспроцентного займа пайщика по акту-2
|
||||
wallet_op: TRANSFER
|
||||
wallet_from: 4051 # Выданные пайщикам беспроцентные займы
|
||||
wallet_to: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_from: w.cap.loan # Выданные пайщикам беспроцентные займы
|
||||
wallet_to: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
debit: 80 # Паевой фонд (складочный капитал)
|
||||
credit: 58 # Финансовые вложения
|
||||
amount_ref: debt.amount
|
||||
|
||||
@@ -85,8 +85,8 @@ public:
|
||||
*/
|
||||
[[eosio::action]] void walletop(eosio::name coopname,
|
||||
uint8_t op_code,
|
||||
uint64_t wallet_from,
|
||||
uint64_t wallet_to,
|
||||
eosio::name wallet_from,
|
||||
eosio::name wallet_to,
|
||||
eosio::asset amount,
|
||||
eosio::checksum256 process_hash,
|
||||
std::string memo);
|
||||
@@ -164,8 +164,8 @@ public:
|
||||
[[eosio::action]] void walmove(eosio::name coopname,
|
||||
eosio::name initiator,
|
||||
eosio::name username,
|
||||
uint64_t from_wallet,
|
||||
uint64_t to_wallet,
|
||||
eosio::name from_wallet,
|
||||
eosio::name to_wallet,
|
||||
eosio::asset amount,
|
||||
eosio::checksum256 process_hash,
|
||||
std::string memo);
|
||||
@@ -194,7 +194,7 @@ public:
|
||||
* @param amount сумма (как в оригинале)
|
||||
* @param mirror_wallet_op тип wallet-операции зеркала (REVOKE/TRANSFER/WALLET_ONLY)
|
||||
* @param mirror_wallet_from кошелёк-источник зеркала
|
||||
* @param mirror_wallet_to кошелёк-получатель зеркала (0 для REVOKE)
|
||||
* @param mirror_wallet_to кошелёк-получатель зеркала (пустое имя для REVOKE)
|
||||
* @param mirror_debit_account_id Dr-счёт зеркала (0 для WALLET_ONLY)
|
||||
* @param mirror_credit_account_id Cr-счёт зеркала (0 для WALLET_ONLY)
|
||||
* @param process_hash уникальный хэш для зеркальной операции
|
||||
@@ -209,8 +209,8 @@ public:
|
||||
eosio::name username,
|
||||
eosio::asset amount,
|
||||
uint8_t mirror_wallet_op,
|
||||
uint64_t mirror_wallet_from,
|
||||
uint64_t mirror_wallet_to,
|
||||
eosio::name mirror_wallet_from,
|
||||
eosio::name mirror_wallet_to,
|
||||
uint64_t mirror_debit_account_id,
|
||||
uint64_t mirror_credit_account_id,
|
||||
eosio::checksum256 process_hash,
|
||||
|
||||
@@ -29,8 +29,8 @@ void ledger2::revert(eosio::name coopname,
|
||||
eosio::name username,
|
||||
eosio::asset amount,
|
||||
uint8_t mirror_wallet_op,
|
||||
uint64_t mirror_wallet_from,
|
||||
uint64_t mirror_wallet_to,
|
||||
eosio::name mirror_wallet_from,
|
||||
eosio::name mirror_wallet_to,
|
||||
uint64_t mirror_debit_account_id,
|
||||
uint64_t mirror_credit_account_id,
|
||||
eosio::checksum256 process_hash,
|
||||
@@ -75,13 +75,13 @@ void ledger2::revert(eosio::name coopname,
|
||||
"revert: BLOCK/UNBLOCK не подлежат откату через revert (они симметричны сами себе)");
|
||||
|
||||
// -------- validate mirror wallets/accounts --------
|
||||
if (mirror_wallet_from != 0) {
|
||||
eosio::check(!ledger2_get_wallet_name_by_id(mirror_wallet_from).empty(),
|
||||
std::string{"revert: неизвестный mirror_wallet_from "} + std::to_string(mirror_wallet_from));
|
||||
if (mirror_wallet_from.value != 0) {
|
||||
eosio::check(ledger2_is_known_wallet(mirror_wallet_from),
|
||||
std::string{"revert: неизвестный mirror_wallet_from "} + mirror_wallet_from.to_string());
|
||||
}
|
||||
if (mirror_wallet_to != 0) {
|
||||
eosio::check(!ledger2_get_wallet_name_by_id(mirror_wallet_to).empty(),
|
||||
std::string{"revert: неизвестный mirror_wallet_to "} + std::to_string(mirror_wallet_to));
|
||||
if (mirror_wallet_to.value != 0) {
|
||||
eosio::check(ledger2_is_known_wallet(mirror_wallet_to),
|
||||
std::string{"revert: неизвестный mirror_wallet_to "} + mirror_wallet_to.to_string());
|
||||
}
|
||||
|
||||
const bool wallet_only = (mirror_wallet_op == static_cast<uint8_t>(WalletOp::WALLET_ONLY));
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
void ledger2::walmove(eosio::name coopname,
|
||||
eosio::name initiator,
|
||||
eosio::name username,
|
||||
uint64_t from_wallet,
|
||||
uint64_t to_wallet,
|
||||
eosio::name from_wallet,
|
||||
eosio::name to_wallet,
|
||||
eosio::asset amount,
|
||||
eosio::checksum256 process_hash,
|
||||
std::string memo) {
|
||||
@@ -44,13 +44,13 @@ void ledger2::walmove(eosio::name coopname,
|
||||
"walmove: некорректный символ валюты");
|
||||
|
||||
// -------- validate wallets --------
|
||||
eosio::check(from_wallet != 0, "walmove: from_wallet обязателен");
|
||||
eosio::check(to_wallet != 0, "walmove: to_wallet обязателен");
|
||||
eosio::check(from_wallet.value != 0, "walmove: from_wallet обязателен");
|
||||
eosio::check(to_wallet.value != 0, "walmove: to_wallet обязателен");
|
||||
eosio::check(from_wallet != to_wallet, "walmove: from_wallet == to_wallet");
|
||||
eosio::check(!ledger2_get_wallet_name_by_id(from_wallet).empty(),
|
||||
std::string{"walmove: неизвестный from_wallet "} + std::to_string(from_wallet));
|
||||
eosio::check(!ledger2_get_wallet_name_by_id(to_wallet).empty(),
|
||||
std::string{"walmove: неизвестный to_wallet "} + std::to_string(to_wallet));
|
||||
eosio::check(ledger2_is_known_wallet(from_wallet),
|
||||
std::string{"walmove: неизвестный from_wallet "} + from_wallet.to_string());
|
||||
eosio::check(ledger2_is_known_wallet(to_wallet),
|
||||
std::string{"walmove: неизвестный to_wallet "} + to_wallet.to_string());
|
||||
|
||||
// -------- validate memo (обязательный для adjustment) --------
|
||||
eosio::check(!memo.empty(), "walmove: memo обязателен — укажите обоснование");
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
[[eosio::action]]
|
||||
void ledger2::walletop(eosio::name coopname,
|
||||
uint8_t op_code,
|
||||
uint64_t wallet_from,
|
||||
uint64_t wallet_to,
|
||||
eosio::name wallet_from,
|
||||
eosio::name wallet_to,
|
||||
eosio::asset amount,
|
||||
eosio::checksum256 process_hash,
|
||||
std::string memo) {
|
||||
@@ -49,16 +49,16 @@ void ledger2::walletop(eosio::name coopname,
|
||||
wallets2_index wallets(get_self(), coopname.value);
|
||||
const eosio::name payer = get_self();
|
||||
|
||||
auto upsert_wallet = [&](uint64_t wallet_id) -> wallets2_index::const_iterator {
|
||||
auto it = wallets.find(wallet_id);
|
||||
auto upsert_wallet = [&](eosio::name wallet_id) -> wallets2_index::const_iterator {
|
||||
auto it = wallets.find(wallet_id.value);
|
||||
if (it == wallets.end()) {
|
||||
const auto name_view = ledger2_get_wallet_name_by_id(wallet_id);
|
||||
eosio::check(!name_view.empty(),
|
||||
std::string{"walletop: unknown wallet id "} + std::to_string(wallet_id));
|
||||
const std::string name{name_view};
|
||||
const auto human_view = ledger2_get_wallet_human_name(wallet_id);
|
||||
eosio::check(!human_view.empty(),
|
||||
std::string{"walletop: unknown wallet "} + wallet_id.to_string());
|
||||
const std::string human{human_view};
|
||||
it = wallets.emplace(payer, [&](auto& w) {
|
||||
w.id = wallet_id;
|
||||
w.name = name;
|
||||
w.name = human;
|
||||
w.available = eosio::asset(0, amount.symbol);
|
||||
w.blocked = eosio::asset(0, amount.symbol);
|
||||
});
|
||||
@@ -66,8 +66,8 @@ void ledger2::walletop(eosio::name coopname,
|
||||
return it;
|
||||
};
|
||||
|
||||
auto cleanup_if_empty = [&](uint64_t wallet_id) {
|
||||
auto it = wallets.find(wallet_id);
|
||||
auto cleanup_if_empty = [&](eosio::name wallet_id) {
|
||||
auto it = wallets.find(wallet_id.value);
|
||||
if (it != wallets.end() && it->is_empty()) {
|
||||
wallets.erase(it);
|
||||
}
|
||||
@@ -75,8 +75,8 @@ void ledger2::walletop(eosio::name coopname,
|
||||
|
||||
switch (static_cast<WalletOp>(op_code)) {
|
||||
case WalletOp::ISSUE: {
|
||||
eosio::check(wallet_from == 0, "walletop ISSUE: wallet_from должен быть 0");
|
||||
eosio::check(wallet_to != 0, "walletop ISSUE: требуется wallet_to");
|
||||
eosio::check(wallet_from.value == 0, "walletop ISSUE: wallet_from должен быть пустым");
|
||||
eosio::check(wallet_to.value != 0, "walletop ISSUE: требуется wallet_to");
|
||||
auto it = upsert_wallet(wallet_to);
|
||||
wallets.modify(it, payer, [&](auto& w) { w.available += amount; });
|
||||
break;
|
||||
@@ -85,14 +85,14 @@ void ledger2::walletop(eosio::name coopname,
|
||||
case WalletOp::WALLET_ONLY: {
|
||||
// Оба типа — перенос available между кошельками. WALLET_ONLY отличается
|
||||
// только отсутствием inline debit/credit (см. apply.cpp).
|
||||
eosio::check(wallet_from != 0 && wallet_to != 0,
|
||||
eosio::check(wallet_from.value != 0 && wallet_to.value != 0,
|
||||
"walletop TRANSFER/WALLET_ONLY: требуются wallet_from и wallet_to");
|
||||
eosio::check(wallet_from != wallet_to,
|
||||
"walletop TRANSFER/WALLET_ONLY: wallet_from == wallet_to");
|
||||
auto from_it = wallets.find(wallet_from);
|
||||
auto from_it = wallets.find(wallet_from.value);
|
||||
eosio::check(from_it != wallets.end() && from_it->available >= amount,
|
||||
std::string{"walletop TRANSFER: недостаточно средств на кошельке "} +
|
||||
std::to_string(wallet_from));
|
||||
wallet_from.to_string());
|
||||
wallets.modify(from_it, payer, [&](auto& w) { w.available -= amount; });
|
||||
auto to_it = upsert_wallet(wallet_to);
|
||||
wallets.modify(to_it, payer, [&](auto& w) { w.available += amount; });
|
||||
@@ -100,12 +100,12 @@ void ledger2::walletop(eosio::name coopname,
|
||||
break;
|
||||
}
|
||||
case WalletOp::BLOCK: {
|
||||
eosio::check(wallet_from != 0, "walletop BLOCK: требуется wallet_from");
|
||||
eosio::check(wallet_to == 0, "walletop BLOCK: wallet_to должен быть 0");
|
||||
auto it = wallets.find(wallet_from);
|
||||
eosio::check(wallet_from.value != 0, "walletop BLOCK: требуется wallet_from");
|
||||
eosio::check(wallet_to.value == 0, "walletop BLOCK: wallet_to должен быть пустым");
|
||||
auto it = wallets.find(wallet_from.value);
|
||||
eosio::check(it != wallets.end() && it->available >= amount,
|
||||
std::string{"walletop BLOCK: недостаточно available на кошельке "} +
|
||||
std::to_string(wallet_from));
|
||||
wallet_from.to_string());
|
||||
wallets.modify(it, payer, [&](auto& w) {
|
||||
w.available -= amount;
|
||||
w.blocked += amount;
|
||||
@@ -113,12 +113,12 @@ void ledger2::walletop(eosio::name coopname,
|
||||
break;
|
||||
}
|
||||
case WalletOp::UNBLOCK: {
|
||||
eosio::check(wallet_from != 0, "walletop UNBLOCK: требуется wallet_from");
|
||||
eosio::check(wallet_to == 0, "walletop UNBLOCK: wallet_to должен быть 0");
|
||||
auto it = wallets.find(wallet_from);
|
||||
eosio::check(wallet_from.value != 0, "walletop UNBLOCK: требуется wallet_from");
|
||||
eosio::check(wallet_to.value == 0, "walletop UNBLOCK: wallet_to должен быть пустым");
|
||||
auto it = wallets.find(wallet_from.value);
|
||||
eosio::check(it != wallets.end() && it->blocked >= amount,
|
||||
std::string{"walletop UNBLOCK: недостаточно blocked на кошельке "} +
|
||||
std::to_string(wallet_from));
|
||||
wallet_from.to_string());
|
||||
wallets.modify(it, payer, [&](auto& w) {
|
||||
w.blocked -= amount;
|
||||
w.available += amount;
|
||||
@@ -128,12 +128,12 @@ void ledger2::walletop(eosio::name coopname,
|
||||
case WalletOp::REVOKE: {
|
||||
// Зеркало ISSUE: убираем amount с wallet_from без увеличения куда-либо.
|
||||
// Используется только из ledger2::revert при откате ISSUE-операций.
|
||||
eosio::check(wallet_from != 0, "walletop REVOKE: требуется wallet_from");
|
||||
eosio::check(wallet_to == 0, "walletop REVOKE: wallet_to должен быть 0");
|
||||
auto it = wallets.find(wallet_from);
|
||||
eosio::check(wallet_from.value != 0, "walletop REVOKE: требуется wallet_from");
|
||||
eosio::check(wallet_to.value == 0, "walletop REVOKE: wallet_to должен быть пустым");
|
||||
auto it = wallets.find(wallet_from.value);
|
||||
eosio::check(it != wallets.end() && it->available >= amount,
|
||||
std::string{"walletop REVOKE: недостаточно available на кошельке "} +
|
||||
std::to_string(wallet_from));
|
||||
wallet_from.to_string());
|
||||
wallets.modify(it, payer, [&](auto& w) { w.available -= amount; });
|
||||
cleanup_if_empty(wallet_from);
|
||||
break;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* системы учёта, progwallet.blocked не проводится через 80-й счёт,
|
||||
* поэтому любая попытка провести его через Dr 51 / Cr 80 вызовет
|
||||
* двойной учёт на бухуровне. Вместо этого переносим только
|
||||
* wallet-аналитику (9001 BLAGOROST_INVEST, 10001 GENERATOR_COMMIT).
|
||||
* wallet-аналитику (w.cap.bginv BLAGOROST_INVEST, w.cap.gncom GENERATOR_COMMIT).
|
||||
*
|
||||
* Алгоритм на каждый кооператив:
|
||||
*
|
||||
@@ -38,14 +38,14 @@
|
||||
* share_legacy >= share_money
|
||||
*
|
||||
* 4. Отправка 4 inline apply (ненулевые пропускаются):
|
||||
* apply(migration::MIN_SHARE, min_total) → Dr 51 / Cr 80, MIN_SHARE_FUND 2002
|
||||
* apply(migration::SHARE, share_remain) → Dr 51 / Cr 80, SHARE_FUND_PAY 2001
|
||||
* apply(migration::ENTRY, entry_legacy) → Dr 51 / Cr 86, ENTRANCE_FEES 3001
|
||||
* apply(migration::RID, rid_share) → Dr 04 / Cr 80, SHARE_FUND_RID 2003
|
||||
* apply(migration::MIN_SHARE, min_total) → Dr 51 / Cr 80, MIN_SHARE_FUND (w.reg.minshr)
|
||||
* apply(migration::SHARE, share_remain) → Dr 51 / Cr 80, SHARE_FUND_PAY (w.wal.share)
|
||||
* apply(migration::ENTRY, entry_legacy) → Dr 51 / Cr 86, ENTRANCE_FEES (w.reg.entry)
|
||||
* apply(migration::RID, rid_share) → Dr 04 / Cr 80, SHARE_FUND_RID (w.wal.sharid)
|
||||
*
|
||||
* 5. Прямой emplace в wallets2 для progwallets (БЕЗ бух-проводок):
|
||||
* Σ progwallet[blagorost].blocked → wallets2[BLAGOROST_INVEST 9001]
|
||||
* Σ progwallet[generator].blocked → wallets2[GENERATOR_COMMIT 10001]
|
||||
* Σ progwallet[blagorost].blocked → wallets2[BLAGOROST_INVEST w.cap.bginv]
|
||||
* Σ progwallet[generator].blocked → wallets2[GENERATOR_COMMIT w.cap.gncom]
|
||||
*
|
||||
* Если запись wallets2 уже есть (после inline apply сработали) —
|
||||
* aggregate через wallets.modify(available += sum). Иначе — emplace.
|
||||
@@ -168,27 +168,28 @@ inline void send_transit(eosio::name self_name,
|
||||
*/
|
||||
inline void emplace_wallet_only(eosio::name self_name,
|
||||
eosio::name coopname,
|
||||
uint64_t wallet_id,
|
||||
eosio::name wallet_id,
|
||||
const eosio::asset& amt) {
|
||||
if (amt.amount == 0) return;
|
||||
|
||||
wallets2_index wallets(self_name, coopname.value);
|
||||
const auto name_view = ledger2_get_wallet_name_by_id(wallet_id);
|
||||
eosio::check(!name_view.empty(),
|
||||
std::string{"migrate: unknown wallet id "} + std::to_string(wallet_id));
|
||||
const auto human_view = ledger2_get_wallet_human_name(wallet_id);
|
||||
eosio::check(!human_view.empty(),
|
||||
std::string{"migrate: unknown wallet "} + wallet_id.to_string());
|
||||
|
||||
auto it = wallets.find(wallet_id);
|
||||
auto it = wallets.find(wallet_id.value);
|
||||
if (it == wallets.end()) {
|
||||
wallets.emplace(self_name, [&](auto& w) {
|
||||
w.id = wallet_id;
|
||||
w.name = std::string(name_view);
|
||||
w.name = std::string(human_view);
|
||||
w.available = amt;
|
||||
w.blocked = eosio::asset(0, amt.symbol);
|
||||
});
|
||||
} else {
|
||||
// Если кошелёк уже создан (например, предыдущим inline apply TRANSIT_*) —
|
||||
// просто доливаем сумму в available. Не должно случаться при чистой
|
||||
// миграции (9001/10001 не используются базовыми TRANSIT_*), но безопасно.
|
||||
// миграции (w.cap.bginv/w.cap.gncom не используются базовыми TRANSIT_*),
|
||||
// но безопасно.
|
||||
wallets.modify(it, self_name, [&](auto& w) { w.available += amt; });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,14 +130,15 @@ enum class WalletOp : uint8_t {
|
||||
* @brief Описание одной именованной операции.
|
||||
*
|
||||
* Для WALLET_ONLY поля `debit_account_id` / `credit_account_id` равны 0
|
||||
* (compile-time валидацией ниже).
|
||||
* (compile-time валидацией ниже). Для ISSUE `wallet_from = eosio::name{}`,
|
||||
* для BLOCK/UNBLOCK/REVOKE `wallet_to = eosio::name{}`.
|
||||
*/
|
||||
struct OperationRegistryEntry {
|
||||
eosio::name code; ///< operation_code с префиксом `o.<contract>.<verb>`
|
||||
eosio::name process_type; ///< тип процесса с префиксом `p.<contract>.<noun>`
|
||||
WalletOp wallet_op;
|
||||
uint64_t wallet_from; ///< 0 для ISSUE
|
||||
uint64_t wallet_to; ///< 0 для BLOCK/UNBLOCK
|
||||
eosio::name wallet_from; ///< пустое имя для ISSUE
|
||||
eosio::name wallet_to; ///< пустое имя для BLOCK/UNBLOCK/REVOKE
|
||||
uint64_t debit_account_id; ///< 0 для WALLET_ONLY
|
||||
uint64_t credit_account_id; ///< 0 для WALLET_ONLY
|
||||
const char* human_name;
|
||||
@@ -150,17 +151,17 @@ struct OperationRegistryEntry {
|
||||
*/
|
||||
static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
|
||||
// 1. Вступительный взнос: Dr 51 / Cr 86, ISSUE ENTRANCE_FEES
|
||||
{ operations::registrator::PAY_ENTRANCE, processes::registrator::ACCEPT, WalletOp::ISSUE, 0, ledger2_wallets::ENTRANCE_FEES,
|
||||
{ operations::registrator::PAY_ENTRANCE, processes::registrator::ACCEPT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::ENTRANCE_FEES,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::TARGET_RECEIPTS,
|
||||
"Вступительный взнос пайщика" },
|
||||
|
||||
// 2. Минимальный паевой взнос (при регистрации): Dr 51 / Cr 80, ISSUE MIN_SHARE_FUND
|
||||
{ operations::registrator::PUT_MINSHARE, processes::registrator::ACCEPT, WalletOp::ISSUE, 0, ledger2_wallets::MIN_SHARE_FUND,
|
||||
{ operations::registrator::PUT_MINSHARE, processes::registrator::ACCEPT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::MIN_SHARE_FUND,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Минимальный паевой взнос пайщика при регистрации" },
|
||||
|
||||
// 3. Внесение паевого взноса: Dr 51 / Cr 80, ISSUE SHARE_FUND_PAY
|
||||
{ operations::wallet::COMPLETE_DEPOSIT, processes::wallet::DEPOSIT, WalletOp::ISSUE, 0, ledger2_wallets::SHARE_FUND_PAY,
|
||||
{ operations::wallet::COMPLETE_DEPOSIT, processes::wallet::DEPOSIT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::SHARE_FUND_PAY,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Внесение пайщиком паевого взноса" },
|
||||
|
||||
@@ -171,7 +172,7 @@ static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
|
||||
"Возврат паевого взноса пайщику" },
|
||||
|
||||
// 5. Импорт пайщика Благорост (offline): Dr 51 / Cr 80, ISSUE BLAGOROST_INVEST
|
||||
{ operations::capital::IMPORT, processes::capital::IMPORT, WalletOp::ISSUE, 0, ledger2_wallets::BLAGOROST_INVEST,
|
||||
{ operations::capital::IMPORT, processes::capital::IMPORT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::BLAGOROST_INVEST,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Паевой взнос по целевой потребительской программе «Благорост» (офлайн-импорт)" },
|
||||
|
||||
@@ -182,7 +183,7 @@ static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
|
||||
"Инвестиция в ЦПП «Благорост» (перенос между кошельками паевого фонда)" },
|
||||
|
||||
// 7. Коммит РИД: Dr 08 / Cr 80, ISSUE GENERATOR_COMMIT
|
||||
{ operations::capital::COMMIT_RID, processes::capital::RID, WalletOp::ISSUE, 0, ledger2_wallets::GENERATOR_COMMIT,
|
||||
{ operations::capital::COMMIT_RID, processes::capital::RID, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::GENERATOR_COMMIT,
|
||||
ledger2_accounts::NON_CURRENT_INVESTMENTS, ledger2_accounts::SHARE_FUND,
|
||||
"Коммит результата интеллектуальной деятельности по программе «Благорост»" },
|
||||
|
||||
@@ -193,12 +194,12 @@ static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
|
||||
"Приём результата интеллектуальной деятельности в паевой фонд" },
|
||||
|
||||
// 9. Акт-2 имущественный паевой взнос: Dr 51 / Cr 80, ISSUE BLAGOROST_PROPERTY
|
||||
{ operations::capital::ACCEPT_PROPERTY, processes::capital::PROPERTY, WalletOp::ISSUE, 0, ledger2_wallets::BLAGOROST_PROPERTY,
|
||||
{ operations::capital::ACCEPT_PROPERTY, processes::capital::PROPERTY, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::BLAGOROST_PROPERTY,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Паевой взнос (не денежный) по программе «Благорост»" },
|
||||
|
||||
// 10. Выдача беспроцентного займа пайщику: Dr 58 / Cr 51, ISSUE LOAN_ISSUED
|
||||
{ operations::capital::LEND, processes::capital::DEBT, WalletOp::ISSUE, 0, ledger2_wallets::LOAN_ISSUED,
|
||||
{ operations::capital::LEND, processes::capital::DEBT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::LOAN_ISSUED,
|
||||
ledger2_accounts::FINANCIAL_INVESTMENTS, ledger2_accounts::BANK_ACCOUNT,
|
||||
"Выдача пайщику беспроцентного займа" },
|
||||
|
||||
@@ -209,7 +210,7 @@ static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
|
||||
"Возврат беспроцентного займа пайщика по акту-2" },
|
||||
|
||||
// 12. Подтверждение поставки: Dr 51 / Cr 80, ISSUE SHARE_FUND_PAY
|
||||
{ operations::marketplace::CONFIRM_SUPPLY, processes::marketplace::REQUEST, WalletOp::ISSUE, 0, ledger2_wallets::SHARE_FUND_PAY,
|
||||
{ operations::marketplace::CONFIRM_SUPPLY, processes::marketplace::REQUEST, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::SHARE_FUND_PAY,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Подтверждение поставки товара/услуги" },
|
||||
|
||||
@@ -228,22 +229,22 @@ static constexpr OperationRegistryEntry OPERATION_REGISTRY[] = {
|
||||
// ----- Миграционные (o.mig.*) — вызываются только из migrate.cpp -----
|
||||
|
||||
// 15. Миграция: минимальный паевой: Dr 51 / Cr 80, ISSUE MIN_SHARE_FUND
|
||||
{ operations::migration::MIN_SHARE, processes::migration::TRANSIT, WalletOp::ISSUE, 0, ledger2_wallets::MIN_SHARE_FUND,
|
||||
{ operations::migration::MIN_SHARE, processes::migration::TRANSIT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::MIN_SHARE_FUND,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Транзитный перенос: минимальные паевые взносы при миграции" },
|
||||
|
||||
// 16. Миграция: остаток паевых деньгами: Dr 51 / Cr 80, ISSUE SHARE_FUND_PAY
|
||||
{ operations::migration::SHARE, processes::migration::TRANSIT, WalletOp::ISSUE, 0, ledger2_wallets::SHARE_FUND_PAY,
|
||||
{ operations::migration::SHARE, processes::migration::TRANSIT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::SHARE_FUND_PAY,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::SHARE_FUND,
|
||||
"Транзитный перенос: остаток паевых взносов деньгами при миграции" },
|
||||
|
||||
// 17. Миграция: вступительные: Dr 51 / Cr 86, ISSUE ENTRANCE_FEES
|
||||
{ operations::migration::ENTRY, processes::migration::TRANSIT, WalletOp::ISSUE, 0, ledger2_wallets::ENTRANCE_FEES,
|
||||
{ operations::migration::ENTRY, processes::migration::TRANSIT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::ENTRANCE_FEES,
|
||||
ledger2_accounts::BANK_ACCOUNT, ledger2_accounts::TARGET_RECEIPTS,
|
||||
"Транзитный перенос: вступительные взносы при миграции" },
|
||||
|
||||
// 18. Миграция: РИД в НМА: Dr 04 / Cr 80, ISSUE SHARE_FUND_RID
|
||||
{ operations::migration::RID, processes::migration::TRANSIT, WalletOp::ISSUE, 0, ledger2_wallets::SHARE_FUND_RID,
|
||||
{ operations::migration::RID, processes::migration::TRANSIT, WalletOp::ISSUE, eosio::name{}, ledger2_wallets::SHARE_FUND_RID,
|
||||
ledger2_accounts::INTANGIBLE_ASSETS, ledger2_accounts::SHARE_FUND,
|
||||
"Транзитный перенос: принятые РИД в паевой фонд при миграции" },
|
||||
};
|
||||
@@ -294,6 +295,7 @@ namespace ledger2_registry_detail {
|
||||
const auto& e = OPERATION_REGISTRY[i];
|
||||
if (e.wallet_op == WalletOp::TRANSFER || e.wallet_op == WalletOp::WALLET_ONLY) {
|
||||
if (e.wallet_from == e.wallet_to) return false;
|
||||
if (e.wallet_from.value == 0 || e.wallet_to.value == 0) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -312,8 +314,8 @@ namespace ledger2_registry_detail {
|
||||
constexpr bool wallets_exist_in_registry() {
|
||||
for (size_t i = 0; i < OPERATION_REGISTRY_SIZE; ++i) {
|
||||
const auto& e = OPERATION_REGISTRY[i];
|
||||
if (e.wallet_from != 0 && ledger2_get_wallet_name_by_id(e.wallet_from).empty()) return false;
|
||||
if (e.wallet_to != 0 && ledger2_get_wallet_name_by_id(e.wallet_to).empty()) return false;
|
||||
if (e.wallet_from.value != 0 && !ledger2_is_known_wallet(e.wallet_from)) return false;
|
||||
if (e.wallet_to.value != 0 && !ledger2_is_known_wallet(e.wallet_to)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
#include <eosio/eosio.hpp>
|
||||
|
||||
/**
|
||||
* @brief Стандарт кошельков ledger2 (пересмотр 2026-04-20).
|
||||
* @brief Стандарт кошельков ledger2 (пересмотр 2026-04-27).
|
||||
*
|
||||
* Кошельки ledger2 — это аналитические разрезы бухгалтерских счетов:
|
||||
* «куда/откуда движутся средства» на уровне ЦПП и фондов. Учёт остатков
|
||||
@@ -13,71 +15,65 @@
|
||||
* отдельного «зеркального» wallet-а для 51 НЕТ — любая money-in операция
|
||||
* сразу адресуется целевому кошельку-назначению.
|
||||
*
|
||||
* Нумерация — ×1000, группы:
|
||||
* 2xxx — Паевой фонд (журнал Cr 80)
|
||||
* 3xxx — Целевое финансирование (Cr 86)
|
||||
* 4xxx — Выплаты / обязательства / финансовые вложения (sinks, loans)
|
||||
* 5xxx — Служебные (ручные корректировки)
|
||||
* 9xxx — ЦПП «Благорост»
|
||||
* 10xxx — ЦПП «Генератор» (промежуточное состояние коммитов, Dr 08)
|
||||
* 11xxx — ЦПП «Marketplace» (резерв)
|
||||
* Идентификатор кошелька — `eosio::name` с префиксом `w.<contract>.<waltype>`
|
||||
* (по аналогии с операциями `o.<contract>.<verb>` и процессами
|
||||
* `p.<contract>.<noun>`). Длина ≤ 13 base32-символов.
|
||||
*
|
||||
* Пересмотр 2026-04-20:
|
||||
* - Удалён 1001 CASH_MAIN: 51-й счёт ведётся только в accounts2.
|
||||
* - Удалены 4050 LOAN_RECEIVED / 4052 DEBT_CLOSED_SINK: счёт 67 убран,
|
||||
* займы идут через 58 (cap.loanissue: Dr 58 / Cr 51; cap.loanrepay:
|
||||
* Dr 80 / Cr 58).
|
||||
* - Добавлены 9001-9004 Благорост и 10001-10002 Генератор для разнесения
|
||||
* инвестиций/имущества/коммитов по программам.
|
||||
* - Добавлен 5001 MANUAL_ADJUST — резерв под ручные корректировки
|
||||
* (action ledger2::adjust, не реализован в MVP).
|
||||
* Группы:
|
||||
* w.wal.* — Паевой фонд (журнал Cr 80) и возвраты пайщикам
|
||||
* w.reg.* — Регистрация (минимальный паевой, вступительные)
|
||||
* w.sov.* — Целевое финансирование (членские, делегатские)
|
||||
* w.cap.* — Программы паевого фонда (Благорост, Генератор) и займы
|
||||
* w.mkt.* — Маркетплейс (выплаты поставщикам, общий фонд «Стол Заказов»)
|
||||
* w.led.* — Служебные (ручные корректировки)
|
||||
*
|
||||
* При первом ISSUE/TRANSFER кошелёк создаётся автоматически по имени
|
||||
* Sentinel `eosio::name{}` (пустое имя, value=0) — «кошелёк вне системы»
|
||||
* для ISSUE (нет wallet_from) и REVOKE (нет wallet_to).
|
||||
*
|
||||
* При первом ISSUE/TRANSFER кошелёк создаётся автоматически по записи
|
||||
* из WALLET_REGISTRY. При обнулении available+blocked запись удаляется.
|
||||
*
|
||||
* @ingroup public_ledger2_consts
|
||||
*/
|
||||
struct ledger2_wallets {
|
||||
// Группа 2xxx — паевой фонд (Cr 80)
|
||||
static constexpr uint64_t SHARE_FUND_PAY = 2001; ///< ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
static constexpr uint64_t MIN_SHARE_FUND = 2002; ///< Минимальный паевой взнос (при регистрации)
|
||||
static constexpr uint64_t SHARE_FUND_RID = 2003; ///< Паевой фонд — РИД, принятые в НМА (Dr 04 / Cr 80)
|
||||
// wallet — паевой фонд + возвраты
|
||||
static constexpr eosio::name SHARE_FUND_PAY = "w.wal.share"_n; ///< ЦПП «Цифровой Кошелёк» — паевые взносы деньгами (Cr 80)
|
||||
static constexpr eosio::name SHARE_FUND_RID = "w.wal.sharid"_n; ///< Паевой фонд — РИД, принятые в НМА (Dr 04 / Cr 80)
|
||||
static constexpr eosio::name WITHDRAWALS_SINK = "w.wal.wthdrw"_n; ///< Возвраты паевых взносов пайщикам (sink TRANSFER)
|
||||
|
||||
// Группа 3xxx — целевое финансирование (Cr 86)
|
||||
static constexpr uint64_t ENTRANCE_FEES = 3001; ///< Вступительные взносы
|
||||
static constexpr uint64_t MEMBERSHIP_FEES = 3002; ///< Членские взносы (платформенные)
|
||||
static constexpr uint64_t DELEGATE_FEES = 3003; ///< Делегатские членские взносы (цель CONVERT_TO_AXN)
|
||||
// registrator — минимальный паевой + вступительные
|
||||
static constexpr eosio::name MIN_SHARE_FUND = "w.reg.minshr"_n; ///< Минимальный паевой взнос при регистрации (Cr 80)
|
||||
static constexpr eosio::name ENTRANCE_FEES = "w.reg.entry"_n; ///< Вступительные взносы (Cr 86)
|
||||
|
||||
// Группа 4xxx — выплаты / обязательства / финансовые вложения
|
||||
static constexpr uint64_t WITHDRAWALS_SINK = 4001; ///< Возвраты паевых взносов (цель WITHDRAW_COMPLETE)
|
||||
static constexpr uint64_t SUPPLIER_PAYMENTS = 4002; ///< Выплаты поставщикам (цель RECEIVE_CONFIRM)
|
||||
static constexpr uint64_t LOAN_ISSUED = 4051; ///< Выданные пайщикам беспроцентные займы (Dr 58 / Cr 51)
|
||||
// soviet — членские взносы
|
||||
static constexpr eosio::name MEMBERSHIP_FEES = "w.sov.member"_n; ///< Членские взносы (платформенные) (Cr 86)
|
||||
static constexpr eosio::name DELEGATE_FEES = "w.sov.delgte"_n; ///< Делегатские членские взносы (цель CONVERT_TO_AXN) (Cr 86)
|
||||
|
||||
// Группа 5xxx — служебные
|
||||
static constexpr uint64_t MANUAL_ADJUST = 5001; ///< Ручные корректировки (резерв под ledger2::adjust)
|
||||
// capital — программы Благорост, Генератор + займы
|
||||
static constexpr eosio::name LOAN_ISSUED = "w.cap.loan"_n; ///< Выданные пайщикам беспроцентные займы (Dr 58 / Cr 51)
|
||||
static constexpr eosio::name BLAGOROST_INVEST = "w.cap.bginv"_n; ///< Благорост — инвестиции деньгами (Cr 80)
|
||||
static constexpr eosio::name BLAGOROST_RID = "w.cap.bgrid"_n; ///< Благорост — принятые РИД (Dr 04 / Cr 08 после accept)
|
||||
static constexpr eosio::name BLAGOROST_PROPERTY = "w.cap.bgprop"_n; ///< Благорост — имущественные паевые взносы
|
||||
static constexpr eosio::name BLAGOROST_MEMBERSHIP = "w.cap.bgmem"_n; ///< Благорост — членские взносы по программе (Cr 86)
|
||||
static constexpr eosio::name GENERATOR_COMMIT = "w.cap.gncom"_n; ///< Генератор — паевой взнос имуществом в статусе «принятый коммит» (Dr 08 / Cr 80)
|
||||
static constexpr eosio::name GENERATOR_MEMBERSHIP = "w.cap.gnmem"_n; ///< Генератор — членские взносы по программе (Cr 86)
|
||||
|
||||
// Группа 9xxx — ЦПП «Благорост»
|
||||
static constexpr uint64_t BLAGOROST_INVEST = 9001; ///< Благорост — инвестиции деньгами
|
||||
static constexpr uint64_t BLAGOROST_RID = 9002; ///< Благорост — принятые РИД (Dr 04 / Cr 08 после accept)
|
||||
static constexpr uint64_t BLAGOROST_PROPERTY = 9003; ///< Благорост — имущественные паевые взносы
|
||||
static constexpr uint64_t BLAGOROST_MEMBERSHIP = 9004; ///< Благорост — членские взносы по программе (Cr 86)
|
||||
// marketplace — выплаты + общий фонд
|
||||
static constexpr eosio::name SUPPLIER_PAYMENTS = "w.mkt.payout"_n; ///< Выплаты поставщикам (sink RECEIVE_CONFIRM)
|
||||
static constexpr eosio::name MARKETPLACE_FUND = "w.mkt.fund"_n; ///< ЦПП «Стол Заказов» — общий кошелёк программы (резерв)
|
||||
|
||||
// Группа 10xxx — ЦПП «Генератор» (промежуточное состояние Dr 08)
|
||||
static constexpr uint64_t GENERATOR_COMMIT = 10001; ///< Генератор — паевой взнос имуществом в статусе «принятый коммит» (Dr 08 / Cr 80)
|
||||
static constexpr uint64_t GENERATOR_MEMBERSHIP = 10002; ///< Генератор — членские взносы по программе (Cr 86)
|
||||
|
||||
// Группа 11xxx — ЦПП «Стол Заказов» (резерв)
|
||||
static constexpr uint64_t MARKETPLACE_FUND = 11001; ///< ЦПП «Стол Заказов» — общий кошелёк программы (пустой в MVP)
|
||||
// ledger2 — служебные
|
||||
static constexpr eosio::name MANUAL_ADJUST = "w.led.adjust"_n; ///< Ручные корректировки (резерв под ledger2::adjust)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Справочник кошелька: id → имя.
|
||||
* @brief Справочник кошелька: machine name → human-readable name.
|
||||
*
|
||||
* `constexpr std::array` + `string_view` — без dynamic init в WASM.
|
||||
*/
|
||||
struct Ledger2WalletMeta {
|
||||
uint64_t id;
|
||||
std::string_view name;
|
||||
eosio::name name;
|
||||
std::string_view human_name;
|
||||
};
|
||||
|
||||
inline constexpr std::array<Ledger2WalletMeta, 17> LEDGER2_WALLET_REGISTRY = {{
|
||||
@@ -102,24 +98,49 @@ inline constexpr std::array<Ledger2WalletMeta, 17> LEDGER2_WALLET_REGISTRY = {{
|
||||
|
||||
static constexpr size_t LEDGER2_WALLET_REGISTRY_SIZE = LEDGER2_WALLET_REGISTRY.size();
|
||||
|
||||
// Compile-time проверка уникальности id кошельков.
|
||||
// Compile-time проверка уникальности имён кошельков.
|
||||
namespace ledger2_wallets_detail {
|
||||
constexpr bool wallet_ids_unique() {
|
||||
constexpr bool wallet_names_unique() {
|
||||
for (size_t i = 0; i < LEDGER2_WALLET_REGISTRY_SIZE; ++i) {
|
||||
for (size_t j = i + 1; j < LEDGER2_WALLET_REGISTRY_SIZE; ++j) {
|
||||
if (LEDGER2_WALLET_REGISTRY[i].id == LEDGER2_WALLET_REGISTRY[j].id) return false;
|
||||
if (LEDGER2_WALLET_REGISTRY[i].name == LEDGER2_WALLET_REGISTRY[j].name) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool wallet_names_nonempty() {
|
||||
for (size_t i = 0; i < LEDGER2_WALLET_REGISTRY_SIZE; ++i) {
|
||||
if (LEDGER2_WALLET_REGISTRY[i].name.value == 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(ledger2_wallets_detail::wallet_ids_unique(),
|
||||
"LEDGER2_WALLET_REGISTRY: duplicate wallet id detected");
|
||||
static_assert(ledger2_wallets_detail::wallet_names_unique(),
|
||||
"LEDGER2_WALLET_REGISTRY: duplicate wallet name detected");
|
||||
static_assert(ledger2_wallets_detail::wallet_names_nonempty(),
|
||||
"LEDGER2_WALLET_REGISTRY: empty eosio::name (sentinel) не должно быть в реестре");
|
||||
|
||||
inline constexpr std::string_view ledger2_get_wallet_name_by_id(uint64_t wallet_id) {
|
||||
/**
|
||||
* @brief Возвращает human-readable имя кошелька по его eosio::name.
|
||||
*
|
||||
* Возвращает пустой `string_view` для незарегистрированных имён и для пустого
|
||||
* имени (sentinel — кошелёк вне системы при ISSUE/REVOKE).
|
||||
*/
|
||||
inline constexpr std::string_view ledger2_get_wallet_human_name(eosio::name wallet_name) {
|
||||
for (size_t i = 0; i < LEDGER2_WALLET_REGISTRY_SIZE; ++i) {
|
||||
if (LEDGER2_WALLET_REGISTRY[i].id == wallet_id) return LEDGER2_WALLET_REGISTRY[i].name;
|
||||
if (LEDGER2_WALLET_REGISTRY[i].name == wallet_name) return LEDGER2_WALLET_REGISTRY[i].human_name;
|
||||
}
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Проверяет, что `wallet_name` присутствует в LEDGER2_WALLET_REGISTRY.
|
||||
*/
|
||||
inline constexpr bool ledger2_is_known_wallet(eosio::name wallet_name) {
|
||||
for (size_t i = 0; i < LEDGER2_WALLET_REGISTRY_SIZE; ++i) {
|
||||
if (LEDGER2_WALLET_REGISTRY[i].name == wallet_name) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -13,18 +13,20 @@
|
||||
*
|
||||
* @brief Кошелёк управленческого учёта ledger2.
|
||||
*
|
||||
* Простой порядковый id (без смещения). Запись создаётся upsert-ом
|
||||
* Идентификатор — `eosio::name` с префиксом `w.<contract>.<waltype>`
|
||||
* (см. `lib/core/ledger2/wallets.hpp::LEDGER2_WALLET_REGISTRY`). Поле `name` —
|
||||
* человекочитаемое отображение из реестра. Запись создаётся upsert-ом
|
||||
* при первом ISSUE/TRANSFER на кошелёк и удаляется, когда
|
||||
* available == 0 && blocked == 0. Писем «writeoff» не существует —
|
||||
* все выплаты моделируются как TRANSFER в кошельки-накопители.
|
||||
*/
|
||||
struct [[eosio::table, eosio::contract(LEDGER2)]] wallet2 {
|
||||
uint64_t id;
|
||||
eosio::name id;
|
||||
std::string name;
|
||||
eosio::asset available;
|
||||
eosio::asset blocked;
|
||||
|
||||
uint64_t primary_key() const { return id; }
|
||||
uint64_t primary_key() const { return id.value; }
|
||||
|
||||
bool is_empty() const {
|
||||
return available.amount == 0 && blocked.amount == 0;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# кооператив с двойной конвертацией (деньги → имущество и обратно).
|
||||
#
|
||||
# Многоступенчатый процесс (10+ узлов состояний). Две ledger2-операции:
|
||||
# • o.mkt.supply — подтверждение поставки на КУ (ISSUE → 2001, Дт 51 / Кт 80)
|
||||
# • o.mkt.recv — выплата поставщику после получения (TRANSFER 2001 → 4002, Дт 80 / Кт 51)
|
||||
# • o.mkt.supply — подтверждение поставки на КУ (ISSUE → w.wal.share, Дт 51 / Кт 80)
|
||||
# • o.mkt.recv — выплата поставщику после получения (TRANSFER w.wal.share → w.mkt.payout, Дт 80 / Кт 51)
|
||||
#
|
||||
# Источники правды в коде:
|
||||
# • cpp/marketplace/marketplace.hpp — actions
|
||||
@@ -105,7 +105,7 @@ actions:
|
||||
purpose: >
|
||||
Заказчик подписывает второй акт — приём имущества подтверждён.
|
||||
Применяется ledger2-операция o.mkt.recv — выплата поставщику
|
||||
(TRANSFER 2001 → 4002, Дт 80 / Кт 51), устанавливается гарантийный период.
|
||||
(TRANSFER w.wal.share → w.mkt.payout, Дт 80 / Кт 51), устанавливается гарантийный период.
|
||||
- name: marketplace::complete
|
||||
human: Завершить
|
||||
actor: chairman
|
||||
@@ -338,7 +338,7 @@ scenario:
|
||||
action: marketplace::receivecnf
|
||||
description: >
|
||||
Заказчик подписывает RECEIVE_ACT_CONF. Применяется o.mkt.recv —
|
||||
выплата поставщику (TRANSFER 2001 → 4002, Дт 80 / Кт 51), установлен
|
||||
выплата поставщику (TRANSFER w.wal.share → w.mkt.payout, Дт 80 / Кт 51), установлен
|
||||
гарантийный период.
|
||||
- step: 8
|
||||
title: Завершение по гарантии
|
||||
@@ -431,8 +431,8 @@ operations:
|
||||
- ledger_code: o.mkt.supply
|
||||
human_name: Подтверждение поставки
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_from: ''
|
||||
wallet_to: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
debit: 51 # Расчётный счёт
|
||||
credit: 80 # Паевой фонд (складочный капитал)
|
||||
amount_ref: request.total_cost
|
||||
@@ -445,8 +445,8 @@ operations:
|
||||
- ledger_code: o.mkt.recv
|
||||
human_name: Подтверждение получения — выплата поставщику
|
||||
wallet_op: TRANSFER
|
||||
wallet_from: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_to: 4002 # Выплаты поставщикам
|
||||
wallet_from: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_to: w.mkt.payout # Выплаты поставщикам
|
||||
debit: 80 # Паевой фонд
|
||||
credit: 51 # Расчётный счёт
|
||||
amount_ref: request.base_cost
|
||||
|
||||
@@ -247,8 +247,8 @@ operations:
|
||||
- ledger_code: o.reg.payent
|
||||
human_name: Вступительный взнос пайщика
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 3001 # Вступительные взносы
|
||||
wallet_from: ''
|
||||
wallet_to: w.reg.entry # Вступительные взносы
|
||||
debit: 51 # Расчётный счёт
|
||||
credit: 86 # Целевое финансирование
|
||||
amount_ref: candidate.initial
|
||||
@@ -261,8 +261,8 @@ operations:
|
||||
- ledger_code: o.reg.putmin
|
||||
human_name: Минимальный паевой взнос при регистрации
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 2002 # Минимальный паевой взнос
|
||||
wallet_from: ''
|
||||
wallet_to: w.reg.minshr # Минимальный паевой взнос
|
||||
debit: 51 # Расчётный счёт
|
||||
credit: 80 # Паевой фонд (складочный капитал)
|
||||
amount_ref: candidate.minimum
|
||||
|
||||
@@ -173,8 +173,8 @@ operations:
|
||||
- ledger_code: o.wal.depcpl
|
||||
human_name: Внесение пайщиком паевого взноса
|
||||
wallet_op: ISSUE
|
||||
wallet_from: null
|
||||
wallet_to: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_from: ''
|
||||
wallet_to: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
debit: 51 # Расчётный счёт
|
||||
credit: 80 # Паевой фонд (складочный капитал)
|
||||
amount_ref: deposit.quantity
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# Пятиактовый процесс с авторизацией советом. Запись заявки живёт в таблице
|
||||
# `withdraws` от создания до выплаты или отказа. На закрывающем действии
|
||||
# completewthd срабатывает одна операция o.wal.wthcpl (TRANSFER 2001 → 4001).
|
||||
# completewthd срабатывает одна операция o.wal.wthcpl (TRANSFER w.wal.share → w.wal.wthdrw).
|
||||
#
|
||||
# Источники правды в коде:
|
||||
# • cpp/wallet/wallet.hpp — actions
|
||||
@@ -30,7 +30,7 @@ purpose: >
|
||||
совет рассматривает заявку и принимает решение, после авторизации платёж
|
||||
отправляется в Gateway. На подтверждении выплаты в ledger2 применяется
|
||||
одна операция o.wal.wthcpl: средства переводятся с кошелька пайщика на
|
||||
системный кошелёк выплат (4001) с обратной проводкой Дт 80 / Кт 51.
|
||||
системный кошелёк выплат (w.wal.wthdrw) с обратной проводкой Дт 80 / Кт 51.
|
||||
roles:
|
||||
- contributor
|
||||
- soviet
|
||||
@@ -67,7 +67,7 @@ actions:
|
||||
role: closer
|
||||
purpose: >
|
||||
Gateway подтвердил списание средств в пользу пайщика. Это закрывающее
|
||||
действие: применяется операция o.wal.wthcpl (TRANSFER 2001 → 4001),
|
||||
действие: применяется операция o.wal.wthcpl (TRANSFER w.wal.share → w.wal.wthdrw),
|
||||
разблокированная сумма уходит со счёта 80 на счёт 51, запись заявки
|
||||
удаляется.
|
||||
- name: wallet::declinewthd
|
||||
@@ -106,7 +106,7 @@ states:
|
||||
human: Возврат выплачен
|
||||
description: >
|
||||
Gateway подтвердил списание, средства переведены с кошелька пайщика
|
||||
на системный кошелёк выплат (2001 → 4001), в бухгалтерии прошла
|
||||
на системный кошелёк выплат (w.wal.share → w.wal.wthdrw), в бухгалтерии прошла
|
||||
обратная проводка Дт 80 / Кт 51. Запись заявки удалена.
|
||||
kind: final
|
||||
- name: removed
|
||||
@@ -124,7 +124,7 @@ transitions:
|
||||
actor: contributor
|
||||
guards:
|
||||
- Пайщик имеет статус active.
|
||||
- Сумма возврата ≤ доступного остатка на SHARE_FUND_PAY (2001).
|
||||
- Сумма возврата ≤ доступного остатка на SHARE_FUND_PAY (w.wal.share).
|
||||
- withdraw_hash уникален.
|
||||
- Заявление подписано ЭЦП пайщика.
|
||||
|
||||
@@ -227,13 +227,13 @@ scenario:
|
||||
action: wallet::completewthd
|
||||
description: >
|
||||
Gateway подтверждает списание средств в пользу пайщика. Контракт
|
||||
применяет ledger2-операцию o.wal.wthcpl (TRANSFER 2001 → 4001 с
|
||||
применяет ledger2-операцию o.wal.wthcpl (TRANSFER w.wal.share → w.wal.wthdrw с
|
||||
обратной проводкой Дт 80 / Кт 51) и удаляет запись заявки.
|
||||
pre:
|
||||
- Заявка в статусе `authorized`.
|
||||
- Gateway подтвердил списание.
|
||||
post:
|
||||
- Сумма переведена с SHARE_FUND_PAY (2001) на WITHDRAWALS (4001).
|
||||
- Сумма переведена с SHARE_FUND_PAY (w.wal.share) на WITHDRAWALS (w.wal.wthdrw).
|
||||
- В ledger2 применена операция o.wal.wthcpl.
|
||||
- Запись заявки удалена.
|
||||
|
||||
@@ -278,15 +278,15 @@ operations:
|
||||
- ledger_code: o.wal.wthcpl
|
||||
human_name: Возврат паевого взноса пайщику
|
||||
wallet_op: TRANSFER
|
||||
wallet_from: 2001 # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_to: 4001 # Возвраты паевых взносов пайщикам
|
||||
wallet_from: w.wal.share # ЦПП «Цифровой Кошелёк» — паевые взносы деньгами
|
||||
wallet_to: w.wal.wthdrw # Возвраты паевых взносов пайщикам
|
||||
debit: 80 # Паевой фонд (складочный капитал)
|
||||
credit: 51 # Расчётный счёт
|
||||
amount_ref: withdraw.quantity
|
||||
triggered_by: wallet::completewthd
|
||||
description: >
|
||||
Обратная операция к o.wal.depcpl: средства уходят с кошелька пайщика
|
||||
«ЦПП Цифровой Кошелёк» (2001) на системный кошелёк выплат (4001).
|
||||
«ЦПП Цифровой Кошелёк» (w.wal.share) на системный кошелёк выплат (w.wal.wthdrw).
|
||||
В бухгалтерии прошла проводка Дт 80 / Кт 51 — паевой фонд уменьшился,
|
||||
деньги ушли с расчётного счёта пайщику.
|
||||
|
||||
|
||||
@@ -6319,7 +6319,7 @@ input GetInvestInput {
|
||||
}
|
||||
|
||||
input GetLedger2HistoryInput {
|
||||
"""ID счёта/кошелька (×1000)"""
|
||||
"""Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий."""
|
||||
accountId: Int
|
||||
|
||||
"""Имена blockchain-действий: apply | walletop | debit | credit"""
|
||||
@@ -6342,6 +6342,11 @@ input GetLedger2HistoryInput {
|
||||
processHash: String
|
||||
sortOrder: String = "DESC"
|
||||
username: String
|
||||
|
||||
"""
|
||||
eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop действий.
|
||||
"""
|
||||
walletName: String
|
||||
}
|
||||
|
||||
input GetLedgerHistoryInput {
|
||||
@@ -6678,11 +6683,11 @@ type Ledger2Operation {
|
||||
quantity: String
|
||||
username: String
|
||||
|
||||
"""walletop: wallet_from (исходящий)"""
|
||||
walletFrom: Int
|
||||
"""walletop: wallet_from (eosio::name w.<contract>.<waltype>)"""
|
||||
walletFrom: String
|
||||
|
||||
"""walletop: wallet_to (входящий)"""
|
||||
walletTo: Int
|
||||
"""walletop: wallet_to (eosio::name w.<contract>.<waltype>)"""
|
||||
walletTo: String
|
||||
}
|
||||
|
||||
type Ledger2Wallet {
|
||||
@@ -6692,8 +6697,8 @@ type Ledger2Wallet {
|
||||
"""Заблокированный баланс"""
|
||||
blocked: String!
|
||||
|
||||
"""ID кошелька (×1000 offset): 1001/2001/3001/4001"""
|
||||
id: Int!
|
||||
"""eosio::name-идентификатор кошелька (w.<contract>.<waltype>)"""
|
||||
id: String!
|
||||
|
||||
"""Название кошелька"""
|
||||
name: String!
|
||||
@@ -9518,7 +9523,7 @@ type Query {
|
||||
getLedger2History(input: GetLedger2HistoryInput!): Ledger2HistoryResponse!
|
||||
|
||||
"""
|
||||
Общекооперативные кошельки из ledger2::wallets (1001/2001/3001/4001). Кошельки пайщиков живут в контракте soviet — сюда не попадают.
|
||||
Общекооперативные кошельки из ledger2::wallets (eosio::name w.<contract>.<waltype>). Кошельки пайщиков живут в контракте soviet — сюда не попадают.
|
||||
"""
|
||||
getLedger2Wallets(coopname: String!): [Ledger2Wallet!]!
|
||||
|
||||
@@ -11746,8 +11751,8 @@ type WaitWeight {
|
||||
input WalmoveInput {
|
||||
coopname: String!
|
||||
|
||||
"""id кошелька-источника"""
|
||||
fromWallet: Int!
|
||||
"""eosio::name кошелька-источника (w.<contract>.<waltype>)"""
|
||||
fromWallet: String!
|
||||
|
||||
"""Обязательное обоснование корректировки"""
|
||||
memo: String!
|
||||
@@ -11757,8 +11762,8 @@ input WalmoveInput {
|
||||
"""
|
||||
quantity: String!
|
||||
|
||||
"""id кошелька-приёмника"""
|
||||
toWallet: Int!
|
||||
"""eosio::name кошелька-приёмника (w.<contract>.<waltype>)"""
|
||||
toWallet: String!
|
||||
|
||||
"""Владелец кошельков (для коллективных — coopname)"""
|
||||
username: String!
|
||||
|
||||
@@ -22,11 +22,20 @@ export class GetLedger2HistoryInputDTO {
|
||||
@IsString()
|
||||
coopname!: string;
|
||||
|
||||
@Field(() => Int, { nullable: true, description: 'ID счёта/кошелька (×1000)' })
|
||||
@Field(() => Int, { nullable: true, description: 'Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий.' })
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
accountId?: number;
|
||||
|
||||
@Field(() => String, {
|
||||
nullable: true,
|
||||
description: 'eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop действий.',
|
||||
})
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(13)
|
||||
walletName?: string;
|
||||
|
||||
@Field(() => [String], {
|
||||
nullable: true,
|
||||
description: 'Имена blockchain-действий: apply | walletop | debit | credit',
|
||||
|
||||
@@ -38,11 +38,11 @@ export class Ledger2OperationDTO {
|
||||
@Field(() => Int, { nullable: true, description: 'ID счёта/кошелька (×1000)' })
|
||||
accountId?: number | null;
|
||||
|
||||
@Field(() => Int, { nullable: true, description: 'walletop: wallet_from (исходящий)' })
|
||||
walletFrom?: number | null;
|
||||
@Field(() => String, { nullable: true, description: 'walletop: wallet_from (eosio::name w.<contract>.<waltype>)' })
|
||||
walletFrom?: string | null;
|
||||
|
||||
@Field(() => Int, { nullable: true, description: 'walletop: wallet_to (входящий)' })
|
||||
walletTo?: number | null;
|
||||
@Field(() => String, { nullable: true, description: 'walletop: wallet_to (eosio::name w.<contract>.<waltype>)' })
|
||||
walletTo?: string | null;
|
||||
|
||||
@Field(() => String, { nullable: true, description: 'Asset "100.0000 RUB"' })
|
||||
quantity?: string | null;
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { Field, Int, ObjectType } from '@nestjs/graphql';
|
||||
import { Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
/**
|
||||
* Общекооперативный кошелёк ledger2 (1001/2001/3001/4001...).
|
||||
* Общекооперативный кошелёк ledger2.
|
||||
* Кошельки пайщиков живут в контракте soviet — они сюда не попадают.
|
||||
*
|
||||
* `id` — eosio::name-идентификатор `w.<contract>.<waltype>` (например
|
||||
* `w.wal.share`, `w.cap.bginv`). См. `cooptypes/ledger2/wallets.ts`.
|
||||
*/
|
||||
@ObjectType('Ledger2Wallet')
|
||||
export class Ledger2WalletDTO {
|
||||
@Field(() => Int, { description: 'ID кошелька (×1000 offset): 1001/2001/3001/4001' })
|
||||
id!: number;
|
||||
@Field(() => String, { description: 'eosio::name-идентификатор кошелька (w.<contract>.<waltype>)' })
|
||||
id!: string;
|
||||
|
||||
@Field(() => String, { description: 'Название кошелька' })
|
||||
name!: string;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Field, Int, InputType } from '@nestjs/graphql';
|
||||
import { IsInt, IsString, MaxLength, MinLength, Matches, Min } from 'class-validator';
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
import { IsString, MaxLength, MinLength, Matches, Length } from 'class-validator';
|
||||
|
||||
/**
|
||||
* Input для мутации `walmoveWallets` (operation `o.adj.walmove`).
|
||||
*
|
||||
* `quantity` — строка с символом, как в действии apply: `"100.0000 RUB"`.
|
||||
* `fromWallet`/`toWallet` — eosio::name-идентификаторы кошельков
|
||||
* (`w.<contract>.<waltype>`), см. `cooptypes/ledger2/wallets.ts`.
|
||||
*
|
||||
* Backend валидирует совместимость from_wallet/to_wallet с одним account_id
|
||||
* (через `Ledger2.LEDGER2_OPERATION_REGISTRY`) ДО подписания.
|
||||
*/
|
||||
@@ -18,15 +21,15 @@ export class WalmoveInputDTO {
|
||||
@IsString()
|
||||
username!: string;
|
||||
|
||||
@Field(() => Int, { description: 'id кошелька-источника' })
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
fromWallet!: number;
|
||||
@Field(() => String, { description: 'eosio::name кошелька-источника (w.<contract>.<waltype>)' })
|
||||
@IsString()
|
||||
@Length(1, 13)
|
||||
fromWallet!: string;
|
||||
|
||||
@Field(() => Int, { description: 'id кошелька-приёмника' })
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
toWallet!: number;
|
||||
@Field(() => String, { description: 'eosio::name кошелька-приёмника (w.<contract>.<waltype>)' })
|
||||
@IsString()
|
||||
@Length(1, 13)
|
||||
toWallet!: string;
|
||||
|
||||
@Field(() => String, { description: 'Сумма с символом, например "100.0000 RUB"' })
|
||||
@IsString()
|
||||
|
||||
@@ -39,7 +39,7 @@ export class Ledger2Resolver {
|
||||
@Query(() => [Ledger2WalletDTO], {
|
||||
name: 'getLedger2Wallets',
|
||||
description:
|
||||
'Общекооперативные кошельки из ledger2::wallets (1001/2001/3001/4001). ' +
|
||||
'Общекооперативные кошельки из ledger2::wallets (eosio::name w.<contract>.<waltype>). ' +
|
||||
'Кошельки пайщиков живут в контракте soviet — сюда не попадают.',
|
||||
})
|
||||
@UseGuards(GqlJwtAuthGuard, RolesGuard)
|
||||
|
||||
@@ -116,26 +116,28 @@ export class Ledger2Service {
|
||||
* wallet_from, debit для wallet_to — для standard-flow). Все стандартные
|
||||
* кошельки имеют **один** account_id во всех операциях, поэтому первая
|
||||
* найденная привязка достаточна.
|
||||
*
|
||||
* `walletName` — eosio::name кошелька (`w.<contract>.<waltype>`).
|
||||
*/
|
||||
private resolveWalletAccountId(walletId: number): number | null {
|
||||
private resolveWalletAccountId(walletName: string): number | null {
|
||||
for (const op of Ledger2.LEDGER2_OPERATION_REGISTRY) {
|
||||
if (op.kind === 'adjustment') continue;
|
||||
if (op.wallet_op === 'WALLET_ONLY') continue; // у WALLET_ONLY нет debit/credit
|
||||
if (op.wallet_from === walletId && op.credit !== null) return op.credit;
|
||||
if (op.wallet_to === walletId && op.credit !== null && op.wallet_op === 'ISSUE') return op.credit;
|
||||
if (op.wallet_to === walletId && op.debit !== null) return op.debit;
|
||||
if (op.wallet_from === walletId && op.debit !== null) return op.debit;
|
||||
if (op.wallet_from === walletName && op.credit !== null) return op.credit;
|
||||
if (op.wallet_to === walletName && op.credit !== null && op.wallet_op === 'ISSUE') return op.credit;
|
||||
if (op.wallet_to === walletName && op.debit !== null) return op.debit;
|
||||
if (op.wallet_from === walletName && op.debit !== null) return op.debit;
|
||||
}
|
||||
// Кошельки, которые встречаются только в WALLET_ONLY (например 9001 в o.cap.invest)
|
||||
// Кошельки, которые встречаются только в WALLET_ONLY (например w.cap.bginv в o.cap.invest)
|
||||
// — выводим из источника: WALLET_ONLY переносит между кошельками одного счёта,
|
||||
// значит партнёрский кошелёк по WALLET_ONLY имеет тот же account_id, что и
|
||||
// его пара в стандартной операции.
|
||||
for (const op of Ledger2.LEDGER2_OPERATION_REGISTRY) {
|
||||
if (op.wallet_op !== 'WALLET_ONLY' || op.kind === 'adjustment') continue;
|
||||
if (op.wallet_from === walletId && op.wallet_to !== null) {
|
||||
if (op.wallet_from === walletName && op.wallet_to !== null) {
|
||||
return this.resolveWalletAccountId(op.wallet_to);
|
||||
}
|
||||
if (op.wallet_to === walletId && op.wallet_from !== null) {
|
||||
if (op.wallet_to === walletName && op.wallet_from !== null) {
|
||||
return this.resolveWalletAccountId(op.wallet_from);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ export interface Ledger2OperationDomainInterface {
|
||||
processHash: string | null;
|
||||
/** Кто инициировал действие; для миграции может быть null. */
|
||||
username: string | null;
|
||||
/** Для walletop/debit/credit — id счёта/кошелька (×1000 offset). */
|
||||
/** Для debit/credit — id бух.счёта (×1000 offset, например 51000/80000). null для walletop/apply. */
|
||||
accountId: number | null;
|
||||
/** Для walletop — wallet_from (исходящий кошелёк). */
|
||||
walletFrom: number | null;
|
||||
/** Для walletop — wallet_to (входящий кошелёк). */
|
||||
walletTo: number | null;
|
||||
/** Для walletop — wallet_from (eosio::name `w.<contract>.<waltype>`). */
|
||||
walletFrom: string | null;
|
||||
/** Для walletop — wallet_to (eosio::name `w.<contract>.<waltype>`). */
|
||||
walletTo: string | null;
|
||||
/** Сумма в формате asset (`"100.0000 RUB"`) — применимо к walletop/debit/credit. */
|
||||
quantity: string | null;
|
||||
memo: string | null;
|
||||
@@ -31,8 +31,10 @@ export interface Ledger2OperationDomainInterface {
|
||||
|
||||
export interface Ledger2HistoryFilterDomainInterface {
|
||||
coopname: string;
|
||||
/** Фильтр по конкретному счёту/кошельку (×1000 offset). */
|
||||
/** Фильтр по бух.счёту (×1000 offset, например 51000/80000) — для debit/credit. */
|
||||
accountId?: number;
|
||||
/** Фильтр по eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop. */
|
||||
walletName?: string;
|
||||
/** Одно из имён действий `apply|walletop|debit|credit`. Пусто = все. */
|
||||
actionNames?: string[];
|
||||
/** Код операции из OPERATION_REGISTRY (только для `apply`). */
|
||||
|
||||
@@ -2,22 +2,14 @@
|
||||
* Общекооперативный кошелёк ledger2 (таблица `ledger2::wallets`).
|
||||
*
|
||||
* Это **не** кошельки пайщиков — те живут в контракте `soviet`. Здесь —
|
||||
* аналитические разрезы бухгалтерских счетов уровня кооператива:
|
||||
* 2001 — паевой фонд: взносы деньгами;
|
||||
* 2002 — минимальный паевой взнос;
|
||||
* 2003 — паевой фонд: принятые РИД;
|
||||
* 3001–3003 — вступительные / членские / делегатские взносы;
|
||||
* 4001 — возвраты паевых взносов пайщикам;
|
||||
* 4002 — выплаты поставщикам;
|
||||
* 4051 — выданные беспроцентные займы;
|
||||
* 9xxx / 10xxx / 11xxx — кошельки ЦПП «Благорост» / «Генератор» / «Стол Заказов».
|
||||
* аналитические разрезы бухгалтерских счетов уровня кооператива.
|
||||
*
|
||||
* Полный реестр — `components/context/notes/LEDGER2_CHART_OF_ACCOUNTS.md` и
|
||||
* `contracts/cpp/lib/core/ledger2/wallets.hpp`. ID идут блоками ×1000 по
|
||||
* родительскому бухсчёту (Epic 1 Story 1.13).
|
||||
* `id` — eosio::name-идентификатор `w.<contract>.<waltype>` (например
|
||||
* `w.wal.share`, `w.cap.bginv`, `w.reg.entry`). Полный реестр — в
|
||||
* `cooptypes/ledger2/wallets.ts` и `contracts/cpp/lib/core/ledger2/wallets.hpp`.
|
||||
*/
|
||||
export interface Ledger2WalletDomainInterface {
|
||||
id: number;
|
||||
id: string;
|
||||
name: string;
|
||||
available: string;
|
||||
blocked: string;
|
||||
|
||||
@@ -9,8 +9,10 @@ export interface WalmoveBlockchainDomainInterface {
|
||||
initiator: string;
|
||||
/** Владелец кошельков (для аналитики; для коллективных — обычно coopname). */
|
||||
username: string;
|
||||
fromWallet: number;
|
||||
toWallet: number;
|
||||
/** eosio::name кошелька-источника (`w.<contract>.<waltype>`). */
|
||||
fromWallet: string;
|
||||
/** eosio::name кошелька-приёмника (`w.<contract>.<waltype>`). */
|
||||
toWallet: string;
|
||||
/** Сумма с символом, например `"100.00 RUB"`. */
|
||||
quantity: string;
|
||||
/** SHA-256 хэш корректировки (генерирует backend). */
|
||||
|
||||
@@ -88,7 +88,7 @@ export const PROCESS_HASH_LOCATOR: Readonly<Record<string, HashLocation[]>> = Ob
|
||||
|
||||
'p.cap.import': [{ code: 'capital', table: 'contributors', field: 'contributor_hash' }],
|
||||
|
||||
// p.cap.invest — wallet-only перенос 2001 → 9001 без Dr/Cr.
|
||||
// p.cap.invest — wallet-only перенос w.wal.share → w.cap.bginv без Dr/Cr.
|
||||
'p.cap.invest': [{ code: 'capital', table: 'contributors', field: 'contributor_hash' }],
|
||||
|
||||
// capital::pgproperties.property_hash — приём имущества в паевой фонд.
|
||||
|
||||
+47
-20
@@ -66,7 +66,7 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
return (rows as Array<{ value: Record<string, unknown> }>).map((row) => {
|
||||
const v = row.value ?? {};
|
||||
return {
|
||||
id: parseInt(String(v.id ?? 0), 10),
|
||||
id: String(v.id ?? ''),
|
||||
name: String(v.name ?? ''),
|
||||
available: String(v.available ?? '0.0000 RUB'),
|
||||
blocked: String(v.blocked ?? '0.0000 RUB'),
|
||||
@@ -87,8 +87,9 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
const clauses: string[] = [];
|
||||
|
||||
if (filter.accountId !== undefined) {
|
||||
// apply-события не имеют accountId/wallet_id в data — связь идёт через process_hash
|
||||
// с siblings (walletop/debit/credit). Для raw-siblings достаточно прямого совпадения.
|
||||
// Бух.счёт (debit/credit действий) — числовой. apply-события не имеют account_id
|
||||
// в data, связь идёт через process_hash с siblings (debit/credit). Для raw-siblings
|
||||
// достаточно прямого совпадения.
|
||||
const siblingOnly =
|
||||
!!filter.actionNames &&
|
||||
filter.actionNames.length > 0 &&
|
||||
@@ -98,9 +99,6 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
`(
|
||||
(a.data ->> 'id')::text = $${pIdx}
|
||||
OR (a.data ->> 'account_id')::text = $${pIdx}
|
||||
OR (a.data ->> 'wallet_id')::text = $${pIdx}
|
||||
OR (a.data ->> 'wallet_from')::text = $${pIdx}
|
||||
OR (a.data ->> 'wallet_to')::text = $${pIdx}
|
||||
)`,
|
||||
);
|
||||
} else {
|
||||
@@ -114,9 +112,6 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
AND (
|
||||
(b.data ->> 'id')::text = $${pIdx}
|
||||
OR (b.data ->> 'account_id')::text = $${pIdx}
|
||||
OR (b.data ->> 'wallet_id')::text = $${pIdx}
|
||||
OR (b.data ->> 'wallet_from')::text = $${pIdx}
|
||||
OR (b.data ->> 'wallet_to')::text = $${pIdx}
|
||||
)
|
||||
)`,
|
||||
);
|
||||
@@ -124,6 +119,41 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
params.push(String(filter.accountId));
|
||||
pIdx += 1;
|
||||
}
|
||||
if (filter.walletName) {
|
||||
// Кошелёк (walletop действий) — eosio::name. Для apply-событий wallet_from/to нет
|
||||
// в data, поэтому фильтр через process_hash подтягивает все 3 действия (apply +
|
||||
// walletop + debit/credit) одного процесса, в котором участвует этот кошелёк.
|
||||
const siblingOnly =
|
||||
!!filter.actionNames &&
|
||||
filter.actionNames.length > 0 &&
|
||||
!filter.actionNames.includes('apply');
|
||||
if (siblingOnly) {
|
||||
clauses.push(
|
||||
`(
|
||||
(a.data ->> 'wallet_from') = $${pIdx}
|
||||
OR (a.data ->> 'wallet_to') = $${pIdx}
|
||||
OR (a.data ->> 'id') = $${pIdx}
|
||||
)`,
|
||||
);
|
||||
} else {
|
||||
clauses.push(
|
||||
`LOWER(a.data ->> 'process_hash') IN (
|
||||
SELECT LOWER(b.data ->> 'process_hash')
|
||||
FROM blockchain_actions b
|
||||
WHERE b.account = $1
|
||||
AND b.data ->> 'coopname' = $2
|
||||
AND b.data ->> 'process_hash' IS NOT NULL
|
||||
AND (
|
||||
(b.data ->> 'wallet_from') = $${pIdx}
|
||||
OR (b.data ->> 'wallet_to') = $${pIdx}
|
||||
OR (b.data ->> 'id') = $${pIdx}
|
||||
)
|
||||
)`,
|
||||
);
|
||||
}
|
||||
params.push(filter.walletName);
|
||||
pIdx += 1;
|
||||
}
|
||||
if (filter.processHash) {
|
||||
clauses.push(`LOWER(a.data ->> 'process_hash') = $${pIdx}`);
|
||||
params.push(filter.processHash.toLowerCase());
|
||||
@@ -201,15 +231,12 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
(a.data ->> 'operation_code') AS "operationCode",
|
||||
LOWER(a.data ->> 'process_hash') AS "processHash",
|
||||
(a.data ->> 'username') AS "username",
|
||||
COALESCE(
|
||||
NULLIF(a.data ->> 'id', '')::bigint,
|
||||
NULLIF(a.data ->> 'account_id', '')::bigint,
|
||||
NULLIF(a.data ->> 'wallet_id', '')::bigint,
|
||||
NULLIF(a.data ->> 'wallet_to', '')::bigint,
|
||||
NULLIF(a.data ->> 'wallet_from', '')::bigint
|
||||
) AS "accountId",
|
||||
NULLIF(a.data ->> 'wallet_from', '')::bigint AS "walletFrom",
|
||||
NULLIF(a.data ->> 'wallet_to', '')::bigint AS "walletTo",
|
||||
CASE WHEN a.name IN ('debit', 'credit')
|
||||
THEN NULLIF(a.data ->> 'account_id', '')::bigint
|
||||
ELSE NULL
|
||||
END AS "accountId",
|
||||
NULLIF(a.data ->> 'wallet_from', '') AS "walletFrom",
|
||||
NULLIF(a.data ->> 'wallet_to', '') AS "walletTo",
|
||||
COALESCE(
|
||||
NULLIF(a.data ->> 'quantity', ''),
|
||||
NULLIF(a.data ->> 'amount', '')
|
||||
@@ -234,8 +261,8 @@ export class TypeOrmLedger2StateRepository implements Ledger2StatePort {
|
||||
processHash: (r.processHash as string | null) ?? null,
|
||||
username: (r.username as string | null) ?? null,
|
||||
accountId: r.accountId !== null && r.accountId !== undefined ? Number(r.accountId) : null,
|
||||
walletFrom: r.walletFrom !== null && r.walletFrom !== undefined ? Number(r.walletFrom) : null,
|
||||
walletTo: r.walletTo !== null && r.walletTo !== undefined ? Number(r.walletTo) : null,
|
||||
walletFrom: r.walletFrom != null ? String(r.walletFrom) : null,
|
||||
walletTo: r.walletTo != null ? String(r.walletTo) : null,
|
||||
quantity: (r.quantity as string | null) ?? null,
|
||||
memo: (r.memo as string | null) ?? null,
|
||||
createdAt: r.createdAt instanceof Date ? r.createdAt : new Date(String(r.createdAt)),
|
||||
|
||||
@@ -25,9 +25,12 @@ export interface IAccount2 {
|
||||
/**
|
||||
* Строка таблицы `wallets` контракта ledger2 (аналитический разрез бухсчёта).
|
||||
* Source: `table_ledger2_wallet.hpp`.
|
||||
*
|
||||
* `id` — eosio::name-идентификатор кошелька (`w.<contract>.<waltype>`),
|
||||
* см. cooptypes/ledger2/wallets.ts. Поле `name` — человекочитаемое название.
|
||||
*/
|
||||
export interface IWallet2 {
|
||||
id: number
|
||||
id: IName
|
||||
name: string
|
||||
available: IAsset
|
||||
blocked: IAsset
|
||||
@@ -66,8 +69,8 @@ export interface IWalmove {
|
||||
coopname: IName
|
||||
initiator: IName
|
||||
username: IName
|
||||
from_wallet: number
|
||||
to_wallet: number
|
||||
from_wallet: IName
|
||||
to_wallet: IName
|
||||
amount: IAsset
|
||||
process_hash: IChecksum256
|
||||
memo: string
|
||||
@@ -92,8 +95,8 @@ export interface IRevert {
|
||||
* 2=BLOCK / 3=UNBLOCK не разрешены — они симметричны сами себе.
|
||||
*/
|
||||
mirror_wallet_op: number
|
||||
mirror_wallet_from: number
|
||||
mirror_wallet_to: number
|
||||
mirror_wallet_from: IName
|
||||
mirror_wallet_to: IName
|
||||
mirror_debit_account_id: number
|
||||
mirror_credit_account_id: number
|
||||
process_hash: IChecksum256
|
||||
|
||||
@@ -8,7 +8,12 @@
|
||||
* Нейминг: `o.<contract>.<verb>`, где префикс `o.` — operation, далее имя
|
||||
* контракта-источника (reg/wal/cap/mkt/sov/mig), затем короткий глагол.
|
||||
* Длина eosio::name ≤ 12 символов (13-й символ имеет ограничение по алфавиту).
|
||||
*
|
||||
* Идентификаторы кошельков (`wallet_from`/`wallet_to`) — eosio::name с
|
||||
* префиксом `w.<contract>.<waltype>` (см. `./wallets.ts`). Пустая строка
|
||||
* (`""`) — sentinel «кошелёк вне системы» для ISSUE и REVOKE.
|
||||
*/
|
||||
import type { IName } from '../interfaces/ledger2'
|
||||
|
||||
export type WalletOp = 'ISSUE' | 'TRANSFER' | 'BLOCK' | 'UNBLOCK' | 'WALLET_ONLY' | 'REVOKE'
|
||||
|
||||
@@ -27,10 +32,10 @@ export interface OperationMeta {
|
||||
* REVERSAL = REVOKE/TRANSFER/WALLET_ONLY в зависимости от зеркала).
|
||||
*/
|
||||
wallet_op: WalletOp | null
|
||||
/** id кошелька-источника (null для ISSUE и для adjustment-операций). */
|
||||
wallet_from: number | null
|
||||
/** id кошелька-приёмника (null для BLOCK/UNBLOCK и для adjustment-операций). */
|
||||
wallet_to: number | null
|
||||
/** Кошелёк-источник (null для ISSUE и для adjustment-операций). */
|
||||
wallet_from: IName | null
|
||||
/** Кошелёк-приёмник (null для BLOCK/UNBLOCK и для adjustment-операций). */
|
||||
wallet_to: IName | null
|
||||
/** Код счёта Дт (null для WALLET_ONLY и для adjustment-операций). */
|
||||
debit: number | null
|
||||
/** Код счёта Кт (null для WALLET_ONLY и для adjustment-операций). */
|
||||
@@ -53,97 +58,97 @@ export interface OperationMeta {
|
||||
export const LEDGER2_OPERATION_REGISTRY: readonly OperationMeta[] = [
|
||||
// registrator
|
||||
{ code: 'o.reg.payent', process_type: 'p.reg.accept', contract: 'registrator',
|
||||
name: 'PAY_ENTRANCE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 3001,
|
||||
name: 'PAY_ENTRANCE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.reg.entry',
|
||||
debit: 51, credit: 86,
|
||||
human_name: 'Вступительный взнос пайщика' },
|
||||
|
||||
{ code: 'o.reg.putmin', process_type: 'p.reg.accept', contract: 'registrator',
|
||||
name: 'PUT_MINSHARE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 2002,
|
||||
name: 'PUT_MINSHARE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.reg.minshr',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Минимальный паевой взнос пайщика при регистрации' },
|
||||
|
||||
// wallet
|
||||
{ code: 'o.wal.depcpl', process_type: 'p.wal.depo', contract: 'wallet',
|
||||
name: 'COMPLETE_DEPOSIT', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 2001,
|
||||
name: 'COMPLETE_DEPOSIT', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.wal.share',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Внесение пайщиком паевого взноса' },
|
||||
|
||||
{ code: 'o.wal.wthcpl', process_type: 'p.wal.wthdrw', contract: 'wallet',
|
||||
name: 'COMPLETE_WITHDRAW', wallet_op: 'TRANSFER', wallet_from: 2001, wallet_to: 4001,
|
||||
name: 'COMPLETE_WITHDRAW', wallet_op: 'TRANSFER', wallet_from: 'w.wal.share', wallet_to: 'w.wal.wthdrw',
|
||||
debit: 80, credit: 51,
|
||||
human_name: 'Возврат паевого взноса пайщику' },
|
||||
|
||||
// capital
|
||||
{ code: 'o.cap.import', process_type: 'p.cap.import', contract: 'capital',
|
||||
name: 'IMPORT', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 9001,
|
||||
name: 'IMPORT', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.cap.bginv',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Паевой взнос по ЦПП «Благорост» (офлайн-импорт)' },
|
||||
|
||||
{ code: 'o.cap.invest', process_type: 'p.cap.invest', contract: 'capital',
|
||||
name: 'INVEST', wallet_op: 'WALLET_ONLY', wallet_from: 2001, wallet_to: 9001,
|
||||
name: 'INVEST', wallet_op: 'WALLET_ONLY', wallet_from: 'w.wal.share', wallet_to: 'w.cap.bginv',
|
||||
debit: null, credit: null,
|
||||
human_name: 'Инвестиция в ЦПП «Благорост» (перенос между кошельками)' },
|
||||
|
||||
{ code: 'o.cap.commit', process_type: 'p.cap.rid', contract: 'capital',
|
||||
name: 'COMMIT_RID', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 10001,
|
||||
name: 'COMMIT_RID', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.cap.gncom',
|
||||
debit: 8, credit: 80,
|
||||
human_name: 'Коммит РИД по программе «Благорост»' },
|
||||
|
||||
{ code: 'o.cap.accept', process_type: 'p.cap.rid', contract: 'capital',
|
||||
name: 'ACCEPT_RID', wallet_op: 'TRANSFER', wallet_from: 10001, wallet_to: 9002,
|
||||
name: 'ACCEPT_RID', wallet_op: 'TRANSFER', wallet_from: 'w.cap.gncom', wallet_to: 'w.cap.bgrid',
|
||||
debit: 4, credit: 8,
|
||||
human_name: 'Приём РИД в паевой фонд' },
|
||||
|
||||
{ code: 'o.cap.actprp', process_type: 'p.cap.prop', contract: 'capital',
|
||||
name: 'ACCEPT_PROPERTY', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 9003,
|
||||
name: 'ACCEPT_PROPERTY', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.cap.bgprop',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Паевой взнос (имущественный) по программе «Благорост»' },
|
||||
|
||||
{ code: 'o.cap.lend', process_type: 'p.cap.debt', contract: 'capital',
|
||||
name: 'LEND', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 4051,
|
||||
name: 'LEND', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.cap.loan',
|
||||
debit: 58, credit: 51,
|
||||
human_name: 'Выдача пайщику беспроцентного займа' },
|
||||
|
||||
{ code: 'o.cap.repay', process_type: 'p.cap.rid', contract: 'capital',
|
||||
name: 'REPAY', wallet_op: 'TRANSFER', wallet_from: 4051, wallet_to: 2001,
|
||||
name: 'REPAY', wallet_op: 'TRANSFER', wallet_from: 'w.cap.loan', wallet_to: 'w.wal.share',
|
||||
debit: 80, credit: 58,
|
||||
human_name: 'Возврат беспроцентного займа пайщика по акту-2' },
|
||||
|
||||
// marketplace
|
||||
{ code: 'o.mkt.supply', process_type: 'p.mkt.reqst', contract: 'marketplace',
|
||||
name: 'CONFIRM_SUPPLY', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 2001,
|
||||
name: 'CONFIRM_SUPPLY', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.wal.share',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Подтверждение поставки' },
|
||||
|
||||
{ code: 'o.mkt.recv', process_type: 'p.mkt.reqst', contract: 'marketplace',
|
||||
name: 'CONFIRM_RECEIPT', wallet_op: 'TRANSFER', wallet_from: 2001, wallet_to: 4002,
|
||||
name: 'CONFIRM_RECEIPT', wallet_op: 'TRANSFER', wallet_from: 'w.wal.share', wallet_to: 'w.mkt.payout',
|
||||
debit: 80, credit: 51,
|
||||
human_name: 'Подтверждение получения — выплата поставщику' },
|
||||
|
||||
// soviet
|
||||
{ code: 'o.sov.axncnv', process_type: 'p.sov.axncnv', contract: 'soviet',
|
||||
name: 'CONVERT_AXN', wallet_op: 'TRANSFER', wallet_from: 2001, wallet_to: 3003,
|
||||
name: 'CONVERT_AXN', wallet_op: 'TRANSFER', wallet_from: 'w.wal.share', wallet_to: 'w.sov.delgte',
|
||||
debit: 80, credit: 86,
|
||||
human_name: 'Трансляция паевого в членский взнос инфраструктуры' },
|
||||
|
||||
// migration
|
||||
{ code: 'o.mig.minshr', process_type: 'p.mig.trans', contract: 'migration',
|
||||
name: 'MIN_SHARE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 2002,
|
||||
name: 'MIN_SHARE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.reg.minshr',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Транзит: минимальные паевые взносы' },
|
||||
|
||||
{ code: 'o.mig.share', process_type: 'p.mig.trans', contract: 'migration',
|
||||
name: 'SHARE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 2001,
|
||||
name: 'SHARE', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.wal.share',
|
||||
debit: 51, credit: 80,
|
||||
human_name: 'Транзит: остаток паевых взносов деньгами' },
|
||||
|
||||
{ code: 'o.mig.entry', process_type: 'p.mig.trans', contract: 'migration',
|
||||
name: 'ENTRY', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 3001,
|
||||
name: 'ENTRY', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.reg.entry',
|
||||
debit: 51, credit: 86,
|
||||
human_name: 'Транзит: вступительные взносы' },
|
||||
|
||||
{ code: 'o.mig.rid', process_type: 'p.mig.trans', contract: 'migration',
|
||||
name: 'RID', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 2003,
|
||||
name: 'RID', wallet_op: 'ISSUE', wallet_from: null, wallet_to: 'w.wal.sharid',
|
||||
debit: 4, credit: 80,
|
||||
human_name: 'Транзит: принятые РИД в паевой фонд' },
|
||||
|
||||
|
||||
@@ -4,41 +4,64 @@
|
||||
* (`LEDGER2_WALLET_REGISTRY`). При добавлении/переименовании кошелька
|
||||
* синхронизировать обе стороны.
|
||||
*
|
||||
* Используется для tooltip-подсказок в UI (standards-site, desktop).
|
||||
* Идентификатор кошелька — `eosio::name` с префиксом `w.<contract>.<waltype>`
|
||||
* по аналогии с операциями (`o.<contract>.<verb>`) и процессами
|
||||
* (`p.<contract>.<noun>`). Длина ≤ 13 base32-символов.
|
||||
*
|
||||
* `human_name` — отображаемое имя в UI (standards-site, desktop).
|
||||
*/
|
||||
import type { IName } from '../interfaces/ledger2'
|
||||
|
||||
export interface WalletMeta {
|
||||
id: number
|
||||
name: string
|
||||
/** Машинный идентификатор — eosio::name в контракте. */
|
||||
name: IName
|
||||
/** Человекочитаемое название для UI. */
|
||||
human_name: string
|
||||
}
|
||||
|
||||
export const LEDGER2_WALLET_REGISTRY: readonly WalletMeta[] = [
|
||||
// id=0 — frontend-only: в контракте нет, но walletop issue/consume использует
|
||||
// 0 как «кошелёк-источник/сток извне системы» (эмиссия / сжигание).
|
||||
{ id: 0, name: 'Выпуск' },
|
||||
{ id: 2001, name: 'ЦПП «Цифровой Кошелёк» — паевые взносы деньгами' },
|
||||
{ id: 2002, name: 'Минимальный паевой взнос' },
|
||||
{ id: 2003, name: 'Паевой фонд — принятые РИД' },
|
||||
{ id: 3001, name: 'Вступительные взносы' },
|
||||
{ id: 3002, name: 'Членские взносы (платформенные)' },
|
||||
{ id: 3003, name: 'Делегатские членские взносы' },
|
||||
{ id: 4001, name: 'Возвраты паевых взносов пайщикам' },
|
||||
{ id: 4002, name: 'Выплаты поставщикам' },
|
||||
{ id: 4051, name: 'Выданные пайщикам беспроцентные займы' },
|
||||
{ id: 5001, name: 'Ручные корректировки' },
|
||||
{ id: 9001, name: 'ЦПП «Благорост» — инвестиции деньгами' },
|
||||
{ id: 9002, name: 'ЦПП «Благорост» — принятые РИД' },
|
||||
{ id: 9003, name: 'ЦПП «Благорост» — имущественные паевые взносы' },
|
||||
{ id: 9004, name: 'ЦПП «Благорост» — членские взносы' },
|
||||
{ id: 10001, name: 'ЦПП «Генератор» — принятый коммит (имущество)' },
|
||||
{ id: 10002, name: 'ЦПП «Генератор» — членские взносы' },
|
||||
{ id: 11001, name: 'ЦПП «Стол Заказов» — общий кошелёк' },
|
||||
// Группа паевого фонда (Cr 80)
|
||||
{ name: 'w.wal.share', human_name: 'ЦПП «Цифровой Кошелёк» — паевые взносы деньгами' },
|
||||
{ name: 'w.reg.minshr', human_name: 'Минимальный паевой взнос' },
|
||||
{ name: 'w.wal.sharid', human_name: 'Паевой фонд — принятые РИД' },
|
||||
|
||||
// Целевое финансирование (Cr 86)
|
||||
{ name: 'w.reg.entry', human_name: 'Вступительные взносы' },
|
||||
{ name: 'w.sov.member', human_name: 'Членские взносы (платформенные)' },
|
||||
{ name: 'w.sov.delgte', human_name: 'Делегатские членские взносы' },
|
||||
|
||||
// Выплаты / обязательства / финансовые вложения
|
||||
{ name: 'w.wal.wthdrw', human_name: 'Возвраты паевых взносов пайщикам' },
|
||||
{ name: 'w.mkt.payout', human_name: 'Выплаты поставщикам' },
|
||||
{ name: 'w.cap.loan', human_name: 'Выданные пайщикам беспроцентные займы' },
|
||||
|
||||
// Служебные
|
||||
{ name: 'w.led.adjust', human_name: 'Ручные корректировки' },
|
||||
|
||||
// ЦПП «Благорост»
|
||||
{ name: 'w.cap.bginv', human_name: 'ЦПП «Благорост» — инвестиции деньгами' },
|
||||
{ name: 'w.cap.bgrid', human_name: 'ЦПП «Благорост» — принятые РИД' },
|
||||
{ name: 'w.cap.bgprop', human_name: 'ЦПП «Благорост» — имущественные паевые взносы' },
|
||||
{ name: 'w.cap.bgmem', human_name: 'ЦПП «Благорост» — членские взносы' },
|
||||
|
||||
// ЦПП «Генератор»
|
||||
{ name: 'w.cap.gncom', human_name: 'ЦПП «Генератор» — принятый коммит (имущество)' },
|
||||
{ name: 'w.cap.gnmem', human_name: 'ЦПП «Генератор» — членские взносы' },
|
||||
|
||||
// ЦПП «Стол Заказов»
|
||||
{ name: 'w.mkt.fund', human_name: 'ЦПП «Стол Заказов» — общий кошелёк' },
|
||||
] as const
|
||||
|
||||
const walletNameById = new Map<number, string>(
|
||||
LEDGER2_WALLET_REGISTRY.map((w) => [w.id, w.name]),
|
||||
const walletHumanByName = new Map<string, string>(
|
||||
LEDGER2_WALLET_REGISTRY.map((w) => [w.name, w.human_name]),
|
||||
)
|
||||
|
||||
export function getWalletName(id: number | null | undefined): string | undefined {
|
||||
if (id == null) return undefined
|
||||
return walletNameById.get(id)
|
||||
/**
|
||||
* Возвращает человекочитаемое имя кошелька по его eosio::name-идентификатору.
|
||||
* Возвращает undefined для незарегистрированных имён и для пустого имени
|
||||
* (sentinel "" — кошелёк-источник/сток вне системы при ISSUE/REVOKE).
|
||||
*/
|
||||
export function getWalletHumanName(name: IName | null | undefined): string | undefined {
|
||||
if (!name) return undefined
|
||||
return walletHumanByName.get(name)
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ div.page-shell
|
||||
q-card.q-mt-md(flat)
|
||||
q-card-section
|
||||
.row.q-gutter-sm.items-center.q-mb-sm(
|
||||
v-if='filters.accountId !== null || filters.processHash || filters.username'
|
||||
v-if='filters.accountId !== null || filters.walletName || filters.processHash || filters.username'
|
||||
)
|
||||
q-chip(
|
||||
v-if='filters.accountId !== null'
|
||||
v-if='filters.accountId !== null || filters.walletName'
|
||||
removable
|
||||
color='primary'
|
||||
text-color='white'
|
||||
@@ -198,10 +198,10 @@ div.page-shell
|
||||
DirectionCell(:direction='cp.row.direction')
|
||||
template(#body-cell-walletFrom='cp')
|
||||
q-td(:props='cp')
|
||||
WalletIdCell(:wallet-id='cp.row.walletFrom')
|
||||
WalletIdCell(:wallet-name='cp.row.walletFrom')
|
||||
template(#body-cell-walletTo='cp')
|
||||
q-td(:props='cp')
|
||||
WalletIdCell(:wallet-id='cp.row.walletTo')
|
||||
WalletIdCell(:wallet-name='cp.row.walletTo')
|
||||
template(#body-cell-quantity='cp')
|
||||
q-td.text-right(:props='cp') {{ formatAmount(cp.row.quantity) }}
|
||||
.text-caption.text-grey-6(v-else) Движений по кошелькам нет
|
||||
@@ -381,7 +381,10 @@ const pagination = ref({ page: 1, rowsPerPage: 50, rowsNumber: 0 })
|
||||
const filters = reactive<{
|
||||
dateFrom: string
|
||||
dateTo: string
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для фильтра по debit/credit. */
|
||||
accountId: number | null
|
||||
/** eosio::name кошелька (`w.<contract>.<waltype>`) — для фильтра по walletop. */
|
||||
walletName: string | null
|
||||
accountKind: 'wallet' | 'account' | null
|
||||
accountName: string
|
||||
processHash: string | null
|
||||
@@ -393,6 +396,7 @@ const filters = reactive<{
|
||||
dateFrom: '',
|
||||
dateTo: '',
|
||||
accountId: null,
|
||||
walletName: null,
|
||||
accountKind: null,
|
||||
accountName: '',
|
||||
processHash: null,
|
||||
@@ -436,19 +440,23 @@ async function applyProcessHashSearch(): Promise<void> {
|
||||
|
||||
|
||||
const accountFilterLabel = computed(() => {
|
||||
if (filters.accountId === null) return ''
|
||||
if (filters.accountKind === 'wallet') {
|
||||
return `Кошелёк ${filters.accountId}${filters.accountName ? ` — ${filters.accountName}` : ''}`
|
||||
if (filters.accountKind === 'wallet' && filters.walletName) {
|
||||
return `Кошелёк ${filters.walletName}${filters.accountName ? ` — ${filters.accountName}` : ''}`
|
||||
}
|
||||
const displayCode = Math.round(filters.accountId / 1000)
|
||||
return `Счёт ${displayCode}${filters.accountName ? ` — ${filters.accountName}` : ''}`
|
||||
if (filters.accountId !== null) {
|
||||
const displayCode = Math.round(filters.accountId / 1000)
|
||||
return `Счёт ${displayCode}${filters.accountName ? ` — ${filters.accountName}` : ''}`
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
async function clearAccountFilter() {
|
||||
filters.accountId = null
|
||||
filters.walletName = null
|
||||
filters.accountKind = null
|
||||
filters.accountName = ''
|
||||
const q = { ...route.query }
|
||||
delete q.wallet_name
|
||||
delete q.wallet_id
|
||||
delete q.account_id
|
||||
await router.replace({ query: q })
|
||||
@@ -472,17 +480,21 @@ async function clearUsernameFilter() {
|
||||
reload()
|
||||
}
|
||||
|
||||
async function resolveAccountName(id: number, kind: 'wallet' | 'account') {
|
||||
async function resolveWalletName(walletName: string) {
|
||||
try {
|
||||
if (kind === 'wallet') {
|
||||
const wallets = await ledger2Store.loadWallets(info.coopname)
|
||||
const w = wallets.find((x) => x.id === id)
|
||||
if (w) filters.accountName = w.name
|
||||
} else {
|
||||
const accounts = await ledger2Store.loadAccounts(info.coopname)
|
||||
const a = accounts.find((x) => x.id === id)
|
||||
if (a) filters.accountName = a.name
|
||||
}
|
||||
const wallets = await ledger2Store.loadWallets(info.coopname)
|
||||
const w = wallets.find((x) => x.id === walletName)
|
||||
if (w) filters.accountName = w.name
|
||||
} catch {
|
||||
// молча — chip покажется без названия
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveAccountName(id: number) {
|
||||
try {
|
||||
const accounts = await ledger2Store.loadAccounts(info.coopname)
|
||||
const a = accounts.find((x) => x.id === id)
|
||||
if (a) filters.accountName = a.name
|
||||
} catch {
|
||||
// молча — chip покажется без названия
|
||||
}
|
||||
@@ -514,8 +526,9 @@ const accountColumns = [
|
||||
interface WalletRow {
|
||||
globalSequence: string
|
||||
direction: 'in' | 'out' | 'move'
|
||||
walletFrom: number | null
|
||||
walletTo: number | null
|
||||
/** eosio::name кошелька (`w.<contract>.<waltype>`) или null. */
|
||||
walletFrom: string | null
|
||||
walletTo: string | null
|
||||
quantity: string | null
|
||||
}
|
||||
interface AccountRow {
|
||||
@@ -565,6 +578,7 @@ const hasAnyFilter = computed(
|
||||
!!filters.dateFrom ||
|
||||
!!filters.dateTo ||
|
||||
filters.accountId !== null ||
|
||||
!!filters.walletName ||
|
||||
!!filters.processHash ||
|
||||
!!filters.username ||
|
||||
filters.adjustmentsOnly,
|
||||
@@ -574,6 +588,7 @@ async function resetFilters() {
|
||||
filters.dateFrom = ''
|
||||
filters.dateTo = ''
|
||||
filters.accountId = null
|
||||
filters.walletName = null
|
||||
filters.accountKind = null
|
||||
filters.accountName = ''
|
||||
filters.processHash = null
|
||||
@@ -581,6 +596,7 @@ async function resetFilters() {
|
||||
filters.username = null
|
||||
filters.adjustmentsOnly = false
|
||||
const q = { ...route.query }
|
||||
delete q.wallet_name
|
||||
delete q.wallet_id
|
||||
delete q.account_id
|
||||
delete q.process_hash
|
||||
@@ -647,6 +663,7 @@ async function load() {
|
||||
// process_hash, но не operation_code как payload-поле). Поэтому фильтр
|
||||
// «Только корректировки» работает через actionNames=[walmove,revert].
|
||||
if (filters.accountId !== null) input.accountId = filters.accountId
|
||||
if (filters.walletName) input.walletName = filters.walletName
|
||||
if (filters.processHash) input.processHash = filters.processHash
|
||||
if (filters.username) input.username = filters.username
|
||||
if (filters.dateFrom) input.dateFrom = new Date(filters.dateFrom)
|
||||
@@ -711,11 +728,11 @@ onMounted(async () => {
|
||||
if (route.query.account_id) {
|
||||
filters.accountId = Number(route.query.account_id)
|
||||
filters.accountKind = 'account'
|
||||
resolveAccountName(filters.accountId, 'account')
|
||||
} else if (route.query.wallet_id) {
|
||||
filters.accountId = Number(route.query.wallet_id)
|
||||
resolveAccountName(filters.accountId)
|
||||
} else if (route.query.wallet_name) {
|
||||
filters.walletName = String(route.query.wallet_name)
|
||||
filters.accountKind = 'wallet'
|
||||
resolveAccountName(filters.accountId, 'wallet')
|
||||
resolveWalletName(filters.walletName)
|
||||
}
|
||||
if (route.query.process_hash) {
|
||||
filters.processHash = String(route.query.process_hash).toLowerCase()
|
||||
|
||||
@@ -51,7 +51,7 @@ div.page-shell
|
||||
flat dense size='sm' color='primary'
|
||||
icon='fa-solid fa-arrow-right'
|
||||
label='К операциям'
|
||||
:to='{ name: "reports-operations", query: { wallet_id: props.row.id } }'
|
||||
:to='{ name: "reports-operations", query: { wallet_name: props.row.id } }'
|
||||
)
|
||||
q-table(
|
||||
flat dense
|
||||
@@ -65,13 +65,13 @@ div.page-shell
|
||||
)
|
||||
template(#body-cell-direction='cp')
|
||||
q-td(:props='cp')
|
||||
DirectionCell(:direction='directionFor(cp.row, props.row.id)')
|
||||
DirectionCell(:direction='directionFor(cp.row, String(props.row.id))')
|
||||
template(#body-cell-walletFrom='cp')
|
||||
q-td(:props='cp')
|
||||
WalletIdCell(:wallet-id='cp.row.walletFrom')
|
||||
WalletIdCell(:wallet-name='cp.row.walletFrom')
|
||||
template(#body-cell-walletTo='cp')
|
||||
q-td(:props='cp')
|
||||
WalletIdCell(:wallet-id='cp.row.walletTo')
|
||||
WalletIdCell(:wallet-name='cp.row.walletTo')
|
||||
template(#body-cell-quantity='cp')
|
||||
q-td.text-right(:props='cp') {{ cp.row.quantity ? formatAsset2Digits(cp.row.quantity) : '—' }}
|
||||
template(#body-cell-memo='cp')
|
||||
@@ -144,11 +144,12 @@ const loading = ref(false)
|
||||
const pagination = ref({ rowsPerPage: 0 })
|
||||
const wallets = ref<ILedger2Wallet[]>([])
|
||||
|
||||
const expanded = ref(new Set<number>())
|
||||
const childOps = ref(new Map<number, ILedger2Operation[]>())
|
||||
const childLoading = ref(new Set<number>())
|
||||
// Идентификатор кошелька — eosio::name (строка `w.<contract>.<waltype>`).
|
||||
const expanded = ref(new Set<string>())
|
||||
const childOps = ref(new Map<string, ILedger2Operation[]>())
|
||||
const childLoading = ref(new Set<string>())
|
||||
|
||||
const transferDialog = reactive<{ open: boolean; fromWallet: number | null }>({
|
||||
const transferDialog = reactive<{ open: boolean; fromWallet: string | null }>({
|
||||
open: false,
|
||||
fromWallet: null,
|
||||
})
|
||||
@@ -158,8 +159,8 @@ function openTransferEmpty(): void {
|
||||
transferDialog.open = true
|
||||
}
|
||||
|
||||
function openTransferFor(walletId: number): void {
|
||||
transferDialog.fromWallet = walletId
|
||||
function openTransferFor(walletName: string): void {
|
||||
transferDialog.fromWallet = walletName
|
||||
transferDialog.open = true
|
||||
}
|
||||
|
||||
@@ -204,17 +205,17 @@ const childColumns: any[] = [
|
||||
{ name: 'open', align: 'right', label: '', field: 'processHash' },
|
||||
]
|
||||
|
||||
function directionFor(op: ILedger2Operation, walletId: number): 'in' | 'out' | 'move' {
|
||||
function directionFor(op: ILedger2Operation, walletName: string): 'in' | 'out' | 'move' {
|
||||
const from = op.walletFrom ?? null
|
||||
const to = op.walletTo ?? null
|
||||
if (from === walletId && to && to !== walletId) return 'out'
|
||||
if (to === walletId && from && from !== walletId) return 'in'
|
||||
if (to === walletId && !from) return 'in'
|
||||
if (from === walletId && !to) return 'out'
|
||||
if (from === walletName && to && to !== walletName) return 'out'
|
||||
if (to === walletName && from && from !== walletName) return 'in'
|
||||
if (to === walletName && !from) return 'in'
|
||||
if (from === walletName && !to) return 'out'
|
||||
return 'move'
|
||||
}
|
||||
|
||||
async function toggleExpand(id: number) {
|
||||
async function toggleExpand(id: string) {
|
||||
if (expanded.value.has(id)) {
|
||||
expanded.value.delete(id)
|
||||
return
|
||||
@@ -225,7 +226,7 @@ async function toggleExpand(id: number) {
|
||||
try {
|
||||
const resp = await ledger2Store.loadHistory({
|
||||
coopname: info.coopname,
|
||||
accountId: id,
|
||||
walletName: id,
|
||||
actionNames: ['walletop'],
|
||||
limit: 20,
|
||||
sortOrder: 'DESC',
|
||||
|
||||
+14
-11
@@ -92,8 +92,9 @@ import { useLedger2Store, type ILedger2Wallet } from 'src/entities/Ledger2'
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
/** Если задано — диалог открыт «из строки кошелька»: from_wallet залочен. */
|
||||
fixedFromWallet?: number | null
|
||||
/** Если задано — диалог открыт «из строки кошелька»: from_wallet залочен.
|
||||
* Значение — eosio::name кошелька (`w.<contract>.<waltype>`). */
|
||||
fixedFromWallet?: string | null
|
||||
/** Список кошельков для выбора (общекооперативные ledger2 wallets). */
|
||||
wallets: ILedger2Wallet[]
|
||||
}
|
||||
@@ -111,8 +112,8 @@ const formRef = ref<{ validate: () => Promise<boolean> } | null>(null)
|
||||
const loading = ref(false)
|
||||
|
||||
const form = reactive({
|
||||
fromWallet: null as number | null,
|
||||
toWallet: null as number | null,
|
||||
fromWallet: null as string | null,
|
||||
toWallet: null as string | null,
|
||||
amountStr: '',
|
||||
memo: '',
|
||||
})
|
||||
@@ -121,20 +122,22 @@ const form = reactive({
|
||||
* Привязка wallet→account по cooptypes (LEDGER2_OPERATION_REGISTRY).
|
||||
* Та же логика, что в backend: первая стандартная операция, где встречается
|
||||
* этот кошелёк, даёт его account_id (debit/credit зависит от роли).
|
||||
*
|
||||
* `walletName` — eosio::name кошелька (`w.<contract>.<waltype>`).
|
||||
*/
|
||||
function resolveAccountId(walletId: number): number | null {
|
||||
function resolveAccountId(walletName: string): number | null {
|
||||
for (const op of Ledger2.LEDGER2_OPERATION_REGISTRY) {
|
||||
if (op.kind === 'adjustment') continue
|
||||
if (op.wallet_op === 'WALLET_ONLY') continue
|
||||
if (op.wallet_from === walletId && op.credit !== null) return op.credit
|
||||
if (op.wallet_to === walletId && op.wallet_op === 'ISSUE' && op.credit !== null) return op.credit
|
||||
if (op.wallet_to === walletId && op.debit !== null) return op.debit
|
||||
if (op.wallet_from === walletId && op.debit !== null) return op.debit
|
||||
if (op.wallet_from === walletName && op.credit !== null) return op.credit
|
||||
if (op.wallet_to === walletName && op.wallet_op === 'ISSUE' && op.credit !== null) return op.credit
|
||||
if (op.wallet_to === walletName && op.debit !== null) return op.debit
|
||||
if (op.wallet_from === walletName && op.debit !== null) return op.debit
|
||||
}
|
||||
for (const op of Ledger2.LEDGER2_OPERATION_REGISTRY) {
|
||||
if (op.wallet_op !== 'WALLET_ONLY' || op.kind === 'adjustment') continue
|
||||
if (op.wallet_from === walletId && op.wallet_to !== null) return resolveAccountId(op.wallet_to)
|
||||
if (op.wallet_to === walletId && op.wallet_from !== null) return resolveAccountId(op.wallet_from)
|
||||
if (op.wallet_from === walletName && op.wallet_to !== null) return resolveAccountId(op.wallet_to)
|
||||
if (op.wallet_to === walletName && op.wallet_from !== null) return resolveAccountId(op.wallet_from)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template lang="pug">
|
||||
span(v-if='walletId === null || walletId === undefined').text-grey-6 —
|
||||
span(v-if='!walletName').text-grey-6 —
|
||||
span.wallet-id-cell(v-else)
|
||||
EntityIdBadge(
|
||||
:rawId='walletId'
|
||||
:rawId='walletName'
|
||||
copy-on-click
|
||||
)
|
||||
q-tooltip(v-if='tooltipText' anchor='top middle' self='bottom middle') {{ tooltipText }}
|
||||
@@ -11,15 +11,15 @@ span.wallet-id-cell(v-else)
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { EntityIdBadge } from 'src/shared/ui'
|
||||
import { getWalletName } from 'src/shared/lib/ledger2'
|
||||
import { getWalletHumanName } from 'src/shared/lib/ledger2'
|
||||
|
||||
const props = defineProps<{
|
||||
walletId: number | null | undefined
|
||||
walletName: string | null | undefined
|
||||
}>()
|
||||
|
||||
const tooltipText = computed(() => {
|
||||
if (props.walletId === null || props.walletId === undefined) return ''
|
||||
const name = getWalletName(props.walletId)
|
||||
return name ? `${name} (клик — копировать)` : 'Клик — копировать'
|
||||
if (!props.walletName) return ''
|
||||
const human = getWalletHumanName(props.walletName)
|
||||
return human ? `${human} (клик — копировать)` : 'Клик — копировать'
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -21,7 +21,8 @@ interface ILedger2Store {
|
||||
loadWallets: (coopname: string) => Promise<ILedger2Wallet[]>
|
||||
loadHistory: (input: ILedger2HistoryFilterInput) => Promise<ILedger2HistoryResponse | undefined>
|
||||
getAccountById: (id: number) => ILedger2Account | undefined
|
||||
getWalletById: (id: number) => ILedger2Wallet | undefined
|
||||
/** `name` — eosio::name кошелька (`w.<contract>.<waltype>`). */
|
||||
getWalletByName: (name: string) => ILedger2Wallet | undefined
|
||||
walmoveWallets: (input: IWalmoveInput) => Promise<ILedger2AdjustmentResult>
|
||||
}
|
||||
|
||||
@@ -60,8 +61,8 @@ export const useLedger2Store = defineStore(namespace, (): ILedger2Store => {
|
||||
return accounts.value.find((a) => a.id === id)
|
||||
}
|
||||
|
||||
function getWalletById(id: number): ILedger2Wallet | undefined {
|
||||
return wallets.value.find((w) => w.id === id)
|
||||
function getWalletByName(name: string): ILedger2Wallet | undefined {
|
||||
return wallets.value.find((w) => w.id === name)
|
||||
}
|
||||
|
||||
async function walmoveWallets(input: IWalmoveInput): Promise<ILedger2AdjustmentResult> {
|
||||
@@ -76,7 +77,7 @@ export const useLedger2Store = defineStore(namespace, (): ILedger2Store => {
|
||||
loadWallets,
|
||||
loadHistory,
|
||||
getAccountById,
|
||||
getWalletById,
|
||||
getWalletByName,
|
||||
walmoveWallets,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -12,4 +12,4 @@ import { Ledger2 } from 'cooptypes'
|
||||
export type WalletMeta = Ledger2.WalletMeta
|
||||
|
||||
export const LEDGER2_WALLET_REGISTRY = Ledger2.LEDGER2_WALLET_REGISTRY
|
||||
export const getWalletName = Ledger2.getWalletName
|
||||
export const getWalletHumanName = Ledger2.getWalletHumanName
|
||||
|
||||
@@ -5641,7 +5641,7 @@ export type ValueTypes = {
|
||||
_id: string | Variable<any, string>
|
||||
};
|
||||
["GetLedger2HistoryInput"]: {
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?: number | undefined | null | Variable<any, string>,
|
||||
/** Имена blockchain-действий: apply | walletop | debit | credit */
|
||||
actionNames?: Array<string> | undefined | null | Variable<any, string>,
|
||||
@@ -5657,7 +5657,9 @@ export type ValueTypes = {
|
||||
/** process_hash для выборки всех действий одной операции */
|
||||
processHash?: string | undefined | null | Variable<any, string>,
|
||||
sortOrder?: string | undefined | null | Variable<any, string>,
|
||||
username?: string | undefined | null | Variable<any, string>
|
||||
username?: string | undefined | null | Variable<any, string>,
|
||||
/** eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop действий. */
|
||||
walletName?: string | undefined | null | Variable<any, string>
|
||||
};
|
||||
["GetLedgerHistoryInput"]: {
|
||||
/** ID счета для фильтрации. Если не указан, возвращаются операции по всем счетам */
|
||||
@@ -5874,7 +5876,7 @@ export type ValueTypes = {
|
||||
['...on Ledger2HistoryResponse']?: Omit<ValueTypes["Ledger2HistoryResponse"], "...on Ledger2HistoryResponse">
|
||||
}>;
|
||||
["Ledger2Operation"]: AliasType<{
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?:boolean | `@${string}`,
|
||||
/** apply | walletop | debit | credit */
|
||||
action?:boolean | `@${string}`,
|
||||
@@ -5891,9 +5893,9 @@ export type ValueTypes = {
|
||||
/** Asset "100.0000 RUB" */
|
||||
quantity?:boolean | `@${string}`,
|
||||
username?:boolean | `@${string}`,
|
||||
/** walletop: wallet_from (исходящий) */
|
||||
/** walletop: wallet_from (eosio::name w.<contract>.<waltype>) */
|
||||
walletFrom?:boolean | `@${string}`,
|
||||
/** walletop: wallet_to (входящий) */
|
||||
/** walletop: wallet_to (eosio::name w.<contract>.<waltype>) */
|
||||
walletTo?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`,
|
||||
['...on Ledger2Operation']?: Omit<ValueTypes["Ledger2Operation"], "...on Ledger2Operation">
|
||||
@@ -5903,7 +5905,7 @@ export type ValueTypes = {
|
||||
available?:boolean | `@${string}`,
|
||||
/** Заблокированный баланс */
|
||||
blocked?:boolean | `@${string}`,
|
||||
/** ID кошелька (×1000 offset): 1001/2001/3001/4001 */
|
||||
/** eosio::name-идентификатор кошелька (w.<contract>.<waltype>) */
|
||||
id?:boolean | `@${string}`,
|
||||
/** Название кошелька */
|
||||
name?:boolean | `@${string}`,
|
||||
@@ -9234,14 +9236,14 @@ validateReportEdits?: [{ editsJson: string | Variable<any, string>, reportType:
|
||||
}>;
|
||||
["WalmoveInput"]: {
|
||||
coopname: string | Variable<any, string>,
|
||||
/** id кошелька-источника */
|
||||
fromWallet: number | Variable<any, string>,
|
||||
/** eosio::name кошелька-источника (w.<contract>.<waltype>) */
|
||||
fromWallet: string | Variable<any, string>,
|
||||
/** Обязательное обоснование корректировки */
|
||||
memo: string | Variable<any, string>,
|
||||
/** Сумма с символом, например "100.0000 RUB" */
|
||||
quantity: string | Variable<any, string>,
|
||||
/** id кошелька-приёмника */
|
||||
toWallet: number | Variable<any, string>,
|
||||
/** eosio::name кошелька-приёмника (w.<contract>.<waltype>) */
|
||||
toWallet: string | Variable<any, string>,
|
||||
/** Владелец кошельков (для коллективных — coopname) */
|
||||
username: string | Variable<any, string>
|
||||
};
|
||||
@@ -13749,7 +13751,7 @@ export type ResolverInputTypes = {
|
||||
_id: string
|
||||
};
|
||||
["GetLedger2HistoryInput"]: {
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?: number | undefined | null,
|
||||
/** Имена blockchain-действий: apply | walletop | debit | credit */
|
||||
actionNames?: Array<string> | undefined | null,
|
||||
@@ -13765,7 +13767,9 @@ export type ResolverInputTypes = {
|
||||
/** process_hash для выборки всех действий одной операции */
|
||||
processHash?: string | undefined | null,
|
||||
sortOrder?: string | undefined | null,
|
||||
username?: string | undefined | null
|
||||
username?: string | undefined | null,
|
||||
/** eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop действий. */
|
||||
walletName?: string | undefined | null
|
||||
};
|
||||
["GetLedgerHistoryInput"]: {
|
||||
/** ID счета для фильтрации. Если не указан, возвращаются операции по всем счетам */
|
||||
@@ -13975,7 +13979,7 @@ export type ResolverInputTypes = {
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
["Ledger2Operation"]: AliasType<{
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?:boolean | `@${string}`,
|
||||
/** apply | walletop | debit | credit */
|
||||
action?:boolean | `@${string}`,
|
||||
@@ -13992,9 +13996,9 @@ export type ResolverInputTypes = {
|
||||
/** Asset "100.0000 RUB" */
|
||||
quantity?:boolean | `@${string}`,
|
||||
username?:boolean | `@${string}`,
|
||||
/** walletop: wallet_from (исходящий) */
|
||||
/** walletop: wallet_from (eosio::name w.<contract>.<waltype>) */
|
||||
walletFrom?:boolean | `@${string}`,
|
||||
/** walletop: wallet_to (входящий) */
|
||||
/** walletop: wallet_to (eosio::name w.<contract>.<waltype>) */
|
||||
walletTo?:boolean | `@${string}`,
|
||||
__typename?: boolean | `@${string}`
|
||||
}>;
|
||||
@@ -14003,7 +14007,7 @@ export type ResolverInputTypes = {
|
||||
available?:boolean | `@${string}`,
|
||||
/** Заблокированный баланс */
|
||||
blocked?:boolean | `@${string}`,
|
||||
/** ID кошелька (×1000 offset): 1001/2001/3001/4001 */
|
||||
/** eosio::name-идентификатор кошелька (w.<contract>.<waltype>) */
|
||||
id?:boolean | `@${string}`,
|
||||
/** Название кошелька */
|
||||
name?:boolean | `@${string}`,
|
||||
@@ -17227,14 +17231,14 @@ validateReportEdits?: [{ editsJson: string, reportType: ResolverInputTypes["Repo
|
||||
}>;
|
||||
["WalmoveInput"]: {
|
||||
coopname: string,
|
||||
/** id кошелька-источника */
|
||||
fromWallet: number,
|
||||
/** eosio::name кошелька-источника (w.<contract>.<waltype>) */
|
||||
fromWallet: string,
|
||||
/** Обязательное обоснование корректировки */
|
||||
memo: string,
|
||||
/** Сумма с символом, например "100.0000 RUB" */
|
||||
quantity: string,
|
||||
/** id кошелька-приёмника */
|
||||
toWallet: number,
|
||||
/** eosio::name кошелька-приёмника (w.<contract>.<waltype>) */
|
||||
toWallet: string,
|
||||
/** Владелец кошельков (для коллективных — coopname) */
|
||||
username: string
|
||||
};
|
||||
@@ -21623,7 +21627,7 @@ export type ModelTypes = {
|
||||
_id: string
|
||||
};
|
||||
["GetLedger2HistoryInput"]: {
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?: number | undefined | null,
|
||||
/** Имена blockchain-действий: apply | walletop | debit | credit */
|
||||
actionNames?: Array<string> | undefined | null,
|
||||
@@ -21639,7 +21643,9 @@ export type ModelTypes = {
|
||||
/** process_hash для выборки всех действий одной операции */
|
||||
processHash?: string | undefined | null,
|
||||
sortOrder?: string | undefined | null,
|
||||
username?: string | undefined | null
|
||||
username?: string | undefined | null,
|
||||
/** eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop действий. */
|
||||
walletName?: string | undefined | null
|
||||
};
|
||||
["GetLedgerHistoryInput"]: {
|
||||
/** ID счета для фильтрации. Если не указан, возвращаются операции по всем счетам */
|
||||
@@ -21838,7 +21844,7 @@ export type ModelTypes = {
|
||||
totalPages: number
|
||||
};
|
||||
["Ledger2Operation"]: {
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?: number | undefined | null,
|
||||
/** apply | walletop | debit | credit */
|
||||
action: string,
|
||||
@@ -21855,18 +21861,18 @@ export type ModelTypes = {
|
||||
/** Asset "100.0000 RUB" */
|
||||
quantity?: string | undefined | null,
|
||||
username?: string | undefined | null,
|
||||
/** walletop: wallet_from (исходящий) */
|
||||
walletFrom?: number | undefined | null,
|
||||
/** walletop: wallet_to (входящий) */
|
||||
walletTo?: number | undefined | null
|
||||
/** walletop: wallet_from (eosio::name w.<contract>.<waltype>) */
|
||||
walletFrom?: string | undefined | null,
|
||||
/** walletop: wallet_to (eosio::name w.<contract>.<waltype>) */
|
||||
walletTo?: string | undefined | null
|
||||
};
|
||||
["Ledger2Wallet"]: {
|
||||
/** Доступный баланс */
|
||||
available: string,
|
||||
/** Заблокированный баланс */
|
||||
blocked: string,
|
||||
/** ID кошелька (×1000 offset): 1001/2001/3001/4001 */
|
||||
id: number,
|
||||
/** eosio::name-идентификатор кошелька (w.<contract>.<waltype>) */
|
||||
id: string,
|
||||
/** Название кошелька */
|
||||
name: string
|
||||
};
|
||||
@@ -23694,7 +23700,7 @@ export type ModelTypes = {
|
||||
getLedger2Accounts: Array<ModelTypes["Ledger2Account"]>,
|
||||
/** История операций ledger2 с серверными фильтрами (action/accountId/username/date-range). */
|
||||
getLedger2History: ModelTypes["Ledger2HistoryResponse"],
|
||||
/** Общекооперативные кошельки из ledger2::wallets (1001/2001/3001/4001). Кошельки пайщиков живут в контракте soviet — сюда не попадают. */
|
||||
/** Общекооперативные кошельки из ledger2::wallets (eosio::name w.<contract>.<waltype>). Кошельки пайщиков живут в контракте soviet — сюда не попадают. */
|
||||
getLedger2Wallets: Array<ModelTypes["Ledger2Wallet"]>,
|
||||
/** Получить историю операций по счетам кооператива. Возвращает список операций с возможностью фильтрации по account_id и пагинацией. Операции сортируются по дате создания (новые первыми). */
|
||||
getLedgerHistory: ModelTypes["LedgerHistoryResponse"],
|
||||
@@ -25212,14 +25218,14 @@ export type ModelTypes = {
|
||||
};
|
||||
["WalmoveInput"]: {
|
||||
coopname: string,
|
||||
/** id кошелька-источника */
|
||||
fromWallet: number,
|
||||
/** eosio::name кошелька-источника (w.<contract>.<waltype>) */
|
||||
fromWallet: string,
|
||||
/** Обязательное обоснование корректировки */
|
||||
memo: string,
|
||||
/** Сумма с символом, например "100.0000 RUB" */
|
||||
quantity: string,
|
||||
/** id кошелька-приёмника */
|
||||
toWallet: number,
|
||||
/** eosio::name кошелька-приёмника (w.<contract>.<waltype>) */
|
||||
toWallet: string,
|
||||
/** Владелец кошельков (для коллективных — coopname) */
|
||||
username: string
|
||||
};
|
||||
@@ -29831,7 +29837,7 @@ export type GraphQLTypes = {
|
||||
_id: string
|
||||
};
|
||||
["GetLedger2HistoryInput"]: {
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?: number | undefined | null,
|
||||
/** Имена blockchain-действий: apply | walletop | debit | credit */
|
||||
actionNames?: Array<string> | undefined | null,
|
||||
@@ -29847,7 +29853,9 @@ export type GraphQLTypes = {
|
||||
/** process_hash для выборки всех действий одной операции */
|
||||
processHash?: string | undefined | null,
|
||||
sortOrder?: string | undefined | null,
|
||||
username?: string | undefined | null
|
||||
username?: string | undefined | null,
|
||||
/** eosio::name кошелька (`w.<contract>.<waltype>`) — для walletop действий. */
|
||||
walletName?: string | undefined | null
|
||||
};
|
||||
["GetLedgerHistoryInput"]: {
|
||||
/** ID счета для фильтрации. Если не указан, возвращаются операции по всем счетам */
|
||||
@@ -30065,7 +30073,7 @@ export type GraphQLTypes = {
|
||||
};
|
||||
["Ledger2Operation"]: {
|
||||
__typename: "Ledger2Operation",
|
||||
/** ID счёта/кошелька (×1000) */
|
||||
/** Бух.счёт (×1000): 51000/80000/86000 — для debit/credit действий. */
|
||||
accountId?: number | undefined | null,
|
||||
/** apply | walletop | debit | credit */
|
||||
action: string,
|
||||
@@ -30082,10 +30090,10 @@ export type GraphQLTypes = {
|
||||
/** Asset "100.0000 RUB" */
|
||||
quantity?: string | undefined | null,
|
||||
username?: string | undefined | null,
|
||||
/** walletop: wallet_from (исходящий) */
|
||||
walletFrom?: number | undefined | null,
|
||||
/** walletop: wallet_to (входящий) */
|
||||
walletTo?: number | undefined | null,
|
||||
/** walletop: wallet_from (eosio::name w.<contract>.<waltype>) */
|
||||
walletFrom?: string | undefined | null,
|
||||
/** walletop: wallet_to (eosio::name w.<contract>.<waltype>) */
|
||||
walletTo?: string | undefined | null,
|
||||
['...on Ledger2Operation']: Omit<GraphQLTypes["Ledger2Operation"], "...on Ledger2Operation">
|
||||
};
|
||||
["Ledger2Wallet"]: {
|
||||
@@ -30094,8 +30102,8 @@ export type GraphQLTypes = {
|
||||
available: string,
|
||||
/** Заблокированный баланс */
|
||||
blocked: string,
|
||||
/** ID кошелька (×1000 offset): 1001/2001/3001/4001 */
|
||||
id: number,
|
||||
/** eosio::name-идентификатор кошелька (w.<contract>.<waltype>) */
|
||||
id: string,
|
||||
/** Название кошелька */
|
||||
name: string,
|
||||
['...on Ledger2Wallet']: Omit<GraphQLTypes["Ledger2Wallet"], "...on Ledger2Wallet">
|
||||
@@ -32081,7 +32089,7 @@ export type GraphQLTypes = {
|
||||
getLedger2Accounts: Array<GraphQLTypes["Ledger2Account"]>,
|
||||
/** История операций ledger2 с серверными фильтрами (action/accountId/username/date-range). */
|
||||
getLedger2History: GraphQLTypes["Ledger2HistoryResponse"],
|
||||
/** Общекооперативные кошельки из ledger2::wallets (1001/2001/3001/4001). Кошельки пайщиков живут в контракте soviet — сюда не попадают. */
|
||||
/** Общекооперативные кошельки из ledger2::wallets (eosio::name w.<contract>.<waltype>). Кошельки пайщиков живут в контракте soviet — сюда не попадают. */
|
||||
getLedger2Wallets: Array<GraphQLTypes["Ledger2Wallet"]>,
|
||||
/** Получить историю операций по счетам кооператива. Возвращает список операций с возможностью фильтрации по account_id и пагинацией. Операции сортируются по дате создания (новые первыми). */
|
||||
getLedgerHistory: GraphQLTypes["LedgerHistoryResponse"],
|
||||
@@ -33691,14 +33699,14 @@ export type GraphQLTypes = {
|
||||
};
|
||||
["WalmoveInput"]: {
|
||||
coopname: string,
|
||||
/** id кошелька-источника */
|
||||
fromWallet: number,
|
||||
/** eosio::name кошелька-источника (w.<contract>.<waltype>) */
|
||||
fromWallet: string,
|
||||
/** Обязательное обоснование корректировки */
|
||||
memo: string,
|
||||
/** Сумма с символом, например "100.0000 RUB" */
|
||||
quantity: string,
|
||||
/** id кошелька-приёмника */
|
||||
toWallet: number,
|
||||
/** eosio::name кошелька-приёмника (w.<contract>.<waltype>) */
|
||||
toWallet: string,
|
||||
/** Владелец кошельков (для коллективных — coopname) */
|
||||
username: string
|
||||
};
|
||||
|
||||
Generated
+330
-72
@@ -1043,6 +1043,18 @@ importers:
|
||||
specifier: ^6.1.1
|
||||
version: 6.3.0
|
||||
|
||||
components/docs-harness:
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.59.1
|
||||
version: 1.59.1
|
||||
playwright:
|
||||
specifier: ^1.59.1
|
||||
version: 1.59.1
|
||||
sharp:
|
||||
specifier: ^0.34.5
|
||||
version: 0.34.5
|
||||
|
||||
components/factory:
|
||||
dependencies:
|
||||
ajv:
|
||||
@@ -4239,6 +4251,143 @@ packages:
|
||||
'@iconify/utils@3.1.0':
|
||||
resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==}
|
||||
|
||||
'@img/colour@1.1.0':
|
||||
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@inquirer/ansi@1.0.2':
|
||||
resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -4743,14 +4892,12 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@livekit/rtc-node-linux-x64-gnu@0.13.24':
|
||||
resolution: {integrity: sha512-vKOxzN/SsrtV8zIVwZCi31bZUhlb6RhJZ0NnY5MwKGSRFPi7Dwt8fmr0Vh0YmsY/p+4eZjKxvFmy7L3WVE54zw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@livekit/rtc-node-win32-x64-msvc@0.13.24':
|
||||
resolution: {integrity: sha512-yTzqwndq2oKLUkXW2i/BkZMJC6kZOpRO/DKvkkKQvqc3Q+JuWz1m48GmyjIwTOKF28QjqEU3+IrnD65Uu+mFOg==}
|
||||
@@ -5202,28 +5349,24 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@nx/nx-linux-arm64-musl@20.8.4':
|
||||
resolution: {integrity: sha512-AlZZFolS/S0FahRKG7rJ0Z9CgmIkyzHgGaoy3qNEMDEjFhR3jt2ZZSLp90W7zjgrxojOo90ajNMrg2UmtcQRDA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@nx/nx-linux-x64-gnu@20.8.4':
|
||||
resolution: {integrity: sha512-MSu+xVNdR95tuuO+eL/a/ZeMlhfrZ627On5xaCZXnJ+lFxNg/S4nlKZQk0Eq5hYALCd/GKgFGasRdlRdOtvGPg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@nx/nx-linux-x64-musl@20.8.4':
|
||||
resolution: {integrity: sha512-KxpQpyLCgIIHWZ4iRSUN9ohCwn1ZSDASbuFCdG3mohryzCy8WrPkuPcb+68J3wuQhmA5w//Xpp/dL0hHoit9zQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@nx/nx-win32-arm64-msvc@20.8.4':
|
||||
resolution: {integrity: sha512-ffLBrxM9ibk+eWSY995kiFFRTSRb9HkD5T1s/uZyxV6jfxYPaZDBAWAETDneyBXps7WtaOMu+kVZlXQ3X+TfIA==}
|
||||
@@ -5720,42 +5863,36 @@ packages:
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm-musl@2.5.6':
|
||||
resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-arm64-glibc@2.5.6':
|
||||
resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm64-musl@2.5.6':
|
||||
resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-x64-glibc@2.5.6':
|
||||
resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-x64-musl@2.5.6':
|
||||
resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-win32-arm64@2.5.6':
|
||||
resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
|
||||
@@ -5833,6 +5970,11 @@ packages:
|
||||
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
|
||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||
|
||||
'@playwright/test@1.59.1':
|
||||
resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@pm2/agent@2.0.4':
|
||||
resolution: {integrity: sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==}
|
||||
|
||||
@@ -5998,42 +6140,36 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.12':
|
||||
resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12':
|
||||
resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12':
|
||||
resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.12':
|
||||
resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.12':
|
||||
resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.12':
|
||||
resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==}
|
||||
@@ -6180,79 +6316,66 @@ packages:
|
||||
resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.0':
|
||||
resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.0':
|
||||
resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.0':
|
||||
resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.0':
|
||||
resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.0':
|
||||
resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.0':
|
||||
resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.0':
|
||||
resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.0':
|
||||
resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.0':
|
||||
resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.0':
|
||||
resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.0':
|
||||
resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.0':
|
||||
resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.0':
|
||||
resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==}
|
||||
@@ -7321,49 +7444,41 @@ packages:
|
||||
resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@unrs/resolver-binding-linux-arm64-musl@1.11.1':
|
||||
resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@unrs/resolver-binding-linux-ppc64-gnu@1.11.1':
|
||||
resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@unrs/resolver-binding-linux-riscv64-gnu@1.11.1':
|
||||
resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@unrs/resolver-binding-linux-riscv64-musl@1.11.1':
|
||||
resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@unrs/resolver-binding-linux-s390x-gnu@1.11.1':
|
||||
resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@unrs/resolver-binding-linux-x64-gnu@1.11.1':
|
||||
resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@unrs/resolver-binding-linux-x64-musl@1.11.1':
|
||||
resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@unrs/resolver-binding-wasm32-wasi@1.11.1':
|
||||
resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==}
|
||||
@@ -11135,6 +11250,11 @@ packages:
|
||||
fs@0.0.1-security:
|
||||
resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==}
|
||||
|
||||
fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
@@ -12904,28 +13024,24 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.32.0:
|
||||
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.32.0:
|
||||
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.32.0:
|
||||
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.32.0:
|
||||
resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
|
||||
@@ -14908,6 +15024,16 @@ packages:
|
||||
resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
playwright-core@1.59.1:
|
||||
resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.59.1:
|
||||
resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
plur@4.0.0:
|
||||
resolution: {integrity: sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -16113,56 +16239,48 @@ packages:
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-linux-arm@1.98.0:
|
||||
resolution: {integrity: sha512-03baQZCxVyEp8v1NWBRlzGYrmVT/LK7ZrHlF1piscGiGxwfdxoLXVuxsylx3qn/dD/4i/rh7Bzk7reK1br9jvQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-linux-musl-arm64@1.98.0:
|
||||
resolution: {integrity: sha512-LeqNxQA8y4opjhe68CcFvMzCSrBuJqYVFbwElEj9bagHXQHTp9xVPJRn6VcrC+0VLEDq13HVXMv7RslIuU0zmA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-musl-arm@1.98.0:
|
||||
resolution: {integrity: sha512-OBkjTDPYR4hSaueOGIM6FDpl9nt/VZwbSRpbNu9/eEJcxE8G/vynRugW8KRZmCFjPy8j/jkGBvvS+k9iOqKV3g==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-musl-riscv64@1.98.0:
|
||||
resolution: {integrity: sha512-7w6hSuOHKt8FZsmjRb3iGSxEzM87fO9+M8nt5JIQYMhHTj5C+JY/vcske0v715HCVj5e1xyTnbGXf8FcASeAIw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-musl-x64@1.98.0:
|
||||
resolution: {integrity: sha512-QikNyDEJOVqPmxyCFkci8ZdCwEssdItfjQFJB+D+Uy5HFqcS5Lv3d3GxWNX/h1dSb23RPyQdQc267ok5SbEyJw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-riscv64@1.98.0:
|
||||
resolution: {integrity: sha512-E7fNytc/v4xFBQKzgzBddV/jretA4ULAPO6XmtBiQu4zZBdBozuSxsQLe2+XXeb0X4S2GIl72V7IPABdqke/vA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-linux-x64@1.98.0:
|
||||
resolution: {integrity: sha512-VsvP0t/uw00mMNPv3vwyYKUrFbqzxQHnRMO+bHdAMjvLw4NFf6mscpym9Bzf+NXwi1ZNKnB6DtXjmcpcvqFqYg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-unknown-all@1.98.0:
|
||||
resolution: {integrity: sha512-C4MMzcAo3oEDQnW7L8SBgB9F2Fq5qHPnaYTZRMOH3Mp/7kM4OooBInXpCiiFjLnjY95hzP4KyctVx0uYR6MYlQ==}
|
||||
@@ -16335,6 +16453,10 @@ packages:
|
||||
shallowequal@1.1.0:
|
||||
resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
|
||||
|
||||
sharp@0.34.5:
|
||||
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
shebang-command@1.2.0:
|
||||
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -18862,7 +18984,7 @@ snapshots:
|
||||
'@stylistic/eslint-plugin': 2.13.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@vitest/eslint-plugin': 1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@1.6.1(@types/node@20.19.37)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1))
|
||||
'@vitest/eslint-plugin': 1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@1.6.1(@types/node@20.19.37)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1))
|
||||
eslint: 9.39.4(jiti@2.6.1)
|
||||
eslint-config-flat-gitignore: 0.1.8
|
||||
eslint-flat-config-utils: 0.3.1
|
||||
@@ -18879,7 +19001,7 @@ snapshots:
|
||||
eslint-plugin-regexp: 2.10.0(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-toml: 0.11.1(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-unicorn: 55.0.0(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-vue: 9.33.0(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-yml: 1.19.1(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-processor-vue-blocks: 0.1.2(@vue/compiler-sfc@3.5.31)(eslint@9.39.4(jiti@2.6.1))
|
||||
@@ -18927,7 +19049,7 @@ snapshots:
|
||||
eslint-plugin-regexp: 2.10.0(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-toml: 0.12.0(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-unicorn: 56.0.1(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-vue: 9.33.0(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-plugin-yml: 1.19.1(eslint@9.39.4(jiti@2.6.1))
|
||||
eslint-processor-vue-blocks: 1.0.0(@vue/compiler-sfc@3.5.31)(eslint@9.39.4(jiti@2.6.1))
|
||||
@@ -22140,6 +22262,102 @@ snapshots:
|
||||
'@iconify/types': 2.0.0
|
||||
mlly: 1.8.2
|
||||
|
||||
'@img/colour@1.1.0': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.9.1
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@inquirer/ansi@1.0.2': {}
|
||||
|
||||
'@inquirer/ansi@2.0.4': {}
|
||||
@@ -24359,6 +24577,10 @@ snapshots:
|
||||
|
||||
'@pkgr/core@0.2.9': {}
|
||||
|
||||
'@playwright/test@1.59.1':
|
||||
dependencies:
|
||||
playwright: 1.59.1
|
||||
|
||||
'@pm2/agent@2.0.4':
|
||||
dependencies:
|
||||
async: 3.2.6
|
||||
@@ -26291,18 +26513,6 @@ snapshots:
|
||||
vite: 8.0.3(@types/node@22.19.15)(esbuild@0.27.4)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
|
||||
vue: 3.5.31(typescript@5.9.3)
|
||||
|
||||
'@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@1.6.1(@types/node@20.19.37)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1))':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.57.2
|
||||
'@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
eslint: 9.39.4(jiti@2.6.1)
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
vitest: 1.6.1(@types/node@20.19.37)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0)(typescript@5.9.3)(vitest@4.1.1(@opentelemetry/api@1.9.1)(@types/node@20.19.37)(vite@8.0.3(@types/node@20.19.37)(esbuild@0.27.4)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.57.2
|
||||
@@ -26327,6 +26537,18 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@1.6.1(@types/node@20.19.37)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1))':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.57.2
|
||||
'@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
eslint: 9.39.4(jiti@2.6.1)
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
vitest: 1.6.1(@types/node@20.19.37)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)(vitest@2.1.9(@types/node@22.19.15)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.46.1))':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.57.2
|
||||
@@ -30600,12 +30822,6 @@ snapshots:
|
||||
semver: 7.7.4
|
||||
strip-indent: 3.0.0
|
||||
|
||||
eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@7.18.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)):
|
||||
dependencies:
|
||||
eslint: 9.39.4(jiti@2.6.1)
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
|
||||
|
||||
eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0):
|
||||
dependencies:
|
||||
eslint: 7.32.0
|
||||
@@ -31592,6 +31808,9 @@ snapshots:
|
||||
|
||||
fs@0.0.1-security: {}
|
||||
|
||||
fsevents@2.3.2:
|
||||
optional: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
@@ -36239,6 +36458,14 @@ snapshots:
|
||||
pvutils: 1.1.5
|
||||
tslib: 2.8.1
|
||||
|
||||
playwright-core@1.59.1: {}
|
||||
|
||||
playwright@1.59.1:
|
||||
dependencies:
|
||||
playwright-core: 1.59.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
plur@4.0.0:
|
||||
dependencies:
|
||||
irregular-plurals: 3.5.0
|
||||
@@ -37953,6 +38180,37 @@ snapshots:
|
||||
|
||||
shallowequal@1.1.0: {}
|
||||
|
||||
sharp@0.34.5:
|
||||
dependencies:
|
||||
'@img/colour': 1.1.0
|
||||
detect-libc: 2.1.2
|
||||
semver: 7.7.4
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.34.5
|
||||
'@img/sharp-darwin-x64': 0.34.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
'@img/sharp-linux-arm': 0.34.5
|
||||
'@img/sharp-linux-arm64': 0.34.5
|
||||
'@img/sharp-linux-ppc64': 0.34.5
|
||||
'@img/sharp-linux-riscv64': 0.34.5
|
||||
'@img/sharp-linux-s390x': 0.34.5
|
||||
'@img/sharp-linux-x64': 0.34.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.34.5
|
||||
'@img/sharp-linuxmusl-x64': 0.34.5
|
||||
'@img/sharp-wasm32': 0.34.5
|
||||
'@img/sharp-win32-arm64': 0.34.5
|
||||
'@img/sharp-win32-ia32': 0.34.5
|
||||
'@img/sharp-win32-x64': 0.34.5
|
||||
|
||||
shebang-command@1.2.0:
|
||||
dependencies:
|
||||
shebang-regex: 1.0.0
|
||||
|
||||
Reference in New Issue
Block a user