diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a642770 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,244 @@ +# Trump Alpha — Frontend (trumpsignal.com) + +> Next.js 16 dashboard for the Trump Alpha backend. Real-time signals, +> Hyperliquid position management UI, KOL talks-vs-trades view, Macro Vibes +> regime panel. Read-only for the public; wallet-bound features (Pro) for +> auto-trade subscribers. + +This is the AI-readable entry doc. Read this first on entering the repo. + +--- + +## What this repo is + +- **Pure frontend** — Next.js 16 App Router, TypeScript, server components + + client components, deployed to Vercel. +- **Talks to a Python backend** at `https://api.trumpsignal.com` (or + `localhost:8000` in dev). All trading state, signals, AI scoring, + Hyperliquid integration lives in the sibling **`/Users/k/Public/Claude/ + backend`** repo. See its CLAUDE.md. +- **No server-side trading logic** lives here. Frontend is a thin layer + over the API + WebSocket — even "open a position" routes to a backend + endpoint that does the signed-request verification + HL call. + +--- + +## Stack quirks (Next.js 16 specific) + +- **`proxy.ts` replaces `middleware.ts`** in Next.js 16. Routes that need + CORS / locale rewriting go through `proxy.ts` at the root. +- **`params` is async (`Promise<{...}>`)** in all dynamic routes. ALL page + components await it: + ```tsx + export default async function Page({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params + ... + } + ``` + Forgetting the `await` redirects to `/undefined/...` silently. Several + pages were broken this way pre-v2.0 — be alert if you copy older patterns. +- **i18n is shelved.** The `[locale]` segment exists, `messages/zh.json` + exists, but Chinese branches are kept as dead code with a comment + `// i18n shelved — see messages/zh.json`. Don't activate without an ADR. + Currently `isZh = false` is hardcoded in metadata generators. +- **`runtime = 'edge'`** on a few routes (`app/icon.tsx`, OG image generator). + Edge runtime has no fs / no Node APIs — don't import server-side libs there. + +--- + +## Route map + +``` +app/ +├── layout.tsx Root layout: JSON-LD schema.org, fonts, meta +├── page.tsx / (root) → redirects to /en +├── icon.tsx Dynamic favicon (α on dark bg, edge runtime) +├── apple-icon.tsx PWA install icon +├── opengraph-image.tsx OG card generator (1200x630) +├── manifest.ts PWA manifest +├── sitemap.ts SEO sitemap.xml +├── robots.ts robots.txt +└── api/ + └── proxy/[...path]/ Catch-all proxy to backend (CORS workaround) + +app/[locale]/ +├── page.tsx Landing — pinned signals, live ticker, Trump feed +├── DashboardClient.tsx Main 'use client' wrapper for the home dashboard +├── trump/page.tsx /en/trump — Trump Truth Social signal stream +├── macro/page.tsx /en/macro — Macro Vibes regime panel ★ renamed from /btc +├── kol/page.tsx /en/kol — KOL talks-vs-trades +├── trades/page.tsx /en/trades — closed trade history +├── posts/page.tsx /en/posts — all Posts (signal + Trump) +├── archive/page.tsx /en/archive — historical / paginated +├── settings/page.tsx /en/settings — wallet connect, HL key, prefs +├── analytics/page.tsx /en/analytics — performance metrics +├── case-studies/page.tsx /en/case-studies — documented event walkthroughs +├── methodology/page.tsx /en/methodology — how signals work +├── glossary/page.tsx /en/glossary — AHR999, MVRV-Z, KOL, etc. +├── privacy/page.tsx +├── terms/page.tsx +├── contact/page.tsx +└── globals.css Design system tokens + .macro-* classes +``` + +--- + +## Components map (the meaningful ones) + +``` +components/ +├── nav/Navbar.tsx Top nav + tabs (Trump | Macro Vibes | KOL ...) +├── signals/ +│ ├── SignalMonitor.tsx Live signal stream (WS-driven) +│ ├── SourceChips.tsx Filter chips per source +│ ├── SystemControl.tsx Sys1/sys2 toggle widgets, Auto-Trade switch +│ └── ConfirmCloseTrade.tsx Modal for manual close +├── dashboard/ +│ ├── PostCards.tsx Trump post cards +│ ├── SignalMonitor.tsx (older — being consolidated) +│ └── BtcReversalAlert.tsx Pinned alert when sys2 fires +├── btc/MacroPanel.tsx ★ 8-indicator Macro Vibes layout (4 sections, +│ composite needle, threshold chips, peak-trail viz) +├── positions/ +│ ├── OpenPositions.tsx Polls /positions/open + /positions/today every 15s +│ └── TradeCard.tsx Single trade row w/ grow toggle + close button +├── kol/KolDigest.tsx Daily KOL summary widget +├── telegram/ +│ ├── TelegramCard.tsx Settings — connect via 6-char code +│ └── SignConfirmSheet.tsx EIP-191 signed request preview +├── nav/WalletConnect.tsx Wagmi-style wallet connect (MetaMask etc.) +├── ui/ +│ ├── InfoTip.tsx CSS-only tooltip with `?` icon +│ ├── PageHint.tsx Strong page subtitle (replaces page-sub) +│ ├── Toast.tsx +│ └── Modal.tsx +└── ws/WsProvider.tsx WebSocket singleton context provider +``` + +--- + +## API layer + +All API calls go through **`lib/api.ts`**. Single `fetchJson` wrapper: + +- Reads base URL from env (`NEXT_PUBLIC_API_URL`) or proxies through + `/api/proxy/[...path]/` for same-origin CORS-free calls. +- Wallet-scoped reads (`/user/.../public`, `/positions/open`) pass wallet + as query param + signed ts/sig. +- Mutations (subscribe, manual_close, set_auto_trade, manual-window) build + an EIP-191 signed payload via wagmi → POST signed envelope. + +**Auth model**: no sessions, no cookies. Wallet address + signed timestamp ++ signature on every mutating call. Verification lives in the backend +(`signed_request.verify_signed_request`). The same wallet that signed the +HL API key envelope at subscribe time is the only one that can later +mutate the subscription. + +--- + +## State management + +- **No global store** (no Redux/Zustand). Tree-local state + props. +- **SWR-style cache** in `lib/cache.ts` for the API-heavy pages. +- **WebSocket** singleton via `WsProvider` — used by `SignalMonitor` and + live price tickers. +- **localStorage** holds wallet address only (for re-connect UX). HL API + keys NEVER touch the client — they're submitted once at subscribe, sent + encrypted, and decrypted only inside the backend. + +--- + +## Design system + +Tokens in `app/[locale]/globals.css`: + +- **Colors** — `oklch()` color space throughout. Brand orange = `#f5a524`, + brand dark = `#0a0907`. `var(--up)` green / `var(--down)` red / `var(--ink-1..3)` + text tiers. +- **Dark mode** via `[data-theme="dark"]` attribute on ``. Most + components use `oklch(L% c h)` so dark/light switching is automatic. +- **Macro Vibes specific** — extensive `.macro-*` classes for the 8-indicator + layout. Threshold chips have `:not(.active) { opacity: 0.45 }` and `.active` + is tone-filled (green/red/amber). + +--- + +## Things that LOOK like bugs but aren't + +- **Old code references "/en/btc"** — Macro Vibes was renamed from "BTC + Signal" in v2.0. All routes are now `/en/macro`. If you find a stale + `/en/btc` reference, it's a real bug — fix it (we've found and fixed 3). +- **`isZh = false` in metadata generators** — i18n was shelved pre-launch. + See "Stack quirks" above. +- **Multiple `proxy.ts` patterns** — Next.js 16 split middleware behaviour. + Keep proxy logic in the single `proxy.ts` at root. +- **`'use client'` directives on many pages** — necessary for client-side + WS / wallet interactions. Don't try to convert without verifying the WS + + wagmi imports work in server components. + +--- + +## How to verify changes locally + +```bash +# Type check (must pass with 0 errors) +npx tsc --noEmit + +# Production build (catches missing pages, stale imports) +rm -rf .next && npx next build + +# Dev server +npm run dev + +# Pages-200 sweep (every locale page returns 200) +for p in /en /en/trump /en/macro /en/kol /en/trades /en/posts /en/settings \ + /en/methodology /en/glossary /en/case-studies /en/privacy /en/terms; do + echo "$p $(curl -so /dev/null -w '%{http_code}' http://localhost:3000$p)" +done +``` + +--- + +## SEO / GEO surface (don't break) + +- **`app/layout.tsx`** has JSON-LD schema.org markup (Organization, + SoftwareApplication, FAQ). Search engines + AI crawlers read this. +- **`public/llms.txt`** — canonical doc for AI crawlers (Perplexity, ChatGPT + browse, Google AI Overviews). Edit BOTH this file AND `layout.tsx` when + renaming product features. +- **`app/sitemap.ts`** — sitemap.xml. Add new routes here. +- **OG image** — `app/opengraph-image.tsx` dynamically renders the social + card. Keep the brand pill list in sync with current features. + +--- + +## Coupling to backend + +- **API contract lives in TypeScript types under `lib/api.ts`** (e.g. + `OpenPositionsResponse`, `TodayStats`, `BotTrade`). These must match the + backend Pydantic models in `app/api/*/positions.py` etc. +- When backend adds a field (e.g. `BotTrade.released_at`), this repo's + `lib/api.ts` types may need updating to surface it in the UI. Currently + released trades are FILTERED OUT by the backend's `/positions/open` — + they don't appear here, so no UI for "managed vs released" yet. +- When backend renames a route (e.g. `/btc/page.tsx` → `/macro/page.tsx`), + search for ALL references (including telegram deep-link map in + `backend/app/services/telegram.py`). + +--- + +## Deploy + +Vercel auto-deploys `main` branch pushes. No special build flags. Env vars +in Vercel dashboard: +- `NEXT_PUBLIC_API_URL` — backend HTTPS origin +- `NEXT_PUBLIC_SITE_URL` — canonical site URL (used for OG, sitemap) +- `NEXT_PUBLIC_WS_URL` — WebSocket endpoint (usually `wss://api...`) + +--- + +## Sibling repo + +- **`/Users/k/Public/Claude/backend`** — Python/FastAPI backend, includes + Hyperliquid integration, Telegram bot, AI scoring (DeepSeek), all + signal scanners, the adoption/release flow. See its CLAUDE.md.