# Design: `enable-ddb-meta` 配置 — 控制 meta 从 DDB 而非 PD 获取

日期：2026-08-21
状态：已批准（2026-08-21 按用户反馈简化实现，本文档已同步更新）

## 背景与目标

`CacheClusterBranchRepo`（`pkg/repository/cache.go`）的 meta 查询链为
`local → pd → infra`（`doQuery` 内硬编码）。

目标：新增配置项，启用后 meta 从 DynamoDB 获取，完全替代 PD 源。

## 需求决策

| 决策点 | 结论 |
|---|---|
| 查询链语义 | 启用后 ddb **完全替换** pd：`local → ddb → infra`；未启用保持 `local → pd → infra` |
| 配置形式 | bool 开关（与 `EnableRcu`/`EnableIASku` 模式一致） |
| infra 源 | 保留作为最后兜底 |
| RUVersion 为空 | 可接受（DDB 源无此字段，`UseRUV2()` 恒 false，ruv2 计量不生效，后续再补） |
| 实现方式 | 最小改动：按配置切换 `sources` 列表，保留现有 `fns` map 结构，不引入新抽象 |

## 设计

### 1. 配置项（`pkg/config/config.go`）

```go
EnableDDBMeta bool `mapstructure:"enable-ddb-meta" default:"false"`
```

放在 `Config` 顶层，与 `EnableRcu`/`EnableIASku` 并列。默认 false，行为不变。

### 2. 查询链切换（`pkg/repository/cache.go`）

保持原有 `fns` map 结构不变，仅将 `doQuery` 中硬编码的 sources 列表改为
构造时按配置决定，存入 struct 字段 `sources []string`：

```go
sources := []string{"local", "pd", "infra"}
if config.Global().EnableDDBMeta {
    if cloudProvider != "aws" {
        return nil, fmt.Errorf("enable-ddb-meta is true but cloud provider is %s, must be aws", cloudProvider)
    }
    sources = []string{"local", "ddb", "infra"}
}
```

`doQuery` 遍历 `r.sources` 查 `fns` map，其余行为（not-found 跳过、非 local
源命中写入 local duckdb 缓存、全部 miss 返回 not found）不变。

### 3. 启动校验

构造函数内联校验（见上）：`EnableDDBMeta == true` 且 `cloudProvider != "aws"`
时返回错误 fail fast，避免 `dynamoClusterRepo` 为 nil 时的运行时 panic。

## 行为影响

- RUVersion 从 ddb 取时为空 → `UseRUV2()` 恒 false（已确认可接受）
- ddb 源固有行为不变：按 `tags_kubernetes` 过滤、跳过 `e2e` 前缀集群、多结果报错
- local 缓存行为不变：TTL（默认 30min）内切换配置后旧缓存仍命中，属预期
- `ListEssentialPlanClusters`（rcu controller 使用）仍走 PD，**out of scope**
- `DiffMetaData`（diff_meta.go）仍走 PD/DDB 原有路径，不受本配置影响

## 测试

新增 `pkg/repository/cache_test.go`：以 stub fns + 临时 duckdb 直接驱动 `doQuery`
（不走真实 HTTP/DDB）：

- not-found 逐级 fall-through，顺序正确
- ddb 命中后短路，结果写入 local 缓存（primary/keyspace 双 key 可读回）
- local 命中跳过缓存写入
- 非 not-found 错误立即返回

构造函数 fail-fast 分支因 `config.Global()` 不可注入而未做单测，由部署验证覆盖
（见 PR test plan）。

## 改动范围

| 文件 | 改动 |
|---|---|
| `pkg/config/config.go` | +1 配置字段 |
| `pkg/repository/cache.go` | struct +1 字段；构造函数按配置选 sources；`doQuery` 遍历 `r.sources` |
| `pkg/repository/cache_test.go` | 新增 `doQuery` 行为测试 |
