cf99e7556c
- 更新 CI/CD 子域名反向代理配置 - 调整 Nginx 静态文件服务器配置 - 更新 CONTEXT.md 领域共享语言文档 - 添加 CLAUDE.md 代理工作指南 - 更新 Playwright E2E 测试配置
193 lines
13 KiB
Markdown
193 lines
13 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Common Commands
|
|
|
|
```bash
|
|
# Development
|
|
npm run dev # Start dev server on port 3000
|
|
npm run dev:clean # Clean .next/dist then start dev server
|
|
|
|
# Build & Preview
|
|
npm run build # Build production files to dist/
|
|
npm run build:clean # Clean then build
|
|
npm run preview # Serve dist/ on port 3000 (npx serve)
|
|
|
|
# Linting & Type Checking
|
|
npm run lint # ESLint (configured in config/lint/.eslintrc.json)
|
|
npm run type-check # tsc --noEmit
|
|
|
|
# E2E Testing (Playwright)
|
|
npm run test # Run all E2E tests
|
|
npm run test:e2e # Same as above
|
|
npm run test:smoke # Only @smoke-tagged tests
|
|
npm run test:visual # Visual regression (Desktop Chrome)
|
|
npm run test:visual:all # Visual regression (all projects)
|
|
npm run test:visual:update # Update visual snapshots
|
|
npx playwright test --grep "test name" # Run a single E2E test by name
|
|
|
|
# Unit Testing (Jest)
|
|
npm run test:unit # Run all unit tests
|
|
npm run test:coverage # Coverage report (thresholds: 80% branches/functions/lines)
|
|
npx jest --testPathPattern="button" # Run a single test file matching pattern
|
|
|
|
# Quality Checks
|
|
npm run check:contrast # Color contrast audit
|
|
npm run check:headings # Heading hierarchy audit
|
|
npm run lighthouse # Lighthouse CI performance audit
|
|
|
|
# Database (Prisma + SQLite)
|
|
npm run db:seed # Seed the dev database
|
|
npm run db:reset # Reset database with migrations
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Tech Stack
|
|
- **Next.js 14** (App Router) with **hybrid rendering** — static pages + API routes (Note: `output: 'export'` was recently removed; the project is transitioning away from pure static export)
|
|
- **React 18**, **TypeScript 5** (strict mode with `noUncheckedIndexedAccess`)
|
|
- **Tailwind CSS 3** with design tokens exposed as CSS custom properties (all tokenized via `var()` references in `tailwind.config.js`)
|
|
- **Framer Motion** for animations, **Lucide React** for icons, **Zod** for validation
|
|
- **shadcn/ui** pattern (Radix UI + class-variance-authority + tailwind-merge)
|
|
- **Prisma** with SQLite for backend data (admin, auth, CMS)
|
|
|
|
### Path Alias
|
|
`@/` maps to `src/` — configured in both `tsconfig.json` (`paths`) and `jest.config.js` (`moduleNameMapper`).
|
|
|
|
### TypeScript Strictness
|
|
Beyond `strict: true`, the project enables:
|
|
- `noUncheckedIndexedAccess: true` — array/object index access returns `T | undefined`, requiring null checks. This is a significant constraint to be aware of when writing code.
|
|
- `noImplicitReturns`, `noFallthroughCasesInSwitch`, `noUnusedLocals`, `noUnusedParameters`
|
|
|
|
### Route Structure (App Router)
|
|
```
|
|
src/app/
|
|
├── layout.tsx # Root layout: fonts, metadata, theme, analytics, SEO schemas
|
|
├── (marketing)/ # Route group — all public marketing pages
|
|
│ ├── layout.tsx # Shared: Header + Footer + PageTransition + ErrorBoundary
|
|
│ ├── page.tsx # Home (delegates to home-content-cms.tsx)
|
|
│ ├── about/ # About page (client.tsx)
|
|
│ ├── news/ # News list + [slug] detail
|
|
│ ├── contact/ # Contact form
|
|
│ ├── products/ # Products hub (HSI model)
|
|
│ │ ├── page.tsx # Product listing (enterprise suites + standalone)
|
|
│ │ ├── [id]/ # Product detail (four-layer narrative)
|
|
│ │ ├── standalone/[id]/ # Standalone product detail
|
|
│ │ ├── erp-upgrade/ # Specific product landing pages
|
|
│ │ └── erp-upgrade-v3/
|
|
│ ├── services/ # Services list + [id] detail
|
|
│ ├── solutions/ # Solutions list + [id] detail (cross-references products)
|
|
│ ├── cases/ # Case studies
|
|
│ └── team/ # Team page
|
|
├── api/
|
|
│ ├── admin/ # Admin API
|
|
│ ├── auth/ # Authentication API
|
|
│ ├── cms/ # CMS API routes (draft mode, revalidation)
|
|
│ └── contact/ # Contact form submission
|
|
├── privacy/, terms/ # Legal pages
|
|
└── fonts/ # Local font files (Geist Sans/Mono)
|
|
```
|
|
|
|
### Archiving Convention
|
|
When replacing a page or component with a new version, move the old one to an `_archive/` subdirectory (e.g., `src/app/(marketing)/_archive/` for old homepage iterations). The archive is excluded from TypeScript compilation via `tsconfig.json`.
|
|
|
|
### Dark Mode
|
|
Dark mode uses the `data-theme="dark"` HTML attribute (not Tailwind's `dark:` class). An inline `<script>` in the root layout sets the attribute before paint to prevent flash of unstyled content (FOUC). The Tailwind config uses `darkMode: 'class'` as the mechanism, driven by the `data-theme` attribute via CSS selectors.
|
|
|
|
### HSI Information Architecture
|
|
The site follows a **Hub-Spoke-Independent** model (see `CONTEXT.md` and ADR-0002):
|
|
- **Hub**: `/products` — product catalog, split into "企业套装" (6 enterprise products) and "专业产品" (standalone)
|
|
- **Spoke**: `/solutions` — industry scenarios, each recommending product combinations from the Hub
|
|
- **Independent**: Standalone products in the specialized zone have their own narrative path
|
|
|
|
### Four-Layer Narrative Model
|
|
Every detail page (product/service/solution/standalone) follows the same four-layer structure:
|
|
1. **L1 Hero**: Emotional entry with visual, title, value prop, status badge
|
|
2. **L2 Value Rationale**: Product-specific — features/benefits for products, pain-points→architecture for solutions, challenges→results for services
|
|
3. **L3 Trust Proof**: Case studies, data proofs, certifications, testimonials (currently stubbed — company is pre-launch)
|
|
4. **L4 CTA Conversion**: Primary action + secondary action + cross-recommendations
|
|
|
|
The detail components implementing this live in `src/components/detail/`:
|
|
- `detail-hero.tsx`, `detail-product-value.tsx`, `detail-trust-section.tsx`, `detail-cta-section.tsx`
|
|
- `solution-value.tsx`, `service-value.tsx` (type-specific L2 variants)
|
|
- `detail-cross-recommend.tsx` (cross-links between products↔solutions↔services)
|
|
|
|
### CMS Content Architecture
|
|
The app has a **mock CMS layer** at `src/lib/cms/` that simulates a headless CMS (no real backend — designed to be swapped with real API calls later):
|
|
- `types.ts` — ContentModel, ContentItem, ContentZone, ThemeConfig definitions
|
|
- `ContentZoneRenderer.tsx` — Renders a zone's items in grid/list/carousel layouts, delegating each item to `getItemRenderer(modelCode)` from the component registry
|
|
- `mock-home.ts` — Mock data for the homepage zones
|
|
- `component-registry.ts` — Maps model codes to React renderer components
|
|
|
|
The homepage (`home-content-cms.tsx`) initializes the CMS and fetches mock content zones (hero, stats, services, solutions, cases, news).
|
|
|
|
### Design Token System
|
|
All visual tokens are defined as **CSS custom properties** in `src/app/globals.css` (`:root` block) and mapped into Tailwind's config via `var()` references:
|
|
- **Colors**: `--color-ink` (deep charcoal #0A0E14), `--color-brand` (vermilion #C41E3A), accent colors for service-coding (blue, teal, amber, purple), functional colors (success, warning, error, info), dark-section overrides
|
|
- **Typography**: `--font-size-*`, `--line-height-*`, `--letter-spacing-*` all mapped to Tailwind's `fontSize`/`lineHeight`/`letterSpacing` scales
|
|
- **Spacing, radius, shadows** all tokenized through CSS variables
|
|
- **Transitions**: `--transition-fast/normal/slow`, `--ease-ink` (cubic-bezier), `--ease-sharp`, `--ease-spring-soft`
|
|
- **Dark mode**: `data-theme="dark"` attribute (set via inline script before paint to prevent flash)
|
|
|
|
### Design DNA Framework
|
|
The site follows a three-dimensional design system (see `CONTEXT.md`):
|
|
- **Dimension 1 — Design System**: Quantifiable tokens (colors, typography, spacing, radius, shadows, motion, components)
|
|
- **Dimension 2 — Design Style**: Qualitative perception (atmosphere, visual language, composition, imagery, brand tone)
|
|
- **Dimension 3 — Visual Effects**: Scroll animations, micro-interactions, parallax, SVG effects
|
|
|
|
The **Consulting Professional** aesthetic (inspired by Accenture + Bain) is the primary skeleton. **Ink cultural elements** (水墨) are secondary decorations limited to ≤6 locations (logo, dividers, transition animations, footer texture).
|
|
|
|
**Brand red (#C41E3A) usage rule**: Every page must have ≥3 brand-red touchpoints. It must never be used as paragraph text color, large backgrounds, or alongside accent colors in the same card. Area ≤10%.
|
|
|
|
**Motion design**: Animations are purposeful (not decorative), fast (150-300ms), use `ease-ink` [0.22, 1, 0.36, 1] as default easing, and stagger children by 30-60ms. No continuous looping animations except pulse-soft for skeletons. No spring easings for content entry. No animations >700ms.
|
|
|
|
### Data Layer
|
|
All structured content data is in `src/lib/constants/` as TypeScript constants — no API/database for marketing content:
|
|
- `products.ts` — 6 enterprise products (ERP, CRM, CMS, BI, SDS, OA) + standalone products (NovaVis)
|
|
- `services.ts`, `solutions.ts` — Service and solution definitions
|
|
- `cases.ts` — Case studies with industry filtering
|
|
- `navigation.ts` — Nav structure + mega dropdown data
|
|
- `company.ts`, `stats.ts`, `team.ts`, `news.ts`, `methodology.ts`
|
|
- `hero-themes.ts` — Per-product hero visual theme variants
|
|
- `cross-references.ts` — Cross-links between products/solutions/services
|
|
|
|
Each product/solution/service implements the `Product`/`Solution`/`Service` interface which includes `caseStudies[]`, `dataProofs[]`, `certifications[]`, etc. for the four-layer narrative.
|
|
|
|
### Backend Layer (Prisma + API Routes)
|
|
The project has a backend layer for admin/auth/CMS functionality:
|
|
- **Prisma** with SQLite (`prisma/dev.db`) for admin user data, auth, and CMS content management
|
|
- API routes at `src/app/api/admin/`, `auth/`, `cms/`, `contact/`
|
|
- The marketing pages use mock data from `src/lib/cms/mock-home.ts`, but the CMS API routes suggest a real CMS backend is planned
|
|
|
|
### Component Organization
|
|
```
|
|
src/components/
|
|
├── ui/ # Base: Button, Card, Input, Badge, ScrollReveal, AnimatedCounter, etc.
|
|
├── layout/ # Header, Footer, MobileTabBar, Breadcrumb, MegaDropdown, MobileMenu
|
|
├── sections/ # Page section components: HeroSectionV2, ServiceGrid, CTASection, etc.
|
|
├── detail/ # Four-layer narrative: DetailHero, ProductValueSection, DetailTrustSection, etc.
|
|
├── seo/ # Structured data (OrganizationSchema, WebsiteSchema, etc.)
|
|
├── analytics/ # GA4, error tracking, cookie consent, scroll depth, outbound links
|
|
├── cms/ # CMS renderers (ContentRenderer, SectionRenderer, FieldRenderer)
|
|
├── content/ # sections.tsx, testimonials.tsx
|
|
└── providers/ # (currently empty)
|
|
```
|
|
|
|
### Testing Setup
|
|
- **Jest** (unit): Tests alongside source in `src/**/*.test.{ts,tsx}`, coverage threshold 80%. Config in `config/test/jest.config.js`. Uses `@/` path alias and ts-jest with `jsx: 'react-jsx'` transform (since tsconfig uses `'preserve'`). Run single tests with `npx jest --testPathPattern="component-name"`.
|
|
- **Playwright** (E2E): Tests in `e2e/`, config in `e2e/playwright.config.ts`. Auto-starts `npm run preview` as web server. Visual regression snapshots in `e2e/visual-snapshots/`. Three browser projects (chromium, firefox, webkit) plus dedicated visual regression projects at desktop/tablet/mobile breakpoints. Run single tests with `npx playwright test --grep "test name"`.
|
|
|
|
### Build Output
|
|
The project builds to `dist/` (configured via `distDir` in `next.config.mjs`). It is served via Nginx (see `nginx-static-production.conf`) with CDN support (`assetPrefix` respects `CDN_DOMAIN` env var). Images are unoptimized (static export limitation). Note: `output: 'export'` was recently removed from the config — the project may be moving toward a hybrid SSR + static model.
|
|
|
|
### Commit Convention
|
|
Uses Conventional Commits with commitlint (`@commitlint/config-conventional`). Husky + lint-staged enforces linting on pre-commit.
|
|
|
|
### Component Versioning History
|
|
The project has gone through multiple design iterations. Older component versions:
|
|
- `components/detail-v2/` — previous iteration (deleted per git status, migration to `detail/` completed)
|
|
- `components/detail-v3/` — another iteration (deleted, same reason)
|
|
- `home-content-v2.tsx` through `home-content-v11.tsx` — archived homepage iterations in `(marketing)/_archive/`
|
|
- The current canonical components are in `components/detail/` and `home-content-cms.tsx`
|