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>
This commit is contained in:
@@ -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<T>` 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 `<html>`. 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.
|
||||||
Reference in New Issue
Block a user