4.4 进阶技巧和最佳实践
🎯 本章目标
本章将深入探讨 Spec-kit 的高级应用场景:
- ✅ 宪法框架的深度应用
- ✅ 契约优先开发(Contract-First Development)
- ✅ 多技术栈并行探索
- ✅ 团队协作模式
- ✅ CI/CD 集成
- ✅ 调试与故障排查
🏛️ 宪法框架深度应用
什么是宪法框架?
宪法(Constitution) 是项目的"不可协商原则",确保所有开发决策符合核心价值观。
宪法的作用:
✅ 统一团队标准(避免"各自为政")
✅ 自动化质量门控(AI 自动验证)
✅ 防止技术债务(复杂度证明机制)
✅ 加速决策(明确边界)经典宪法条款示例
Article I: 简洁优先(Simplicity First)
# Article I: Simplicity First
**原则**: 所有功能必须使用 ≤3 个外部依赖
**理由**:
- 减少维护负担
- 降低安全风险
- 提升长期可维护性
**验证方法**:
```bash
# 检查 Python 项目
cat requirements.txt | grep -v '^#' | grep -v '^$' | wc -l
# 结果必须 ≤ 3
# 检查 Node.js 项目
jq '.dependencies | length' package.json
# 结果必须 ≤ 3违规处理:
- 必须在 plan.md 中证明复杂度合理性
- 提供简化方案的评估
- 记录为什么简单方案不可行
示例: ✅ 合规: FastAPI (1 dep) ✅ 合规: FastAPI + SQLAlchemy + pytest (3 deps) ❌ 违规: FastAPI + SQLAlchemy + pytest + Redis + Celery (5 deps)
#### Article II: 测试驱动开发(TDD)
```markdown
# Article II: Test-Driven Development
**原则**: 所有代码必须先写测试再写实现
**理由**:
- 确保可测试性
- 防止回归
- 文档化行为
**验证方法**:
```bash
# Git 提交历史必须显示测试先于实现
git log --oneline --grep="test" --grep="implement" --all
# 正确顺序:
# abc123 Add failing test for user registration
# def456 Implement user registration to pass test
# 错误顺序:
# abc123 Implement user registration
# def456 Add tests for user registration ❌强制执行:
- Pre-commit hook 检查测试覆盖率
- CI 管道要求测试先于实现的提交顺序
- Code review 必须验证 TDD 流程
示例:
# Step 1: 先写测试(会失败)
def test_user_registration():
response = client.post("/api/users", json={
"email": "test@example.com",
"password": "SecurePass123"
})
assert response.status_code == 201
assert "user_id" in response.json()
# Step 2: 实现功能(让测试通过)
@app.post("/api/users", status_code=201)
def register_user(user: UserCreate):
# Implementation
return {"user_id": 42}
#### Article III: 契约优先(Contract-First)
```markdown
# Article III: Contract-First API Development
**原则**: 所有 API 必须先定义 OpenAPI 规范再实现
**理由**:
- 前后端并行开发
- 自动生成文档
- 契约测试保证一致性
**验证方法**:
```bash
# 检查 contracts/ 目录必须在实现之前创建
git log --diff-filter=A --find-renames --pretty=format:"%H %s" -- "specs/*/contracts/*.yaml"
# 验证实现符合契约
openapi-spec-validator specs/001-feature/contracts/api.yaml工作流:
- 产品经理 + 后端 + 前端共同定义 OpenAPI 契约
- 前端基于契约创建 Mock 服务器
- 后端基于契约实现 API
- 集成时零惊喜(契约保证一致性)
工具链:
# 从 OpenAPI 生成 TypeScript 类型
npx openapi-typescript specs/001-feature/contracts/api.yaml -o types/api.ts
# 从 OpenAPI 生成 Python Pydantic models
datamodel-code-generator --input api.yaml --output schemas.py
# 创建 Mock 服务器(前端开发用)
npx @stoplight/prism-cli mock specs/001-feature/contracts/api.yaml
#### Article IV: 性能预算(Performance Budget)
```markdown
# Article IV: Performance Budget
**原则**: 所有功能必须满足性能预算
**预算标准**:
| 指标 | 目标 | 测量方法 |
|------|------|----------|
| API 响应时间 | < 200ms (P95) | Load testing |
| 页面加载时间 | < 2s (FCP) | Lighthouse |
| 数据库查询 | < 50ms | Query profiling |
| Bundle 大小 | < 200KB (gzipped) | webpack-bundle-analyzer |
**验证方法**:
```bash
# API 性能测试
ab -n 1000 -c 10 http://localhost:8000/api/endpoint
# 前端性能测试
lighthouse https://example.com --only-categories=performance --chrome-flags="--headless"
# 数据库查询分析
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';超预算处理:
- 必须在 plan.md 中证明为什么需要超预算
- 提供优化方案和时间表
- 记录性能 trade-off
示例:
## Performance Budget Justification
| Feature | Budget | Actual | Status | Justification |
|---------|--------|--------|--------|--------------|
| User Login | 200ms | 180ms | ✅ Pass | - |
| Photo Upload | 200ms | 350ms | ❌ Fail | Large file processing required |
### Photo Upload 性能证明:
- 简化方案: 客户端压缩(rejected - 移动端 CPU 限制)
- 当前方案: 服务端压缩 + 异步处理
- 优化计划:
1. 引入 CDN(预计减少 100ms)
2. 使用 WebAssembly 压缩(预计减少 50ms)
3. 目标: 降至 200ms 以内(2 周内完成)
### 宪法的演进
**版本管理:**
```markdown
# Project Constitution
**Version**: 2.1.0
**Ratified**: 2025-01-01
**Last Amended**: 2025-01-15
## Version History
- v2.1.0 (2025-01-15): Added Article V (Security Standards)
- v2.0.0 (2025-01-10): BREAKING - Changed Article I dependency limit from 5 to 3
- v1.1.0 (2025-01-05): Added Article IV (Performance Budget)
- v1.0.0 (2025-01-01): Initial constitution
## Amendment Process
1. Proposal: 任何团队成员可以提出修正案
2. Discussion: 团队讨论 (minimum 3 days)
3. Vote: 需要 2/3 多数同意
4. Update: 更新 constitution.md,增加版本号
5. Migrate: 所有活跃 feature 必须验证新宪法合规性宪法升级工作流:
# 1. 备份当前宪法
cp .specify/memory/constitution.md .specify/memory/constitution.v1.0.0.md
# 2. 更新宪法
# 编辑 .specify/memory/constitution.md
# 3. 验证所有活跃 feature 符合新宪法
for feature in specs/*/; do
echo "Validating $feature"
/speckit.analyze --constitution-version=2.0.0 --feature=$feature
done
# 4. 提交变更
git add .specify/memory/constitution.md
git commit -m "Constitution v2.0.0: Reduce dependency limit to 3
BREAKING CHANGE: Article I now requires ≤3 dependencies (was 5)
All active features validated against new constitution.
Features requiring adjustment: 003-analytics (pending refactor)"📜 契约优先开发(Contract-First Development)
核心理念
传统方式:
后端实现 API → 前端对接 → 发现不一致 → 返工契约优先方式:
定义 OpenAPI 契约 → 前后端并行开发 → 集成零惊喜完整工作流示例
Step 1: 定义 OpenAPI 契约(团队协作)
参与角色: 产品经理、后端开发、前端开发、QA
# specs/001-user-management/contracts/api.yaml
openapi: 3.0.0
info:
title: User Management API
version: 1.0.0
components:
schemas:
User:
type: object
required: [id, email, name]
properties:
id:
type: integer
example: 42
email:
type: string
format: email
example: user@example.com
name:
type: string
minLength: 1
maxLength: 100
example: John Doe
created_at:
type: string
format: date-time
example: "2025-01-15T10:30:00Z"
paths:
/api/users:
get:
summary: List users
operationId: listUsers
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: per_page
in: query
schema:
type: integer
default: 20
maximum: 100
responses:
'200':
description: User list
content:
application/json:
schema:
type: object
properties:
users:
type: array
items:
$ref: '#/components/schemas/User'
total:
type: integer
page:
type: integer
per_page:
type: integer
post:
summary: Create user
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, name, password]
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
password:
type: string
format: password
minLength: 8
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Validation error
'409':
description: Email already existsStep 2: 验证契约合法性
# 安装验证工具
npm install -g @apidevtools/swagger-cli
# 验证 OpenAPI 规范
swagger-cli validate specs/001-user-management/contracts/api.yaml
# 输出:
# specs/001-user-management/contracts/api.yaml is valid ✅Step 3: 前端并行开发(使用 Mock 服务器)
# 启动 Mock 服务器(自动基于 OpenAPI 生成)
npx @stoplight/prism-cli mock specs/001-user-management/contracts/api.yaml
# 输出:
# [Prism] Server is running on http://127.0.0.1:4010前端代码(立即开始开发):
// frontend/src/api/users.ts
import axios from 'axios';
// 使用 Mock 服务器
const API_BASE = process.env.NODE_ENV === 'development'
? 'http://127.0.0.1:4010' // Mock server
: 'https://api.production.com'; // Real API
interface User {
id: number;
email: string;
name: string;
created_at: string;
}
interface UserListResponse {
users: User[];
total: number;
page: number;
per_page: number;
}
export async function listUsers(page = 1, perPage = 20): Promise<UserListResponse> {
const response = await axios.get(`${API_BASE}/api/users`, {
params: { page, per_page: perPage }
});
return response.data;
}
export async function createUser(email: string, name: string, password: string): Promise<User> {
const response = await axios.post(`${API_BASE}/api/users`, {
email,
name,
password
});
return response.data;
}
// 前端可以立即开发 UI,无需等待后端!Step 4: 后端并行开发(基于契约实现)
# backend/src/schemas.py
# 从 OpenAPI 自动生成 Pydantic models
from pydantic import BaseModel, EmailStr, Field
from datetime import datetime
class UserResponse(BaseModel):
id: int
email: EmailStr
name: str = Field(..., min_length=1, max_length=100)
created_at: datetime
class UserCreate(BaseModel):
email: EmailStr
name: str = Field(..., min_length=1, max_length=100)
password: str = Field(..., min_length=8)
class UserListResponse(BaseModel):
users: list[UserResponse]
total: int
page: int
per_page: int# backend/src/api/users.py
from fastapi import APIRouter, HTTPException, Query
from src.schemas import UserResponse, UserCreate, UserListResponse
from src.models import User
from src.database import get_db
router = APIRouter(prefix="/api", tags=["Users"])
@router.get("/users", response_model=UserListResponse)
async def list_users(
page: int = Query(1, ge=1),
per_page: int = Query(20, ge=1, le=100),
db=Depends(get_db)
):
"""
List users with pagination.
Implements: GET /api/users from OpenAPI contract
"""
offset = (page - 1) * per_page
users = db.query(User).offset(offset).limit(per_page).all()
total = db.query(User).count()
return UserListResponse(
users=users,
total=total,
page=page,
per_page=per_page
)
@router.post("/users", response_model=UserResponse, status_code=201)
async def create_user(user_data: UserCreate, db=Depends(get_db)):
"""
Create a new user.
Implements: POST /api/users from OpenAPI contract
"""
# Check email uniqueness
existing = db.query(User).filter(User.email == user_data.email).first()
if existing:
raise HTTPException(status_code=409, detail="Email already exists")
# Hash password
hashed_password = hash_password(user_data.password)
# Create user
user = User(
email=user_data.email,
name=user_data.name,
password_hash=hashed_password
)
db.add(user)
db.commit()
db.refresh(user)
return userStep 5: 契约测试(验证实现符合契约)
# backend/tests/test_contract_compliance.py
import pytest
from fastapi.testclient import TestClient
from openapi_core import create_spec
from openapi_core.validation.request import openapi_request_validator
from openapi_core.validation.response import openapi_response_validator
@pytest.fixture
def openapi_spec():
with open('specs/001-user-management/contracts/api.yaml') as f:
return create_spec(yaml.safe_load(f))
def test_list_users_contract(client: TestClient, openapi_spec):
"""验证 GET /api/users 实现符合契约"""
response = client.get("/api/users?page=1&per_page=10")
# 验证响应结构符合 OpenAPI schema
validator = openapi_response_validator(openapi_spec)
result = validator.validate(response)
assert result.errors == [] # 无验证错误
assert response.status_code == 200
data = response.json()
assert "users" in data
assert "total" in data
assert isinstance(data["users"], list)
def test_create_user_contract(client: TestClient, openapi_spec):
"""验证 POST /api/users 实现符合契约"""
response = client.post("/api/users", json={
"email": "test@example.com",
"name": "Test User",
"password": "SecurePass123"
})
# 验证响应符合契约
validator = openapi_response_validator(openapi_spec)
result = validator.validate(response)
assert result.errors == []
assert response.status_code == 201
data = response.json()
assert "id" in data
assert data["email"] == "test@example.com"Step 6: 集成(前后端对接)
// 前端切换到真实 API
const API_BASE = 'https://api.production.com'; // 从 Mock 切换到真实
// 由于都遵循同一个 OpenAPI 契约,集成时零惊喜!契约优先的价值:
节省时间:前后端并行开发,节省 40-60% 时间
减少 bug:契约保证一致性,集成 bug 减少 80%
自动文档:OpenAPI 自动生成文档,永远最新
类型安全:自动生成类型定义,编译时发现错误🌲 多技术栈并行探索
使用场景
创业团队不确定最佳技术栈时,可以从同一份规格生成多个实现,对比后选择最优方案。
完整案例:仪表盘项目
Step 1: 编写技术无关的规格
/speckit.specify 用户仪表盘,显示任务统计、最近活动、快速操作生成 specs/001-dashboard/spec.md(技术无关):
## User Scenarios
### P1: 任务统计概览
- Given 用户登录系统
- When 访问仪表盘
- Then 显示:
- 待办任务数量
- 已完成任务数量
- 今日新增任务
- 本周完成率趋势图
### P2: 最近活动流
- Given 用户有操作记录
- When 滚动仪表盘
- Then 显示最近 10 条活动(创建、完成、删除任务)
- And 每条活动显示:图标、描述、时间戳
## Success Criteria
- SC-001: 仪表盘加载 < 1 second
- SC-002: 支持 1000+ 任务无性能下降
- SC-003: 实时更新(WebSocket)Step 2: 生成 3 个并行技术方案
方案 A: React + Node.js + MongoDB
/speckit.plan React 18 + TypeScript + Node.js Express + MongoDB + Socket.io关键技术决策(plan-react-node.md):
## Technical Context
- Frontend: React 18 + TypeScript + Vite
- Backend: Node.js 20 + Express 4
- Database: MongoDB 6
- Real-time: Socket.io
- State: Zustand
## 优势
✅ 全栈 JavaScript(学习曲线低)
✅ MongoDB 灵活 schema(适合快速迭代)
✅ Socket.io 开箱即用
## 劣势
❌ MongoDB 无事务(复杂查询弱)
❌ Node.js 单线程(CPU 密集型差)方案 B: Vue + Python + PostgreSQL
/speckit.plan Vue 3 + TypeScript + Python FastAPI + PostgreSQL + Server-Sent Events关键技术决策(plan-vue-python.md):
## Technical Context
- Frontend: Vue 3 + TypeScript + Vite
- Backend: Python 3.11 + FastAPI
- Database: PostgreSQL 15
- Real-time: Server-Sent Events (SSE)
- State: Pinia
## 优势
✅ PostgreSQL 强大查询能力
✅ FastAPI 高性能(Starlette + Pydantic)
✅ Python 生态丰富(数据分析)
## 劣势
❌ SSE 单向通信(需要 polling 补充)
❌ Python 部署复杂度高方案 C: Svelte + Go + SQLite
/speckit.plan Svelte + Go + SQLite + WebSocket关键技术决策(plan-svelte-go.md):
## Technical Context
- Frontend: Svelte 4 + TypeScript
- Backend: Go 1.21 + Gin
- Database: SQLite 3
- Real-time: Gorilla WebSocket
- Deployment: Single binary
## 优势
✅ 极致性能(Go + Svelte 编译优化)
✅ 部署简单(单个可执行文件)
✅ SQLite 零配置(嵌入式数据库)
## 劣势
❌ SQLite 并发写限制(多用户场景弱)
❌ Go 生态较小(库不如 Python/Node丰富)Step 3: 并行实现(3 个开发者)
# 开发者 A
cd implementations/react-node
/speckit.tasks --plan=../../specs/001-dashboard/plan-react-node.md
/speckit.implement
# 开发者 B
cd implementations/vue-python
/speckit.tasks --plan=../../specs/001-dashboard/plan-vue-python.md
/speckit.implement
# 开发者 C
cd implementations/svelte-go
/speckit.tasks --plan=../../specs/001-dashboard/plan-svelte-go.md
/speckit.implementStep 4: 基准测试对比
性能测试脚本:
#!/bin/bash
# benchmark.sh
echo "=== 性能基准测试 ==="
# 测试 1: 冷启动时间
echo "冷启动时间:"
for impl in react-node vue-python svelte-go; do
cd implementations/$impl
time curl -s http://localhost:3000/api/dashboard > /dev/null
cd ../..
done
# 测试 2: 吞吐量 (1000 requests)
echo "吞吐量测试:"
ab -n 1000 -c 10 http://localhost:3000/api/dashboard
# 测试 3: 内存使用
echo "内存使用:"
ps aux | grep "node\|python\|go-app"
# 测试 4: Bundle 大小
echo "前端 Bundle 大小:"
du -sh implementations/*/dist测试结果:
┌─────────────┬──────────┬─────────┬────────┬──────────┐
│ 实现方案 │ 冷启动 │ 吞吐量 │ 内存 │ Bundle │
├─────────────┼──────────┼─────────┼────────┼──────────┤
│ React+Node │ 850ms │ 450 RPS │ 180MB │ 245KB │
│ Vue+Python │ 320ms │ 1200RPS │ 95MB │ 180KB │
│ Svelte+Go │ 120ms │ 2500RPS │ 25MB │ 85KB │
└─────────────┴──────────┴─────────┴────────┴──────────┘
结论:Svelte + Go 在所有指标上领先Step 5: 开发体验对比
开发者反馈:
| 维度 | React+Node | Vue+Python | Svelte+Go |
|------|-----------|-----------|----------|
| 学习曲线 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| 开发速度 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 调试体验 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 生态丰富度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 部署难度 | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
开发者 A: "React 生态最成熟,但 bundle 太大"
开发者 B: "Python 开发最快,FastAPI 很爽"
开发者 C: "Go 性能无敌,部署超简单,但库少一些"Step 6: 最终决策
决策矩阵:
优先级权重:
- 性能: 40%(核心需求)
- 开发速度: 30%
- 部署简易: 20%
- 生态: 10%
加权得分:
- React+Node: 2.8 / 5.0
- Vue+Python: 3.6 / 5.0 ← 推荐
- Svelte+Go: 3.9 / 5.0 ← **最终选择**
最终选择:Svelte + Go
理由:性能优势明显,部署极简,学习曲线可接受保留方案: Vue + Python 作为备选(如果 Go 生态不足时切换)
👥 团队协作模式
模式 1:规格先行协作
角色分工:
产品经理 → 编写 spec.md(What & Why)
↓
技术负责人 → Review spec,提出澄清问题
↓
产品经理 → 澄清(/speckit.clarify)
↓
后端团队 → 生成 plan.md(后端技术栈)
前端团队 → 生成 plan.md(前端技术栈)
↓(并行开发)
后端 → 实现 API
前端 → 实现 UI
↓
集成测试 → 验证功能Git 工作流:
# 1. 产品经理创建 spec
git checkout -b 001-user-dashboard
/speckit.specify 用户仪表盘功能
git add specs/001-user-dashboard/spec.md
git commit -m "spec: Add user dashboard specification"
git push origin 001-user-dashboard
# 2. 技术负责人 Review
gh pr create --title "Spec: User Dashboard" --body "Please review specification"
# Team reviews in GitHub PR comments
# 3. 澄清后,产品经理更新 spec
/speckit.clarify
git add specs/001-user-dashboard/spec.md
git commit -m "spec: Clarify real-time update requirements"
git push
# 4. 后端团队创建 plan
git checkout 001-user-dashboard
/speckit.plan FastAPI + PostgreSQL + WebSocket
git add specs/001-user-dashboard/plan-backend.md
git commit -m "plan: Backend technical design"
git push
# 5. 前端团队创建 plan(基于同一个 spec)
/speckit.plan React + TypeScript + Socket.io
git add specs/001-user-dashboard/plan-frontend.md
git commit -m "plan: Frontend technical design"
git push
# 6. 并行实现
# 后端团队
cd backend
/speckit.tasks --plan=../specs/001-user-dashboard/plan-backend.md
/speckit.implement
git add backend/
git commit -m "feat: Implement user dashboard API"
# 前端团队(同时进行)
cd frontend
/speckit.tasks --plan=../specs/001-user-dashboard/plan-frontend.md
/speckit.implement
git add frontend/
git commit -m "feat: Implement user dashboard UI"
# 7. 集成
git merge 001-user-dashboard
# 由于都基于同一个 spec + 契约,集成顺利模式 2:宪法驱动标准化
团队宪法示例:
# Team Constitution v2.0
## Article I: Code Review 标准
所有代码必须通过至少 2 人 review
**验证方法**:
```bash
# GitHub branch protection rules
gh api repos/:owner/:repo/branches/main/protection \
--field required_pull_request_reviews[required_approving_review_count]=2Article II: 测试覆盖率
所有新代码测试覆盖率 ≥ 80%
验证方法:
# CI pipeline
pytest --cov=src --cov-report=term --cov-fail-under=80Article III: 安全扫描
所有依赖必须通过安全扫描
验证方法:
# CI pipeline
npm audit --audit-level=high
safety check --jsonArticle IV: 性能预算
所有 API 响应 < 200ms (P95)
验证方法:
# Load testing in CI
k6 run performance-test.js
**CI/CD 集成(自动验证宪法):**
```yaml
# .github/workflows/constitution-check.yml
name: Constitution Compliance
on:
pull_request:
branches: [main]
jobs:
check-constitution:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Article I - Verify PR approvals
run: |
approvals=$(gh pr view ${{ github.event.pull_request.number }} --json reviews --jq '.reviews | length')
if [ "$approvals" -lt 2 ]; then
echo "❌ Article I violated: Need 2 approvals, got $approvals"
exit 1
fi
- name: Article II - Test coverage
run: |
pytest --cov=src --cov-report=term --cov-fail-under=80
- name: Article III - Security scan
run: |
npm audit --audit-level=high
safety check
- name: Article IV - Performance test
run: |
k6 run --quiet performance-test.js
# Fails if P95 > 200ms🚀 CI/CD 集成
完整 CI/CD 管道
# .github/workflows/spec-driven-pipeline.yml
name: Spec-Driven CI/CD
on:
push:
branches: [main]
paths:
- 'specs/**'
- 'src/**'
- 'tests/**'
jobs:
validate-spec:
name: Validate Specification
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Spec-kit
run: |
pip install uv
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
- name: Validate against constitution
run: |
# 检查所有 spec 符合宪法
for spec in specs/*/spec.md; do
echo "Validating $spec"
specify analyze --spec=$spec --constitution=.specify/memory/constitution.md
done
- name: Verify OpenAPI contracts
run: |
npm install -g @apidevtools/swagger-cli
for contract in specs/*/contracts/*.yaml; do
swagger-cli validate $contract
done
test-backend:
name: Backend Tests
needs: validate-spec
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r backend/requirements.txt
pip install pytest pytest-cov
- name: Run tests
run: |
cd backend
pytest --cov=src --cov-report=xml --cov-fail-under=80
- name: Contract compliance tests
run: |
# 验证实现符合 OpenAPI 契约
pytest tests/test_contract_compliance.py
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./backend/coverage.xml
test-frontend:
name: Frontend Tests
needs: validate-spec
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: |
cd frontend
npm ci
- name: Run tests
run: |
cd frontend
npm run test:coverage
- name: Build
run: |
cd frontend
npm run build
- name: Check bundle size
run: |
cd frontend
size=$(du -sb dist | awk '{print $1}')
max_size=$((200 * 1024)) # 200KB
if [ $size -gt $max_size ]; then
echo "❌ Bundle too large: ${size}B > ${max_size}B"
exit 1
fi
performance-test:
name: Performance Testing
needs: [test-backend, test-frontend]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup services
run: |
docker-compose -f docker-compose.test.yml up -d
sleep 10 # Wait for services to be ready
- name: Install k6
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: Run load tests
run: |
k6 run --quiet performance/load-test.js
# Fails if metrics don't meet constitution requirements
deploy-staging:
name: Deploy to Staging
needs: [test-backend, test-frontend, performance-test]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy backend
run: |
# Deploy to staging environment
./scripts/deploy-staging.sh backend
- name: Deploy frontend
run: |
./scripts/deploy-staging.sh frontend
- name: Smoke tests
run: |
# Verify deployment
curl -f https://staging.example.com/health || exit 1
curl -f https://staging.example.com/ || exit 1🐛 调试与故障排查
常见问题 1: Spec 与 Plan 不一致
症状:
实现的功能与 spec.md 描述不符排查方法:
# 运行一致性检查
/speckit.analyze
# 输出:
# ❌ Inconsistency detected:
# - spec.md requires "User can filter by tags"
# - plan.md does not mention tag filtering
# - tasks.md has no tag-related tasks解决方案:
# 更新 plan 包含遗漏的功能
/speckit.plan [重新生成,包含标签过滤]
# 更新 tasks
/speckit.tasks
# 重新实现
/speckit.implement常见问题 2: 宪法违规
症状:
plan.md 中使用了 5 个依赖,违反宪法(≤3)排查方法:
# 检查依赖数量
grep "^dependencies:" plan.md -A 10 | wc -l
# 输出:5 ❌(违规)解决方案:
## Complexity Justification(在 plan.md 中添加)
| Dependency | Justification | Simpler Alternative | Why Rejected |
|------------|---------------|---------------------|--------------|
| FastAPI | Web framework | Flask | FastAPI async performance needed |
| SQLAlchemy | ORM | Raw SQL | Complex queries, migrations |
| Pytest | Testing | unittest | Better fixtures, plugins |
| Redis | Caching | In-memory | Distributed deployment requirement |
| Celery | Task queue | Threading | Requires distributed workers |
**Total Dependencies**: 5
**Constitution Limit**: 3
**Approval Required**: Yes
**Mitigation Plan**:
1. Phase 1: Ship with 5 deps (approved violation)
2. Phase 2 (Q2 2025): Replace Celery with lightweight alternative
3. Target: Reduce to 4 deps by Q2, 3 deps by Q3常见问题 3: 契约测试失败
症状:
Contract test failed: Response does not match OpenAPI schema排查方法:
# tests/test_contract_compliance.py
def test_create_user_contract(client):
response = client.post("/api/users", json={...})
# 详细错误信息
from openapi_core.validation.response import openapi_response_validator
validator = openapi_response_validator(openapi_spec)
result = validator.validate(response)
for error in result.errors:
print(f"❌ {error}")
# 输出:
# ❌ Response body does not match schema:
# Missing required field: 'created_at'解决方案:
# 修复实现,添加缺失字段
@app.post("/api/users")
def create_user(user_data: UserCreate):
user = User(
email=user_data.email,
name=user_data.name,
created_at=datetime.utcnow() # ← 添加缺失字段
)
# ...
return user💡 最佳实践总结
✅ DO(推荐做法)
早期定义宪法
✅ 项目启动时就创建宪法 ✅ 团队共同讨论,达成共识 ✅ 版本化管理宪法契约优先
✅ API 先定义 OpenAPI 契约 ✅ 前后端基于契约并行开发 ✅ 使用 Mock 服务器 ✅ 契约测试保证一致性多方案探索
✅ 技术选型不确定时,生成多个 plan ✅ 并行实现 POC,基准测试对比 ✅ 数据驱动决策自动化验证
✅ CI/CD 管道验证宪法合规性 ✅ 自动运行契约测试 ✅ 性能测试门控
❌ DON'T(避免做法)
跳过宪法
❌ 直接开始写代码 ❌ 每个人各自为政 ❌ 事后才定义标准先实现再定义契约
❌ 后端实现完再定义 API ❌ 前端等待后端完成 ❌ 手工编写 API 文档单一技术栈盲目推进
❌ 不验证就选择技术栈 ❌ 没有对比基准测试 ❌ 凭感觉做决策
🚀 下一步
恭喜你掌握了 Spec-kit 的高级技巧!现在你已经学会:
✅ 宪法框架的深度应用 ✅ 契约优先开发完整流程 ✅ 多技术栈并行探索 ✅ 团队协作最佳实践 ✅ CI/CD 集成方案 ✅ 调试与故障排查
下一步: 4.5 本章小结 - 回顾核心知识点,查看常见问题和资源推荐!
Spec-kit 核心概念教程 v1.0 | 2025 Edition | 基于 GitHub Spec-kit 官方仓库