- docs/acceptance/qa-tracker.md:跨周期缺陷单一真源台账(§7=第五轮)。 - 周期 1/2 + iPhone SE/axe 验收证据目录、ACCEPTANCE_REVIEW 快照入库。 - 同步 README/CONTEXT/CLAUDE/DESIGN/testing/deployment/lessons-learned 口径; next.config/Dockerfile/nginx/Jenkinsfile/docker-compose/sentry/prisma 对齐 standalone 产物装配与部署形态。
Novalon Website
四川睿新致远科技有限公司官方网站 - 企业数字化转型服务商
项目概述
本项目是四川睿新致远科技有限公司的企业官网,采用 Next.js 16 + React 18 + TypeScript 技术栈构建,以静态生成(SSG)为主、混合渲染(SSR/ISR)为辅,提供现代化的企业展示、产品服务介绍、案例展示、新闻动态等功能。
核心功能
- 首页展示 - Hero 区域、核心业务、产品服务、成功案例、关于我们、新闻动态
- 服务详情 - 软件开发、云服务、数据分析、信息安全等服务详细介绍
- 产品展示 - 产品列表和详情页面
- 案例展示 - 成功案例列表和详情
- 新闻动态 - 公司新闻、产品发布、合作动态、行业资讯
- 响应式设计 - 完美适配桌面端、平板和移动设备
- SEO 优化 - 结构化数据、元信息优化
项目规划
- 2026-07:UI 重构(四层叙事模型、咨询专业风)、CMS 全覆盖、安全加固、封版发布
v1.0.0-phase1 - 2026-08:全量测试基线建立(单元 ~1600 / E2E
800 / UJ-01UJ-11)/ 官网产品模块品牌矩阵定位(产品外链独立站)/ 结构性文案全站 CMS 化(page-copy)/ 信任证据阶段 0(成立 <1 年策略) - 2026-08-20:生产部署上线 + 生产目录 Drizzle 残留归档清理
详细历史里程碑、测试验收报告见 docs/deployment.md 与 docs/testing 目录。
项目进度
-
首页/关于/产品/新闻等核心页面可访问性修复
-
JWT、中间件、表单、CMS 接口安全加固
-
CMS 全覆盖:法律页、新闻、团队、案例、服务、方案、产品、独立产品、首页运营位(ContentZone)、RBAC/工作流/媒体/通知全部从 CMS 读取并启用 ISR(3600s)
-
CMS 管理后台:角色权限界面(
/admin/roles)、内容模型 × 操作权限矩阵、super_admin 锁定 -
全量测试体系:单元 134 suites / 1697 例 / 功能 E2E 1080 例(270 例 × chromium + chromium-mobile + firefox + webkit 四个 project)/ 视觉回归 125 例(25 例 × 桌面·平板·移动·firefox·webkit 五个 project)/ 用户旅程 UJ-01~UJ-11 / Lighthouse / k6 负载压力 / 安全扫描,全部通过。计数为 2026-09-23 本树复跑实测(
npm run test:coverage⇒Test Suites: 134 passed/Tests: 1697 passed/ EXIT=0;cd e2e && npx playwright test --list⇒Total: 1205 tests in 22 files= 1080 + 125),非估算;计数随树漂移,引用请附复算命令 -
官网产品模块定位(IHG/字节式品牌矩阵,2026-08-19):官网品牌宣传为主,产品矩阵页为聚合入口;成熟产品
externalUrl外链独立站(NovaVis → novavis.p.novalon.cn);未成熟产品详情页占位,独立站上线后切换外链 -
结构性文案全站 CMS 化(2026-08-19):新增
page-copy内容模型承载全部营销页面章节标题/眉标/描述/CTA/空状态(首页 + 服务/方案/产品/案例/新闻列表页),「CMS 优先 + 硬编码兜底」不白屏;seed 写入 6 条,本地 db:seed 已生效 -
信任证据补齐·阶段 0(成立 <1 年策略,2026-08-20):信任策略从「结果证据」转向「可验证的过程 + 能力 + 治理证据」——首页「首批客户共创计划」板块(共创进行中/产品内测中/成果授权公开三档如实状态 + 招募 CTA)+ 关于页资质「建设中」如实空态,零编造
-
生产部署上线(2026-08-20):
deploy.sh deploy(本地 dist → 远端容器重建)+ 生产库 seed(page-copy/methodology 数据)完成;生产目录 Drizzle 残留源码归档清理;站点全路由 200、生产库 Prisma 结构 -
数字口径结构强制(2026-09-20,critique P0 收尾):共享数字样式渲染的指标(
metrics/outcomes/dataProofs)统一携带basis: target|team-history|verified,渲染端自动附口径角注、未声明保守回落target;CMS 新增basisselect 录入字段;删除产品详情页「每一项指标都源自真实客户案例」「经实际场景验证」等虚构佐证并补注角注;metrics-basis.test.ts机械校验声明完整性并拦截虚构佐证禁词 -
信任证据补齐·阶段 1/2(待内测/试点客户素材):如实披露「共创中/内测中/已交付」三档 + 经授权客户(脱敏);有交付成果后经授权公示可量化结果(零编造原则)——口径字段与 admin 录入口已就绪,待真实数据把
basis从target升级为verified
技术栈
| 类别 | 技术 | 版本 |
|---|---|---|
| 框架 | Next.js | 16.2.11 |
| UI 库 | React | 18.3.1 |
| 语言 | TypeScript | 5.x |
| 样式 | Tailwind CSS | 3.4.17 |
| 代码检查 | ESLint | 9.25.1 |
| 组件库 | shadcn/ui (Radix UI) | - |
| 动画 | Framer Motion | 12.x |
| 图标 | Lucide React | 0.563.0 |
| 数据验证 | Zod | 4.3.6 |
| 图表 | @antv/g2 | 5.4.8 |
| 3D 效果 | Three.js | 0.183.1 |
快速开始
环境要求
- Node.js 18+
- npm / yarn / pnpm / bun
安装依赖
npm install
开发模式
npm run dev
构建生产版本
npm run build
输出目录: dist/
预览生产版本
npm run build # 先产出 dist/
npm run preview # == npm run start == `next start -p 3000`(不是 `npx serve`)
preview 是 start 的同义别名,两者都是 next start -p 3000。项目为 output: 'standalone',Next 16 在此组合下会打印
"next start" does not work with "output: standalone" configuration. Use "node .next/standalone/server.js" instead.
——这是警告而非抛错,服务仍会起来,但走的是不受支持的降级路径,因此它已不再被任何门禁当作产物口径:
- 受支持的启动方式是
node dist/standalone/server.js(静态资源由package.json:9的postbuild在npm run build末尾自动拷入dist/standalone/,standalone 产物本身不含dist/static与public,缺了它们/_next/static/**全 404)。该启动方式尚未做成 npm script,目前由check:axe、check:headings、e2e/playwright.config.ts:134(E2E_TARGET=production)与Jenkinsfile各自直接node起。 npm run test:e2e:prod走的是上面这条受支持路径(e2e/playwright.config.ts:132-135),不是next start。npm run check:headings存在产物时直起 standalone,仅在产物缺失时回退npm run preview并打印告警(scripts/utils/check-heading-hierarchy.ts:52-67,验收 N-24③)。
详见 CLAUDE.md「Build & Preview」。
项目结构
novalon-website/
├── src/ # 源代码
│ ├── app/ # Next.js App Router
│ │ ├── (marketing)/ # 营销页面路由组
│ │ │ ├── page.tsx # 首页
│ │ │ ├── home-content-v15.tsx # 首页内容装配(V1.5)
│ │ │ ├── about/ # 关于我们
│ │ │ ├── team/ # 团队
│ │ │ ├── cases/ # 成功案例
│ │ │ ├── contact/ # 联系我们
│ │ │ ├── methodology/ # 方法论
│ │ │ ├── news/ # 新闻动态
│ │ │ ├── products/ # 产品服务
│ │ │ ├── services/ # 核心业务
│ │ │ └── solutions/ # 解决方案
│ │ ├── admin/ # CMS 管理后台
│ │ ├── api/ # 服务端接口(表单、CMS、鉴权)
│ │ ├── privacy/ # 隐私政策
│ │ ├── terms/ # 服务条款
│ │ ├── layout.tsx # 根布局
│ │ ├── error.tsx # 根段错误页面
│ │ ├── global-error.tsx # 全局错误边界
│ │ └── not-found.tsx # 404 页面
│ ├── components/ # React 组件
│ │ ├── ui/ # 基础 UI 组件
│ │ ├── layout/ # 布局组件
│ │ ├── sections/ # 页面区块组件
│ │ ├── content/ # 内容渲染组件(`sections.tsx`)
│ │ ├── detail/ # 详情页组件
│ │ ├── admin/ # 后台组件
│ │ ├── theme/ # 主题组件
│ │ ├── seo/ # SEO 组件
│ │ └── analytics/ # 分析组件
│ ├── hooks/ # 自定义 Hooks
│ ├── lib/ # 工具与领域逻辑(含 `cms/`、`constants/`、`media/`)
│ └── types/ # 类型声明
├── e2e/ # Playwright E2E + 视觉回归(**无独立 package.json**,依赖装在根目录)
├── tests/ # 非 Playwright 资产
│ ├── performance/ # k6 负载/压力脚本(由 k6 CLI 跑,不在 npm scripts 内)
│ ├── lib/ # 集成测试
│ ├── styles/ # 样式测试
│ └── screenshots/ # 截图基线
├── docs/ # 项目文档
├── scripts/ # 脚本文件
├── config/ # 配置文件
├── public/ # 静态资源
└── dist/ # 构建输出
页面路由
| 路由 | 描述 |
|---|---|
/ |
首页 |
/about |
关于我们 |
/services |
核心业务列表 |
/services/[id] |
业务详情 |
/products |
产品服务列表 |
/products/[id] |
产品详情 |
/cases |
成功案例列表 |
/cases/[id] |
案例详情 |
/news |
新闻动态列表 |
/news/[slug] |
新闻详情 |
/contact |
联系我们 |
/privacy |
隐私政策 |
/terms |
服务条款 |
NPM 脚本
| 命令 | 描述 |
|---|---|
npm run dev |
启动开发服务器 |
npm run build |
构建生产版本 |
npm start |
启动生产服务器 |
npm run lint |
运行 ESLint 检查 |
npm run type-check |
TypeScript 类型检查 |
npm run test |
全链路 E2E:test:functional(4 project ⇒ 1080 实例)→ test:visual:all(5 project ⇒ 125 实例)串行,--list 合计 1205。webServer 默认是 dev server,见 test:e2e:prod |
npm run test:unit |
运行单元测试(Jest,2026-09-23 本树复跑实测 134 suites / 1697 tests) |
npm run test:coverage |
运行测试覆盖率。阈值单一真源 config/test/jest.config.js 的 coverageThreshold(全局 statements/lines/functions ≥ 75%、branches ≥ 82%);实测值单一记录位见 docs/development/quality-gates.md §3,本文件不再复制百分比以免再次互斥 |
npm run test:e2e:fast |
运行 E2E 快速测试(@smoke + @critical 标签) |
npm run test:e2e:standard |
运行 E2E 标准回归测试(@regression 标签) |
npm run test:smoke |
运行 E2E 冒烟测试(@smoke 标签) |
npm run test:critical |
运行 E2E 关键路径测试(@critical 标签) |
npm run test:e2e:journey |
运行用户旅程测试(@journey 标签,UJ-01/UJ-02) |
npm run test:e2e:prod |
产物目标 E2E(E2E_TARGET=production → harness 新起 node dist/standalone/server.js,不是 npm run start——standalone 下 next start 不受支持;@smoke|@critical|@journey × 4 project)。只有 GA4 的 16 例在这里真正断言;生产响应头不在此 grep 集合内(它属 @security 标签与 test:security:headers,勿混)(2026-09-23 实测:排除 2 个写库 spec 后 92 例通过、0 skipped);须先 npm run build(postbuild 负责装配 dist/static + public) |
npm run test:e2e:mobile |
运行移动端 E2E 测试(@mobile 标签:55 个用例(16 mobile.spec.ts + 5 mobile-user-journeys.spec.ts + 14 mobile-accessibility.spec.ts + 18 mobile-performance.spec.ts + 2 uj-11-home-conversion.spec.ts),4 个功能 project 全跑 ⇒ 220 个实例;cd e2e && npx playwright test --list --grep @mobile 实测 Total: 220 tests in 5 files) |
npm run test:e2e:mobile:performance |
运行移动端性能基线测试(FCP/LCP/加载时间) |
npm run test:e2e:mobile:accessibility |
运行移动端可访问性测试(axe-core WCAG 2.1 AA) |
npm run test:mutation |
运行变异测试(Stryker,评估测试质量)。分数不在此声明:全量轮耗时以十分钟计且 --inPlace 会改动工作树,本轮未复跑;最近一次落盘记录为整体 36.98%(docs/test-strategy-plan.md P4.5 / 验收清单条目,2026-08 轮次),引用时须附该出处与 npm run test:mutation 复算命令 |
npm run test:mutation:quick |
快速变异测试(--mutate 'src/lib/utils.ts',同一落盘记录 91.18%,出处同上) |
npm run test:security |
安全扫描(npm audit + 安全响应头检查) |
npm run test:security:headers |
安全响应头检查(X-Content-Type-Options, CSP, HSTS 等) |
npm run check:a11y |
可访问性静态门禁伞:check:contrast(令牌对比度,只读 globals.css)+ check:headings(标题层级,有产物直起 standalone、缺产物才回退 preview)+ check:brand-token(双通道红) |
npm run check:axe:routes |
生成全站路由清单:sitemap ∪ 预渲染产物 ∪ 站内链接 BFS → /tmp/axe-routes.xml(scripts/accessibility/crawl-routes.mjs;退出码 0/2) |
npm run check:axe |
双引擎 × 双主题逐页 axe 节点计数 + 三条规则级通道的分母断言(scripts/accessibility/axe-node-count.mjs);退出码 0 通过 / 1 判红 / 2 清单缺失。需先有 node dist/standalone/server.js 在 :3100;不在 test:all 内,CI 由 Jenkinsfile「♿♿」阶段(仅 main)执行 |
npm run test:all |
全量门禁检查,package.json:48 原文七段:type-check + lint + coverage + test:integration:real + check:a11y + fast E2E + security headers;其 E2E 段仍是 dev 目标,GA4 @critical 在其中 skipped,需另跑 test:e2e:prod |
npm run lighthouse |
运行 Lighthouse 性能测试 |
代码质量门禁
项目配置了自动化质量门禁,确保代码提交前通过所有质量检查:
- ESLint: 代码风格检查(pre-commit 经 husky + lint-staged 跑
eslint --fix,CI 跑全仓npm run lint;判定口径 0 error,warning 不判红) - commitlint: 提交信息规范(
.husky/commit-msg) - Jest: 代码覆盖率检查(阈值单一真源
config/test/jest.config.js) - 可访问性:
npm run check:a11y(对比度 / 标题层级 / 双通道红),CI 在「♿ 可访问性门禁」阶段逐条执行同一组 - TypeScript:
npm run type-check—— 不在 pre-commit(.lintstagedrc.json只跑eslint --fix),推送前须自行执行 - E2E 目标:
npm run test打 dev server;GA4 的 16 个@critical实例在该轮为 skipped,产物口径见npm run test:e2e:prod(详见 docs/development/quality-gates.md §5–§7)
提交规范
使用 Conventional Commits 规范:
<type>(<scope>): <subject>
提交类型:
feat: 新功能fix: 修复bugdocs: 文档更新style: 代码格式调整refactor: 重构perf: 性能优化test: 测试相关chore: 构建/工具相关
测试
项目采用多层测试策略,涵盖单元测试、集成测试、E2E 测试、用户旅程测试、视觉回归测试、变异测试等。
测试工具链
| 工具 | 用途 | 配置 |
|---|---|---|
| Jest | 单元测试(2026-09-23 本树复跑:134 suites / 1697 tests) | config/test/jest.config.js |
| Playwright | E2E / 视觉回归 / 用户旅程测试(--list 实测 1205 例 = 功能 1080 + 视觉 125) |
e2e/playwright.config.ts |
| Stryker | 变异测试(评估测试质量) | stryker.config.json |
| Allure | 测试报告可视化 | Allure Playwright reporter |
| k6 | 负载/压力/API 性能测试 | tests/performance/ |
| Lighthouse CI | 性能/可访问性/SEO 审计 | config/test/lighthouserc.json |
E2E 测试标签体系
| 标签 | 用途 | 执行命令 |
|---|---|---|
@smoke |
冒烟测试:核心功能 | npm run test:smoke |
@critical |
关键路径:CMS 工作流等 | npm run test:critical |
@smoke + @critical |
快速回归(<5min) | npm run test:e2e:fast |
@regression |
全量回归(<15min) | npm run test:e2e:standard |
@journey |
用户旅程(UJ-01/UJ-02) | npm run test:e2e:journey |
@mobile |
移动端专项测试(55 个用例:16 基础 + 5 用户旅程 + 14 可访问性 + 18 性能 + 2 UJ-11c;× 4 project = 220 实例) | npm run test:e2e:mobile |
| (无标签) | 视觉回归:@visual 标签并不存在(e2e/ 全量 grep 为 0 命中),视觉用例由 5 个 visual-* project 通过 testMatch 选中,且只跑 visual-regression.spec.ts(25 例 × 5 project = 125 实例) |
npm run test:visual:all |
运行测试
# 单元测试
npm run test:unit # 134 suites / 1697 tests(2026-09-23 本树复跑)
# 测试覆盖率
npm run test:coverage # 阈值: 全局 statements/lines/functions ≥75%、branches ≥82%
# 实测值见 docs/development/quality-gates.md §3(此处不复制百分比)
# E2E 测试
npm run test # 全量 E2E = 功能 1080 + 视觉 125 = 1205 实例
# 落盘通过数引自 docs/acceptance/2026-09-21-gates/skipped-tests-final-tree.json
# (totalResults 1195 = 1167 passed / 28 skipped,生成于 2026-09-22 的 chain6 最终树);
# 本轮未重跑全量 E2E(需 dev server + 4 引擎 + 视觉基线,且 28 条 skip 需按该文件逐条解释)
npm run test:e2e:fast # 快速回归(@smoke + @critical)
npm run test:e2e:standard # 标准回归(@regression)
npm run test:e2e:journey # 用户旅程(@journey)
# 移动端测试
npm run test:e2e:mobile # 全量移动端(55 个 @mobile 用例 × 4 project = 220 实例)
npm run test:e2e:mobile:performance # 移动端性能基线
npm run test:e2e:mobile:accessibility # 移动端可访问性
# 变异测试(分数只引 docs/test-strategy-plan.md 的落盘记录,本仓未复跑)
npm run test:mutation # 全量变异测试
npm run test:mutation:quick # 快速变异(仅 utils.ts)
# 全量门禁检查
npm run test:all # type-check + lint + coverage + integration:real + check:a11y + fast E2E(dev 目标) + security headers
部署
统一发布脚本(推荐)
项目发布统一通过 scripts/deploy.sh 完成,包含构建、发布、回滚、状态查看:
# 构建产物(`next build`,output=standalone;脚本再把 public/ 同步进 dist、把 dist/static 复制为 dist/_next/static 供 Nginx 直服)
./scripts/deploy.sh build
# 构建并发布到生产服务器(默认命令,等价于 ./scripts/deploy.sh deploy)
./scripts/deploy.sh deploy
# 使用现有 dist/ 直接发布(跳过本地构建)
./scripts/deploy.sh deploy --skip-build
# 回滚到最近一次远程备份
./scripts/deploy.sh rollback
# 查看生产环境发布状态
./scripts/deploy.sh status
# 查看完整帮助
./scripts/deploy.sh help
常用选项:
./scripts/deploy.sh deploy --skip-build --auto-rollback
./scripts/deploy.sh deploy --server-ip 139.155.109.62 --project-name novalon-website
也可通过环境变量覆盖默认配置:SERVER_IP、SERVER_USER、DEPLOY_ROOT、PROJECT_NAME、NGINX_CONTAINER、DOMAIN、BACKUP_RETENTION_COUNT、DIST_DIR。
npm 快捷命令:npm run deploy、npm run deploy:skip-build、npm run deploy:rollback、npm run deploy:status。
混合渲染构建(当前)
项目当前使用 output: 'standalone',构建产物位于 dist/:
npm run build
生产部署采用混合渲染:
- Nginx 直接托管
dist/中的公共静态资源(图片、字体、_next/static等) /api/*、/admin/*及 ISR/SSR 回源代理到 Next.js 容器novalon-website:3000- Next.js 容器通过
Dockerfile.prod+docker-compose.server.yml启动,SQLite 数据库挂载在./data
# 本地构建
npm run build
# 服务器构建并启动 Next.js 容器
cd /home/novalon/docker-app/novalon-website
docker-compose -f docker-compose.server.yml up -d --build
生产环境历史残留清理(Drizzle)
生产服务器 /home/novalon/docker-app/novalon-website 曾残留一套使用 Drizzle ORM 的历史源码(src/db/、drizzle/、drizzle.config.ts)。经核实,生产实际运行的环境为 Prisma CMS(容器从 dist/ standalone 构建,含 @prisma/client 与 prisma/seed.ts),上述 Drizzle 源码不参与任何构建/部署/运行。
2026-08-20 已将 Drizzle 专属残留归档至 archive-Drizzle-20260820_094628/(含 src/db/、drizzle/、drizzle.config.ts)。同批做了一次更大范围整理:将历史源码/测试/文档/旧备份归档至 archive-src-cleanup-20260820_095755/(含 src/、playwright-*、test-framework、tests、e2e、reports、docs、monitoring、html 等)与 archive-misc-20260820_095824/(含根 data.db、scripts.backup、test-results、旧 dist_backup_20260818_* 等)。生产确认保留运行时资产:dist/、public/、data/、uploads/、Dockerfile.prod、docker-compose.server.yml、.env*、deploy.sh、scripts/。生产站点与数据库均不受影响(容器 healthy、全路由 200、共创板块正常)。后续如需彻底移除归档目录(共约 908M),可在运行稳定数周后删除。
CI/CD
Jenkins Pipeline(Jenkinsfile)在部署阶段调用 ./scripts/deploy.sh deploy --skip-build,部署失败时自动调用 ./scripts/deploy.sh rollback 回滚。
文档
详细文档位于 docs/ 目录:
- 架构文档 - 系统架构设计
- 组件文档 - 组件使用指南
- 测试文档 - 测试策略和指南
- 部署文档 - 部署流程说明
- 经验教训 - 跨任务经验教训汇总,避免重复踩坑
- 问题排查 - 常见问题快速索引与解决方案
许可证
Copyright © 2026 四川睿新致远科技有限公司