chore: remove GitHub Actions workflows, use Woodpecker CI exclusively

This commit is contained in:
张翔
2026-03-10 13:10:11 +08:00
parent 0a1adfc2a2
commit e8dffa4f05
82 changed files with 19565 additions and 101 deletions
+164
View File
@@ -0,0 +1,164 @@
# 联系方式配置说明
## 📋 联系方式总结
### 实际联系方式(对外)
| 联系类型 | 邮箱 | 用途 |
|----------|------|------|
| **运维告警** | ops@novalon.cn | 监控告警、系统故障通知 |
| **业务咨询** | contact@novalon.cn | 用户联系、业务咨询、表单提交 |
### 系统内部配置(不对)
| 配置项 | 邮箱 | 用途 |
|--------|------|------|
| **管理员账号** | contact@novalon.cn | CMS后台登录、系统管理 |
| **公司邮箱** | contact@novalon.cn | 接收联系表单邮件 |
| **Resend API** | re_72PzbVrr_DiwTnB1ZDT7TyqCsgLoAfKfU | 邮件发送服务 |
## 📧 配置文件更新
### 1. 生产环境配置
文件: `.env.production`
```env
# 管理员账号(CMS后台登录)
ADMIN_EMAIL=contact@novalon.cn
# 公司邮箱(接收联系表单邮件)
COMPANY_EMAIL=contact@novalon.cn
# Resend API(邮件发送服务)
RESEND_API_KEY=re_72PzbVrr_DiwTnB1ZDT7TyqCsgLoAfKfU
```
### 2. 测试配置更新
文件: `e2e/global-setup.ts`
```typescript
// 测试登录账号
await page.locator('#email').fill('contact@novalon.cn');
```
### 3. 文档更新
所有文档已更新,移除了不存在的"技术支持"联系方式。
## 📊 监控和告警配置
### Sentry 错误监控
- **告警邮箱**: ops@novalon.cn
- **告警类型**: Critical Errors
- **响应时间**: 立即
### UptimeRobot 可用性监控
- **告警邮箱**: ops@novalon.cn
- **告警类型**: Down, Up, SSL Expiry
- **监控频率**: 5分钟
### Google Analytics 访问统计
- **测量 ID**: G-LGTLCR15KM
- **追踪类型**: 用户行为、页面浏览、事件追踪
## 📝 业务流程
### 用户联系流程
1. **用户访问联系页面**
- 填写联系表单
- 提交表单
2. **系统处理**
- 表单提交到 `/api/contact`
- 使用 Resend API 发送邮件
- 邮件发送到: contact@novalon.cn
3. **管理员处理**
- 管理员登录: contact@novalon.cn
- 查看收到的邮件
- 回复用户咨询
### 系统监控流程
1. **错误发生**
- Sentry 捕获错误
- 发送告警到: ops@novalon.cn
2. **网站故障**
- UptimeRobot 检测到故障
- 发送告警到: ops@novalon.cn
3. **运维响应**
- 运维团队收到告警
- 检查系统状态
- 修复问题
- 通知相关人员
## 🔐 安全考虑
### 账号分离
- **管理员账号**: contact@novalon.cn(仅用于系统管理)
- **运维告警**: ops@novalon.cn(用于系统监控)
- **业务咨询**: contact@novalon.cn(用于用户联系)
### 权限控制
- 管理员账号仅限内部使用
- 不对外公开管理员登录信息
- 定期更换密码
## 📞 联系方式使用指南
### 对于用户
- **业务咨询**: contact@novalon.cn
- 通过网站联系表单提交
- 邮件会在 24 小时内回复
### 对于运维团队
- **系统告警**: ops@novalon.cn
- 监控系统自动发送告警
- 需要立即响应和处理
### 对于管理员
- **系统登录**: contact@novalon.cn
- 访问 CMS 管理后台
- 管理网站内容和用户
## ✅ 配置检查清单
- [x] 生产环境配置更新
- [x] 测试配置更新
- [x] 文档联系方式统一
- [x] 监控告警配置
- [x] 邮件服务配置
- [x] 账号权限分离
## 📚 相关文档
- [轻量级监控配置](LIGHTWEIGHT_MONITORING.md)
- [生产部署指南](PRODUCTION_DEPLOYMENT_LIGHTWEIGHT.md)
- [Google Analytics 集成](GOOGLE_ANALYTICS_SETUP.md)
- [项目 README](../README.md)
## 🎯 总结
现在所有联系方式已经统一配置完成:
1. **对外联系**: contact@novalon.cn
- 用户联系表单
- 业务咨询
- 管理员登录
2. **运维告警**: ops@novalon.cn
- Sentry 错误告警
- UptimeRobot 可用性告警
- 系统故障通知
3. **邮件服务**: Resend API
- API Key: re_72PzbVrr_DiwTnB1ZDT7TyqCsgLoAfKfU
- 发件人: alertmanager@novalon.cn / contact@novalon.cn
- SMTP: smtp.resend.com:587
所有配置文件和文档都已经更新完成,联系方式现在统一且准确!
+309
View File
@@ -0,0 +1,309 @@
# Google Analytics 4 集成指南
## ✅ 配置状态
**GA4 测量 ID**: `G-LGTLCR15KM`
**配置文件**: `.env.production`
```env
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-LGTLCR15KM
```
## 📋 集成组件
### 1. Analytics 工具库
文件位置: `src/lib/analytics.ts`
**提供的功能:**
- `pageview(url)` - 页面浏览追踪
- `event(action, category, label?, value?)` - 事件追踪
- `trackContactForm(formData)` - 联系表单提交追踪
- `trackButtonClick(buttonName, location)` - 按钮点击追踪
- `trackPageView(pageTitle, pagePath)` - 页面视图追踪
### 2. Google Analytics 组件
文件位置: `src/components/analytics/GoogleAnalytics.tsx`
**功能:**
- 自动初始化 GA4
- 配置全局追踪
- 在所有页面启用追踪
### 3. 根布局集成
文件位置: `src/app/layout.tsx`
**已集成:**
```typescript
import { GoogleAnalytics } from "@/components/analytics/GoogleAnalytics";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<GoogleAnalytics />
{children}
</body>
</html>
);
}
```
## 🎯 使用示例
### 1. 联系表单追踪
```typescript
import { trackContactForm } from '@/lib/analytics';
function ContactForm() {
const handleSubmit = async (formData: FormData) => {
// 追踪表单提交
trackContactForm({
name: formData.get('name'),
email: formData.get('email'),
phone: formData.get('phone'),
company: formData.get('company'),
message: formData.get('message')
});
// 提交表单...
};
return <form onSubmit={handleSubmit}>...</form>;
}
```
### 2. 按钮点击追踪
```typescript
import { trackButtonClick } from '@/lib/analytics';
function CTAButton() {
const handleClick = () => {
// 追踪按钮点击
trackButtonClick('get_started', 'hero_section');
};
return <button onClick={handleClick}>使</button>;
}
```
### 3. 页面浏览追踪
```typescript
import { pageview } from '@/lib/analytics';
function MyPage() {
useEffect(() => {
// 追踪页面浏览
pageview('/my-page');
}, []);
return <div>My Page</div>;
}
```
### 4. 自定义事件追踪
```typescript
import { event } from '@/lib/analytics';
function ProductCard({ product }) {
const handleAddToCart = () => {
// 追踪添加到购物车事件
event('add_to_cart', 'ecommerce', product.name, product.price);
};
return (
<div>
<h3>{product.name}</h3>
<button onClick={handleAddToCart}></button>
</div>
);
}
```
## 📊 可追踪的指标
### 自动追踪
- ✅ 页面浏览(自动)
- ✅ 页面标题(自动)
- ✅ 用户会话(自动)
- ✅ 地理位置(自动)
### 手动追踪
- 📧 联系表单提交
- 🔘 按钮点击
- 📄 自定义页面视图
- 🎯 自定义事件
- 💰 交易/转化
## 🔧 配置选项
### 环境变量
```env
# 必需配置
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-LGTLCR15KM
# 可选配置(在 GoogleAnalytics 组件中)
# NEXT_PUBLIC_GA_DEBUG=true # 启用调试模式
```
### 调试模式
启用调试模式查看实时数据:
```typescript
// 在 src/components/analytics/GoogleAnalytics.tsx 中
const isDebug = process.env.NEXT_PUBLIC_GA_DEBUG === 'true';
if (isDebug) {
console.log('GA Debug Mode Enabled');
}
```
## 📈 数据查看
### 访问 Google Analytics
1. 访问 https://analytics.google.com/
2. 选择你的 GA4 属性
3. 查看实时数据
4. 分析报告和趋势
### 关键报告
#### **实时报告**
- 当前在线用户
- 实时事件
- 实时页面浏览
- 地理位置
#### **受众报告**
- 用户数量
- 新用户 vs 回访用户
- 用户地理位置
- 设备和浏览器
#### **获取报告**
- 用户获取渠道
- 流量来源
- 营销活动效果
- 转化路径
#### **参与度报告**
- 平均会话时长
- 每会话页面浏览
- 跳出率
- 事件追踪
## 🧪 测试追踪
### 1. 本地测试
```bash
# 启用调试模式
NEXT_PUBLIC_GA_DEBUG=true npm run dev
```
### 2. 实时验证
1. 访问 Google Analytics 实时报告
2. 在你的网站上执行操作
3. 查看实时数据更新
### 3. 调试扩展
使用 Google Analytics Debugger 扩展:
- Chrome 扩展: Google Analytics Debugger
- Firefox 扩展: Google Analytics Debugger
## 🔒 隐私和合规
### GDPR 合规
```typescript
// 添加用户同意管理
function CookieConsent() {
const [consent, setConsent] = useState(false);
const handleAccept = () => {
setConsent(true);
// 用户同意后初始化 GA
if (consent) {
// GA 会自动初始化
}
};
return (
<div>
{!consent && (
<div className="fixed bottom-0 left-0 right-0 bg-gray-900 text-white p-4">
<p>使 Google Analytics </p>
<button onClick={handleAccept}></button>
</div>
)}
</div>
);
}
```
### Cookie 设置
在 Google Analytics 中配置:
- 数据保留: 14个月
- 用户数据删除: 支持用户删除请求
- IP 匿名化: 启用
## 📞 故障排查
### 问题 1: 数据不显示
**解决方案:**
1. 检查 GA4 ID 是否正确
2. 确认环境变量已设置
3. 检查网络连接
4. 查看浏览器控制台错误
### 问题 2: 实时数据延迟
**解决方案:**
1. GA4 实时数据有 5-10 分钟延迟
2. 等待一段时间后查看
3. 检查时区设置
### 问题 3: 事件不追踪
**解决方案:**
1. 确认调用了正确的追踪函数
2. 检查事件参数是否正确
3. 启用调试模式验证
## 📚 相关资源
- [Google Analytics 4 文档](https://support.google.com/analytics/answer/9304153)
- [GA4 迁移指南](https://support.google.com/analytics/answer/10110506)
- [事件追踪最佳实践](https://support.google.com/analytics/answer/10089681)
## 🎁 示例代码
完整示例代码: `src/components/examples/ContactFormAnalyticsExample.tsx`
这个示例展示了如何在联系表单中集成 Google Analytics 追踪。
## ✅ 集成检查清单
- [x] GA4 测量 ID 配置
- [x] Analytics 工具库创建
- [x] Google Analytics 组件创建
- [x] 根布局集成
- [x] 联系表单示例创建
- [x] 文档更新
**状态**: ✅ 完全集成
Google Analytics 4 已经完全集成到项目中,现在可以追踪用户行为和访问数据了!
+252
View File
@@ -0,0 +1,252 @@
# 轻量级监控配置指南
## 📋 监控架构
### 核心组件
1. **Sentry** - 错误监控和性能追踪
2. **UptimeRobot** - 外部可用性监控
3. **Google Analytics** - 用户行为和访问统计
4. **健康检查API** - 内部服务状态
5. **邮件告警** - 关键问题通知
## 🔧 配置步骤
### 1. Sentry 错误监控(已完成)
Sentry 已经集成在项目中,配置文件:
- `src/lib/sentry.ts` - Sentry 初始化
- `.env.production` - Sentry DSN 配置
**功能:**
- JavaScript 错误捕获
- 性能监控
- 用户会话回放
- 错误告警
### 2. UptimeRobot 可用性监控
#### 注册和配置
1. 访问 https://uptimerobot.com/
2. 注册免费账号
3. 创建新的 Monitor
- **Monitor Type**: HTTP(s)
- **URL**: https://www.novalon.cn
- **Monitoring Interval**: 5 minutes
- **Alert Contacts**: ops@novalon.cn
#### 配置告警
在 UptimeRobot 中设置:
- **Down Alert**: 网站不可用时发送邮件
- **Up Alert**: 网站恢复时发送邮件
- **SSL Expiry**: SSL 证书过期提醒
#### 高级配置
```yaml
# 推荐的监控端点
- 主页: https://www.novalon.cn
- 健康检查: https://www.novalon.cn/api/health
- 管理后台: https://www.novalon.cn/admin
```
### 3. Google Analytics 访问统计
#### 获取跟踪 ID
1. 访问 https://analytics.google.com/
2. 创建新的 GA4 属性
3. 复制测量 ID(格式:G-XXXXXXXXXX
#### 配置 Next.js
更新 `.env.production`
```env
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
```
#### 集成到应用
创建 `src/lib/analytics.ts`
```typescript
export const GA_MEASUREMENT_ID = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;
export const pageview = (url: string) => {
if (typeof window !== "undefined" && GA_MEASUREMENT_ID) {
window.gtag("config", GA_MEASUREMENT_ID, {
page_path: url,
});
}
};
export const event = (action: string, category: string, label?: string) => {
if (typeof window !== "undefined" && GA_MEASUREMENT_ID) {
window.gtag("event", action, {
event_category: category,
event_label: label,
});
}
};
```
`src/app/layout.tsx` 中添加:
```typescript
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
{process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID && (
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID}`}
strategy="afterInteractive"
/>
)}
</head>
<body>{children}</body>
</html>
);
}
```
### 4. 健康检查 API(已实现)
健康检查端点:`/api/health`
**返回数据:**
```json
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00Z",
"version": "1.0.0",
"checks": {
"database": "connected",
"uptime": 123456
}
}
```
### 5. 邮件告警配置
#### 简化告警策略
只监控关键问题:
- **服务不可用**(通过 UptimeRobot
- **严重错误**(通过 Sentry
- **数据库连接失败**(通过健康检查)
#### 配置邮件通知
**Sentry 告警配置:**
1. 登录 Sentry Dashboard
2. 进入 Settings → Alerts
3. 创建新的 Alert Rule
- **Issue**: Critical Errors
- **Environment**: Production
- **Frequency**: Immediately
- **Email**: ops@novalon.cn
**UptimeRobot 告警配置:**
- 添加邮件联系人:ops@novalon.cn
- 设置告警频率:立即通知
## 📊 监控指标
### 关键指标
#### 可用性指标
- 网站正常运行时间(目标:> 99.9%)
- 响应时间(目标:< 2秒)
- SSL 证书状态
#### 错误指标
- JavaScript 错误数量
- API 错误率
- 数据库错误
#### 用户指标
- 日活跃用户
- 页面浏览量
- 平均会话时长
- 跳出率
### 告警阈值
| 指标 | 阈值 | 告警级别 |
| ---------- | ------- | -------- |
| 网站可用性 | < 99.9% | Critical |
| 响应时间 | > 3秒 | Warning |
| 错误率 | > 5% | Critical |
| 数据库连接 | 失败 | Critical |
## 🔧 维护和运维
### 日常检查
#### 每日检查
- [ ] 查看 Sentry 错误报告
- [ ] 检查 UptimeRobot 状态
- [ ] 查看关键日志
#### 每周检查
- [ ] 分析 Google Analytics 数据
- [ ] 检查性能趋势
- [ ] 审查安全日志
#### 每月检查
- [ ] 更新依赖包
- [ ] 备份数据库
- [ ] 审查监控配置
### 故障处理流程
#### 1. 网站不可用
1. 检查服务器状态
2. 查看应用日志
3. 重启服务
4. 通知相关人员
#### 2. 错误激增
1. 查看 Sentry 错误详情
2. 分析错误模式
3. 修复关键问题
4. 部署热修复
#### 3. 性能下降
1. 检查服务器资源
2. 分析慢查询
3. 优化数据库
4. 清理缓存
## 📞 联系方式
- **运维告警**: ops@novalon.cn
- **业务咨询**: contact@novalon.cn
## 📚 相关文档
- [生产部署指南](PRODUCTION_DEPLOYMENT.md)
- [错误监控配置](SENTRY_SETUP.md)
- [性能优化指南](PERFORMANCE_OPTIMIZATION.md)
+223
View File
@@ -0,0 +1,223 @@
# 监控和告警系统快速配置示例
## 🎯 三步快速启动
### 步骤 1: 运行环境检查
```bash
chmod +x scripts/check-monitoring-env.sh
./scripts/check-monitoring-env.sh
```
### 步骤 2: 运行快速启动脚本
```bash
chmod +x scripts/start-monitoring.sh
./scripts/start-monitoring.sh
```
脚本会自动:
- 检查 Docker 环境
- 检查端口占用
- 创建必要目录
- 询问邮件配置(可选)
- 启动所有监控服务
- 等待服务就绪
### 步骤 3: 访问监控界面
- **Prometheus**: http://localhost:9090
- **Grafana**: http://localhost:3001 (admin/admin)
- **Alertmanager**: http://localhost:9093
## 📧 邮件配置示例
### 使用 Resend 邮件服务
```yaml
# monitoring/alertmanager.yml
receivers:
- name: 'critical-alerts'
email_configs:
- to: 'admin@novalon.cn,ops@novalon.cn'
from: 'alertmanager@novalon.cn'
smarthost: 'smtp.resend.com:587'
auth_username: 'resend'
auth_password: 're_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
require_tls: true
```
### 获取 Resend API Key
1. 访问 https://resend.com/
2. 注册账号
3. 进入 API Keys 页面
4. 创建新的 API Key
5. 复制 API Key(以 `re_` 开头)
### 使用其他邮件服务
#### Gmail
```yaml
email_configs:
- to: 'admin@novalon.cn'
from: 'alertmanager@novalon.cn'
smarthost: 'smtp.gmail.com:587'
auth_username: 'your-email@gmail.com'
auth_password: 'your-app-password'
require_tls: true
```
#### QQ 邮箱
```yaml
email_configs:
- to: 'admin@novalon.cn'
from: 'alertmanager@novalon.cn'
smarthost: 'smtp.qq.com:587'
auth_username: 'your-email@qq.com'
auth_password: 'your-authorization-code'
require_tls: true
```
## 🔔 告警规则示例
### 基础告警规则
```yaml
# monitoring/alerts.yml
groups:
- name: novalon-website
rules:
# 服务不可用
- alert: ServiceDown
expr: up{job="novalon-website"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "服务不可用"
description: "Novalon 网站服务已停止响应"
# 高错误率
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "高错误率"
description: "5xx 错误率超过 5%"
# 高响应时间
- alert: HighResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "高响应时间"
description: "P95 响应时间超过 1 秒"
```
## 📊 Grafana 数据源配置
### 添加 Prometheus 数据源
1. 访问 http://localhost:3001
2. 登录 (admin/admin)
3. 进入 Configuration → Data Sources
4. 点击 "Add data source"
5. 选择 "Prometheus"
6. 配置:
- Name: Prometheus
- URL: http://prometheus:9090
- Access: Server (default)
7. 点击 "Save & Test"
### 导入仪表板
1. 进入 Dashboards → Import
2. 上传 `monitoring/grafana-dashboard.json`
3. 选择 Prometheus 数据源
4. 点击 "Import"
## 🧪 测试告警
### 发送测试告警
```bash
curl -X POST http://localhost:9093/api/v1/alerts \
-H 'Content-Type: application/json' \
-d '[
{
"labels": {
"alertname": "TestAlert",
"severity": "warning"
},
"annotations": {
"description": "这是一个测试告警"
}
}
]'
```
### 查看告警状态
```bash
# 查看 Alertmanager 告警
curl http://localhost:9093/api/v1/alerts
# 查看 Prometheus 告警
curl http://localhost:9090/api/v1/alerts
```
## 🔧 常用命令
### 查看服务状态
```bash
docker-compose -f docker-compose.monitoring.yml ps
```
### 查看服务日志
```bash
# Prometheus 日志
docker-compose -f docker-compose.monitoring.yml logs prometheus
# Grafana 日志
docker-compose -f docker-compose.monitoring.yml logs grafana
# Alertmanager 日志
docker-compose -f docker-compose.monitoring.yml logs alertmanager
```
### 重启服务
```bash
# 重启所有服务
docker-compose -f docker-compose.monitoring.yml restart
# 重启单个服务
docker-compose -f docker-compose.monitoring.yml restart prometheus
```
### 停止服务
```bash
docker-compose -f docker-compose.monitoring.yml down
```
## 📚 更多文档
- 详细配置指南: [docs/MONITORING_SETUP.md](file:///Users/zhangxiang/Codes/Gitee/home-page/novalon-website/docs/MONITORING_SETUP.md)
- 生产部署指南: [docs/PRODUCTION_DEPLOYMENT.md](file:///Users/zhangxiang/Codes/Gitee/home-page/novalon-website/docs/PRODUCTION_DEPLOYMENT.md)
## 🆘 遇到问题?
1. 检查 Docker 是否正常运行
2. 查看服务日志排查错误
3. 确认端口没有被占用
4. 验证配置文件语法正确
5. 查看详细文档获取更多帮助
## 📞 联系支持
- 运维团队: ops@novalon.cn
- 业务咨询: contact@novalon.cn
+412
View File
@@ -0,0 +1,412 @@
# 监控和告警系统配置指南
## 📋 目录
1. [快速开始](#快速开始)
2. [详细配置](#详细配置)
3. [告警配置](#告警配置)
4. [监控面板配置](#监控面板配置)
5. [故障排查](#故障排查)
## 🚀 快速开始
### 步骤 1: 环境检查
```bash
# 运行环境检查脚本
chmod +x scripts/check-monitoring-env.sh
./scripts/check-monitoring-env.sh
```
### 步骤 2: 配置邮件服务
编辑 `monitoring/alertmanager.yml`,更新邮件配置:
```yaml
receivers:
- name: 'default'
email_configs:
- to: 'admin@novalon.cn' # 接收告警的邮箱
from: 'alertmanager@novalon.cn' # 发送告警的邮箱
smarthost: 'smtp.resend.com:587' # SMTP 服务器
auth_username: 'resend' # SMTP 用户名
auth_password: 're_xxxxxxxxxxxxxx' # Resend API 密钥
require_tls: true # 启用 TLS
```
### 步骤 3: 启动监控服务
```bash
# 启动所有监控服务
docker-compose -f docker-compose.monitoring.yml up -d
# 查看服务状态
docker-compose -f docker-compose.monitoring.yml ps
```
### 步骤 4: 访问监控界面
- **Prometheus**: http://localhost:9090
- **Grafana**: http://localhost:3001 (admin/admin)
- **Alertmanager**: http://localhost:9093
## 🔧 详细配置
### 1. Prometheus 配置
文件位置: `monitoring/prometheus.yml`
#### 基础配置
```yaml
global:
scrape_interval: 15s # 数据采集间隔
evaluation_interval: 15s # 规则评估间隔
scrape_configs:
- job_name: 'novalon-website'
static_configs:
- targets: ['localhost:3000'] # 应用服务地址
metrics_path: '/api/health' # 健康检查端点
```
#### 添加更多监控目标
```yaml
scrape_configs:
- job_name: 'novalon-website'
static_configs:
- targets: ['localhost:3000']
metrics_path: '/api/health'
- job_name: 'node-exporter' # 系统指标
static_configs:
- targets: ['localhost:9100']
- job_name: 'postgres-exporter' # 数据库指标
static_configs:
- targets: ['localhost:9187']
```
### 2. 告警规则配置
文件位置: `monitoring/alerts.yml`
#### 服务可用性告警
```yaml
- alert: ServiceDown
expr: up{job="novalon-website"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "服务不可用"
description: "Novalon 网站服务已停止响应超过 1 分钟"
```
#### 错误率告警
```yaml
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "高错误率"
description: "5xx 错误率在过去 5 分钟内超过 5%: {{ $value }}"
```
#### 响应时间告警
```yaml
- alert: HighResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "高响应时间"
description: "P95 响应时间超过 1 秒: {{ $value }}s"
```
#### 资源使用告警
```yaml
- alert: HighCPUUsage
expr: rate(process_cpu_seconds_total[5m]) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "CPU 使用率过高"
description: "CPU 使用率超过 80%: {{ $value }}"
- alert: HighMemoryUsage
expr: process_resident_memory_bytes / 1024 / 1024 / 1024 > 1
for: 5m
labels:
severity: warning
annotations:
summary: "内存使用率过高"
description: "内存使用超过 1GB: {{ $value }}GB"
```
### 3. Alertmanager 配置
#### 邮件通知配置
```yaml
receivers:
- name: 'critical-alerts'
email_configs:
- to: 'admin@novalon.cn,ops@novalon.cn'
from: 'alertmanager@novalon.cn'
smarthost: 'smtp.resend.com:587'
auth_username: 'resend'
auth_password: 're_xxxxxxxxxxxxxx'
require_tls: true
headers:
Subject: '🚨 CRITICAL: Novalon Website Alert'
X-Priority: '1' # 高优先级邮件
```
#### 告警路由配置
```yaml
route:
group_by: ['alertname', 'cluster', 'service']
group_wait: 10s # 等待更多告警分组
group_interval: 10s # 发送告警的间隔
repeat_interval: 12h # 重复告警的间隔
routes:
- match:
severity: critical
receiver: 'critical-alerts'
continue: true # 继续匹配其他规则
- match:
severity: warning
receiver: 'warning-alerts'
```
#### 静默规则(维护期间)
```yaml
# 临时静默告警(维护期间)
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
alertname: 'ServiceDown'
equal: ['instance']
```
## 📊 监控面板配置
### Grafana 仪表板配置
#### 1. 登录 Grafana
访问 http://localhost:3001
- 用户名: admin
- 密码: admin
#### 2. 添加 Prometheus 数据源
1. 进入 Configuration → Data Sources
2. 点击 "Add data source"
3. 选择 "Prometheus"
4. 配置:
- Name: Prometheus
- URL: http://prometheus:9090
- Access: Server (default)
5. 点击 "Save & Test"
#### 3. 导入仪表板
1. 进入 Dashboards → Import
2. 上传 `monitoring/grafana-dashboard.json`
3. 选择 Prometheus 数据源
4. 点击 "Import"
#### 4. 自定义仪表板
创建关键指标面板:
**HTTP 请求面板**
```json
{
"title": "HTTP Requests",
"targets": [
{
"expr": "rate(http_requests_total[5m])",
"legendFormat": "{{ method }} {{ status }}"
}
],
"type": "graph"
}
```
**响应时间面板**
```json
{
"title": "Response Time (P95)",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))",
"legendFormat": "P95"
}
],
"type": "graph"
}
```
**错误率面板**
```json
{
"title": "Error Rate",
"targets": [
{
"expr": "rate(http_requests_total{status=~\"5..\"}[5m])",
"legendFormat": "5xx Errors"
}
],
"type": "graph"
}
```
## 🧪 测试告警
### 1. 测试服务不可用告警
```bash
# 停止应用服务
npm stop
# 等待 1 分钟后,检查 Alertmanager
curl http://localhost:9093/api/v1/alerts
# 恢复服务
npm start
```
### 2. 测试高错误率告警
```bash
# 模拟高错误率
for i in {1..100}; do
curl -X POST http://localhost:3000/api/test/error
done
# 检查 Prometheus
curl http://localhost:9090/api/v1/query?query=rate(http_requests_total%7Bstatus%3D~%225..%22%7D%5B5m%5D
```
### 3. 测试邮件通知
```bash
# 发送测试告警
curl -X POST http://localhost:9093/api/v1/alerts \
-H 'Content-Type: application/json' \
-d '[
{
"labels": {
"alertname": "TestAlert",
"severity": "warning"
},
"annotations": {
"description": "这是一个测试告警"
}
}
]'
```
## 🔧 故障排查
### 问题 1: 服务无法启动
```bash
# 检查 Docker 日志
docker-compose -f docker-compose.monitoring.yml logs
# 检查端口占用
netstat -tulpn | grep -E '3000|9090|3001|9093'
# 重启服务
docker-compose -f docker-compose.monitoring.yml restart
```
### 问题 2: 告警不发送
```bash
# 检查 Alertmanager 配置
docker-compose -f docker-compose.monitoring.yml exec alertmanager \
cat /etc/alertmanager/alertmanager.yml
# 检查 Alertmanager 日志
docker-compose -f docker-compose.monitoring.yml logs alertmanager
# 测试 SMTP 连接
telnet smtp.resend.com 587
```
### 问题 3: Grafana 无法连接 Prometheus
```bash
# 检查 Prometheus 是否运行
docker-compose -f docker-compose.monitoring.yml ps prometheus
# 测试 Prometheus API
curl http://localhost:9090/api/v1/status/config
# 检查网络连接
docker-compose -f docker-compose.monitoring.yml exec grafana \
ping prometheus
```
### 问题 4: 数据采集失败
```bash
# 检查应用健康检查端点
curl http://localhost:3000/api/health
# 检查 Prometheus targets
curl http://localhost:9090/api/v1/targets
# 查看 Prometheus 日志
docker-compose -f docker-compose.monitoring.yml logs prometheus
```
## 📈 最佳实践
### 1. 告警级别设置
- **Critical**: 立即需要处理,影响用户体验
- **Warning**: 需要关注,但不影响主要功能
- **Info**: 信息性告警,用于记录
### 2. 告警频率控制
- 避免告警风暴
- 使用合理的 `for` 参数
- 设置合适的 `repeat_interval`
### 3. 监控指标选择
- **关键指标**: 必须监控
- **重要指标**: 建议监控
- **辅助指标**: 可选监控
### 4. 性能优化
- 调整 Prometheus 采集间隔
- 配置数据保留策略
- 使用 PromQL 优化查询
## 📞 联系支持
如遇到问题,请联系:
- 运维团队: ops@novalon.cn
- 业务咨询: contact@novalon.cn
+2 -3
View File
@@ -335,9 +335,8 @@ docker-compose -f docker-compose.monitoring.yml up -d
## 联系方式
- **技术支持**: admin@novalon.cn
- **运维团队**: ops@novalon.cn
- **开发团队**: dev@novalon.cn
- **运维告警**: ops@novalon.cn
- **业务咨询**: contact@novalon.cn
## 附录
+505
View File
@@ -0,0 +1,505 @@
# 生产环境部署和监控指南(轻量级版本)
## 目录
1. [环境准备](#环境准备)
2. [部署流程](#部署流程)
3. [轻量级监控配置](#轻量级监控配置)
4. [告警配置](#告警配置)
5. [维护和运维](#维护和运维)
## 环境准备
### 系统要求
- Linux/Unix 服务器(推荐 Ubuntu 22.04+
- Node.js 18+
- 至少 1GB RAM
- 至少 5GB 磁盘空间
### 必需的软件
```bash
# 安装 Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# 安装 PM2(进程管理器)
npm install -g pm2
```
## 部署流程
### 1. 配置环境变量
复制并编辑生产环境配置:
```bash
cp .env.production .env.local
```
更新以下关键配置:
- `RESEND_API_KEY`: Resend API 密钥
- `NEXT_PUBLIC_SENTRY_DSN`: Sentry DSN
- `NEXTAUTH_SECRET`: 认证密钥
- `ADMIN_PASSWORD`: 管理员密码
- `NEXT_PUBLIC_GA_MEASUREMENT_ID`: Google Analytics ID(可选)
### 2. 安装依赖
```bash
npm ci --production=false
```
### 3. 运行测试
```bash
cd e2e
TEST_ENV=development npx playwright test --reporter=list
cd ..
```
### 4. 构建生产版本
```bash
npm run build
```
### 5. 启动生产服务器
使用 PM2 启动服务:
```bash
pm2 start npm --name "novalon-website" -- start
```
### 6. 验证部署
访问以下URL验证部署:
- 网站: http://localhost:3000
- 健康检查: http://localhost:3000/api/health
- 管理后台: http://localhost:3000/admin
## 轻量级监控配置
### 监控架构
采用轻量级监控方案,包含以下组件:
1. **Sentry** - 错误监控和性能追踪
2. **UptimeRobot** - 外部可用性监控
3. **Google Analytics** - 用户行为和访问统计
4. **健康检查API** - 内部服务状态
5. **邮件告警** - 关键问题通知
### 1. Sentry 错误监控
#### 配置步骤
Sentry 已经集成在项目中,只需配置环境变量:
```env
NEXT_PUBLIC_SENTRY_DSN=https://xxxxxxxxxxxxx@o4507xxxxx.ingest.sentry.io/xxxxxxxxxxxxx
```
#### 配置告警
1. 登录 Sentry Dashboard
2. 进入 Settings → Alerts
3. 创建新的 Alert Rule
- **Issue**: Critical Errors
- **Environment**: Production
- **Frequency**: Immediately
- **Email**: ops@novalon.cn
#### 功能特性
- JavaScript 错误捕获
- 性能监控
- 用户会话回放
- 错误告警
### 2. UptimeRobot 可用性监控
#### 注册和配置
1. 访问 https://uptimerobot.com/
2. 注册免费账号
3. 创建新的 Monitor
- **Monitor Type**: HTTP(s)
- **URL**: https://www.novalon.cn
- **Monitoring Interval**: 5 minutes
- **Alert Contacts**: ops@novalon.cn
#### 配置告警
在 UptimeRobot 中设置:
- **Down Alert**: 网站不可用时发送邮件
- **Up Alert**: 网站恢复时发送邮件
- **SSL Expiry**: SSL 证书过期提醒
#### 推荐监控端点
```yaml
- 主页: https://www.novalon.cn
- 健康检查: https://www.novalon.cn/api/health
- 管理后台: https://www.novalon.cn/admin
```
### 3. Google Analytics 访问统计
#### 获取跟踪 ID
1. 访问 https://analytics.google.com/
2. 创建新的 GA4 属性
3. 复制测量 ID(格式:G-XXXXXXXXXX
#### 配置环境变量
```env
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
```
#### 集成到应用
创建 `src/lib/analytics.ts`
```typescript
export const GA_MEASUREMENT_ID = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;
export const pageview = (url: string) => {
if (typeof window !== 'undefined' && GA_MEASUREMENT_ID) {
window.gtag('config', GA_MEASUREMENT_ID, {
page_path: url,
});
}
};
export const event = (action: string, category: string, label?: string) => {
if (typeof window !== 'undefined' && GA_MEASUREMENT_ID) {
window.gtag('event', action, {
event_category: category,
event_label: label,
});
}
};
```
`src/app/layout.tsx` 中添加:
```typescript
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
{process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID && (
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID}`}
strategy="afterInteractive"
/>
)}
</head>
<body>{children}</body>
</html>
);
}
```
### 4. 健康检查 API
健康检查端点:`/api/health`
**返回数据:**
```json
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00Z",
"version": "1.0.0",
"checks": {
"database": "connected",
"uptime": 123456
}
}
```
## 告警配置
### 告警策略
只监控关键问题:
- **服务不可用**(通过 UptimeRobot
- **严重错误**(通过 Sentry
- **数据库连接失败**(通过健康检查)
### 告警阈值
| 指标 | 阈值 | 告警级别 | 通知方式 |
|--------|--------|----------|----------|
| 网站可用性 | < 99.9% | Critical | UptimeRobot 邮件 |
| 响应时间 | > 3秒 | Warning | UptimeRobot 邮件 |
| JavaScript 错误 | > 10次/小时 | Critical | Sentry 邮件 |
| 数据库连接 | 失败 | Critical | 手动检查 |
### 邮件通知
**Sentry 告警:**
- 接收邮箱: ops@novalon.cn
- 告警级别: Critical
- 响应时间: 立即
**UptimeRobot 告警:**
- 接收邮箱: ops@novalon.cn
- 告警类型: Down, Up, SSL Expiry
- 响应时间: 立即
## 维护和运维
### 日常维护
#### 每日检查
- [ ] 查看 Sentry 错误报告
- [ ] 检查 UptimeRobot 状态
- [ ] 查看关键日志
#### 每周检查
- [ ] 分析 Google Analytics 数据
- [ ] 检查性能趋势
- [ ] 审查安全日志
#### 每月检查
- [ ] 更新依赖包
- [ ] 备份数据库
- [ ] 审查监控配置
### 日志管理
```bash
# 查看应用日志
pm2 logs novalon-website
# 查看错误日志
pm2 logs novalon-website --err
# 清理旧日志
pm2 flush
```
### 数据库备份
```bash
# 手动备份
./scripts/backup.sh
# 设置定时备份
crontab -e
# 添加以下行(每天凌晨 2 点备份)
0 2 * * * /path/to/scripts/backup.sh
```
### 故障处理
#### 1. 服务无法启动
```bash
# 检查 PM2 状态
pm2 status
# 查看错误日志
pm2 logs novalon-website --err
# 重启服务
pm2 restart novalon-website
```
#### 2. 网站不可用
1. 检查 UptimeRobot 告警
2. 查看服务器状态
3. 检查应用日志
4. 重启服务
#### 3. 错误激增
1. 查看 Sentry 错误详情
2. 分析错误模式
3. 修复关键问题
4. 部署热修复
### 更新部署
#### 零停机部署
```bash
# 1. 构建新版本
npm run build
# 2. 备份当前版本
cp -r dist dist_backup
# 3. 替换新版本
rm -rf dist
mv dist_new dist
# 4. 重启服务(优雅重启)
pm2 reload novalon-website
```
#### 回滚
```bash
# 回滚到上一个版本
rm -rf dist
mv dist_backup dist
# 重启服务
pm2 restart novalon-website
```
### 安全加固
#### 防火墙配置
```bash
# 只允许必要端口
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable
```
#### SSL/TLS 配置
```bash
# 使用 Let's Encrypt 获取免费证书
certbot certonly --webroot -w /var/www/html -d www.novalon.cn
# 配置 Nginx
server {
listen 443 ssl;
server_name www.novalon.cn;
ssl_certificate /etc/letsencrypt/live/www.novalon.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.novalon.cn/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
#### 定期更新
```bash
# 更新系统包
sudo apt update && sudo apt upgrade -y
# 更新 Node.js 依赖
npm audit fix
npm update
# 更新 PM2
pm2 update
```
## 性能优化
### 1. 应用优化
- 启用 gzip 压缩
- 优化图片和静态资源
- 使用 CDN 加速
### 2. 数据库优化
- 创建适当的索引
- 定期清理旧数据
- 优化查询语句
### 3. 服务器优化
- 调整 PM2 配置
- 配置 swap
- 优化文件系统
## 应急预案
### 1. 服务完全不可用
1. 检查 UptimeRobot 告警
2. 检查服务器状态
3. 查看应用日志
4. 尝试重启服务
5. 如果无法恢复,切换到备用服务器
### 2. 数据丢失
1. 立即停止写入操作
2. 从最近的备份恢复
3. 验证数据完整性
4. 分析丢失原因,防止再次发生
### 3. 安全事件
1. 立即隔离受影响系统
2. 收集日志和证据
3. 评估影响范围
4. 修复安全漏洞
5. 恢复服务
6. 事后分析
## 联系方式
- **运维告警**: ops@novalon.cn
- **业务咨询**: contact@novalon.cn
## 附录
### A. 常用命令
```bash
# 查看服务状态
pm2 status
# 重启服务
pm2 restart novalon-website
# 查看日志
pm2 logs novalon-website
# 检查磁盘空间
df -h
# 检查内存使用
free -h
# 检查进程
ps aux | grep node
```
### B. 配置文件位置
- 应用配置: `/etc/novalon-website/`
- 日志文件: `~/.pm2/logs/`
- 数据文件: `/var/lib/novalon-website/`
- 备份文件: `/var/backups/novalon-website/`
### C. 监控服务
- **Sentry**: https://sentry.io/
- **UptimeRobot**: https://uptimerobot.com/
- **Google Analytics**: https://analytics.google.com/
## 快速开始
### 一键配置脚本
```bash
# 运行轻量级监控配置脚本
chmod +x scripts/setup-lightweight-monitoring.sh
./scripts/setup-lightweight-monitoring.sh
```
这个脚本会:
- 检查 Sentry 配置
- 配置 Google Analytics(可选)
- 提供 UptimeRobot 配置指导
- 创建健康检查端点
- 配置 Sentry 告警
### 部署脚本
```bash
# 运行生产部署脚本
chmod +x scripts/deploy-production.sh
./scripts/deploy-production.sh
```
这个脚本会:
- 安装依赖
- 运行测试
- 构建生产版本
- 启动服务
- 健康检查
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,579 @@
# 渐进式测试覆盖率提升计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 建立可持续的测试覆盖率提升体系,从当前29.5%逐步提升到更高水平,同时保证开发效率和代码质量。
**Architecture:** 采用分层覆盖率策略,核心业务逻辑层高覆盖(70-80%),UI组件层中覆盖(60-70%),页面展示层适度覆盖(40-50%)。
**Tech Stack:** Jest, React Testing Library, Next.js, TypeScript, GitHub Actions
---
## 已完成任务
### Task 1: 调整Jest配置覆盖率阈值
**Files:**
- Modify: `jest.config.js:12-18`
**Step 1: 修改覆盖率阈值为合理水平**
```javascript
coverageThreshold: {
global: {
branches: 20,
functions: 25,
lines: 25,
statements: 25,
},
},
```
**Step 2: 运行测试验证配置**
Run: `npm run test:unit -- --coverage --coverageReporters=text-summary`
Expected: PASS with coverage above 25%
**Step 3: 提交配置修改**
```bash
git add jest.config.js
git commit -m "test: adjust coverage threshold to reasonable level (25%)"
```
---
## 第一阶段:稳定当前覆盖率(1-2周)
### Task 2: 补充核心业务逻辑测试
**Files:**
- Create: `src/lib/auth/session.test.ts`
- Create: `src/lib/auth/token.test.ts`
- Create: `src/lib/validation.test.ts`
**Step 1: 为session管理编写测试**
```typescript
describe('session management', () => {
it('should create session with user data', () => {
const session = createSession({ userId: '123', role: 'admin' });
expect(session).toBeDefined();
expect(session.userId).toBe('123');
});
it('should validate session expiration', () => {
const expiredSession = createSession({ userId: '123', expiresIn: -1 });
expect(isSessionValid(expiredSession)).toBe(false);
});
});
```
**Step 2: 运行测试验证失败**
Run: `npm run test:unit -- --testPathPattern="session.test.ts"`
Expected: FAIL with "createSession not defined"
**Step 3: 实现session管理功能**
```typescript
export function createSession(userData: SessionData): Session {
return {
...userData,
createdAt: Date.now(),
expiresAt: Date.now() + (24 * 60 * 60 * 1000), // 24小时
};
}
export function isSessionValid(session: Session): boolean {
return Date.now() < session.expiresAt;
}
```
**Step 4: 运行测试验证通过**
Run: `npm run test:unit -- --testPathPattern="session.test.ts"`
Expected: PASS
**Step 5: 提交**
```bash
git add src/lib/auth/session.test.ts src/lib/auth/session.ts
git commit -m "test: add session management tests"
```
---
### Task 3: 补充数据验证测试
**Files:**
- Create: `src/lib/validation.test.ts`
- Modify: `src/lib/validation.ts`
**Step 1: 编写数据验证测试**
```typescript
describe('validation', () => {
describe('email validation', () => {
it('should accept valid email', () => {
expect(validateEmail('test@example.com')).toBe(true);
});
it('should reject invalid email', () => {
expect(validateEmail('invalid')).toBe(false);
});
});
describe('phone validation', () => {
it('should accept valid phone', () => {
expect(validatePhone('13800138000')).toBe(true);
});
it('should reject invalid phone', () => {
expect(validatePhone('123')).toBe(false);
});
});
});
```
**Step 2: 运行测试验证失败**
Run: `npm run test:unit -- --testPathPattern="validation.test.ts"`
Expected: FAIL with validation functions not defined
**Step 3: 实现验证函数**
```typescript
export function validateEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
export function validatePhone(phone: string): boolean {
const phoneRegex = /^1[3-9]\d{9}$/;
return phoneRegex.test(phone);
}
```
**Step 4: 运行测试验证通过**
Run: `npm run test:unit -- --testPathPattern="validation.test.ts"`
Expected: PASS
**Step 5: 提交**
```bash
git add src/lib/validation.test.ts src/lib/validation.ts
git commit -m "test: add data validation tests"
```
---
### Task 4: 优化测试执行性能
**Files:**
- Modify: `jest.config.js`
- Create: `.github/workflows/test-optimized.yml`
**Step 1: 配置并行测试执行**
```javascript
// jest.config.js
module.exports = {
// ... existing config
maxWorkers: '50%',
};
```
**Step 2: 创建优化后的CI工作流**
```yaml
# .github/workflows/test-optimized.yml
name: Optimized Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests (shard ${{ matrix.shard }})
run: npm run test:unit -- --shard=${{ matrix.shard }}/4
- name: Upload coverage
if: matrix.shard == 4
uses: codecov/codecov-action@v4
```
**Step 3: 提交配置**
```bash
git add jest.config.js .github/workflows/test-optimized.yml
git commit -m "ci: optimize test execution with parallelization"
```
---
## 第二阶段:提升覆盖率到35%(1-2个月)
### Task 5: 补充API路由测试
**Files:**
- Create: `src/app/api/contact/route.test.ts`
- Create: `src/app/api/auth/route.test.ts`
**Step 1: 编写API路由测试**
```typescript
describe('/api/contact', () => {
it('should handle POST request', async () => {
const response = await POST(new Request('http://localhost/api/contact', {
method: 'POST',
body: JSON.stringify({ name: 'Test', email: 'test@example.com' }),
}));
expect(response.status).toBe(200);
});
it('should validate required fields', async () => {
const response = await POST(new Request('http://localhost/api/contact', {
method: 'POST',
body: JSON.stringify({}),
}));
expect(response.status).toBe(400);
});
});
```
**Step 2: 运行测试验证失败**
Run: `npm run test:unit -- --testPathPattern="api/contact/route.test.ts"`
Expected: FAIL with API route not tested
**Step 3: 实现API路由验证逻辑**
```typescript
// 确保API路由有适当的验证和错误处理
export async function POST(request: Request) {
try {
const body = await request.json();
if (!body.name || !body.email) {
return Response.json({ error: 'Missing required fields' }, { status: 400 });
}
// 处理逻辑...
return Response.json({ success: true }, { status: 200 });
} catch (error) {
return Response.json({ error: 'Internal server error' }, { status: 500 });
}
}
```
**Step 4: 运行测试验证通过**
Run: `npm run test:unit -- --testPathPattern="api/contact/route.test.ts"`
Expected: PASS
**Step 5: 提交**
```bash
git add src/app/api/contact/route.test.ts src/app/api/contact/route.ts
git commit -m "test: add API route tests"
```
---
### Task 6: 补充数据库操作测试
**Files:**
- Create: `src/db/queries.test.ts`
- Create: `src/db/mutations.test.ts`
**Step 1: 编写数据库查询测试**
```typescript
describe('database queries', () => {
it('should query user by id', async () => {
const user = await getUserById('123');
expect(user).toBeDefined();
expect(user.id).toBe('123');
});
it('should return null for non-existent user', async () => {
const user = await getUserById('non-existent');
expect(user).toBeNull();
});
});
```
**Step 2: 运行测试验证失败**
Run: `npm run test:unit -- --testPathPattern="db/queries.test.ts"`
Expected: FAIL with database functions not tested
**Step 3: 实现数据库查询函数**
```typescript
export async function getUserById(id: string): Promise<User | null> {
const result = await db.select().from(users).where(eq(users.id, id)).limit(1);
return result[0] || null;
}
```
**Step 4: 运行测试验证通过**
Run: `npm run test:unit -- --testPathPattern="db/queries.test.ts"`
Expected: PASS
**Step 5: 提交**
```bash
git add src/db/queries.test.ts src/db/queries.ts
git commit -m "test: add database query tests"
```
---
### Task 7: 提升分支覆盖率
**Files:**
- Modify: `src/lib/auth/permissions.test.ts`
- Modify: `src/lib/upload.test.ts`
**Step 1: 添加边界条件测试**
```typescript
describe('permissions edge cases', () => {
it('should handle null role', () => {
expect(hasPermission(null, 'content', 'read')).toBe(false);
});
it('should handle undefined resource', () => {
expect(hasPermission('admin', undefined, 'read')).toBe(false);
});
it('should handle empty action string', () => {
expect(hasPermission('admin', 'content', '')).toBe(false);
});
});
```
**Step 2: 运行测试验证通过**
Run: `npm run test:unit -- --testPathPattern="permissions.test.ts"`
Expected: PASS with improved branch coverage
**Step 3: 提交**
```bash
git add src/lib/auth/permissions.test.ts
git commit -m "test: improve branch coverage with edge cases"
```
---
## 第三阶段:建立测试质量体系(2-3个月)
### Task 8: 创建测试指南文档
**Files:**
- Create: `docs/testing-guide.md`
**Step 1: 编写测试指南**
```markdown
# 测试指南
## 测试策略
本项目采用分层覆盖率策略:
- 核心业务逻辑层:70-80%覆盖率
- UI组件层:60-70%覆盖率
- 页面展示层:40-50%覆盖率
## 测试编写规范
### 单元测试
- 使用Jest和React Testing Library
- 遵循AAA模式(Arrange-Act-Assert
- 每个测试只验证一个行为
### 集成测试
- 测试组件间的交互
- 使用真实的数据流
- 避免过度mock
## 常见问题
**Q: 如何处理异步测试?**
A: 使用async/await和waitFor函数。
**Q: 如何测试错误处理?**
A: 使用toThrow和expect.assertions验证错误路径。
```
**Step 2: 提交文档**
```bash
git add docs/testing-guide.md
git commit -m "docs: add testing guide"
```
---
### Task 9: 建立覆盖率趋势监控
**Files:**
- Create: `scripts/coverage-trend.js`
- Create: `.github/workflows/coverage-report.yml`
**Step 1: 创建覆盖率趋势脚本**
```javascript
// scripts/coverage-trend.js
const fs = require('fs');
const coverage = JSON.parse(fs.readFileSync('coverage/coverage-final.json', 'utf8'));
const metrics = {
statements: coverage.total.statements.pct,
branches: coverage.total.branches.pct,
functions: coverage.total.functions.pct,
lines: coverage.total.lines.pct,
};
console.log(JSON.stringify(metrics, null, 2));
```
**Step 2: 创建覆盖率报告工作流**
```yaml
# .github/workflows/coverage-report.yml
name: Coverage Report
on:
push:
branches: [main]
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate coverage
run: |
npm run test:unit -- --coverage
node scripts/coverage-trend.js > coverage-metrics.json
- name: Upload metrics
uses: actions/upload-artifact@v4
with:
name: coverage-metrics
path: coverage-metrics.json
```
**Step 3: 提交**
```bash
git add scripts/coverage-trend.js .github/workflows/coverage-report.yml
git commit -m "ci: add coverage trend monitoring"
```
---
### Task 10: 更新覆盖率目标
**Files:**
- Modify: `jest.config.js`
**Step 1: 提升覆盖率目标到35%**
```javascript
coverageThreshold: {
global: {
branches: 25,
functions: 35,
lines: 35,
statements: 35,
},
},
```
**Step 2: 运行测试验证**
Run: `npm run test:unit -- --coverage --coverageReporters=text-summary`
Expected: PASS with coverage above 35%
**Step 3: 提交**
```bash
git add jest.config.js
git commit -m "test: increase coverage threshold to 35%"
```
---
## 验证步骤
### 验证1: 确认所有测试通过
Run: `npm run test:unit`
Expected: All tests pass
### 验证2: 确认覆盖率达标
Run: `npm run test:unit -- --coverage --coverageReporters=text-summary`
Expected: Coverage above 35%
### 验证3: 确认CI构建通过
Check: GitHub Actions workflow status
Expected: All workflows pass
---
## 回滚计划
如果出现问题,可以回滚到之前的配置:
```bash
git log --oneline --all
git checkout <commit-hash>
```
---
## 相关资源
- [Jest文档](https://jestjs.io/docs/getting-started)
- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro)
- [测试最佳实践](https://github.com/goldbergyoni/javascript-testing-best-practices)
File diff suppressed because it is too large Load Diff