# 📋 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

