Files
ocdp-go/docs/development/specification.md
mangomqy c5e51ed069 ocdp v1
2025-11-13 02:54:06 +00:00

349 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 📋 OCDP 开发规范
本文档定义了 OCDP 项目的开发规范和架构要求。
## 🎯 整体架构 (Full Stack)
### 1. OpenAPI 驱动开发
采用 OpenAPI 规范来驱动前后端开发,确保 API 契约的一致性。
**优势**
- API 设计优先,前后端并行开发
- 自动生成类型安全的代码
- 文档和代码永远同步
- 减少沟通成本
**实践**
```bash
# 1. 设计 API (编辑 backend/docs/openapi.yaml)
# 2. 验证规范
make openapi-validate
# 3. 生成代码
make openapi-gen
# 4. 实现功能
```
### 2. Docker Compose 部署
使用 Docker Compose 进行整个应用的部署。新版的 Docker 已经将 Compose 集成到 Docker 里面了,所以使用 `docker compose`(带空格)而非旧版的 `docker-compose`(带连字符)。
**部署服务**
- PostgreSQL - 数据持久化
- Redis - 缓存和会话
- Backend - Go 后端服务
- Frontend - React 前端应用
- Nginx - 反向代理(生产环境)
## 🎨 前端规范 (Frontend)
### 1. 纯函数渲染
**要求**:使用纯函数进行组件渲染,避免不必要的副作用。
**原则**
- 组件应该是可预测的(相同输入→相同输出)
- 避免在渲染过程中修改外部状态
- 使用 `useEffect` 等 Hook 处理副作用
- 保持组件的可测试性
**示例**
```typescript
// ✅ 好的实践 - 纯函数组件
interface Props {
name: string;
count: number;
}
const UserCard = ({ name, count }: Props) => {
// 纯函数:只依赖 props不修改外部状态
return (
<div>
<h3>{name}</h3>
<p>Count: {count}</p>
</div>
);
};
// ✅ 副作用在 useEffect 中处理
const UserList = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
// 副作用API 调用)在这里处理
fetchUsers().then(setUsers);
}, []);
return users.map(user => <UserCard {...user} />);
};
// ❌ 不好的实践 - 在渲染中产生副作用
const BadComponent = () => {
// 不要在这里调用 API 或修改外部状态
globalState.count++; // ❌ 副作用
fetchData(); // ❌ 副作用
return <div>Bad</div>;
};
```
### 2. 技术栈
- **框架**: React 18+ (使用 Hooks)
- **语言**: TypeScript 5+
- **构建工具**: Vite
- **样式**: Tailwind CSS
- **路由**: React Router 6+
- **状态管理**: React Context + Hooks
- **API 客户端**: 从 OpenAPI 自动生成
## 🔧 后端规范 (Backend)
### 1. 六边形架构 (Hexagonal Architecture)
后端采用六边形架构(也称为端口和适配器架构),将业务逻辑与技术实现解耦。
**核心目录结构**
```
backend/internal/
├── domain/ # 领域层 - 业务逻辑核心
│ ├── entity/ # 领域实体
│ ├── service/ # 领域服务
│ └── repository/ # 仓库接口(端口)
├── application/ # 应用层 - 用例编排
│ └── usecase/ # 用例实现
└── adapter/ # 适配器层 - 技术实现
├── input/ # 输入适配器
│ └── http/ # HTTP REST API
└── output/ # 输出适配器
├── persistence/
│ ├── mock/ # Mock 实现
│ └── postgres/ # PostgreSQL 实现
├── oci/ # OCI Registry 客户端
└── helm/ # Helm SDK 封装
```
**职责划分**
- **Domain 层**:纯业务逻辑,不依赖任何框架或外部库
- **Application 层**:编排 Domain 层的服务,实现具体的用例
- **Adapter 层**处理所有技术细节HTTP、数据库、第三方 API
### 2. Mock Adapter 实现
**要求**:除了实现 ports 的 adapters 外,还要做 mock。Mock 的是 adapter 的行为反应而非假数据。
**Mock 原则**
- ✅ 模拟真实 adapter 的行为
- ✅ 可以注入真实数据
- ✅ 可以通过调用接口自行加入数据
- ✅ 使用内存来模拟 adapter 的交互
- ❌ 不是返回固定的假数据
**示例**
```go
// Mock Repository - 模拟真实的数据库行为
type RegistryRepositoryMock struct {
registries map[string]*entity.Registry // 内存存储
mu sync.RWMutex
}
func (r *RegistryRepositoryMock) Create(ctx context.Context, registry *entity.Registry) error {
r.mu.Lock()
defer r.mu.Unlock()
// 模拟真实行为:检查重复、生成 ID、加密等
if _, exists := r.registries[registry.ID]; exists {
return errors.New("registry already exists")
}
r.registries[registry.ID] = registry
return nil
}
func (r *RegistryRepositoryMock) GetByID(ctx context.Context, id string) (*entity.Registry, error) {
r.mu.RLock()
defer r.mu.RUnlock()
registry, exists := r.registries[id]
if !exists {
return nil, errors.New("registry not found")
}
return registry, nil
}
```
### 3. Makefile 支持
**要求**:采用 Makefile 来支持 mock 启动以及 real 启动。
**命令规范**
```makefile
# 开发模式Mock Adapter
run-mock:
@echo "Starting backend with Mock adapters..."
MODE=mock go run cmd/api/main.go
# 生产模式Real Adapter
run-real:
@echo "Starting backend with Real adapters..."
MODE=real go run cmd/api/main.go
# 运行测试
test:
go test -v ./...
# 生成代码
generate:
go generate ./...
```
**使用方式**
```bash
# 开发模式(无需数据库)
make run-mock
# 生产模式(需要 PostgreSQL
make run-real
```
### 4. 技术栈
- **语言**: Go 1.21+
- **Web 框架**: Gin (轻量、高性能)
- **ORM**: GORM (可选,用于 PostgreSQL adapter)
- **OCI 客户端**: ORAS Go SDK v2
- **Helm 客户端**: Helm SDK v3
- **K8s 客户端**: client-go
## 📐 架构原则
### 1. 依赖方向
```
Adapter → Application → Domain
(技术) (编排) (业务)
```
- Domain 层不依赖任何外部库(除了标准库)
- Application 层依赖 Domain 层
- Adapter 层依赖 Application 和 Domain 层
### 2. 端口和适配器
**端口Port**:接口定义,在 Domain 层
```go
// domain/repository/registry_repository.go
type RegistryRepository interface {
Create(ctx context.Context, registry *entity.Registry) error
GetByID(ctx context.Context, id string) (*entity.Registry, error)
List(ctx context.Context) ([]*entity.Registry, error)
}
```
**适配器Adapter**:接口实现,在 Adapter 层
```go
// adapter/output/persistence/mock/registry_repository_mock.go
type RegistryRepositoryMock struct {
// Mock 实现
}
// adapter/output/persistence/postgres/registry_repository_postgres.go
type RegistryRepositoryPostgres struct {
// PostgreSQL 实现
}
```
### 3. 依赖注入
使用构造函数注入依赖:
```go
// 创建 Mock 模式的应用
func NewMockApp() *App {
// 创建 Mock Repository
registryRepo := mock.NewRegistryRepositoryMock()
// 创建 Service注入 Repository
registryService := service.NewRegistryService(registryRepo)
// 创建 Handler注入 Service
registryHandler := handler.NewRegistryHandler(registryService)
return &App{
RegistryHandler: registryHandler,
}
}
// 创建 Production 模式的应用
func NewProductionApp(db *gorm.DB) *App {
// 创建 PostgreSQL Repository
registryRepo := postgres.NewRegistryRepositoryPostgres(db)
// ... 其他相同
}
```
## 🔄 开发工作流
### 1. 功能开发流程
```bash
# 1. 设计 API
vim backend/docs/openapi.yaml
# 2. 生成代码
make openapi-gen
# 3. 实现 Domain 层
vim backend/internal/domain/service/xxx_service.go
# 4. 实现 Mock Adapter
vim backend/internal/adapter/output/persistence/mock/xxx_mock.go
# 5. 实现 Handler
vim backend/internal/adapter/input/http/handler/xxx_handler.go
# 6. 启动测试
make run-mock
# 7. 实现前端
vim frontend/src/features/xxx/pages/XxxPage.tsx
# 8. 集成测试
make dev
# 9. 实现 Production Adapter
vim backend/internal/adapter/output/persistence/postgres/xxx_postgres.go
# 10. 部署测试
docker compose up
```
### 2. 测试策略
- **单元测试**Domain 层和 Service 层(使用 Mock Repository
- **集成测试**:使用 Mock Adapter 测试完整流程
- **E2E 测试**:使用真实 Adapter 测试生产环境
## 📚 参考文档
- [后端六边形架构详解](../../backend/HEXAGONAL_ARCHITECTURE.md)
- [OpenAPI 规范](../../backend/docs/openapi.yaml)
- [Docker 部署指南](../deployment/docker-guide.md)
- [安全实现方案](../security/security-implementation.md)
---
**版本**: 1.0
**最后更新**: 2025-11-07