- 更新 CI/CD 子域名反向代理配置 - 调整 Nginx 静态文件服务器配置 - 更新 CONTEXT.md 领域共享语言文档 - 添加 CLAUDE.md 代理工作指南 - 更新 Playwright E2E 测试配置
13 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Common Commands
# 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 intailwind.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 returnsT | 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:
- L1 Hero: Emotional entry with visual, title, value prop, status badge
- L2 Value Rationale: Product-specific — features/benefits for products, pain-points→architecture for solutions, challenges→results for services
- L3 Trust Proof: Case studies, data proofs, certifications, testimonials (currently stubbed — company is pre-launch)
- 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.tsxsolution-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 definitionsContentZoneRenderer.tsx— Renders a zone's items in grid/list/carousel layouts, delegating each item togetItemRenderer(modelCode)from the component registrymock-home.ts— Mock data for the homepage zonescomponent-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'sfontSize/lineHeight/letterSpacingscales - 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 definitionscases.ts— Case studies with industry filteringnavigation.ts— Nav structure + mega dropdown datacompany.ts,stats.ts,team.ts,news.ts,methodology.tshero-themes.ts— Per-product hero visual theme variantscross-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 inconfig/test/jest.config.js. Uses@/path alias and ts-jest withjsx: 'react-jsx'transform (since tsconfig uses'preserve'). Run single tests withnpx jest --testPathPattern="component-name". - Playwright (E2E): Tests in
e2e/, config ine2e/playwright.config.ts. Auto-startsnpm run previewas web server. Visual regression snapshots ine2e/visual-snapshots/. Three browser projects (chromium, firefox, webkit) plus dedicated visual regression projects at desktop/tablet/mobile breakpoints. Run single tests withnpx 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 todetail/completed)components/detail-v3/— another iteration (deleted, same reason)home-content-v2.tsxthroughhome-content-v11.tsx— archived homepage iterations in(marketing)/_archive/- The current canonical components are in
components/detail/andhome-content-cms.tsx