# 聚合 DSL 极简落盘记录

> 日期：本次会话
> 范围：`@pylonts/dsl` 聚合声明层
> 目标：让“多对一 / 一对多”先落地，扩展表（一对一）只设计不实现。

## 1. 背景

聚合判断标准已收敛为：

> 创建 / 保存 / 删除时，是否必须一起做？
> - 是 → 聚合成员
> - 否 → 不聚合（引用）

本次落盘只实现最常用的“一对多”聚合成员：

```ts
defineAggregate({
  root: order,
  members: {
    items: [orderItem],
  },
});
```

- 数组成员 `[orderItem]` = 一对多；
- 非数组成员（扩展表 / 一对一）暂不落代码，保留设计。

## 2. 本次落盘改了什么

### 2.1 源码

| 文件 | 改动 |
|---|---|
| `dsl/src/aggregate.ts` | 极简化 `defineAggregate` |
| `dsl/src/repository.ts` | 注释同步为 `FK / extends` |

`dsl/src/aggregate.ts` 关键变化：

- 去掉 `name` 必填，聚合名自动取 `root.name`；
- `members` 类型简化为：

```ts
Record<string, TableSchema | TableSchema[]>
```

- 删除 `via` / `one` 复杂配置；
- 数组成员校验：
  - 必须恰好包含一张表；
  - 该表必须有且仅有一个外键指向 root 主键；
  - 多个外键指向 root 时明确报错；
- 非数组成员（扩展表）暂不支持，明确报错。

### 2.2 测试

| 文件 | 改动 |
|---|---|
| `dsl/test/aggregate.test.ts` | 改为新极简 API，并增加“非数组成员暂不支持”测试 |
| `dsl/test/repository.test.ts` | 改为新极简 API |

### 2.3 文档

| 文件 | 改动 |
|---|---|
| `dsl/docs/aggregate.md` | 示例去掉 `name`，成员表达改为数组/扩展表，同步扩展表规则 |
| `dsl/docs/table.md` | 新增“扩展表（extends）”设计说明，标注暂不落代码 |
| `dsl/docs/aggregate-implementation.md` | 本文档 |

## 3. 当前 API 形态

```ts
import { defineAggregate } from '@pylonts/dsl';

const orderAggregate = defineAggregate({
  root: order,
  members: {
    items: [orderItem],
  },
});
```

约束：

- `root` 必须有主键；
- `members` 的数组元素必须是普通表；
- 数组元素必须有外键指向 `root` 的主键；
- 如果有多条外键指向 root，必须收敛为一条，否则无法自动推导。

## 4. 如何验证

在仓库根目录或 `dsl/` 目录执行。

### 4.1 运行 DSL 测试

```bash
# 方式一：workspace
npm test --workspace @pylonts/dsl

# 方式二：进入 dsl 目录
cd dsl
npm test
```

可只跑聚合相关测试：

```bash
cd dsl
npx vitest run test/aggregate.test.ts test/repository.test.ts
```

预期结果：

- `aggregate.test.ts` 全部通过；
- `repository.test.ts` 全部通过；
- 新增的“非数组成员暂不支持”用例通过。

### 4.2 类型检查

```bash
npm run typecheck --workspace @pylonts/dsl
```

或：

```bash
cd dsl
npm run typecheck
```

预期结果：无 TypeScript 错误。

### 4.3 构建

```bash
npm run build --workspace @pylonts/dsl
```

或：

```bash
cd dsl
npm run build
```

预期结果：`dist/` 正常生成。

### 4.4 全量回归（如项目要求）

在仓库根按项目现有脚本执行：

```bash
npm run lint all
npm run typecheck
```

或按仓库实际脚本执行 `api tsc + lint all`。

## 5. 验证重点

1. 新的极简 `defineAggregate` 能正常声明聚合；
2. 不再需要传 `name`；
3. `members.items` 直接是 `[orderItem]`，不再有 `via` / `one`；
4. 没有外键指向 root 时会报错；
5. 非数组成员会报“扩展表未实现”；
6. 旧测试已全部迁移到新 API。

## 6. 暂未实现（保留设计）

- 扩展表 `extends: root`：一对一成员；
- 非数组成员：当前会抛错；
- Repository 生成器：仍未实现；
- flow 调用 repository：仍未实现。

这些内容在 `dsl/docs/aggregate.md` 和 `dsl/docs/table.md` 中保留设计。
