Commit Graph

27 Commits

Author SHA1 Message Date
k 3f35a3fba2 feat(ui): visually de-emphasise off-topic Trump posts in the feed
Follow-up to fe88acb. Noise posts (not crypto-relevant, never AI-scored) now
read as 'skip me' at a glance in the list — no need to open them:

- sentiment chip → muted 'off-topic · not crypto' tag (was a colored chip)
- post text → dimmer (ink-4) + shorter preview (90 vs 180 chars)
- aside → single muted 'SKIPPED' tag instead of HOLD pill + empty AI metric

Scored posts (real crypto signals) are visually unchanged — full signal pill,
target chip, impact, and AI confidence.

tsc + build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 03:19:31 +08:00
k fe88acb5a0 fix(ui): don't show misleading 0% AI bar on off-topic Trump posts
Most Trump posts aren't crypto-related, so the entry filter / AI marks them
relevant=false with ai_confidence=0 and no reasoning (never AI-scored). The
post card still rendered 'AI confidence 0%' with an empty progress bar, which
reads as 'AI looked and was 0% confident' rather than the truth: 'skipped as
not crypto-relevant'.

Added an aiScored guard (ai_confidence > 0 || ai_reasoning present):
- collapsed row: shows AI '—' instead of '0%' for unscored posts
- expanded detail: shows 'Not crypto-relevant — skipped AI scoring' instead
  of an empty 0% confidence bar

Scored posts (the ~80 with confidence>0 in test data, and all real signals
once live) are unchanged — full bar + reasoning shown.

tsc + build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 03:16:35 +08:00
k aa6ede051e feat(seo/geo): Dataset + Article + BreadcrumbList structured data, noindex archive
GEO (AI answer engines) — make the signal feeds and case studies machine-citeable:
- Dataset JSON-LD on /trump, /kol, /trades (creator=Endorphin, publisher→#org,
  isAccessibleForFree, temporalCoverage). These are the "data/history/track
  record" entities Perplexity/Gemini/ChatGPT cite.
- case-studies: ItemList of 5 Article nodes, each with headline/description/
  articleBody/about + citation→evidence URL + author=Endorphin. ISO dates
  derived where parseable, omitted for vague labels.
- public/llms-full.txt: single-doc full reference (methodology + glossary +
  case studies w/ sources inlined) for one-fetch AI ingestion; linked from llms.txt.

SEO:
- Breadcrumbs component (components/seo/Breadcrumbs.tsx) → BreadcrumbList JSON-LD
  on the 8 indexable content pages (trump/kol/macro/trades/analytics/
  methodology/glossary/case-studies).
- /archive split into server page + ArchivePageClient; server page sets
  robots noindex (legacy/test data — thin-content risk).
- openGraph added to /trades and /analytics (previously meta+canonical only).

Verified: tsc 0 errors, next build passes, runtime curl confirms all JSON-LD
types render and llms-full.txt serves 200. No trading/API/component-logic changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 03:08:59 +08:00
k f8805f5ba6 fix(dashboard): label 30d Performance tile as 'live net P&L (real trades only)'
Clarifies that the homepage Performance tile reflects only real-money trades
(backend /performance now excludes paper by default). Prevents a paper-only
user from being confused by a $0 headline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 03:04:38 +08:00
k 7368b20318 feat(copy): reposition as Endorphin research desk, de-emphasize AI
Shift sitewide voice from "AI-scored signal tool" to "Endorphin — a crypto
research desk with a real edge". AI drops to the methods layer; "public +
timestamped calls" becomes the credibility/viral hook.

- layout.tsx: new tagline ("signals that move price before the crowd"),
  description rewritten (drops "scored by AI"); Organization JSON-LD is now
  Endorphin with Trump Alpha as its brand; SoftwareApplication gains
  publisher/author → #org; metadata creator/publisher → Endorphin.
- [locale]/page.tsx: home title "Live Crypto Signal Desk" + new description.
- DashboardClient.tsx: hero subtitle rewritten with viral hook.
- methodology intro: prepend Endorphin "research project not a marketing
  funnel" line; keep the "live production logic" credibility line.
- [locale]/layout.tsx footer: "© Trump Alpha — a research project by Endorphin".
- llms.txt + opengraph-image: synced to the same positioning (per CLAUDE.md).

tsc clean, next build passes. Functional names (Macro Vibes/KOL/6 engines)
unchanged to avoid SEO/llms.txt drift. No trading/API/component changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 01:04:22 +08:00
k 594d9817ba fix(analytics): never mix paper + live P&L; settings live-switch copy
Money-safety/accuracy bug: analytics computed total P&L, win rate, drawdown,
and every metric over ALL trades regardless of is_paper. A user who tried
paper mode then went live saw simulated and real P&L summed into one number
on the page whose entire purpose is 'did the bot make REAL money'.

Now: split trades by is_paper. Default to LIVE. A Live/Paper toggle appears
only when the wallet has both; otherwise auto-pick whichever exists. Paper
view shows a prominent 'SIMULATED — not real-money results' banner. All
metrics derive from the selected mode's trades only.

Also: BotConfigPanel handleUpgradeToLive copy now states Auto-Trade is forced
OFF on the paper→live switch (matches backend subscribe.py safety reset).

tsc + next build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 01:03:15 +08:00
k e78a61bd6e fix(settings/analytics): canonical /en/, precise anchor navigation, scope card copy
Canonical URL fixes (parity with trump/macro/kol done earlier):
- analytics/page.tsx: canonical was `${siteUrl}/${locale}/analytics` → /en/
- settings/page.tsx:  canonical was `${siteUrl}/${locale}/settings`  → /en/

Settings scope card anchor navigation:
- Three scope cards ('Trump Signal ↓', 'Macro Vibes ↓', 'Global ↓') all
  pointed to #bot-config — same destination, no differentiation. Renamed:
  #config-trump / #config-macro / #config-global.
- Added matching id='config-trump/macro/global' to the three sections in
  BotConfigPanel so the anchors actually land at the right section.
- Removed misleading 'tab' wording ('Trump Signal tab ↓') — BotConfigPanel
  is not a tab component; it's a single-page vertical form. Copy now reads
  'Configure Trump ↓' etc.
- SystemControl already links to settings#bot-config which still resolves
  (the outer #bot-config wrapper div in SettingsClient is unchanged).

tsc + next build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 00:56:59 +08:00
k 3cf7de7144 feat(seo/geo): WebSite+SearchAction, HowTo, DefinedTermSet, TechArticle, 20+ AI crawlers
SEO structured data (layout.tsx):
- WebSite schema with potentialAction/SearchAction → enables sitelinks
  search box in Google results
- SoftwareApplication: added alternateName array, applicationSubCategory,
  isAccessibleForFree, availability, screenshot, aggregateRating, expanded
  featureList with specifics
- Organization: added logo, contactPoint
- HowTo schema (6 steps, estimatedCost $0, tools list) for "how to set up
  Trump Alpha auto-trader" — gets HowTo rich result + cited by AI assistants
- DefinedTermSet in root layout (AHR999, Pi Cycle, Talks-vs-Trades, Funding
  Reversal) — LLMs use this for entity definitions
- FAQPage: added 6 search-intent questions ("how do I auto trade trump tweets",
  "bot that trades based on Trump posts", "how to know if KOL is dumping",
  "best time to buy Bitcoin in bear market", "what is AHR999", "funding rate")
- All uses of siteUrl + today refactored to _base/_today constants

Per-page structured data:
- methodology/page.tsx: TechArticle JSON-LD (headline, about[], author, dateModified)
- glossary/page.tsx: DefinedTermSet with all terms + URL anchors per term;
  buildGlossaryJsonLd() generates one DefinedTerm per entry; canonical fixed
  to /en/ (was /${locale}/)

Missing metadata added:
- contact: metadata with robots noindex (no SEO value in contact form)
- privacy: metadata + canonical /en/privacy
- terms: metadata + canonical /en/terms

robots.ts — 20+ AI crawler rules:
Added: OAI-SearchBot, Google-Extended, Googlebot-Extended,
meta-externalagent, FacebookBot, Applebot, Applebot-Extended,
cohere-ai, MistralAI-User, YouBot, Brave, CCBot, Slurp, DuckDuckBot,
YandexBot. Now covers Gemini/Google AI Overviews, Meta AI, Apple Siri,
Cohere, Mistral, Brave Leo, and Common Crawl training datasets.

tsc + next build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:04:40 +08:00
k be151edf6e fix(seo/geo): canonical URLs, OG KOL count, FAQ key-storage copy, expand llms.txt
SEO fixes:
- canonical on trump/macro/kol pages now hardcodes /en/ instead of
  /${locale}/ — prevents /zh/* routes (i18n shelved, routes still resolve)
  from generating duplicate-content signals pointing to /zh/ canonicals
- OG image: "15 KOL feeds" → "19" (matches kol_substack.py KOL_FEEDS count)
- FAQ JSON-LD: corrected API key storage description ("stored encrypted in
  your browser's local settings" was wrong — key is server-side encrypted,
  not stored in the browser)

GEO (Generative Engine Optimization):
- llms.txt fully rewritten: +full KOL list (all 19 named), +explicit
  differentiation section, +who-this-is-for, +technology stack detail
  (model names, price sources, DB), +Hyperliquid and isolated-margin
  definitions. AI crawlers (Perplexity, ChatGPT, Claude) use this file
  directly when answering questions about the product.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 16:56:53 +08:00
k a8522a2bf8 fix: Macro fetches by source, Analytics single-basis stats, funding venue label
- Macro page fetches getPosts(200, 1, source) per active tab instead of
  filtering the latest-500 global feed — rare bottom/funding signals no longer
  vanish behind Trump posts (backend now supports ?source=).
- Analytics: compute ALL time windows from the one closed_at-filtered trades
  list; dropped the 30d-only backend /performance special-case that mixed an
  opened_at basis into the same screen as the closed_at metric grid. Trade
  fetch raised 100→500 so the local computation covers ample history.
- Funding panel shows snap.venue (capitalized) instead of hardcoded "Binance".
- lib/api: getPosts gains optional source param; FundingSnapshot gains venue.

tsc + next build clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:15:41 +08:00
k 3ac1431336 fix(analytics): in-page unlock for private performance (parity with trades)
The analytics page had the same view-envelope gap just fixed on the trades
page: a connected wallet that hadn't first visited Settings only saw "Private
performance is locked" with no way to unlock in place. Added an "Unlock
performance" button that mints a view_user envelope (one signature, no gas) —
which both /performance and /trades accept — then reloads. Public
signal-accuracy still loads regardless. Refactored the loader to a reusable
loadAll(forcedEnv?) with an aliveRef guard, mirroring TradesPageClient.

Verified backend contracts unchanged: /performance accepts view_performance
or view_user; /signals/accuracy still returns overall + by_signal +
total_directional_signals. tsc + next build clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:07:06 +08:00
k b2b96bb9c0 fix: Macro panel manage-only (not auto-open), Trump-only auto-trade copy, store docs
SystemControl was rendered as two per-system panels (Trump / Macro) that both
flipped the SAME global auto_trade, and its copy claimed a "qualifying Macro
Vibes signal auto-opens a trade". Both are wrong: bot_engine.process_post
early-returns for System 2, so the auto_trade gate only ever fires for Trump
(System 1). Macro Vibes is manage-only — it never auto-opens.

- Macro (`system="btc"`) panel: replaced the misleading Auto-Trade ON/OFF
  toggle with a manage-only explainer (open on HL → /adopt via Telegram → bot
  manages exits) and a note that the Trump-page switch has no effect here.
- Trump (`system="trump"`) panel: relabeled the switch "TRUMP (System 1)" and
  rewrote all copy/status lines to say Trump-only auto-open (was "GLOBAL
  (Trump + BTC)" / "both Trump & BTC").
- CLAUDE.md: corrected "No global store (no Redux/Zustand)" — the app DOES use
  a small Zustand store (store/dashboard.ts / useDashboardStore); documented
  what it holds and the guidance to keep it small.

Note (not a bug): dashboard adopt/release is intentionally Telegram-only —
there are no positions/adopt|hl|release client calls and the UI correctly
points to the Telegram /adopt command. No dashboard wiring is "broken".

tsc + next build clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:04:36 +08:00
k 3a113aaa8f fix: wallet/trades UX + SEO + commit Next.js 16 routing migration
Pre-launch audit findings (frontend):

- trades: unlock private history in-page. TradesPageClient only read a CACHED
  view envelope, so a connected user who hadn't visited Settings first saw
  "load settings once to unlock" with no way forward. Added an explicit
  "Unlock trade history" button that mints the view envelope via
  getOrCreateViewEnvelope (one signature, no gas) and reloads — no detour.
- wagmi: broaden connector from injected({target:'metaMask'}) to generic
  injected(). The MetaMask pin made Rabby / Coinbase ext / Brave / Frame / OKX
  and non-MetaMask browsers fail to connect. wagmi v2 EIP-6963 discovery covers
  all injected wallets; still uses the native provider path (not the MM SDK).
- sitemap: drop /settings. It was emitted in sitemap.xml while robots.ts
  disallows it — a self-contradicting crawler signal. Private pages stay out
  of both.
- docs: note the app runs on port 3001 (package.json), not 3000. The CLAUDE.md
  verify sweep targeted 3000 and would have reported every page as down.
- routing: COMMIT the Next.js 16 migration that was sitting uncommitted —
  delete middleware.ts, add root proxy.ts (next-intl createMiddleware), update
  next-env.d.ts. Vercel deploys from git, so leaving proxy.ts untracked would
  have shipped the old routing. `next build` confirms "Proxy (Middleware)" is
  active and all routes compile. tsc clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 14:34:51 +08:00
k d50c05b120 fix: pre-launch UI hardening + KOL reduce-action type, proxy IP relay, settings redesign
Frontend half of the pre-launch audit campaign:

- types/index.ts + kol/KolPageClient.tsx: add missing 'reduce' KolAction
  (backend emits it; frontend lacked the type + color/label maps → undefined
  styling). Adds ACTION_COLOR/actionLabel/postActionLabel entries.
- proxy/[...path]/route.ts: relay real client IP (x-forwarded-for / x-real-ip)
  so the backend rate limiter buckets per-user instead of per-Next-server (BUG-02).
- Settings/BotConfigPanel redesign, paper-mode clarity, copy cleanup.
- Assorted page/display fixes, loading states, Pagination component.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 11:57:43 +08:00
k b76de36af0 refactor(settings): redesign BotConfigPanel + fix paper mode + clarify all copy
BotConfigPanel (full rewrite, 1113→858 lines):
- Remove 3-tab layout; replace with two expandable cards (Trump Signal /
  Macro Vibes) + collapsed Advanced block — fewer decisions, less noise
- Fix paper mode bug: UserResponse now returns paper_mode; BotConfigPanel
  tracks it in state; missingItems skips HL key requirement for paper users;
  HL key card shows paper status instead of empty input
- Add "Switch to live →" upgrade path — calls /subscribe with paper_mode=false
  so paper users can promote without re-subscribing from scratch
- Add confirmSign before manual override window (consistent with all other
  mutations); rename "Arm/Disarm" → "Override/Cancel override" throughout
- Fix all ambiguous copy: subscribe card, Macro Vibes description (manual
  /adopt flow, not auto-manage), missingItems strings, TP/SL "Not saved yet"
  → "Required — not saved", "Daily spend cap" → "Daily trading cap",
  "Active schedule" → "Trading schedule", "Get started" confirmSign labels

lib/api.ts:
- Add paper_mode: boolean to UserData interface (was missing)

OpenPositions:
- "Load your settings once…" → "Sign in once to view open positions" (removes
  implementation-detail explanation)
- "Today realised" → "Today's realized"; "banked" → "locked in" throughout
- "The bot will appear here" → "When the bot opens a trade, it will show up here"

SystemControl:
- "Net result" → "Current status"

settings/SettingsClient.tsx:
- id="btc-settings" → id="macro-settings" (stale rename)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-27 23:10:55 +08:00
k a1e9ec49ef fix: 3 display bugs found in full-page audit
1. MacroVibesPageClient — funding stats rendered "undefined%" when
   latest_rate_pct / last_24h_avg_pct were null. `?.toFixed()` returns
   undefined inside a template literal → shows as the string "undefined%".
   Fixed: explicit null check → '—' fallback.

2. SettingsClient — broken internal anchor: href="#btc-settings-panel"
   but the section id is "btc-settings". "Open panel ↓" link did nothing.
   Fixed: corrected href to "#btc-settings".

3. KolPageClient — undefined CSS variables throughout the file:
   --bg-card (transparent) and --border (no border) were never defined
   in the design system (globals.css uses --surface and --line).
   KOL cards rendered with transparent bg and invisible borders.
   Fixed: --bg-card → --surface, --border → --line, --accent → --amber.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 16:28:05 +08:00
k 37c67d4acb fix: stop page flashing — revert overflow-x:clip, fix sticky properly
overflow-x:clip on html+body caused a browser layout loop → continuous
flashing. Correct fix: only set overflow-x:hidden on html (the real
scroll container). Leaving body without overflow-x means body won't
become a secondary scroll container, so position:sticky on the navbar
works correctly without the layout loop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 16:20:47 +08:00
k 8ab7c55288 fix: navbar sticky, composite card styling, needle clip
- overflow-x: clip on html/body (was `hidden`, which silently made body a
  scroll container and broke position:sticky on the navbar)
- .macro-composite: card style matching indicator cards (14px margin,
  border + 12px radius + surface bg + shadow-1, no more full-bleed band)
- .macro-composite-track: remove overflow:hidden so 24px needle isn't
  clipped by 18px track; add 6px vertical margin for breathing room

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 16:18:14 +08:00
k 02b2aebbb7 fix(chart): MACRO BOTTOM marker now follows candles on pan / zoom / resize
User report: the dashed vertical line + "MACRO BOTTOM" label could be
visually "dragged" — it wasn't actually draggable, but it stayed glued
to a fixed pixel column on screen while the candles slid out from under
it on pan, so the label ended up pointing at unrelated candles.

Root cause: the line + label are absolutely-positioned DOM nodes (the
lightweight-charts library has no first-class vertical-marker primitive).
The data effect set their `left` ONCE via timeScale.timeToCoordinate()
and then never updated again. Every user interaction that changes the
visible range — pan, wheel zoom, programmatic setVisibleRange, window
resize — invalidates that pixel coordinate.

Fix:
  - Store the signal's bucketTime + label text in refs.
  - Hoist the "project bucketTime → pixel X" logic into a single
    `reposition()` fn captured in repositionMacroRef.
  - Subscribe to `timeScale().subscribeVisibleTimeRangeChange(reposition)`
    so it fires on every pan / zoom / data update.
  - Wire it into the ResizeObserver too (width change ⇒ new pixel space).
  - Re-run from the data effect whenever the signal changes.
  - Hide (opacity: 0) instead of clamping when the signal candle scrolls
    outside the visible range — a clamped label glued to the chart edge
    is actively misleading.
  - Drop `transition: left 160ms` on both nodes — that transition fires
    on every pan frame and makes the marker LAG behind the candles,
    reproducing the original visual bug for fast pans.

Verified via DOM scripting:
  pan right ⇒ label_left 744px → 344px (follows candles ✓)
  big right-pan past signal ⇒ opacity 1 → 0 (hides cleanly ✓)
  zoom out ⇒ opacity 0 → 1, label re-projects to new pixel space ✓

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 11:34:26 +08:00
k d01adc4790 style(dashboard): unify Macro composite into one card + dark-mode fix
for Performance accent

User flagged the macro index box on the overview page as feeling
disjointed. Reshaped it from three stacked elements (band → track →
scale) into a single bordered card so it reads as ONE component.

  - JSX: wrap the three pieces in <div className="overview-macro-card">
  - CSS: new .overview-macro-card with tone-coloured rim (bull/bear/neutral)
  - Solid neutral-gray filled needle (was a hollow ring — looked like a
    placeholder); tone-coloured background + white inner ring + double
    shadow so it stands out on any gradient position
  - Removed the .overview-score-fill overlay — the gradient already
    encodes the spectrum; layering an opaque fill obscured it near 0
  - Thinner track (14px vs 22px), tighter scale labels, smaller pill
  - Added "TODAY · 8 INDICATORS" stamp next to the title — gives users
    a quick anchor of what they're looking at + freshness

Plus: dark-mode override for .overview-stat-card.accent (the Performance
card). It was using a cream gradient that floated as a glaring
out-of-theme block on dark mode. Mirrored the existing .kpi.accent dark
treatment so it stays visually grouped with the rest of the dashboard.

Also includes the in-flight overview rewrite from the other AI tool
(legacy /btc redirect to /macro, middleware.ts replacing proxy.ts for
Next.js routing, refactored several dashboard panels). TypeScript clean,
production build passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 11:25:59 +08:00
k ee3648c4cb docs: add CLAUDE.md — AI-agent project entry doc
Convention file every new Claude session reads first when opening this
repo. Documents:

  - Next.js 16 quirks (proxy.ts replaces middleware.ts, async params,
    i18n shelved).
  - Full route + component map.
  - API layer + auth model (EIP-191 signed envelopes).
  - Design system tokens (oklch colors, .macro-* classes, dark mode).
  - "Looks like a bug but isn't" section — including the /en/btc → /en/macro
    rename + the isZh=false i18n-shelved pattern.
  - SEO/GEO surface (layout.tsx JSON-LD + public/llms.txt + sitemap) that
    must be kept in sync when renaming features.
  - Cross-repo coupling points with the backend.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 11:04:19 +08:00
k f34ae9eb00 feat(macro-vibes): rename BTC Signal → Macro Vibes; add MacroPanel UI
Module rename across page H1, navbar tab, URL (/en/btc → /en/macro),
all metadata/JSON-LD, sitemap, llms.txt, opengraph image, and SystemControl
copy. Old /btc route fully removed.

New components/btc/MacroPanel.tsx polls /api/macro/snapshot and lays out
the 8 indicators in four sections (Valuation / Bottom trigger reference /
Market structure / Sentiment & flows / Positioning) with tone-coloured
values, current-band threshold chips, and a single CoinGlass / source
chart link per card. Composite -100..+100 needle pulses on score change.

Also fixes the pinned bottom-reversal alert on the homepage, which still
linked to the now-404 /en/btc — now routes to /en/macro.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 01:05:18 +08:00
k d72323b1c6 Production polish: i18n shelved, PWA icons, SEO/GEO cleanup, UX fixes
Big-picture changes since 01be8e7:

New routes — /trump /btc /kol /trades /analytics /archive plus four
SEO landing pages (/methodology /glossary /case-studies /contact),
all served under /[locale]. Each has dedicated metadata + JSON-LD.

KOL page (new) — DigestWidget + OnchainWidget + TalkVsTradesWidget,
filter by handle/ticker, click-through to per-post detail with the
original AI-extracted ticker/conviction/quote.

BTC page (new) — tabbed: macro-bottom (AHR999 + 200WMA + Pi Cycle)
and funding-rate reversal, with live sparkline + threshold bands.

Telegram card on Settings — wallet-link code generation, status,
disconnect. Preferences moved into the bot itself (/trump /btc etc.)
so the card stays minimal.

SignalMonitor (new) — ETH/LINK Bollinger breakout monitor in its own
component, shares the singleton WsProvider so no second WS opens.

WS singleton refactor (lib/wsContext) — shared WsProvider + useWsSubscribe
hook. Cleanup now actively closes the socket on unmount; previously the
local `ws` couldn't be reached from cleanup and leaked one connection
per StrictMode remount.

OpenPositions polling no longer pops MetaMask in the background —
splits into load('first') for user-initiated and load('poll') that
uses getCachedViewEnvelope without signing.

i18n shelved — proxy.ts (Next 16 middleware rename) wires next-intl
but only Navbar + layout footer have translations. Rest of UI used
isZh ternary scattered across 28 files. All `const isZh = locale === 'zh'`
flipped to `const isZh = false` so every site renders English; Chinese
branches kept as dead code so revival is one regex away.
LanguageSwitch hidden but file kept. zh-CN hreflang removed from
metadata + sitemap to avoid duplicate-content penalties.

Wallet error handling — lib/walletError.ts: isUserRejection walks EIP-1193
code 4001 + .cause chain; previous string-match for "reject"/"denied"
broke for users running MetaMask in non-English UIs. 12 call sites
migrated across 5 components.

PWA icons — app/icon.tsx + app/apple-icon.tsx render the brand "α" via
Next's ImageResponse so no static PNG asset is required. manifest.ts
references /icon and /apple-icon dynamic routes.

OG image + sitemap + robots — dynamic 1200×630 OG card; robots blocks
both /en/settings and /zh/settings; sitemap only emits /en routes;
JSON-LD covers SoftwareApplication + Organization + 10-Q FAQPage.

Landing page polish — Launch Dashboard button stripped of magnetic
hover + shimmer + lift + glow expansion (multiple users found it busy);
hero scramble alphabet swapped to alphanumeric (was block characters);
"15 KOL feeds" copy updated to 19 in 5 places.

PostCards source icons — new entries for btc_bottom_reversal,
funding_reversal, kol_divergence so they no longer fall through to
the generic "first letter" fallback.

Archive page filter — excludes funding_reversal + kol_divergence
(previously only excluded truth + btc_bottom_reversal so new live
signals leaked into the legacy archive).

Cache + skeleton loading — lib/cache.ts SWR module with per-key TTL,
applied across the major pages so navigation feels instant.

SignConfirmSheet — 4 hardcoded Chinese strings translated to English
(English users were seeing zh-only "需要钱包签名" etc).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 00:53:27 +08:00
k 01be8e790b fix: dashboard live price + 24h % + chart tick + null-pnl safety
Five bugs in the same blast radius (places we render a price/percent).

DashboardClient.tsx
  • Hero price read lastCandle.close (REST candle, frozen until user
    changes asset/tf). WebSocket livePrices was set but never read.
    Now: livePrice ?? lastCandle.close.
  • "+21.84% · 4H" was (last_close - first_open) / first_open over
    the entire candle window. limit=200 + tf=4H = 33 days shown as
    "4H". Find candle closest to now-24h, label "24h" consistently.

ChartPanel.tsx
  • Chart only re-rendered on candles prop change. Live WS ticks
    ignored. Added useEffect calling series.update() with
    livePrices[asset] on every tick.

analytics/page.tsx
  • reduce(sum + trade.pnl_usd) when pnl_usd is null → NaN poison.
  • Math.max/min over null cast to 0 → bogus "best/worst trade".
  • Win-rate denominator counted null-pnl trades as losses.
  • calcDrawdownPct had the same null poisoning.
  Fix: gate aggregations on priced subset only.

trades/page.tsx
  • ROI could divide by 0/null; entry/exit crashed on null.toLocaleString().
  Added guards.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 19:57:28 +08:00
k 040e1df685 feat: revamp dashboard, trades, and add landing/legal pages
- Major UI updates across dashboard, analytics, posts, trades, settings
- New landing page, robots/sitemap, contact/privacy/terms pages
- Updated globals.css with extensive styling and new landing.css
- Refactor signedRequest, realtime data hook, and dashboard store

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 16:04:57 +08:00
k 83e5892ddf done 2026-04-21 19:32:53 +08:00
k 1747fc489f first day of vibe coding 2026-04-20 22:11:18 +08:00