Skip to content

Commit df8856e

Browse files
authored
feat: restore site-wide vault search
## Why The previously hidden site search depended on an external entity index and did not cover the vault data users browse on the site. ## Lessons learnt A custom server-side index can reuse the cached vault and stablecoin data without exposing matching aliases to the browser. Reusing the existing responsive listing table keeps search aligned with curator, stablecoin, protocol and chain pages. ## Summary - Restore desktop and mobile search with debounced typeahead. - Add server-side search for vaults, curators, protocols, stablecoins and chains, including address lookup and blacklisted-vault treatment. - Reuse responsive listings, add desktop vault mini-maps, SEO metadata, documentation and Playwright coverage.
1 parent 562b011 commit df8856e

56 files changed

Lines changed: 1907 additions & 2255 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
TS_PUBLIC_BACKEND_URL=https://tradingstrategy.ai/api
2727
TS_PUBLIC_GHOST_API_URL=https://trading-strategy.ghost.io
2828
TS_PUBLIC_GHOST_CONTENT_API_KEY=4f54e499a627473f560945d524
29-
TS_PUBLIC_TYPESENSE_API_URL=https://typesense3.tradingstrategy.ai
30-
TS_PUBLIC_TYPESENSE_API_KEY=poBMapJFGbKw9pJ634QWCrlwbbr9w2V2
3129
TS_PUBLIC_DISCORD_URL=https://discord.gg/5M88m9nM8H
3230
TS_PUBLIC_WALLET_CONNECT_PROJECT_ID=9ee7efad98897eb60ba023db6aa72355
3331
TS_PUBLIC_TURNSTILE_SITE_KEY=""
@@ -107,4 +105,4 @@ TS_PRIVATE_VAULT_PRICES_PARQUET_URL=""
107105
#
108106
# Put private data to .env.local
109107
#
110-
###############################################################
108+
###############################################################

.env.dev

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
TS_PUBLIC_FRONTEND_VERSION_TAG=dev
1313
TS_PUBLIC_BACKEND_URL=http://localhost:5173/api
14-
TS_PUBLIC_TYPESENSE_API_URL=http://localhost:5173/api/typesense
1514
TS_PRIVATE_ADMIN_PW=youbetcha # to match normal development value
1615

1716
TS_PUBLIC_STRATEGIES=`[

.env.test

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
TS_PUBLIC_FRONTEND_VERSION_TAG=test
1313
TS_PUBLIC_BACKEND_URL=http://localhost:4173/api
14-
TS_PUBLIC_TYPESENSE_API_URL=http://localhost:4173/api/typesense
1514
TS_PRIVATE_TOP_VAULTS_URL=http://localhost:4173/api/top-vaults/vaults.json
1615
TS_PUBLIC_VAULT_SPARKLINES_URL=http://localhost:4173/api/top-vaults/sparklines
1716
TS_PUBLIC_VAULT_API_URL=http://localhost:4173/api

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Weblog of stuff
22

3+
- Restore site-wide vault search with server-side vault JSON indexing, typeahead and responsive result listings, replacing the retired external integration (2026-07-30)
34
- Rank strategy vaults by displayed annual return within green and red chart groups, and clarify the strategy listing description (2026-07-28)
45
- Add ApeX perpetual futures DEX support — chain logo and entry, perp DEX detection, "Any" default TVL filter on the protocol page, and perp DEX wording in chain descriptions (2026-07-25)
56
- Add tokenised fund listings, NAV market-share chart, and fund-specific vault detail messaging (2026-07-17)

docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ services:
2828
- TS_PUBLIC_SENTRY_DSN
2929
- TS_PUBLIC_GHOST_CONTENT_API_KEY
3030
- TS_PUBLIC_GHOST_API_URL
31-
- TS_PUBLIC_TYPESENSE_API_KEY
32-
- TS_PUBLIC_TYPESENSE_API_URL
3331
- TS_PUBLIC_DISCORD_URL
3432
- TS_PUBLIC_TURNSTILE_SITE_KEY
3533
- TS_PUBLIC_STRATEGIES

docs/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ This project uses Svelte 5 with experimental features enabled in `svelte.config.
3131
- `helpers/` - Utility functions (formatters, date, financial calculations, etc.)
3232
- `schemas/` - Zod validation schemas
3333
- `explorer/` - Market data exploration features
34-
- `search/` - Search functionality
34+
- `search/` - Server-side vault search
3535
- `blog/` - Blog/Ghost CMS integration
3636
- Other feature-specific directories (wizard, breadcrumb, header, etc.)
3737
- `src/params/` - SvelteKit parameter matchers for routes

docs/dependencies.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ This document lists key dependencies used in the Trading Strategy frontend appli
2121
| Service | Purpose |
2222
| ---------------------------- | -------------------------------- |
2323
| Ghost CMS | Blog content |
24-
| Typesense | Search functionality |
2524
| Trading Strategy backend API | Core data and trading operations |
2625

2726
## Build and dev tools

docs/search.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Search
2+
3+
## Overview
4+
5+
The site-wide vault search is implemented in SvelteKit and searches the vault JSON data already used by the frontend.
6+
7+
Search is available from the desktop navigation, the compact mobile navigation and the server-rendered [`/search`](/search) page. The full results page is a normal GET form, so links such as `/search?q=USDC` work without client-side JavaScript.
8+
9+
## Searchable entities and results
10+
11+
The server-only index in `src/lib/search/vault-search.server.ts` creates records for:
12+
13+
- vaults, including case-insensitive contract-address matching;
14+
- curators;
15+
- protocols;
16+
- stablecoins; and
17+
- chains.
18+
19+
Blacklisted vaults remain findable but are shown as the distinct **Blacklisted vault** type, with a struck-through name. They sort after non-blacklisted matches. Vault names show the first eight hexadecimal digits of the address after `0x`.
20+
21+
Every result provides a name, entity type, one-month APY, latest TVL, canonical destination and logo URL. Aggregate entity metrics use eligible, non-blacklisted vaults and USD-normalised TVL. One-month APY is TVL-weighted and excludes invalid or extreme values through the same helper used by vault listings.
22+
23+
Results sort by relevance first, then latest TVL descending and name ascending. The full results table starts sorted by latest TVL, with blacklisted vaults still placed last. The typeahead diversifies the initial suggestions by entity type before filling any remaining positions.
24+
The results page returns at most 100 rows and explicitly reports when a broader query has been truncated.
25+
26+
## Typeahead
27+
28+
`src/lib/search/components/Search.svelte` sends a request to `/search/suggestions` after a 200 ms debounce. It cancels the preceding request and ignores stale responses. The endpoint caps requests at 20 results (the widget asks for 10) and queries at 100 characters.
29+
30+
Keyboard navigation follows the combobox pattern: Arrow keys choose a suggestion, Enter opens the selected result or submits the query, and Escape closes the quick search. On mobile, the widget opens as a full-height dialog and restores focus to its trigger when closed. The dialog is layered above page content and only the mobile dialog locks body scrolling.
31+
On desktop, interacting outside the search closes the quick-results panel.
32+
33+
Desktop vault suggestions and full results show the 90-day price mini-map when chart data is available. Aggregate entities do not show a mini-map.
34+
35+
## Data and caching
36+
37+
The index combines `getCachedTopVaults()` with stablecoin metadata. It is held in server memory for two minutes and is rebuilt early when the vault dataset's `generated_at` value changes. The suggestions response is publicly cacheable for 60 seconds.
38+
39+
The browser receives only public `SearchResult` fields. Matching aliases and normalised search terms remain server-side.
40+
41+
## SEO
42+
43+
The bare `/search` page is included in the static sitemap and `robots.txt` advertises the sitemap. Query-result URLs include `noindex,follow` and use `/search` as their canonical URL, preventing arbitrary query pages from competing in search results while allowing the search page itself to be discovered.
44+
45+
The home page retains WebSite `SearchAction` structured data pointing to `/search?q={search_term_string}`. Google no longer presents a visual sitelinks search box from this markup, but the query URL remains accurate structured-data metadata.
46+
47+
## Tests
48+
49+
`tests/integration/search.test.ts` covers desktop and mobile typeahead, the mobile navigation drawer, the result page, address lookup, blacklisted vault treatment, sortable entity types, desktop-only mini-maps, and all supported entity types. Vault-listing integration tests confirm the old in-listing search control remains absent.
50+
51+
Use:
52+
53+
```shell
54+
pnpm exec playwright test --config tests/integration/playwright.config.ts tests/integration/search.test.ts
55+
```

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
"svelte-check": "^4.4.3",
5555
"typescript": "^5.9.3",
5656
"typescript-eslint": "^8.56.0",
57-
"typesense": "^2.1.0",
5857
"unplugin-icons": "^22.5.0",
5958
"vite": "^7.3.1",
6059
"vite-plugin-devtools-json": "^0.3.0",

pnpm-lock.yaml

Lines changed: 21 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)