## 目标

将 `contract-template` 相关页面从旧的 PostgREST 直连方式切换到新的 FastAPI 业务接口，范围仅覆盖：

- 模板分类
- 模板列表
- 模板搜索
- 模板详情

本清单不包含“起草合同”能力，后续会作为独立模块重新开发。


## 当前前端依赖点

当前前端核心依赖集中在：

- `legal-platform-frontend/lib/api/legacy/contract-template/templates.ts`

这个文件现在直接调用：

- `/api/postgrest/proxy/contract_categories`
- `/api/postgrest/proxy/contract_templates`

受影响页面：

- `app/(audit)/contract-template/search/page.tsx`
- `app/(audit)/contract-template/search/results/page.tsx`
- `app/(audit)/contract-template/list/page.tsx`
- `app/(audit)/contract-template/detail/[id]/page.tsx`


## 推荐新接口

建议前端最终切换为：

1. `GET /api/v3/contract-templates/categories`
2. `GET /api/v3/contract-templates`
3. `GET /api/v3/contract-templates/search`
4. `GET /api/v3/contract-templates/{id}`


## 改造步骤

### 第 1 步：新增新接口客户端文件

建议新增：

- `legal-platform-frontend/lib/api/contract-template/index.ts`

职责：

- 仅封装新的业务后端接口
- 不再依赖 `postgrest-client.ts`
- 返回字段尽量与页面现有消费结构兼容

建议方法：

- `getContractTemplateCategories`
- `getContractTemplateList`
- `searchContractTemplateList`
- `getContractTemplateDetail`


### 第 2 步：定义前端接口类型

建议在新客户端文件中定义或复用以下类型：

- `ContractTemplateCategory`
- `ContractTemplateListItem`
- `ContractTemplatePage`
- `ContractTemplateDetail`
- `ContractTemplateSearchResult`

字段建议优先与新后端对齐，然后在页面边界做一次轻量转换，避免业务层长期保留 snake_case 和 camelCase 混用。


### 第 3 步：改造搜索首页

文件：

- `app/(audit)/contract-template/search/page.tsx`

当前行为：

- 调 `getContractCategoriesWithCount`

改造后：

- 改为调用 `getContractTemplateCategories`
- 直接消费后端返回的 `templateCount`

页面影响：

- `transformCategory` 中的 `template_count` 改为新接口字段


### 第 4 步：改造列表页

文件：

- `app/(audit)/contract-template/list/page.tsx`

当前行为：

- 调 `getContractTemplates`
- 同时调 `getContractCategoriesWithCount`

改造后：

- 列表数据改为 `getContractTemplateList`
- 分类数据改为 `getContractTemplateCategories`

注意事项：

- 当前页面把 `sortBy=relevance` 映射成 `id.asc`，这是旧 PostgREST 兼容逻辑
- 切换新接口后应明确排序语义：
  - `relevance` 仅搜索场景有效
  - 列表页默认建议改为 `updated_at desc`


### 第 5 步：改造搜索结果页

文件：

- `app/(audit)/contract-template/search/results/page.tsx`

当前行为：

- 调 `searchContractTemplates`
- 额外循环所有分类，再逐类搜索统计命中数

改造后：

- 改为一次调用 `searchContractTemplateList`
- 直接使用后端返回的 `categoryStats`

收益：

- 避免当前每次搜索都发起多次分类二次查询
- 页面搜索耗时会明显降低


### 第 6 步：改造详情页

文件：

- `app/(audit)/contract-template/detail/[id]/page.tsx`

当前行为：

- 调 `getContractTemplate`

改造后：

- 改为调用 `getContractTemplateDetail`

注意事项：

- 页面中依赖：
  - `template_code`
  - `file_path`
  - `pdf_file_path`
  - `placeholder_schema`
  - `category.name`
  - `category.description`
- 新接口最好直接扁平返回，前端减少再拼装


### 第 7 步：保留旧文件作为过渡，避免一次性大改

建议不要立刻删除：

- `lib/api/legacy/contract-template/templates.ts`

更稳妥的做法：

1. 新建新接口客户端文件
2. 页面逐个切换
3. 确认没有页面再引用旧文件
4. 再删除旧实现


## 字段映射建议

建议后端返回使用 camelCase 还是 snake_case，前后端尽量统一一次定死。

如果后端沿用当前 Python VO 风格的 snake_case，那么前端建议统一在 API client 中做转换：

- `template_code -> templateCode`
- `category_id -> categoryId`
- `file_path -> filePath`
- `pdf_file_path -> pdfFilePath`
- `placeholder_schema -> placeholderSchema`
- `updated_at -> updatedAt`

不要把这类转换分散在页面组件里。


## 具体函数替换建议

当前旧函数：

- `getContractCategories`
- `getContractCategoriesWithCount`
- `getContractTemplates`
- `getContractTemplate`
- `searchContractTemplates`

建议替换为新函数：

- `getContractTemplateCategories`
- `getContractTemplateList`
- `getContractTemplateDetail`
- `searchContractTemplateList`


## 风险点

1. 排序语义变化
   - 旧逻辑混入了 PostgREST 风格排序拼接
   - 新接口需要明确合法排序字段白名单

2. 搜索分类统计变化
   - 旧页面自己循环查询分类统计
   - 新接口如果不返回 `categoryStats`，页面逻辑还要保留一部分旧实现

3. 详情页字段结构变化
   - 旧页面默认拿 `template.category?.name`
   - 新接口若改成扁平字段，需要同步调整页面 transform

4. token 传递方式变化
   - 旧实现依赖 `postgrest-client.ts`
   - 新接口应统一走 `axios-client.ts` 或新业务客户端


## 建议落地顺序

1. 新增 `lib/api/contract-template/index.ts`
2. 先切 `search/page.tsx`
3. 再切 `list/page.tsx`
4. 再切 `search/results/page.tsx`
5. 最后切 `detail/[id]/page.tsx`
6. 全部验证通过后删除旧 `legacy/contract-template/templates.ts`


## 验收标准

1. `contract-template/search` 能正常展示分类和数量
2. `contract-template/list` 能分页、筛选、排序
3. `contract-template/search/results` 能搜索并展示分类统计
4. `contract-template/detail/[id]` 能正常查看详情与预览
5. 页面不再直接请求 `/api/postgrest/proxy/contract_categories`
6. 页面不再直接请求 `/api/postgrest/proxy/contract_templates`
