[CL-1176] Follow-up: E2E-сценарии (EURT/partial/refund/обратный матч) + toNum на availableShares #1187

Merged
andrei merged 2 commits from feature/claude-cl1176-followup into master 2026-07-22 16:29:35 +00:00
Owner

Что сделано

Два коммита, не попавшие в squash-мерж #1186 (запушены в ветку после мержа):

  1. 4 opt-in E2E-сценария (revert.e2e.scenarios.int.test.ts, гейт E2E_DATABASE_URL): EURT-цикл ходит по coinBalance и не трогает EUR; partial fill (SELL 10 / BUY 4) возвращает пропорциональный released-basis 700×4/10=280 и не реанимирует ACTIVE-ордер; price-improvement refund (resting SELL @90 vs BUY @100) даёт покупателю разницу 100 отдельной P2P_BUY-транзакцией и unwind сходится в ноль; обратное направление (resting BUY + taker SELL) симметрично.
  2. purchase.ts: единственный подтверждённый finding мульти-агентного свипа класса E2E-1 (11 агентов, 7 кандидатов, 6 опровергнуто адверсариальной проверкой) — oversell-guard сравнивал сырое availableShares из $queryRaw под лживым типом number. Фикс паттерном соседнего sharePrice: ::text + toNum(). Уточнён механизм в комментарии auto-match: в этом стеке raw NUMERIC — Prisma.Decimal-объект, следствия для isFinite-guard идентичны строке, toNum() покрывает оба.

Зачем

Закрывает хвост четвёртой адверсариальной проверки: непокрытые money-сценарии и последний экземпляр класса «raw NUMERIC без коэрции».

План тестирования

E2E: оба файла серийно на эфемерной БД из чистого prisma migrate deploy — 5 passed (5). Юнит: payment-stripe + p2p-trade 201 passed. tsc чист, eslint --max-warnings 0 чист.

Где могу ошибаться

  • Сценарии зависят от PLATFORM_FEE_RATE=0.02, заданного внутри теста — от прод-env не зависят.
  • purchase-фикс меняет только сравнение (числовая семантика идентична для валидных значений); поведенческий риск ~0, регрессии покрыты 201 юнитом payment-stripe/p2p-trade.
## Что сделано Два коммита, не попавшие в squash-мерж #1186 (запушены в ветку после мержа): 1. **4 opt-in E2E-сценария** (`revert.e2e.scenarios.int.test.ts`, гейт `E2E_DATABASE_URL`): EURT-цикл ходит по coinBalance и не трогает EUR; partial fill (SELL 10 / BUY 4) возвращает пропорциональный released-basis 700×4/10=280 и не реанимирует ACTIVE-ордер; price-improvement refund (resting SELL @90 vs BUY @100) даёт покупателю разницу 100 отдельной P2P_BUY-транзакцией и unwind сходится в ноль; обратное направление (resting BUY + taker SELL) симметрично. 2. **purchase.ts**: единственный подтверждённый finding мульти-агентного свипа класса E2E-1 (11 агентов, 7 кандидатов, 6 опровергнуто адверсариальной проверкой) — oversell-guard сравнивал сырое `availableShares` из $queryRaw под лживым типом `number`. Фикс паттерном соседнего sharePrice: `::text` + `toNum()`. Уточнён механизм в комментарии auto-match: в этом стеке raw NUMERIC — Prisma.Decimal-объект, следствия для isFinite-guard идентичны строке, toNum() покрывает оба. ## Зачем Закрывает хвост четвёртой адверсариальной проверки: непокрытые money-сценарии и последний экземпляр класса «raw NUMERIC без коэрции». ## План тестирования E2E: оба файла серийно на эфемерной БД из чистого prisma migrate deploy — 5 passed (5). Юнит: payment-stripe + p2p-trade 201 passed. tsc чист, eslint --max-warnings 0 чист. ## Где могу ошибаться - Сценарии зависят от PLATFORM_FEE_RATE=0.02, заданного внутри теста — от прод-env не зависят. - purchase-фикс меняет только сравнение (числовая семантика идентична для валидных значений); поведенческий риск ~0, регрессии покрыты 201 юнитом payment-stripe/p2p-trade.
Четыре opt-in интеграционных сценария поверх базового E2E (реальная БД,
без моков): EURT ходит по coinBalance и не трогает EUR-балансы; partial
fill возвращает пропорциональный released-basis (700×4/10=280) и не
реанимирует ACTIVE-ордер; price-improvement refund (resting SELL @90 vs
BUY @100) даёт покупателю разницу 100 отдельной P2P_BUY транзакцией и
полный unwind сходится в ноль; taker-SELL против resting BUY симметричен.
Все прогоны зелёные на эфемерной БД из чистого prisma migrate deploy.
[CL-1176] purchase: toNum на availableShares из raw (свип класса E2E-1)
All checks were successful
CI / Telegram Mini App (pull_request) Successful in 1m55s
CI / Python SDK (pull_request) Successful in 29s
CI / Contracts (pull_request) Successful in 2m37s
CI / Secrets Scan (pull_request) Successful in 24s
CI / Prisma Migrate Gate (pull_request) Successful in 1m45s
CI / API (pull_request) Successful in 19m8s
CI / App (pull_request) Successful in 19m53s
60bab13634
Мульти-агентный свип всех raw-SQL в api/src на класс бага E2E-1
(NUMERIC из $queryRaw приходит не-number): 7 кандидатов, 6 опровергнуты
адверсариальной проверкой (сравнения/increment корректны для Decimal),
1 подтверждён latent type-lie — oversell-guard purchase.ts:251 сравнивал
сырое значение под лживым типом number. Фикс паттерном соседнего
sharePrice: ::text каст + toNum(). Уточнён механизм в комментарии
auto-match: в этом стеке raw NUMERIC — Prisma.Decimal-объект (не строка),
следствия для isFinite-guard идентичны, toNum() покрывает оба типа.
andrei scheduled this pull request to auto merge when all checks succeed 2026-07-22 16:27:36 +00:00
andrei merged commit f5aa29dc63 into master 2026-07-22 16:29:35 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
europa-tech-srl/europatech!1187
No description provided.