# 🏗️ 架构文档

## 目录

- [2.1.1 需求描述](#211-需求描述)
  - [项目背景](#项目背景)
  - [核心需求](#核心需求)
  - [功能需求](#功能需求)
  - [非功能需求](#非功能需求)
- [2.1.2 业务建模](#212-业务建模)
  - [业务领域](#业务领域)
  - [核心实体](#核心实体)
  - [业务流程](#业务流程)
  - [用例场景](#用例场景)
- [2.1.3 技术建模](#213-技术建模)
  - [2.1.3.1 六边形架构](#2131-六边形架构)
  - [2.1.3.2 技术选型](#2132-技术选型)

---

# 2.1.1 需求描述

## 项目背景

### 问题陈述

在云原生时代，Kubernetes 已成为容器编排的事实标准，Helm 是 Kubernetes 的包管理工具。然而，当前企业在使用 Helm 进行应用部署时面临以下挑战：

1. **多集群管理复杂** - 企业通常有多个 Kubernetes 集群（开发、测试、生产），需要统一的管理界面
2. **制品仓库分散** - Helm Chart 可能分布在多个 OCI Registry（Harbor、Docker Hub、GHCR）中，难以统一浏览
3. **部署流程繁琐** - 需要手动编写 `helm install` 命令，配置复杂的 values.yaml
4. **缺乏可视化** - 命令行操作对非技术人员不友好，缺少直观的 UI
5. **版本管理困难** - 应用升级需要记住历史版本，容易出错
6. **监控信息分散** - 需要单独访问 Kubernetes Dashboard 查看应用状态

### 解决方案

OCDP Backend 提供统一的后端 API 服务，实现：

- ✅ **统一管理** - 集中管理多个 Kubernetes 集群和 OCI Registry
- ✅ **可视化部署** - 通过 API 简化 Helm Chart 的浏览和部署流程
- ✅ **版本控制** - 完整的应用生命周期管理（安装、升级、卸载）
- ✅ **实时监控** - 集成 Kubernetes API，实时获取应用状态和资源使用情况
- ✅ **安全认证** - 支持用户认证和敏感数据加密存储

---

## 核心需求

### 业务需求

| 需求 ID | 需求描述 | 优先级 |
|---------|---------|--------|
| BR-001 | 支持管理多个 Kubernetes 集群 | P0 |
| BR-002 | 支持管理多个 OCI Registry | P0 |
| BR-003 | 浏览和搜索 Helm Chart 制品 | P0 |
| BR-004 | 部署 Helm Chart 到 Kubernetes 集群 | P0 |
| BR-005 | 升级已部署的应用 | P0 |
| BR-006 | 查看应用实时状态和资源使用 | P1 |
| BR-007 | 用户认证和权限管理 | P1 |
| BR-008 | 审计日志记录 | P2 |

### 用户角色

1. **平台管理员** - 管理集群、Registry、用户
2. **开发者** - 部署和管理自己的应用
3. **运维人员** - 监控和维护应用状态
4. **访客** - 只读查看应用列表和状态

---

## 功能需求

### F1. 集群管理

**描述**: 管理多个 Kubernetes 集群的连接配置

**功能点**:
- 添加集群（配置 API Server 地址、证书）
- 查看集群列表和详情
- 测试集群连接健康状态
- 更新和删除集群配置
- 查看集群资源使用情况（CPU、内存、节点数）

**验收标准**:
- ✅ 支持证书认证和 Token 认证
- ✅ 敏感信息（证书、密钥）加密存储
- ✅ 连接失败时给出清晰的错误提示
- ✅ 支持测试连接功能

---

### F2. Registry 管理

**描述**: 管理多个 OCI Registry 的连接配置

**功能点**:
- 添加 Registry（Harbor、Docker Hub、GHCR 等）
- 配置认证信息（用户名/密码）
- 查看 Registry 列表和详情
- 测试 Registry 连接健康状态
- 更新和删除 Registry 配置

**验收标准**:
- ✅ 支持 Basic Auth 和 Bearer Token
- ✅ 密码加密存储
- ✅ 支持 HTTP/HTTPS 和自签名证书
- ✅ 连接测试返回响应时间

---

### F3. Artifact 浏览

**描述**: 浏览和搜索 OCI Registry 中的 Helm Chart

**功能点**:
- 列出 Registry 中的所有仓库
- 列出仓库中的所有制品（tags）
- 查看制品详情（大小、创建时间、annotations）
- 自动识别制品类型（Helm Chart、Docker Image）
- 获取 Helm Chart 的 values schema

**验收标准**:
- ✅ 符合 OCI Distribution Specification
- ✅ 支持 URL 编码的仓库名称（如 `charts/app`）
- ✅ 正确解析 manifest 和 config
- ✅ 计算制品总大小（包含所有 layers）

---

### F4. 应用部署

**描述**: 部署 Helm Chart 到 Kubernetes 集群

**功能点**:
- 选择集群、Registry、Chart 和版本
- 配置 values（JSON 或 YAML）
- 安装应用到指定 namespace
- 查看安装进度和状态
- 获取应用访问端点

**验收标准**:
- ✅ 支持自定义 Release 名称
- ✅ 支持 JSON 和 YAML 格式的 values
- ✅ 记录部署历史

---

### F5. 应用生命周期管理

**描述**: 管理已部署应用的完整生命周期

**功能点**:
- 查看应用列表和详情
- 升级应用到新版本
- 查看部署历史
- 卸载应用

**验收标准**:
- ✅ 升级时保留配置
- ✅ 卸载时可选保留历史
- ✅ 显示每次部署的描述信息

---

### F6. 监控和状态

**描述**: 实时监控应用和集群状态

**功能点**:
- 查看应用实时状态（Running、Failed 等）
- 查看应用资源使用（CPU、内存）
- 查看集群整体监控
- 查看节点资源使用
- 监控摘要统计

**验收标准**:
- ✅ 实时获取 Kubernetes 资源状态
- ✅ 支持 Prometheus 指标集成
- ✅ 显示 Pod 状态和事件
- ✅ 资源使用百分比显示

---

### F7. 认证和授权

**描述**: 用户身份认证和访问控制

**功能点**:
- 用户注册和登录
- JWT Token 认证
- Token 刷新机制
- 密码加密存储

**验收标准**:
- ✅ 使用 bcrypt 哈希密码
- ✅ JWT Token 有效期配置
- ✅ Refresh Token 支持
- ✅ 密码强度验证

---

## 非功能需求

### NFR1. 性能要求

| 指标 | 要求 |
|------|------|
| API 响应时间 | P95 < 500ms |
| 并发用户数 | 支持 100+ 并发 |
| 数据库连接池 | 25 个连接 |
| Helm 操作超时 | 5 分钟 |

### NFR2. 可用性

- **系统可用性**: 99.5%
- **故障恢复时间**: < 5 分钟
- **数据备份**: 每日备份
- **健康检查**: 提供 `/health` 端点

### NFR3. 安全性

- **数据加密**: AES-256 加密敏感数据
- **传输安全**: 支持 HTTPS
- **认证方式**: JWT Token
- **密码策略**: 最小长度 8 位
- **审计日志**: 记录所有操作（未来）

### NFR4. 可扩展性

- **水平扩展**: 支持多实例部署
- **数据库**: PostgreSQL 支持主从复制
- **无状态设计**: API 服务无状态
- **缓存策略**: 支持 Redis（未来）

### NFR5. 可维护性

- **代码质量**: 遵循 Go 最佳实践
- **测试覆盖**: > 70%
- **文档完整**: API 文档、架构文档、部署文档
- **日志记录**: 结构化日志
- **监控指标**: Prometheus 指标（未来）

### NFR6. 兼容性

- **Kubernetes 版本**: 1.24+
- **Helm 版本**: 3.x
- **OCI Registry**: 符合 OCI Distribution Spec
- **数据库**: PostgreSQL 15+
- **Go 版本**: 1.21+

---

# 2.1.2 业务建模

## 业务领域

OCDP Backend 属于**云原生应用管理**领域，主要涉及以下子域：

1. **制品管理域** - OCI Registry、Helm Chart、Docker Image
2. **集群管理域** - Kubernetes Cluster、Node、Namespace
3. **应用部署域** - Helm Release、Application Instance
4. **监控运维域** - Metrics、Logs、Events

---

## 核心实体

### 领域模型图

```
┌─────────────────────────────────────────────────────────────┐
│                     Core Domain Entities                     │
└─────────────────────────────────────────────────────────────┘

┌──────────┐         ┌──────────┐         ┌──────────┐
│   User   │─────────│ Cluster  │─────────│ Instance │
└──────────┘         └──────────┘         └──────────┘
     │                    │                     │
     │                    │                     │
     ▼                    ▼                     ▼
┌──────────┐         ┌──────────┐         ┌──────────┐
│   Auth   │         │  Health  │         │  Status  │
│  Token   │         │  Check   │         │ Resource │
└──────────┘         └──────────┘         └──────────┘

┌──────────┐         ┌──────────┐         ┌──────────┐
│ Registry │─────────│Artifact  │─────────│  Chart   │
└──────────┘         └──────────┘         └──────────┘
     │                    │                     │
     │                    │                     │
     ▼                    ▼                     ▼
┌──────────┐         ┌──────────┐         ┌──────────┐
│  Health  │         │Repository│         │  Values  │
│  Check   │         │          │         │  Schema  │
└──────────┘         └──────────┘         └──────────┘
```

### 实体详解

#### 1. User（用户）

**职责**: 表示系统用户，负责身份认证

**属性**:
- `ID`: 唯一标识符
- `Username`: 用户名（唯一）
- `Email`: 邮箱
- `PasswordHash`: 密码哈希（bcrypt）
- `CreatedAt`: 创建时间
- `UpdatedAt`: 更新时间

**业务规则**:
- 用户名唯一
- 邮箱格式验证
- 密码最小长度 8 位

---

#### 2. Cluster（集群）

**职责**: 表示 Kubernetes 集群连接配置

**属性**:
- `ID`: 唯一标识符
- `Name`: 集群名称
- `Host`: API Server 地址
- `Description`: 描述
- `CAData`: CA 证书（加密存储）
- `CertData`: 客户端证书（加密存储）
- `KeyData`: 客户端密钥（加密存储）
- `Token`: Bearer Token（可选）
- `CreatedAt`: 创建时间
- `UpdatedAt`: 更新时间

**业务规则**:
- 集群名称唯一
- 必须提供证书或 Token
- Host 必须是有效的 HTTPS URL

---

#### 3. Registry（镜像仓库）

**职责**: 表示 OCI Registry 连接配置

**属性**:
- `ID`: 唯一标识符
- `Name`: Registry 名称
- `URL`: Registry URL
- `Description`: 描述
- `Username`: 用户名
- `Password`: 密码（加密存储）
- `Insecure`: 是否跳过 SSL 验证
- `CreatedAt`: 创建时间
- `UpdatedAt`: 更新时间

**业务规则**:
- Registry 名称唯一
- URL 必须是有效的 HTTP/HTTPS URL
- 密码加密存储

---

#### 4. Instance（应用实例）

**职责**: 表示部署在 Kubernetes 中的 Helm Release

**属性**:
- `ID`: 唯一标识符
- `Name`: Release 名称
- `Namespace`: Kubernetes namespace
- `ClusterID`: 所属集群
- `RegistryID`: Chart 来源 Registry
- `Repository`: Chart 仓库名
- `Chart`: Chart 名称
- `Version`: Chart 版本
- `Status`: 部署状态
- `Revision`: 当前版本号
- `Values`: 配置值（JSON）
- `Description`: 描述
- `CreatedAt`: 创建时间
- `UpdatedAt`: 更新时间

**业务规则**:
- 同一集群和 namespace 下 Release 名称唯一
- 必须关联有效的 Cluster 和 Registry
- Values 必须是有效的 JSON 或 YAML

---

#### 5. Artifact（制品）

**职责**: 表示 OCI Registry 中的制品（Helm Chart、Docker Image 等）

**属性**:
- `RepositoryName`: 仓库名称
- `Tag`: 标签
- `Digest`: SHA256 摘要
- `Type`: 制品类型（helm、docker、oci）
- `Size`: 总大小
- `MediaType`: 媒体类型
- `Annotations`: 元数据
- `CreatedAt`: 创建时间

**业务规则**:
- Tag 或 Digest 至少提供一个
- 自动识别制品类型
- 计算所有 layers 的总大小

---

## 业务流程

### 流程 1: 用户注册和登录

```
┌──────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ User │    │ Handler  │    │ Service  │    │   Repo   │
└──┬───┘    └────┬─────┘    └────┬─────┘    └────┬─────┘
   │             │               │               │
   │ Register    │               │               │
   ├────────────>│               │               │
   │             │ Create User   │               │
   │             ├──────────────>│               │
   │             │               │ Hash Password │
   │             │               ├──────┐        │
   │             │               │<─────┘        │
   │             │               │ Save User     │
   │             │               ├──────────────>│
   │             │               │<──────────────┤
   │             │<──────────────┤               │
   │<────────────┤               │               │
   │             │               │               │
   │ Login       │               │               │
   ├────────────>│               │               │
   │             │ Authenticate  │               │
   │             ├──────────────>│               │
   │             │               │ Verify Pwd    │
   │             │               ├──────┐        │
   │             │               │<─────┘        │
   │             │               │ Gen JWT       │
   │             │               ├──────┐        │
   │             │               │<─────┘        │
   │             │<──────────────┤               │
   │<────────────┤ Return Token  │               │
   │             │               │               │
```

---

### 流程 2: 部署应用

```
┌──────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ User │    │ Handler  │    │ Service  │    │HelmClient│    │Kubernetes│
└──┬───┘    └────┬─────┘    └────┬─────┘    └────┬─────┘    └────┬─────┘
   │             │               │               │               │
   │ Deploy App  │               │               │               │
   ├────────────>│               │               │               │
   │             │ Create Inst   │               │               │
   │             ├──────────────>│               │               │
   │             │               │ Validate      │               │
   │             │               ├──────┐        │               │
   │             │               │<─────┘        │               │
   │             │               │ Pull Chart    │               │
   │             │               ├──────────────>│               │
   │             │               │<──────────────┤               │
   │             │               │ Install Chart │               │
   │             │               ├──────────────>│               │
   │             │               │               │ Apply K8s     │
   │             │               │               ├──────────────>│
   │             │               │               │<──────────────┤
   │             │               │<──────────────┤               │
   │             │               │ Save Instance │               │
   │             │               ├──────┐        │               │
   │             │               │<─────┘        │               │
   │             │<──────────────┤               │               │
   │<────────────┤ Return Status │               │               │
   │             │               │               │               │
```

---

### 流程 3: 浏览制品

```
┌──────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ User │    │ Handler  │    │ Service  │    │OCIClient │    │ Registry │
└──┬───┘    └────┬─────┘    └────┬─────┘    └────┬─────┘    └────┬─────┘
   │             │               │               │               │
   │List Repos   │               │               │               │
   ├────────────>│               │               │               │
   │             │ Get Repos     │               │               │
   │             ├──────────────>│               │               │
   │             │               │ List Catalog  │               │
   │             │               ├──────────────>│               │
   │             │               │               │ GET _catalog  │
   │             │               │               ├──────────────>│
   │             │               │               │<──────────────┤
   │             │               │<──────────────┤               │
   │             │<──────────────┤               │               │
   │<────────────┤               │               │               │
   │             │               │               │               │
   │List Tags    │               │               │               │
   ├────────────>│               │               │               │
   │             │ Get Artifacts │               │               │
   │             ├──────────────>│               │               │
   │             │               │ List Tags     │               │
   │             │               ├──────────────>│               │
   │             │               │               │ GET tags/list │
   │             │               │               ├──────────────>│
   │             │               │               │<──────────────┤
   │             │               │ Get Manifest  │               │
   │             │               ├──────────────>│               │
   │             │               │               │ GET manifest  │
   │             │               │               ├──────────────>│
   │             │               │               │<──────────────┤
   │             │               │<──────────────┤               │
   │             │<──────────────┤               │               │
   │<────────────┤               │               │               │
   │             │               │               │               │
```

---

## 用例场景

### UC1: 开发者部署测试应用

**主角**: 开发者 Alice

**前置条件**:
- Alice 已登录系统
- 系统中已配置开发环境集群
- 系统中已配置 Harbor Registry

**基本流程**:
1. Alice 选择"开发集群"
2. Alice 浏览 Harbor 中的"charts/nginx"仓库
3. Alice 选择 nginx 1.0.0 版本
4. Alice 配置 values: `{"replicaCount": 2}`
5. Alice 点击"部署"
6. 系统显示部署进度
7. 部署成功，显示应用访问地址

**后置条件**:
- nginx 应用成功部署到开发集群
- 应用状态为 "deployed"
- Alice 可以访问应用

**异常流程**:
- 3a. Chart 版本不存在 → 显示错误提示
- 5a. 部署失败 → 显示错误日志

---

### UC2: 运维人员升级生产应用

**主角**: 运维 Bob

**前置条件**:
- Bob 已登录系统
- 生产环境有运行中的 nginx 应用（版本 1.0.0）

**基本流程**:
1. Bob 进入"生产集群"应用列表
2. Bob 选择 nginx 应用
3. Bob 查看当前版本和配置
4. Bob 点击"升级"
5. Bob 选择新版本 1.1.0
6. Bob 更新配置: `{"replicaCount": 3}`
7. Bob 添加升级说明
8. Bob 确认升级
9. 系统执行滚动升级
10. 升级成功，Revision 增加到 2

**后置条件**:
- nginx 应用升级到 1.1.0
- 副本数增加到 3
- 历史记录中保留了 Revision 1

**异常流程**:
- 9a. 升级失败 → 显示错误信息，保持原状态
- 9b. 超时 → 取消升级，保持原状态

---

### UC3: 管理员添加新集群

**主角**: 管理员 Charlie

**前置条件**:
- Charlie 已登录系统
- Charlie 有集群的 kubeconfig 文件

**基本流程**:
1. Charlie 进入"集群管理"页面
2. Charlie 点击"添加集群"
3. Charlie 填写集群信息:
   - 名称: "Production Cluster"
   - API Server: "https://k8s.prod.com:6443"
   - 描述: "生产环境集群"
4. Charlie 从 kubeconfig 提取证书数据
5. Charlie 粘贴 CA、Cert、Key 数据
6. Charlie 点击"测试连接"
7. 系统显示"连接成功"
8. Charlie 保存配置

**后置条件**:
- 新集群添加到系统
- 集群证书加密存储
- 其他用户可以使用此集群

**异常流程**:
- 6a. 连接失败 → 显示具体错误信息
- 6b. 证书格式错误 → 提示正确的格式

---

# 2.1.3 技术建模

## 2.1.3.1 六边形架构

### 架构概述

OCDP Backend 采用**六边形架构**（Hexagonal Architecture，也称为端口和适配器架构），这是一种分层架构模式，强调业务逻辑与外部依赖的分离。

### 核心原则

1. **依赖倒置** - 所有层依赖 Domain，Domain 无外部依赖
2. **端口和适配器** - 通过接口（Port）定义交互协议，通过适配器（Adapter）实现具体技术
3. **可测试性** - 业务逻辑可独立测试，无需外部依赖
4. **可替换性** - 适配器可轻松替换（Mock ↔ Production）

### 架构分层图

```
┌─────────────────────────────────────────────────────────────┐
│                     Input Adapters                          │
│                   (HTTP REST API)                           │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐     │
│  │ Auth Handler │  │Cluster Handl │  │Instance Handl│     │
│  └──────────────┘  └──────────────┘  └──────────────┘     │
│                                                              │
└──────────────────────┬──────────────────────────────────────┘
                       │ DTO / Request
                       ↓
┌─────────────────────────────────────────────────────────────┐
│                    Domain Layer                             │
│                   (Business Logic)                          │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    Entities                          │  │
│  │  User | Cluster | Registry | Instance | Artifact    │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    Services                          │  │
│  │  AuthService | ClusterService | InstanceService     │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │             Repository Interfaces (Ports)            │  │
│  │  UserRepo | ClusterRepo | OCIClient | HelmClient    │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────┬──────────────────────────────────────┘
                       │ Interface Contract
                       ↓
┌─────────────────────────────────────────────────────────────┐
│                   Output Adapters                           │
│            (Infrastructure Implementations)                 │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐     │
│  │   Database   │  │  OCI Client  │  │ Helm Client  │     │
│  │              │  │              │  │              │     │
│  ├──────────────┤  ├──────────────┤  ├──────────────┤     │
│  │ Mock: Memory │  │ Mock: Static │  │ Mock: Fake   │     │
│  │ Prod:Postgres│  │ Prod: ORAS   │  │ Prod: Helm   │     │
│  └──────────────┘  └──────────────┘  └──────────────┘     │
│                                                              │
└─────────────────────────────────────────────────────────────┘
```

### 目录结构

```
internal/
├── domain/                    # 🎯 领域层（核心）
│   ├── entity/                # 领域实体
│   │   ├── user.go
│   │   ├── cluster.go
│   │   ├── registry.go
│   │   ├── instance.go
│   │   └── artifact.go
│   │
│   ├── service/               # 业务逻辑服务
│   │   ├── auth_service.go
│   │   ├── cluster_service.go
│   │   ├── registry_service.go
│   │   ├── artifact_service.go
│   │   ├── instance_service.go
│   │   └── monitoring_service.go
│   │
│   └── repository/            # 接口定义（Output Ports）
│       ├── user_repository.go
│       ├── cluster_repository.go
│       ├── registry_repository.go
│       ├── instance_repository.go
│       ├── oci_client.go
│       ├── helm_client.go
│       └── metrics_client.go
│
├── adapter/
│   ├── input/                 # 📥 输入适配器
│   │   └── http/
│   │       ├── rest/          # REST API Handlers
│   │       │   ├── auth_handler.go
│   │       │   ├── cluster_handler.go
│   │       │   ├── registry_handler.go
│   │       │   ├── artifact_handler.go
│   │       │   ├── instance_handler.go
│   │       │   ├── monitoring_handler.go
│   │       │   └── utils.go
│   │       │
│   │       └── dto/           # 数据传输对象
│   │           ├── auth_dto.go
│   │           ├── cluster_dto.go
│   │           ├── registry_dto.go
│   │           └── instance_dto.go
│   │
│   └── output/                # 📤 输出适配器
│       ├── persistence/
│       │   ├── mock/          # ✅ Mock 实现
│       │   │   ├── user_repository_mock.go
│       │   │   ├── cluster_repository_mock.go
│       │   │   ├── registry_repository_mock.go
│       │   │   └── instance_repository_mock.go
│       │   │
│       │   └── postgres/      # 🐘 PostgreSQL 实现
│       │       ├── user_repository.go
│       │       ├── cluster_repository.go
│       │       ├── registry_repository.go
│       │       └── instance_repository.go
│       │
│       ├── oci/
│       │   ├── mock/          # ✅ Mock OCI Client
│       │   │   └── oci_client_mock.go
│       │   └── oras_client.go # ORAS SDK 实现
│       │
│       ├── helm/
│       │   ├── mock/          # ✅ Mock Helm Client
│       │   │   └── helm_client_mock.go
│       │   └── helm_client.go # Helm SDK 实现
│       │
│       ├── metrics/
│       │   ├── mock/          # ✅ Mock Metrics Client
│       │   │   └── metrics_client_mock.go
│       │   └── prometheus_client.go
│       │
│       └── factory.go         # 🏭 适配器工厂
│
├── bootstrap/                 # Bootstrap 预注入模块
│   ├── config.go
│   └── seeder.go
│
└── pkg/                       # 🔧 工具包
    ├── jwt/                   # JWT 工具
    ├── password/              # 密码哈希
    └── encryption/            # AES 加密
```

### 数据流

```
1. HTTP Request
      ↓
2. [REST Handler] (Input Adapter)
   - 验证请求参数
   - 转换为 Domain 对象（Entity）
      ↓
3. [Domain Service] (Business Logic)
   - 执行业务逻辑
   - 调用 Repository 接口（Port）
      ↓
4. [Repository Implementation] (Output Adapter)
   - Mock: 操作内存数据
   - PostgreSQL: 操作数据库
   - ORAS: 与 OCI Registry 交互
   - Helm: 与 Kubernetes 交互
      ↓
5. Response
   - 返回结果到 Service
   - Service 返回到 Handler
   - Handler 转换为 HTTP 响应
```

### 依赖注入

在 `cmd/api/main.go` 中组装所有组件：

```go
func main() {
    // 1. 加载配置
    config := loadConfig()
    
    // 2. 创建适配器工厂
    factory := output.NewAdapterFactory(
        config.AdapterMode,
        config.DatabaseURL,
    )
    
    // 3. 创建 Output Adapters
    repos, _ := factory.CreateAllRepositories()
    ociClient, _ := factory.CreateOCIClient()
    helmClient, _ := factory.CreateHelmClient()
    
    // 4. 创建工具类
    hasher := password.NewBcryptHasher()
    jwtGen := jwt.NewJWTGenerator(config.JWTSecret)
    
    // 5. 创建 Domain Services
    authService := service.NewAuthService(repos.UserRepo, hasher, jwtGen)
    clusterService := service.NewClusterService(repos.ClusterRepo)
    registryService := service.NewRegistryService(repos.RegistryRepo)
    instanceService := service.NewInstanceService(
        repos.InstanceRepo,
        repos.ClusterRepo,
        repos.RegistryRepo,
        helmClient,
    )
    
    // 6. 创建 Input Adapters (REST Handlers)
    authHandler := rest.NewAuthHandler(authService)
    clusterHandler := rest.NewClusterHandler(clusterService)
    instanceHandler := rest.NewInstanceHandler(instanceService)
    
    // 7. 设置路由
    router := setupRouter(
        authHandler,
        clusterHandler,
        instanceHandler,
    )
    
    // 8. 启动服务器
    http.ListenAndServe(":8080", router)
}
```

### 适配器模式

#### 适配器工厂

```go
// internal/adapter/output/factory.go
type AdapterMode string

const (
    ModeMock       AdapterMode = "mock"
    ModeProduction AdapterMode = "production"
)

type AdapterFactory struct {
    mode         AdapterMode
    dbConnString string
}

func (f *AdapterFactory) CreateUserRepository() (repository.UserRepository, error) {
    switch f.mode {
    case ModeMock:
        return mock.NewUserRepositoryMock(), nil
    case ModeProduction:
        return postgres.NewUserRepository(f.dbConnString)
    default:
        return nil, fmt.Errorf("unknown adapter mode: %s", f.mode)
    }
}
```

#### Mock vs Production

| 接口 | Mock 模式 | Production 模式 |
|------|----------|----------------|
| UserRepository | ✅ 内存 map | 🐘 PostgreSQL |
| ClusterRepository | ✅ 内存 map | 🐘 PostgreSQL |
| RegistryRepository | ✅ 内存 map | 🐘 PostgreSQL |
| InstanceRepository | ✅ 内存 map | 🐘 PostgreSQL |
| OCIClient | ✅ 静态数据 | 🌐 ORAS SDK v2 |
| HelmClient | ✅ 模拟部署 | ☸️  Helm SDK |
| MetricsClient | ✅ 假数据 | 📊 Prometheus |

---

## 2.1.3.2 技术选型

### 编程语言

**Go 1.21+**

**选型理由**:
- ✅ 高性能，原生并发支持
- ✅ 静态类型，编译时检查
- ✅ 丰富的云原生生态（Kubernetes client-go、Helm SDK、ORAS）
- ✅ 简单易维护，部署方便（单一二进制文件）
- ✅ 广泛应用于云原生领域

**替代方案**: Java/Spring Boot, Python/FastAPI

---

### Web 框架

**gorilla/mux**

**选型理由**:
- ✅ 轻量级，性能好
- ✅ 灵活的路由匹配（支持正则表达式）
- ✅ 与标准库 `net/http` 完美兼容
- ✅ 活跃的社区支持

**使用示例**:
```go
router := mux.NewRouter()
api := router.PathPrefix("/api/v1").Subrouter()
api.HandleFunc("/clusters", handler.CreateCluster).Methods(http.MethodPost)
api.HandleFunc("/clusters/{clusterId}", handler.GetCluster).Methods(http.MethodGet)
```

**替代方案**: Gin, Echo, Fiber

---

### 数据库

**PostgreSQL 15+**

**选型理由**:
- ✅ 开源、成熟、可靠
- ✅ 支持复杂查询和事务
- ✅ JSONB 类型适合存储动态配置
- ✅ 主从复制、高可用支持
- ✅ 与 Go 生态集成良好

**数据库驱动**: `lib/pq` 或 `pgx`

**替代方案**: MySQL, MongoDB

---

### OCI Registry 客户端

**ORAS Go SDK v2**

**选型理由**:
- ✅ 符合 OCI Distribution Specification
- ✅ 官方维护，质量可靠
- ✅ 支持所有 OCI 兼容的 Registry
- ✅ 完整的 manifest、blob 操作

**使用示例**:
```go
repo, err := remote.NewRepository("harbor.example.com/charts/nginx")
repo.Client = &auth.Client{
    Credential: auth.StaticCredential("username", "password"),
}

tags, err := repo.Tags(ctx)
manifest, err := repo.FetchReference(ctx, "1.0.0")
```

**官网**: https://oras.land/

**替代方案**: containerd, go-containerregistry

---

### Kubernetes 客户端

**client-go**

**选型理由**:
- ✅ Kubernetes 官方 Go 客户端
- ✅ 完整的 API 支持
- ✅ 动态客户端支持
- ✅ 与 Helm SDK 集成

**使用示例**:
```go
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
clientset, err := kubernetes.NewForConfig(config)

pods, err := clientset.CoreV1().Pods("default").List(ctx, metav1.ListOptions{})
```

**替代方案**: 无（标准库）

---

### Helm 客户端

**Helm SDK (helm.sh/helm/v3)**

**选型理由**:
- ✅ Helm 官方 SDK
- ✅ 完整的 Helm 操作支持
- ✅ Chart 解析和渲染
- ✅ Release 生命周期管理

**使用示例**:
```go
actionConfig := new(action.Configuration)
actionConfig.Init(settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf)

install := action.NewInstall(actionConfig)
install.ReleaseName = "my-release"
install.Namespace = "default"

chart, err := loader.Load(chartPath)
release, err := install.Run(chart, values)
```

**替代方案**: 命令行调用 helm（不推荐）

---

### 认证和授权

**JWT (golang-jwt/jwt)**

**选型理由**:
- ✅ 无状态，易扩展
- ✅ 标准化（RFC 7519）
- ✅ 支持过期时间和刷新
- ✅ 广泛应用

**使用示例**:
```go
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    "user_id": user.ID,
    "exp":     time.Now().Add(time.Hour * 24).Unix(),
})

tokenString, err := token.SignedString([]byte(jwtSecret))
```

**替代方案**: OAuth 2.0, Session

---

### 密码哈希

**bcrypt (golang.org/x/crypto/bcrypt)**

**选型理由**:
- ✅ 安全、抗暴力破解
- ✅ 自动加盐
- ✅ 计算成本可调
- ✅ Go 标准扩展库

**使用示例**:
```go
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
err = bcrypt.CompareHashAndPassword(hash, []byte(password))
```

**替代方案**: argon2, scrypt

---

### 数据加密

**AES-256 (crypto/aes + crypto/cipher)**

**选型理由**:
- ✅ 对称加密，性能好
- ✅ 256 位密钥，安全性高
- ✅ Go 标准库支持
- ✅ 适合敏感数据加密（证书、密码）

**使用模式**: GCM（Galois/Counter Mode）

**使用示例**:
```go
block, err := aes.NewCipher(key) // 32 bytes key
gcm, err := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
```

**替代方案**: RSA (非对称加密，性能较差)

---

### 容器化

**Docker + Docker Compose**

**选型理由**:
- ✅ 标准化容器技术
- ✅ 简化部署和环境一致性
- ✅ 丰富的镜像生态
- ✅ Docker Compose 简化多容器编排

**Dockerfile 示例**:
```dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o ocdp-backend cmd/api/main.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/ocdp-backend .
EXPOSE 8080
CMD ["./ocdp-backend"]
```

**替代方案**: Podman, containerd

---

### 日志记录

**标准库 log + 结构化日志（未来：zerolog/zap）**

**当前实现**:
```go
log.Printf("✅ User created: %s", user.Username)
log.Printf("⚠️  Warning: %v", err)
log.Printf("❌ Error: %v", err)
```

**未来优化**:
```go
logger.Info().
    Str("user_id", user.ID).
    Str("username", user.Username).
    Msg("User created")
```

---

### 测试框架

**testify**

**选型理由**:
- ✅ 丰富的断言函数
- ✅ Mock 支持
- ✅ 测试套件支持
- ✅ 活跃的社区

**使用示例**:
```go
import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestCreateUser(t *testing.T) {
    user, err := service.CreateUser(ctx, "test", "password")
    require.NoError(t, err)
    assert.NotEmpty(t, user.ID)
    assert.Equal(t, "test", user.Username)
}
```

---

### 热重载（开发）

**Air**

**选型理由**:
- ✅ Go 项目热重载
- ✅ 监听文件变化自动重启
- ✅ 配置简单

**配置文件**: `.air.toml`

```toml
[build]
  cmd = "go build -o ./tmp/main cmd/api/main.go"
  bin = "./tmp/main"
  include_ext = ["go", "yaml", "json"]
  exclude_dir = ["tmp", "vendor"]
```

**启动**: `air -c .air.toml`

---

### 技术栈总结表

| 组件 | 技术 | 版本 | 用途 |
|------|------|------|------|
| **语言** | Go | 1.21+ | 主要编程语言 |
| **Web 框架** | gorilla/mux | latest | HTTP 路由 |
| **数据库** | PostgreSQL | 15+ | 持久化存储 |
| **数据库驱动** | lib/pq 或 pgx | latest | Go 数据库驱动 |
| **OCI 客户端** | ORAS Go SDK | v2 | OCI Registry 操作 |
| **Kubernetes** | client-go | latest | K8s API 交互 |
| **Helm** | Helm SDK | v3 | Helm 操作 |
| **JWT** | golang-jwt/jwt | v5 | 认证 Token |
| **密码哈希** | bcrypt | latest | 密码加密 |
| **数据加密** | AES-256 | stdlib | 敏感数据加密 |
| **容器化** | Docker | latest | 应用容器化 |
| **编排** | Docker Compose | latest | 多容器编排 |
| **测试** | testify | latest | 单元测试 |
| **热重载** | Air | latest | 开发环境 |

---

### Bootstrap 预注入

**概述**: 在应用启动时自动初始化用户、Registry、Cluster 等数据。

**配置文件**: `config/bootstrap.json`

```json
{
  "enabled": true,
  "users": [
    {
      "username": "admin",
      "password": "admin123",
      "email": "admin@example.com"
    }
  ],
  "registries": [
    {
      "name": "Harbor Production",
      "url": "https://harbor.example.com",
      "username": "admin",
      "password": "secret"
    }
  ],
  "clusters": [
    {
      "name": "Production Cluster",
      "host": "https://k8s.example.com:6443",
      "caData": "LS0tLS...",
      "certData": "LS0tLS...",
      "keyData": "LS0tLS..."
    }
  ]
}
```

**特性**:
- ✅ 自动加密敏感数据
- ✅ 幂等性（重复启动不会重复创建）
- ✅ 可通过环境变量配置
- ✅ 支持禁用

**从 kubeconfig 提取证书**:
```bash
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}'
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}'
kubectl config view --raw -o jsonpath='{.users[0].user.client-key-data}'
```

---

### 开发指南

#### 添加新功能的步骤

1. **定义 Entity** (`internal/domain/entity/`)
2. **定义 Repository 接口** (`internal/domain/repository/`)
3. **实现 Domain Service** (`internal/domain/service/`)
4. **实现 Mock Adapter** (`internal/adapter/output/persistence/mock/`)
5. **实现 Production Adapter** (`internal/adapter/output/persistence/postgres/`)
6. **添加到 Factory** (`internal/adapter/output/factory.go`)
7. **创建 REST Handler** (`internal/adapter/input/http/rest/`)
8. **注册路由** (`cmd/api/main.go`)

#### 依赖方向规则

- ✅ Input Adapters → Domain Layer
- ✅ Domain Layer → Repository Interfaces
- ✅ Output Adapters → Domain Layer (实现接口)
- ❌ Domain Layer → Output Adapters（禁止）

#### 测试策略

- **单元测试**: 测试 Domain Service，使用 Mock Repository
- **集成测试**: 测试 Handler + Service，使用 Mock Adapters
- **E2E 测试**: 完整流程测试，使用真实环境

---

## 相关文档

- [API 与测试](api-and-test.md)
- [部署文档](deployment.md)
- [主 README](../README.md)

---

**Last Updated**: 2025-11-09
