Skip to content

feat(exchange): двунаправленная котировка — PHP→RUB авто без оператора (#741)#755

Merged
chatman-media merged 1 commit into
mainfrom
claude/exchange-bidi-quote-741
Jun 20, 2026
Merged

feat(exchange): двунаправленная котировка — PHP→RUB авто без оператора (#741)#755
chatman-media merged 1 commit into
mainfrom
claude/exchange-bidi-quote-741

Conversation

@chatman-media

Copy link
Copy Markdown
Owner

Closes #741 · фоллоу-ап к #729

Движок котировок был одно-направленным (computeQuote всегда asset→валюта тенанта). Теперь поддержаны обратные пары (PHP→RUB) — клиент получает котировку и оформляет заявку без оператора. tech-lead-план в комментарии issue.

Подход (Вариант A)

Валюта выдачи резолвится из найденной rate-row, не угадывается LLM: тул передаёт asset + опц. payoutAsset, computeQuote берёт quoteAsset из строки. Фид не котирует PHP как source → обратные строки autoUpdate:false (ручной base) + своя relative-карта (не инверсия 1/eff).

Что в PR

  • rates.ts: computeQuote принимает payoutAsset, резолвит quoteCode (явная выдача → валюта тенанта = прежнее поведение). listActiveDirections без фильтра по валюте тенанта, ключ по паре asset|quoteAsset → обе стороны видны. formatDirectionsForClient суффикс per-direction.
  • tools.ts: payoutAsset в compute_exchange_quote/create_exchange_order (+ quoteAsset в idempotencyKey — иначе RUB→PHP и PHP→RUB на одну сумму схлопнулись бы), quote-revive по направлению заявки, list_exchange_directions отдаёт quoteAsset per-direction.
  • fixtures.ts: строка php_to_rub (multiply, baseRate 1.43 RUB/PHP, autoUpdate:false) + relative-карта с отрицательным deviation (спред обменнику, сужается на крупных).

Тесты

  • Обратная котировка PHP→RUB (direction/quoteAsset/multiply) + anti-1/eff round-trip: вернув полученные песо, клиент получает меньше рублей, чем отдал (обменник не в убытке).
  • Регрессия: прямой RUB→PHP без payoutAsset и THB-тенанты не меняются.
  • Весь exchange-сьют 202/0, typecheck чист.

Ограничения (v1)

Тиры обратной пары через RateCardEditor пока не редактируются (он RUB/USDT-source-only) — правятся сидом. Авто-rate-card для PHP-source — отдельный follow-up (нужен PHP-source в фиде).

Refs: эпик #728.

🤖 Generated with Claude Code

#741)

Движок котировок был одно-направленным (всегда asset→валюта тенанта).
Вариант A: резолв валюты выдачи из найденной rate-row (не аргумент LLM).

- rates.ts: computeQuote принимает payoutAsset, резолвит quoteCode (сперва
  явная валюта выдачи, потом валюта тенанта — прежнее поведение); тиры/direction/
  результат по quoteCode. listActiveDirections без фильтра по валюте тенанта,
  ключ по паре asset|quoteAsset → обе стороны видны. formatDirectionsForClient
  суффикс per-direction.
- tools.ts: payoutAsset в compute_exchange_quote/create_exchange_order
  (+ quoteAsset в idempotencyKey — иначе RUB→PHP и PHP→RUB схлопнулись бы),
  quote-revive по направлению заявки, list_exchange_directions отдаёт quoteAsset
  per-direction + обновлённое описание.
- fixtures.ts: строка php_to_rub (multiply, baseRate 1.43 RUB/PHP, autoUpdate:false —
  фид PHP-source не умеет) + своя relative-карта (отрицательный deviation, НЕ
  инверсия 1/eff — спред в пользу обменника на обеих сторонах).

Тесты: обратная котировка PHP→RUB + anti-1/eff round-trip; регрессия RUB→PHP и
THB-тенантов. Весь exchange-сьют 202/0, typecheck чист.

Closes #741

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.63%. Comparing base (69ea866) to head (64de467).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #755   +/-   ##
=======================================
  Coverage   98.63%   98.63%           
=======================================
  Files         332      332           
  Lines       39848    39920   +72     
=======================================
+ Hits        39305    39377   +72     
  Misses        543      543           
Components Coverage Δ
apps/api 98.31% <100.00%> (+0.01%) ⬆️
apps/worker 99.91% <ø> (ø)
apps/vertical-* 100.00% <ø> (ø)
kb 99.64% <ø> (ø)
sales 99.74% <ø> (ø)
conversation-engine 97.65% <ø> (ø)
llm-router 100.00% <ø> (ø)
storage 99.88% <ø> (ø)
verticals 94.77% <ø> (ø)
channels (telegram/whatsapp/facebook/web/core) 99.37% <ø> (ø)
observability 98.71% <ø> (ø)
Files with missing lines Coverage Δ
apps/api/src/lib/exchange/fixtures.ts 99.49% <100.00%> (+0.02%) ⬆️
apps/api/src/lib/exchange/rates.ts 98.64% <100.00%> (+0.06%) ⬆️
apps/api/src/lib/exchange/tools.ts 95.64% <100.00%> (+0.07%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chatman-media chatman-media merged commit b6b9ecc into main Jun 20, 2026
23 checks passed
@chatman-media chatman-media deleted the claude/exchange-bidi-quote-741 branch June 21, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(exchange): двунаправленная котировка — выдача не только в валюте тенанта (PHP→RUB)

1 participant