Feature: Pair search combobox with relevance + liquidity ranking #314
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#314
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Current codebase
Frontend: Trading flows use a dropdown (
MenuSelect) listing all pairs:TradePage.tsx—pairInfosToMenuSelectOptions(pairs)LimitOrdersPage.tsx— sameChartsPage.tsx—indexerPairsToMenuSelectOptionswith sort controlsLabels from
frontend-dapp/src/utils/pairMenuOptions.ts(SYMBOL_A / SYMBOL_B — addr).Indexer:
GET /api/v1/pairs?q=already supports substring search across pair address, token symbols, contract addresses, denoms (indexer/src/db/queries/pairs.rspush_pair_list_filters). Sort options:id,fee,created,symbol,volume_24h— no relevance ranking.Search does not parse pair symbols like
LUNC USTC/ token names distinctly; no tiered relevance buckets; no liquidity tie-break within bucket.Why this is needed
Factory pair count grows in QA/prod. Dropdown scrolling does not scale. Users need fast discovery by:
XXX YYYwhere XXX/YYY match symbol or name)Results should rank by match quality (buckets 1–5), then liquidity (24h volume or pool depth) within bucket.
Constraints / guardrails
terra1…address.qlength stays ≤128 (PAIR_LIST_Q_MAX_LEN).PAIR_LIST_OFFSET_MAX).InvalidPairLinkNotice).Relevant files
TradePage.tsx,LimitOrdersPage.tsx,ChartsPage.tsxfrontend-dapp/src/components/trade/PairSearchSelect.tsxfrontend-dapp/src/utils/pairMenuOptions.tsindexer/src/api/pairs.rs,indexer/src/db/queries/pairs.rsindexer/tests/api_pairs.rs,frontend-dapp/src/utils/__tests__/pairMenuOptions.test.tsfrontend-dapp/src/types/index.ts(IndexerPair)Recommended direction
Indexer
list_pairs_filteredwith relevance scoring SQL (CASE tiers):XXX/YYYsymbol pair matchORDER BY relevance DESC, COALESCE(pv.volume_quote,0) DESC, p.id ASCsort=relevance(default whenqpresent).Frontend
MenuSelectpair picker with searchable combobox calling/api/v1/pairs?q=&sort=relevance&limit=20.pairListBadges.tsif applicable).Acceptance criteria
volume_24hpair ranks first.Test plan (all paths)
terra1…pairLUNCLUNC USTClunzzzzzAttack / abuse / hack vectors
qVerification criteria
make test-frontend+ indexerapi_pairstests green.mentioned in commit
23c85e4685mentioned in commit
5a873ad3d2mentioned in commit
9a90f96ec1mentioned in merge request !792
Implementation complete in MR !792: https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/74
What changed
sort=relevancewith tiered match scoring + 24h volume tie-break; token name and two-token pair symbol filters.PairSearchSelectcombobox on Trade and Limit Orders (debounced indexer search, factory gate, outage fallback, volume badges).docs/frontend.md§ Pair search combobox invariants.Verification
cargo test --test api_pairs list_pairs_relevance_ordering -- --test-threads=1PairSearchSelectdefaultvolume_24h descmake test-frontend(832 passed)make lint-frontend(0 errors)Issue left open until manual QA matrix and a11y spot check on a LocalTerra deploy with ≥6 pairs.
mentioned in commit
43c56c4ea5Verification — GitLab #314 (agent:verify)
Issue: https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/314
Branch verified:
main@c179fa9(MR !792 merged)LocalTerra:
make setup-cloud-localterra— 50 factory pairs indexedAcceptance criteria
PairSearchSelectinTradePage.tsx/LimitOrdersPage.tsx; Charts keepsMenuSelect. Playwrighte2e/limit-orders.spec.ts—role="combobox", no native<select>.curl/ Python againsthttp://127.0.0.1:3001): pair addr, token addr, symbol, pair symbols (EMBER CORAL), substring (emb) — all top hits sensible. Token name tier: SKIP — deploy QA tokens have emptynamein indexer (name=''for all assets); tier-2 not exercisable on this stack.volume_24hfirstcargo test --test api_pairs list_pairs_relevance_ordering -- --test-threads=1(LUNC symbol tier orders high-vol pair before low-vol pair). Live deploy: SKIP tie-break observation — all pairsvolume_quote_24h = 0post-deploy.PairSearchSelectusessort=volume_24h&order=descwhenqempty; opening combobox on/limitslists 20 factory pairs sorted by indexer volume.cargo test --test api_pairs -- --test-threads=1— 15/15 includinglist_pairs_relevance_ordering.Verification criteria
make test-frontendmake lint-frontendapi_pairsEMBER CORALselects first option)#trade-pair-select/#limit-pairhaverole="combobox",aria-expanded, portaledrole="listbox"; keyboard handlers (Arrow/Enter/Escape) inPairSearchSelect.tsx; docsfrontend.md§ Pair search combobox invariantsTest plan extras
zzzzz)/limitswith no pair selected → “No pairs match your search”EMBERin#limit-pair→ “No pairs match your search” (0 options). Expected per issue: degradedfilterPairsByLocalSearchon cached factory labels. Empty-query fallback works; non-empty query fallback does not. Repro: stop indexer tmux session,make dev, open/limits, click pair combobox, typeEMBER./tradeauto-selects a pair; selected pair remains visible during non-matching search (by design inPairSearchSelect— prepends current selection).Follow-up
PairSearchSelect.tsx—pairsQuery.isError+ non-emptydebouncedSearchshould populatefilterPairsByLocalSearchresults; currently returns empty after failed search query).Verification incomplete due to FAIL above — issue remains open.
mentioned in issue #328
marked as related to #328
mentioned in commit
9e7b280513mentioned in merge request !811
Implementation follow-up (#314)
MR !811: https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/93
Fixes verification FAIL: indexer stopped + typed pair search on Trade/Limits combobox.
Root cause
Degraded fallback only matched menu label substrings. Factory labels often use shortened contract addresses (symbols live in
getTokenDisplaySymbol/ registry, not always in the visible label). After the first indexer error, non-empty queries still hit the indexer path and returned empty options.Fix
indexerUnavailableafter firstgetPairsfailure; usefilterFactoryPairsByLocalSearch(symbols, contracts, pair addr,XXX YYYqueries).PairSearchSelect.test.tsx, extendedpairSearchQuery.test.ts.Verification
PairSearchSelect.test.tsxmake test-frontendmake lint-frontendapi_pairsIssue remains open until MR merges and optional manual degraded search spot-check on LocalTerra.
mentioned in commit
fd54fb6ce2mentioned in merge request !812
mentioned in commit
2d1415913cmentioned in merge request !825
mentioned in issue #301
mentioned in commit
2c1a08c30fmentioned in commit
938706dc65mentioned in commit
96be3ab6c5mentioned in commit
e59f9800fementioned in commit
995674b775mentioned in commit
995674b775mentioned in issue #481