199 lines
11 KiB
Markdown
199 lines
11 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## What this is
|
|
|
|
Two independent apps in one repo:
|
|
|
|
1. **Frontend** (`frontend/`) — a Vite + React 19 + TypeScript marketing/content site for "اندیشکده فولاد آینده" (a steel-industry think tank). Persian-first, RTL, bilingual (fa/en). Deploys as a static build via Docker to Hugging Face Spaces on port 7860.
|
|
2. **Admin panel** (`panel/`) — a **standalone** Node/Express + Postgres app with its own `package.json` and `node_modules`, that is BOTH the backend API and the CMS admin UI (served from `panel/public/`). Manages content the site publishes.
|
|
|
|
These two have **no shared build or dependency tree**. `frontend/` and `panel/` are sibling folders at the repo root — neither references the other at build time (the frontend reads the panel only at runtime via `VITE_PANEL_API`).
|
|
|
|
## Commands
|
|
|
|
Frontend (run from `frontend/`):
|
|
```bash
|
|
cd frontend
|
|
npm run dev # Vite dev server (HMR)
|
|
npm run build # tsc -b && vite build (type-checks then bundles)
|
|
npm run lint # eslint .
|
|
npm run preview # serve the production build
|
|
npx tsc -b --noEmit # type-check only — the fast inner loop; use after every edit
|
|
```
|
|
There is **no test framework** configured. "Verifying" a change means `npx tsc -b --noEmit` (must be clean) and looking at the running dev server.
|
|
|
|
Admin panel (run from `panel/`):
|
|
```bash
|
|
cd panel
|
|
npm install # first time only
|
|
npm run seed # create the admin user from .env (ADMIN_USERNAME/PASSWORD)
|
|
npm start # node server.js → http://localhost:3001
|
|
npm run dev # node --watch server.js
|
|
```
|
|
The panel uses Postgres (`pg` Pool over `DATABASE_URL`) behind a better-sqlite3-style `db.prepare().get/all/run()` facade — every call is async and must be awaited.
|
|
|
|
## Frontend architecture
|
|
|
|
- **Routing**: `src/app/router.tsx` (`createBrowserRouter`). `RootLayout` (`src/app/layout/RootLayout.tsx`) wraps every page with `Header`, `Footer`, and the smooth-scroll engine. Pages live in `src/pages/<Name>/<Name>.tsx`; the homepage composes section components from `src/pages/Home/sections/`.
|
|
- **Language**: `useLang()` from `src/context/LangContext` returns `{ lang: 'fa'|'en', toggle }`. Components hold inline `{ fa: {...}, en: {...} }` objects and index by `lang`. RTL is driven by `dir={lang==='fa'?'rtl':'ltr'}` near the page root; many flex containers force `direction:'ltr'` locally to stop RTL from reversing their child order, then set inner text back to `rtl`.
|
|
- **Smooth scroll**: `RootLayout` runs **Lenis synced to the GSAP ticker** (the joinspread.app recipe) — one shared RAF clock so scroll-driven animations don't stutter. It is **desktop-only**: on touch/coarse pointers it hands off to native momentum (avoids the iOS double-smoothing lag). Do not re-add CSS `scroll-behavior: smooth` — it fights Lenis.
|
|
- **Hero** (`src/pages/Home/sections/HeroSection.tsx`): a GSAP `ScrollTrigger` scrub timeline pinned over a `200vh` section (de-zoom + satellite scatter). This is GSAP, not framer-motion.
|
|
- **Styling**: mostly **inline `style` objects**, with Tailwind utility classes for responsive overrides (`max-md:`, `max-lg:`) and a few `!important` overrides. Global CSS variables in `src/index.css` (`--ink`, `--paper`, `--red`, `--color-orange`, etc.). Brand colors are **gold `#CD9E53`** and **navy `#032340`** — these are also hardcoded as `const GOLD`/`const NAVY` in many section files, so a rebrand is a repo-wide find-and-replace, not just a CSS-var change.
|
|
- **Globe** (`src/components/ui/globe.tsx`): three-globe mounted in react-three-fiber via `<primitive>` (NOT via `extend`/JSX-element augmentation — that augmentation poisons global JSX types and breaks unrelated components like `React.ElementType` icons). Country polygons load at runtime from `public/globe-countries.geojson` (bundled, public-domain Natural Earth).
|
|
- **Calendar** (`src/components/ui/EventCalendar.tsx`): a native Jalali (Persian) month grid built with `Intl.DateTimeFormat('en-US-u-ca-persian', …)` — **no date library**. It walks Gregorian `Date`s and reads their Persian parts to lay out the grid.
|
|
- **Content layer**: `src/content/*.ts` and inline arrays hold all section data. These are mock/seed data and are explicitly intended to be replaced by `fetch` calls to the panel API later (see "Wiring", below). Keep new editorial data in this shape so the swap stays mechanical.
|
|
- **Generator shape**: editorial automation must treat `در یک نگاه` and `رادار آینده` as separate products. `در یک نگاه` is short card copy. `رادار آینده` is long-form analysis with multiple inputs, in-text citations, intro/build-up/conclusion, and article blocks that map to `/radar/post/:id`.
|
|
|
|
## Admin panel architecture (`panel/`)
|
|
|
|
- **Stack**: Express 4 + `better-sqlite3` (single file `panel/data.db`), `bcryptjs` + `jsonwebtoken` (HTTP-only cookie named `session`), `multer` uploads to `panel/uploads/`. Admin UI is a **vanilla-JS SPA** in `panel/public/` (`app.js`, no build step).
|
|
- **Schema**: `panel/db.js` (`users`, `articles`, `risk_signals`, `prices`) plus row→object mappers. `articles` is a flexible universal content model discriminated by `category`/`type`.
|
|
- **API** (`panel/server.js`): public reads (`GET /api/articles`, `/api/risks`, `/api/prices`) + auth-gated writes via the `authRequired` middleware. CRUD for articles, risk signals, and users; `/api/uploads`; `/api/contact`. CORS is gated by the `ALLOWED_ORIGINS` env var.
|
|
- **Prices** are scraped from tgju.org by `panel/scraper.js` on a 120s interval when the server runs.
|
|
- **Config**: `panel/.env` (copy from `.env.example`) — `JWT_SECRET`, `ADMIN_*`, `PORT` (3001), `ALLOWED_ORIGINS`, mail creds.
|
|
|
|
## Wiring the panel to the site (not done yet)
|
|
|
|
When asked to make published content appear on the site: add a frontend fetch client (e.g. `src/lib/api.ts` reading `import.meta.env.VITE_API_URL`), replace a section's `src/content/*` import with a hook that calls `GET /api/articles?category=<section>`, and keep the static file as the loading fallback. Do it one section at a time. The `articles` table's `category` column is the per-section discriminator. Recommended schema additions before going live: a `status` (draft/published) column, and an `events` resource for the calendar.
|
|
|
|
<!-- rtk-instructions v2 -->
|
|
# RTK (Rust Token Killer) - Token-Optimized Commands
|
|
|
|
## Golden Rule
|
|
|
|
**Always prefix commands with `rtk`**. If RTK has a dedicated filter, it uses it. If not, it passes through unchanged. This means RTK is always safe to use.
|
|
|
|
**Important**: Even in command chains with `&&`, use `rtk`:
|
|
```bash
|
|
# ❌ Wrong
|
|
git add . && git commit -m "msg" && git push
|
|
|
|
# ✅ Correct
|
|
rtk git add . && rtk git commit -m "msg" && rtk git push
|
|
```
|
|
|
|
## RTK Commands by Workflow
|
|
|
|
### Build & Compile (80-90% savings)
|
|
```bash
|
|
rtk cargo build # Cargo build output
|
|
rtk cargo check # Cargo check output
|
|
rtk cargo clippy # Clippy warnings grouped by file (80%)
|
|
rtk tsc # TypeScript errors grouped by file/code (83%)
|
|
rtk lint # ESLint/Biome violations grouped (84%)
|
|
rtk prettier --check # Files needing format only (70%)
|
|
rtk next build # Next.js build with route metrics (87%)
|
|
```
|
|
|
|
### Test (60-99% savings)
|
|
```bash
|
|
rtk cargo test # Cargo test failures only (90%)
|
|
rtk go test # Go test failures only (90%)
|
|
rtk jest # Jest failures only (99.5%)
|
|
rtk vitest # Vitest failures only (99.5%)
|
|
rtk playwright test # Playwright failures only (94%)
|
|
rtk pytest # Python test failures only (90%)
|
|
rtk rake test # Ruby test failures only (90%)
|
|
rtk rspec # RSpec test failures only (60%)
|
|
rtk test <cmd> # Generic test wrapper - failures only
|
|
```
|
|
|
|
### Git (59-80% savings)
|
|
```bash
|
|
rtk git status # Compact status
|
|
rtk git log # Compact log (works with all git flags)
|
|
rtk git diff # Compact diff (80%)
|
|
rtk git show # Compact show (80%)
|
|
rtk git add # Ultra-compact confirmations (59%)
|
|
rtk git commit # Ultra-compact confirmations (59%)
|
|
rtk git push # Ultra-compact confirmations
|
|
rtk git pull # Ultra-compact confirmations
|
|
rtk git branch # Compact branch list
|
|
rtk git fetch # Compact fetch
|
|
rtk git stash # Compact stash
|
|
rtk git worktree # Compact worktree
|
|
```
|
|
|
|
Note: Git passthrough works for ALL subcommands, even those not explicitly listed.
|
|
|
|
### GitHub (26-87% savings)
|
|
```bash
|
|
rtk gh pr view <num> # Compact PR view (87%)
|
|
rtk gh pr checks # Compact PR checks (79%)
|
|
rtk gh run list # Compact workflow runs (82%)
|
|
rtk gh issue list # Compact issue list (80%)
|
|
rtk gh api # Compact API responses (26%)
|
|
```
|
|
|
|
### JavaScript/TypeScript Tooling (70-90% savings)
|
|
```bash
|
|
rtk pnpm list # Compact dependency tree (70%)
|
|
rtk pnpm outdated # Compact outdated packages (80%)
|
|
rtk pnpm install # Compact install output (90%)
|
|
rtk npm run <script> # Compact npm script output
|
|
rtk npx <cmd> # Compact npx command output
|
|
rtk prisma # Prisma without ASCII art (88%)
|
|
```
|
|
|
|
### Files & Search (60-75% savings)
|
|
```bash
|
|
rtk ls <path> # Tree format, compact (65%)
|
|
rtk read <file> # Code reading with filtering (60%)
|
|
rtk grep <pattern> # Search grouped by file (75%). Format flags (-c, -l, -L, -o, -Z) run raw.
|
|
rtk find <pattern> # Find grouped by directory (70%)
|
|
```
|
|
|
|
### Analysis & Debug (70-90% savings)
|
|
```bash
|
|
rtk err <cmd> # Filter errors only from any command
|
|
rtk log <file> # Deduplicated logs with counts
|
|
rtk json <file> # JSON structure without values
|
|
rtk deps # Dependency overview
|
|
rtk env # Environment variables compact
|
|
rtk summary <cmd> # Smart summary of command output
|
|
rtk diff # Ultra-compact diffs
|
|
```
|
|
|
|
### Infrastructure (85% savings)
|
|
```bash
|
|
rtk docker ps # Compact container list
|
|
rtk docker images # Compact image list
|
|
rtk docker logs <c> # Deduplicated logs
|
|
rtk kubectl get # Compact resource list
|
|
rtk kubectl logs # Deduplicated pod logs
|
|
```
|
|
|
|
### Network (65-70% savings)
|
|
```bash
|
|
rtk curl <url> # Compact HTTP responses (70%)
|
|
rtk wget <url> # Compact download output (65%)
|
|
```
|
|
|
|
### Meta Commands
|
|
```bash
|
|
rtk gain # View token savings statistics
|
|
rtk gain --history # View command history with savings
|
|
rtk discover # Analyze Claude Code sessions for missed RTK usage
|
|
rtk proxy <cmd> # Run command without filtering (for debugging)
|
|
rtk init # Add RTK instructions to CLAUDE.md
|
|
rtk init --global # Add RTK to ~/.claude/CLAUDE.md
|
|
```
|
|
|
|
## Token Savings Overview
|
|
|
|
| Category | Commands | Typical Savings |
|
|
|----------|----------|-----------------|
|
|
| Tests | vitest, playwright, cargo test | 90-99% |
|
|
| Build | next, tsc, lint, prettier | 70-87% |
|
|
| Git | status, log, diff, add, commit | 59-80% |
|
|
| GitHub | gh pr, gh run, gh issue | 26-87% |
|
|
| Package Managers | pnpm, npm, npx | 70-90% |
|
|
| Files | ls, read, grep, find | 60-75% |
|
|
| Infrastructure | docker, kubectl | 85% |
|
|
| Network | curl, wget | 65-70% |
|
|
|
|
Overall average: **60-90% token reduction** on common development operations.
|
|
<!-- /rtk-instructions -->
|