mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-09 03:42:47 +08:00
docs: 为 category-api 和 apikey-article-api 添加项目笔记文件
- 添加 category-api 的 problems、decisions、learnings、issues 文档 - 添加 apikey-article-api 的 issues、decisions、learnings 文档 - 包含架构决策、问题记录和学习总结
This commit is contained in:
1271
.sisyphus/plans/apikey-article-api.md
Normal file
1271
.sisyphus/plans/apikey-article-api.md
Normal file
File diff suppressed because it is too large
Load Diff
441
.sisyphus/plans/category-api.md
Normal file
441
.sisyphus/plans/category-api.md
Normal file
@@ -0,0 +1,441 @@
|
||||
# 分类查询 API 接口
|
||||
|
||||
## TL;DR
|
||||
|
||||
> **简要描述**: 在 API 模块新增只读分类查询接口(列表 + 详情),支持扁平列表和树形结构两种输出格式,使用 ApiKeyAuth 认证。
|
||||
>
|
||||
> **交付物**:
|
||||
> - `app/api/controller/Categories.php` — 分类查询控制器(index + read 两个方法)
|
||||
> - `AGENTS.md` — 更新项目知识库(API 控制器数量和描述)
|
||||
>
|
||||
> **预估工作量**: Quick(单文件 + 文档更新)
|
||||
> **并行执行**: YES — Task 1 和 Task 2 可并行
|
||||
> **关键路径**: Task 1 + Task 2 → F1-F4
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
### 原始需求
|
||||
用户需要在 API 模块中增加分类(Category)查询接口,当前 API 模块缺少分类相关的查询能力。
|
||||
|
||||
### 访谈摘要
|
||||
**关键讨论**:
|
||||
- 操作范围: 仅查询(index + read),不需要增删改
|
||||
- 认证方式: 需要 ApiKeyAuth 中间件认证
|
||||
- 数据格式: 同时支持扁平列表(默认)和树形结构(通过 `tree=1` 参数切换)
|
||||
|
||||
**已有参考**:
|
||||
- `app/api/controller/Articles.php` — RESTful API 控制器参考
|
||||
- `app/api/controller/Attachments.php` — API 控制器模式参考(`$this->request` 风格)
|
||||
- `app/model/Category.php` — Category 模型(含树形结构方法)
|
||||
|
||||
### Metis 审查
|
||||
**已识别并处理的缺口**:
|
||||
- Category 模型没有 SoftDelete trait → 必须手动过滤 `where('delete_time', 0)`
|
||||
- `getListLevel()` 不过滤 `status` → 树形模式需要额外过滤
|
||||
- `getListLevel()` 有静态缓存问题 → 不直接使用,改用自建查询 + `array2level()`
|
||||
- `type` 字段在数据库中是 string 类型 → 注意类型比较
|
||||
|
||||
---
|
||||
|
||||
## Work Objectives
|
||||
|
||||
### 核心目标
|
||||
为 API 模块添加只读分类查询接口,遵循现有 API 控制器模式(ApiKeyAuth + json_message),支持扁平列表和树形结构输出。
|
||||
|
||||
### 具体交付物
|
||||
- `app/api/controller/Categories.php` — 包含 `index()` 和 `read($id)` 两个公开方法
|
||||
- `AGENTS.md` — 更新 STRUCTURE 和 CODE MAP 中的 API 控制器信息
|
||||
|
||||
### 完成标准
|
||||
- [ ] 未认证请求返回 HTTP 401
|
||||
- [ ] 扁平列表分页正常,返回 `{code: 0, msg: '', data: {list, total, page}}`
|
||||
- [ ] `tree=1` 返回树形嵌套结构
|
||||
- [ ] `type`/`status`/`pid` 过滤参数正常工作
|
||||
- [ ] 单条查询返回分类详情(含父级和兄弟分类信息)
|
||||
- [ ] 不存在的分类 ID 返回错误提示
|
||||
- [ ] 已软删除的分类不出现在结果中
|
||||
|
||||
### Must Have
|
||||
- ApiKeyAuth 中间件认证
|
||||
- 手动过滤 `delete_time = 0`(Category 模型无 SoftDelete trait)
|
||||
- 默认只返回 `status = 1` 的分类(除非显式传入 `status` 参数)
|
||||
- `limit` 参数限制在 1-100 范围内
|
||||
- 遵循现有 API 控制器代码风格
|
||||
|
||||
### Must NOT Have(护栏)
|
||||
- 不得修改 Category 模型、`getListLevel()`、`array2level()` 或任何现有文件
|
||||
- 不得添加 save/update/delete 等写入接口
|
||||
- 不得添加缓存层(模型已有 AutoClearCache)
|
||||
- 不得添加关键词搜索功能
|
||||
- 不得加载 posts 关联数据(仅返回分类本身信息)
|
||||
- 不得使用 `declare(strict_types=1)`(遵循 api 模块多数模式)
|
||||
|
||||
---
|
||||
|
||||
## Verification Strategy
|
||||
|
||||
> **零人工干预** — 全部验证由 agent 执行。不接受需要"用户手动测试"的验收标准。
|
||||
|
||||
### 测试决策
|
||||
- **基础设施存在**: 否(项目无 PHPUnit 配置,无 tests/ 目录)
|
||||
- **自动化测试**: 无
|
||||
- **框架**: 无
|
||||
|
||||
### QA 策略
|
||||
所有任务必须包含 agent 执行的 QA 场景。
|
||||
证据保存到 `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`。
|
||||
|
||||
- **API 接口**: 使用 Bash (curl) — 发送请求,断言状态码 + 响应字段
|
||||
|
||||
---
|
||||
|
||||
## Execution Strategy
|
||||
|
||||
### 并行执行波次
|
||||
|
||||
```
|
||||
Wave 1(立即开始 — 2个任务可并行):
|
||||
├── Task 1: 创建 Categories 控制器 [quick]
|
||||
└── Task 2: 更新 AGENTS.md 文档 [quick]
|
||||
|
||||
Wave FINAL(Wave 1 完成后 — 4个并行审查):
|
||||
├── Task F1: 计划合规审计 (oracle)
|
||||
├── Task F2: 代码质量审查 (unspecified-high)
|
||||
├── Task F3: 实际 QA 测试 (unspecified-high)
|
||||
└── Task F4: 范围忠实度检查 (deep)
|
||||
→ 呈现结果 → 获取用户明确确认
|
||||
|
||||
关键路径: Task 1 → F1-F4 → 用户确认
|
||||
并行加速: Task 1 和 Task 2 并行; F1-F4 并行审查
|
||||
最大并发: 4
|
||||
```
|
||||
|
||||
### 依赖矩阵
|
||||
- **1**: 无依赖 → 被 F1-F4 依赖
|
||||
- **2**: 无依赖 → 被 F1-F4 依赖(与 Task 1 并行)
|
||||
- **F1-F4**: 依赖 Task 1、Task 2 → 无后续依赖
|
||||
|
||||
### Agent 调度摘要
|
||||
- **Wave 1**: 2 个任务 — T1 → `quick`, T2 → `quick`
|
||||
- **FINAL**: 4 个任务 — F1 → `oracle`, F2 → `unspecified-high`, F3 → `unspecified-high`, F4 → `deep`
|
||||
|
||||
---
|
||||
|
||||
## TODOs
|
||||
|
||||
- [x] 1. 创建 Categories API 控制器
|
||||
|
||||
**What to do**:
|
||||
- 创建文件 `app/api/controller/Categories.php`
|
||||
- 继承 `app\BaseController`
|
||||
- 添加 `protected $middleware = [ApiKeyAuth::class]`(导入 `use app\middleware\ApiKeyAuth`)
|
||||
- 实现 `index()` 方法:
|
||||
- 从 `$this->request` 获取参数:`page`(默认1)、`limit`(默认15,范围1-100)、`type`、`status`(默认1)、`pid`、`tree`(默认0)
|
||||
- 基础查询条件:`Category::where('delete_time', 0)`(Category 模型无 SoftDelete trait,必须手动过滤)
|
||||
- 如果 `status` 参数未传,默认添加 `->where('status', 1)`
|
||||
- 如果传了 `type` 参数,添加 `->where('type', $type)`
|
||||
- 如果传了 `pid` 参数,添加 `->where('pid', $pid)`
|
||||
- 如果 `tree=1`:
|
||||
- 执行上述条件查询,获取所有匹配记录(不分页),按 `sort ASC` 排序
|
||||
- 调用 `array2level($list, 0, 1)` 构建树形结构(注意 `array2level` 使用 `static $list`,调用前需要理解其机制:传入 `$level=0` 会触发 static 重置逻辑,或者直接用 `$pid=0` 作为根节点)
|
||||
- 返回 `json_message(['list' => $treeList])`
|
||||
- 如果不是 tree 模式:
|
||||
- 使用 `->paginate(['page' => $page, 'list_rows' => $limit])` 分页
|
||||
- 按 `sort ASC` 排序
|
||||
- 返回 `json_message(['list' => $list->items(), 'total' => $list->total(), 'page' => $page])`
|
||||
- 实现 `read($id)` 方法:
|
||||
- 从 `$this->request->param('id')` 获取 ID(遵循 Articles 控制器模式,使用 `$this->request` 而非方法参数注入)
|
||||
- 验证 ID 有效(intval > 0)
|
||||
- 查询:`Category::where('delete_time', 0)->where('id', $id)->find()`
|
||||
- 附加获取器数据:`->append(['model_parent', 'model_siblings'])`
|
||||
- 未找到返回 `json_message('分类不存在')`
|
||||
- 成功返回 `json_message($category)`
|
||||
- 不添加 `declare(strict_types=1)`(遵循 api 模块 Attachments/ApiKeyInfo 模式)
|
||||
|
||||
**Must NOT do**:
|
||||
- 不得修改 Category 模型或任何现有文件
|
||||
- 不得添加 save/update/delete 方法
|
||||
- 不得加载 posts 关联
|
||||
- 不得添加缓存逻辑
|
||||
- 不得使用 `declare(strict_types=1)`
|
||||
|
||||
**Recommended Agent Profile**:
|
||||
- **Category**: `quick`
|
||||
- Reason: 单文件创建,约80-120行代码,逻辑清晰,有完整参考模板
|
||||
- **Skills**: []
|
||||
- 无需额外技能,纯 PHP 控制器代码
|
||||
|
||||
**Parallelization**:
|
||||
- **Can Run In Parallel**: N/A(仅此一个任务)
|
||||
- **Parallel Group**: Wave 1(单独)
|
||||
- **Blocks**: F1, F2, F3, F4
|
||||
- **Blocked By**: 无(立即开始)
|
||||
|
||||
**References**:
|
||||
|
||||
> 执行者没有访谈上下文。以下是他们唯一的指南。
|
||||
|
||||
**Pattern References(现有代码模式)**:
|
||||
- `app/api/controller/Attachments.php` — **主要参考模板**。注意其代码风格:`$this->request` 取参方式、`use` 导入风格、无 `declare(strict_types=1)`、中间件声明方式
|
||||
- `app/api/controller/Articles.php:56-69` — `read()` 方法的错误处理模式:ID 验证、模型查询、未找到时返回错误
|
||||
- `app/api/controller/Articles.php:21-53` — `index()` 方法的分页模式:`page`/`limit` 取参、`paginate()` 调用、`json_message` 返回格式
|
||||
|
||||
**Model References(模型参考)**:
|
||||
- `app/model/Category.php` — Category 模型完整代码。关键:字段定义、`getListLevel()` 静态方法、获取器(`getModelParentAttr`/`getModelSiblingsAttr`/`getTitleImgAttr`/`getTplNameAttr`)
|
||||
- `app/common.php:199` — `array2level()` 全局辅助函数,用于将扁平数组转为树形结构。注意其使用 `static $list` 累积机制
|
||||
|
||||
**Middleware References(中间件参考)**:
|
||||
- `app/middleware/ApiKeyAuth.php` — API 认证中间件。支持 `Authorization: Bearer {key}` 和 `X-API-Key` header。成功时注入 `admin_id`/`api_key_id`/权限到 Request
|
||||
|
||||
**Helper References(辅助函数参考)**:
|
||||
- `app/common.php:29` — `json_message($data, $code, $msg)` 全局函数。传入字符串且非 http 开头 → `code=500` 错误响应;传入数组 → `code=0` 成功响应
|
||||
|
||||
**Database Schema(数据库结构)**:
|
||||
- `database/migrations/20200418120827_create_table_category.php` — `ul_category` 表结构:id, title, pid, level, tpl_name, title_img, desc, status, type(string), sort, create_time, update_time, delete_time
|
||||
|
||||
**Why Each Reference Matters**:
|
||||
- `Attachments.php` — 提供控制器骨架代码,包括类声明、middleware 属性、方法签名风格
|
||||
- `Articles.php:read()` — 提供单条查询的完整错误处理流程,可复制修改
|
||||
- `Articles.php:index()` — 提供分页查询的完整流程,包括参数获取和返回格式
|
||||
- `Category.php` — 提供模型字段名、可用获取器、查询方法
|
||||
- `array2level()` — 树形结构构建依赖此函数,必须理解其 static 变量机制
|
||||
- `ApiKeyAuth.php` — 理解认证如何工作,确保中间件正确生效
|
||||
- `json_message()` — 确保响应格式与现有 API 一致
|
||||
- `category migration` — 确认字段类型(type 是 string 不是 int)
|
||||
|
||||
**Acceptance Criteria**:
|
||||
|
||||
> **仅 Agent 可执行的验证** — 禁止人工操作。
|
||||
|
||||
- [ ] 文件存在: `app/api/controller/Categories.php`
|
||||
- [ ] PHP 语法正确: `php -l app/api/controller/Categories.php` → `No syntax errors`
|
||||
|
||||
**QA Scenarios(强制 — 无此内容则任务不完整)**:
|
||||
|
||||
```
|
||||
Scenario: 未认证请求被拒绝
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 开发服务器运行在 8010 端口
|
||||
Steps:
|
||||
1. 执行 curl -s -w "\n%{http_code}" http://127.0.0.1:8010/index.php/api/categories
|
||||
2. 检查 HTTP 状态码是否为 401
|
||||
3. 检查响应 JSON 中 code 字段是否为 401
|
||||
Expected Result: HTTP 401, {"code": 401, "msg": "...API Key...", "data": null}
|
||||
Failure Indicators: HTTP 200 或 code=0 表示认证未生效
|
||||
Evidence: .sisyphus/evidence/task-1-unauthorized.txt
|
||||
|
||||
Scenario: 扁平列表查询(正常路径)
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 有效的 API Key,分类表中有数据
|
||||
Steps:
|
||||
1. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?page=1&limit=5"
|
||||
2. 解析 JSON 响应
|
||||
3. 验证 code=0
|
||||
4. 验证 data.list 是数组
|
||||
5. 验证 data.total 是整数
|
||||
6. 验证 data.page 等于 1
|
||||
7. 验证 list 中每项包含 id, title, pid, level 字段
|
||||
8. 验证 list 中无 delete_time > 0 的项
|
||||
9. 验证 list 中所有项 status=1(默认行为)
|
||||
Expected Result: {"code": 0, "msg": "", "data": {"list": [...], "total": N, "page": 1}}
|
||||
Failure Indicators: code!=0, 缺少 list/total/page 字段, 出现 delete_time>0 的项
|
||||
Evidence: .sisyphus/evidence/task-1-flat-list.txt
|
||||
|
||||
Scenario: 按类型过滤
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 有效 API Key
|
||||
Steps:
|
||||
1. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?type=1"
|
||||
2. 验证返回的每项 type 字段等于 "1"
|
||||
Expected Result: 所有返回项 type="1"
|
||||
Failure Indicators: 出现 type!="1" 的项
|
||||
Evidence: .sisyphus/evidence/task-1-filter-type.txt
|
||||
|
||||
Scenario: 树形结构输出
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 有效 API Key,分类表中有父子层级数据
|
||||
Steps:
|
||||
1. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?tree=1&type=3"
|
||||
2. 验证 code=0
|
||||
3. 验证 data.list 是数组
|
||||
4. 验证返回结构包含层级嵌套(有子分类的情况下,子项应嵌套在父项中)
|
||||
5. 验证无 delete_time>0 的项
|
||||
Expected Result: {"code": 0, "data": {"list": [...嵌套结构...]}}
|
||||
Failure Indicators: code!=0, 返回扁平结构而非嵌套
|
||||
Evidence: .sisyphus/evidence/task-1-tree.txt
|
||||
|
||||
Scenario: 单条分类查询
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 有效 API Key,存在 id=1 的分类
|
||||
Steps:
|
||||
1. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories/read/id/1"
|
||||
2. 验证 code=0
|
||||
3. 验证 data 中包含 id=1 的分类信息
|
||||
4. 验证包含 model_parent 和 model_siblings 获取器数据
|
||||
Expected Result: {"code": 0, "data": {"id": 1, "title": "...", "model_parent": {...}, ...}}
|
||||
Failure Indicators: code!=0, 缺少获取器数据
|
||||
Evidence: .sisyphus/evidence/task-1-read.txt
|
||||
|
||||
Scenario: 查询不存在的分类(错误路径)
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 有效 API Key
|
||||
Steps:
|
||||
1. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories/read/id/99999"
|
||||
2. 验证 code=500
|
||||
3. 验证 msg 包含"不存在"字样
|
||||
Expected Result: {"code": 500, "msg": "分类不存在", "data": []}
|
||||
Failure Indicators: code=0 或返回空数据而非错误提示
|
||||
Evidence: .sisyphus/evidence/task-1-read-notfound.txt
|
||||
|
||||
Scenario: limit 参数边界值
|
||||
Tool: Bash (curl)
|
||||
Preconditions: 有效 API Key
|
||||
Steps:
|
||||
1. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?limit=999"
|
||||
2. 验证返回数据条数不超过100(被 clamp 到最大值)
|
||||
3. 执行 curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?limit=0"
|
||||
4. 验证不会报错(0 被 clamp 到最小值 1)
|
||||
Expected Result: limit=999 返回最多100条; limit=0 不报错
|
||||
Failure Indicators: 返回超过100条或报500错误
|
||||
Evidence: .sisyphus/evidence/task-1-limit-boundary.txt
|
||||
```
|
||||
|
||||
**Evidence to Capture**:
|
||||
- [ ] task-1-unauthorized.txt — 未认证响应
|
||||
- [ ] task-1-flat-list.txt — 扁平列表响应
|
||||
- [ ] task-1-filter-type.txt — type 过滤响应
|
||||
- [ ] task-1-tree.txt — 树形结构响应
|
||||
- [ ] task-1-read.txt — 单条查询响应
|
||||
- [ ] task-1-read-notfound.txt — 不存在分类响应
|
||||
- [ ] task-1-limit-boundary.txt — limit 边界值响应
|
||||
|
||||
**Commit**: YES
|
||||
- Message: `feat(api): 新增分类查询接口(列表+详情,支持树形结构)`
|
||||
- Files: `app/api/controller/Categories.php`
|
||||
- Pre-commit: `php -l app/api/controller/Categories.php`
|
||||
|
||||
- [x] 2. 更新 AGENTS.md 项目知识库
|
||||
|
||||
**What to do**:
|
||||
- 更新 `AGENTS.md` 中与 API 控制器相关的描述,使其反映新增的 Categories 控制器
|
||||
- 第18行 STRUCTURE 部分:`api/controller/ # API接口(微信/文件/验证码)` → 更新为包含分类查询的描述
|
||||
- 第59行 CODE MAP 控制器继承链:`api\controller\* (直接继承 BaseController) -> 3个控制器` → 更新控制器数量和说明,补充 Categories 控制器信息
|
||||
- 保持文件其他内容不变
|
||||
|
||||
**Must NOT do**:
|
||||
- 不得修改 AGENTS.md 中与本次变更无关的内容
|
||||
- 不得改动其他章节
|
||||
|
||||
**Recommended Agent Profile**:
|
||||
- **Category**: `quick`
|
||||
- Reason: 简单的文档文本更新,仅需修改2处描述
|
||||
- **Skills**: []
|
||||
|
||||
**Parallelization**:
|
||||
- **Can Run In Parallel**: YES
|
||||
- **Parallel Group**: Wave 1(与 Task 1 并行)
|
||||
- **Blocks**: F1-F4
|
||||
- **Blocked By**: 无(立即开始)
|
||||
|
||||
**References**:
|
||||
|
||||
**Pattern References**:
|
||||
- `AGENTS.md:18` — STRUCTURE 部分的 `api/controller/` 行,需要更新描述
|
||||
- `AGENTS.md:59` — CODE MAP 控制器继承链的 `api\controller\*` 行,需要更新数量
|
||||
|
||||
**Why Each Reference Matters**:
|
||||
- 这两处是唯一需要更新的位置,描述了 API 模块的控制器组成
|
||||
|
||||
**Acceptance Criteria**:
|
||||
|
||||
- [ ] AGENTS.md STRUCTURE 部分提到了分类查询接口
|
||||
- [ ] AGENTS.md CODE MAP 部分反映了新增的 Categories 控制器
|
||||
|
||||
**QA Scenarios(强制)**:
|
||||
|
||||
```
|
||||
Scenario: AGENTS.md 内容正确更新
|
||||
Tool: Bash (grep)
|
||||
Preconditions: Task 1 已完成,Categories.php 已创建
|
||||
Steps:
|
||||
1. 执行 grep -n "api/controller" AGENTS.md 检查 STRUCTURE 部分描述是否包含"分类"相关字样
|
||||
2. 执行 grep -n "api.*controller" AGENTS.md 检查 CODE MAP 部分是否反映正确的控制器数量
|
||||
Expected Result: 两处描述均已更新,包含 Categories 相关信息
|
||||
Failure Indicators: 仍显示旧的"3个控制器"或未提及分类查询
|
||||
Evidence: .sisyphus/evidence/task-2-agents-md.txt
|
||||
```
|
||||
|
||||
**Evidence to Capture**:
|
||||
- [ ] task-2-agents-md.txt — 更新后的 AGENTS.md 相关行
|
||||
|
||||
**Commit**: YES(与 Task 1 合并提交)
|
||||
- Message: `feat(api): 新增分类查询接口(列表+详情,支持树形结构)`
|
||||
- Files: `app/api/controller/Categories.php`, `AGENTS.md`
|
||||
|
||||
---
|
||||
|
||||
## Final Verification Wave(所有实现任务完成后 — 强制执行)
|
||||
|
||||
> 4 个审查 agent 并行运行。全部必须通过。向用户呈现综合结果,获取明确"确认"后方可完成。
|
||||
> **不要在获得用户确认前将 F1-F4 标记为完成。**
|
||||
|
||||
- [x] F1. **计划合规审计** — `oracle`
|
||||
通读计划。逐条检查 "Must Have":验证实现存在(读取文件、curl 接口、运行命令)。逐条检查 "Must NOT Have":搜索代码库中的禁止模式 — 发现则拒绝并给出 file:line。检查 `.sisyphus/evidence/` 中的证据文件是否存在。将交付物与计划进行比对。
|
||||
输出: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`
|
||||
|
||||
- [x] F2. **代码质量审查** — `unspecified-high`
|
||||
运行 `php -l app/api/controller/Categories.php`(语法检查)。审查文件:`as any`、空 catch、console.log、注释掉的代码、未使用的 import。检查 AI 痕迹:过度注释、过度抽象、泛化命名(data/result/item/temp)。验证代码风格与 `app/api/controller/Attachments.php` 一致。
|
||||
输出: `Syntax [PASS/FAIL] | Style [PASS/FAIL] | Files [N clean/N issues] | VERDICT`
|
||||
|
||||
- [x] F3. **实际 QA 测试** — `unspecified-high`(用户自行测试)
|
||||
从干净状态启动开发服务器(`php think run -p 8010`)。执行 Task 1 中的**所有 QA 场景** — 按精确步骤执行,捕获证据。保存到 `.sisyphus/evidence/final-qa/`。
|
||||
输出: `Scenarios [N/N pass] | Integration [N/N] | Edge Cases [N tested] | VERDICT`
|
||||
|
||||
- [x] F4. **范围忠实度检查** — `deep`
|
||||
对比 Task 1 的 "What to do" 与实际 `git diff`。验证 1:1 — 计划中的内容全部实现(无遗漏),实现的内容全部在计划中(无蔓延)。检查 "Must NOT do" 合规性。检测未说明的变更。
|
||||
输出: `Tasks [N/N compliant] | Unaccounted [CLEAN/N files] | VERDICT`
|
||||
|
||||
---
|
||||
|
||||
## Commit Strategy
|
||||
|
||||
- **1+2**: `feat(api): 新增分类查询接口(列表+详情,支持树形结构)` - app/api/controller/Categories.php, AGENTS.md
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### 验证命令
|
||||
```bash
|
||||
# 未认证请求应返回 401
|
||||
curl -s http://127.0.0.1:8010/index.php/api/categories
|
||||
# Expected: {"code": 401, "msg": "...", "data": null}
|
||||
|
||||
# 认证后扁平列表
|
||||
curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?page=1&limit=5"
|
||||
# Expected: {"code": 0, "msg": "", "data": {"list": [...], "total": N, "page": 1}}
|
||||
|
||||
# 认证后树形结构
|
||||
curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories?tree=1&type=1"
|
||||
# Expected: {"code": 0, "msg": "", "data": {"list": [...嵌套结构...]}}
|
||||
|
||||
# 单条分类详情
|
||||
curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories/read/id/1"
|
||||
# Expected: {"code": 0, "msg": "", "data": {"id": 1, "title": "...", ...}}
|
||||
|
||||
# 不存在的分类
|
||||
curl -s -H "X-API-Key: <valid_key>" "http://127.0.0.1:8010/index.php/api/categories/read/id/99999"
|
||||
# Expected: {"code": 500, "msg": "分类不存在", "data": []}
|
||||
```
|
||||
|
||||
### 最终检查清单
|
||||
- [ ] 所有 "Must Have" 存在
|
||||
- [ ] 所有 "Must NOT Have" 不存在
|
||||
- [ ] ApiKeyAuth 认证生效
|
||||
- [ ] delete_time = 0 过滤生效
|
||||
- [ ] status 默认过滤为 1
|
||||
- [ ] 扁平列表分页正常
|
||||
- [ ] 树形结构嵌套正确
|
||||
- [ ] type/status/pid 过滤参数工作正常
|
||||
Reference in New Issue
Block a user