Files
new-api-analytics/CLAUDE.md

66 lines
3.1 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
@AGENTS.md
## Commands
```bash
npm run dev # Start dev server (localhost:3000)
npm run build # Production build (standalone output)
npm run start # Start production server
npm run lint # ESLint (eslint-config-next/core-web-vitals + typescript)
```
Docker deployment: port 8019, `docker-compose up` with env supplied by the deployment platform or shell, external network `sinobridge`.
## Architecture
Next.js 16 App Router analytics dashboard for an API gateway. React 19, TypeScript strict mode, Tailwind CSS 4, Recharts 3, PostgreSQL.
**TypeScript: Never use `any` type.** Always define proper interfaces/types for all data structures. Use `unknown` with type narrowing if the type is truly unknown.
### Three Global Contexts (wrapped in `components/ClientProviders.tsx`)
1. **ThemeProvider** (`lib/theme.tsx`) — light/dark/system, localStorage `theme`, supports iframe embedding via `?theme=` query param and postMessage sync
2. **I18nProvider** (`lib/i18n.tsx`) — zh/en, localStorage `locale`, all translation keys in a single `translations` object
3. **TimeRangeProvider** (`lib/time-range-context.tsx`) — today/7d/30d/all/custom, localStorage `time-range`, exposes `getEffectiveRange()` returning `{ start?, end? }` unix timestamps (seconds)
Pages consume these via `useTheme()`, `useI18n()`, `useTimeRange()`. The `TimeRangeSelector` component reads from context (no props).
### Data Flow
Pages call `getEffectiveRange()``buildQuery("/api/...", { start, end })` → API route → `lib/queries.ts` SQL → PostgreSQL → JSON response → Recharts/tables.
### Database Layer (`lib/db.ts`, `lib/queries.ts`)
- `pg` pool (max 10 connections), env var `PG_CONNECTION_STRING`
- All queries filter `type = 2`, timezone `Asia/Shanghai`
- Real model name resolution: `COALESCE(other::jsonb->>'upstream_model_name', model_name)`
- Quota to USD: `quota / 500000`
- Parameterized queries with `$N` positional params
### API Routes (all GET, query-param driven)
| Route | Key Params | Returns |
|-------|-----------|---------|
| `/api/overview` | start, end | Aggregate stats (calls, tokens, users, models, channels) |
| `/api/trends` | start, end, granularity (day/week/month) | Time-series array |
| `/api/rankings` | start, end, type (user/model/channel), limit | Ranked items |
| `/api/detail/[type]/[id]` | start, end | Stats + breakdown (models or users) |
| `/api/logs` | start, end, page, page_size, username, model, token_name | Paginated logs |
| `/api/aggregation` | start, end | All users aggregated (top 500) |
### Styling
CSS variables in `globals.css` — dark theme default (cyan `#00e5ff` accent), light theme (blue `#0284c7`). Key classes: `.glass` (glassmorphic card), `.gradient-text`, `.btn-accent`, `.input-glass`, `.row-glow`. Portal page (`/portal`) has its own extensive animation system.
### Path Alias
`@/*` maps to project root (tsconfig).
### Fonts
Outfit (sans, `--font-geist-sans`) and JetBrains Mono (mono, `--font-geist-mono`) via `next/font/google`.