chore(spec): confirm open questions + add list endpoints [AC-ASA-01]
This commit is contained in:
parent
60953a14c5
commit
2ffcb16861
|
|
@ -0,0 +1,118 @@
|
||||||
|
---
|
||||||
|
module: ai-service-admin
|
||||||
|
title: "AI 中台管理界面(ai-service-admin)任务清单"
|
||||||
|
status: "draft"
|
||||||
|
version: "0.1.0"
|
||||||
|
owners:
|
||||||
|
- "frontend"
|
||||||
|
- "backend"
|
||||||
|
last_updated: "2026-02-24"
|
||||||
|
principles:
|
||||||
|
- atomic
|
||||||
|
- page-oriented
|
||||||
|
---
|
||||||
|
|
||||||
|
# tasks.md(ASA)
|
||||||
|
|
||||||
|
> 原则:
|
||||||
|
> - **原子性**:每个任务应在 0.5 ~ 1.5 天内完成,且可独立提交与回滚。
|
||||||
|
> - **页面导向**:以页面/路由为骨架拆分,组件/能力封装作为页面任务的前置或并行支撑。
|
||||||
|
> - **可追溯**:每个任务必须标注关联的验收标准(AC-ASA-*)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: 基础建设(Foundation)
|
||||||
|
|
||||||
|
- [ ] (P1-01) 初始化 `ai-service-admin` 前端工程(Vue 3 + Element Plus + RuoYi-Vue 基座对齐),落地基础目录结构与路由骨架。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P1-02) 接入 Pinia:实现 `tenant` store(`currentTenantId`)并持久化(localStorage),提供切换租户能力(最小 UI/逻辑)。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P1-03) Axios/SDK 请求层封装:创建统一 `request` 实例,自动注入必填 Header `X-Tenant-Id`(从 Pinia 读取)。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P1-04) 全局异常拦截:实现 401/403 响应拦截策略(401 跳转登录/清理凭证;403 统一提示 + 页面级占位)。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P1-05) 基础组件封装:`BaseTable`(分页/筛选/加载态/空态)、`BaseForm`(校验/提交态/错误提示)并给出示例页。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: 知识库管理(列表页/上传/任务轮询)
|
||||||
|
|
||||||
|
> 页面导向:知识库文档列表页 + 上传入口 + 索引任务状态观测。
|
||||||
|
|
||||||
|
- [ ] (P2-01) 知识库文档列表页:实现列表展示与多条件筛选(kbId、状态、时间、来源),对接 `/admin/kb/documents`(若后端未提供 GET,则先 Mock)。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P2-02) 上传组件:封装 `KbDocumentUpload`(基于 `el-upload`),支持多文件上传、上传中队列展示、失败重试提示。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P2-03) 上传后任务回显:上传成功后从响应中提取 `jobId`,在列表或详情抽屉中展示任务卡片(状态/进度)。
|
||||||
|
- AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [ ] (P2-04) 任务状态轮询:实现 `useJobPolling(jobId)` composable(3s 轮询 `/admin/kb/index/jobs/{jobId}`;完成/失败自动停止;切页/关闭抽屉自动取消)。
|
||||||
|
- AC: [AC-ASA-01, AC-ASA-02]
|
||||||
|
|
||||||
|
- [ ] (P2-05) 失败任务错误详情:实现错误展示弹窗/抽屉(展示 `errorMsg` + requestId),并在列表行高亮失败状态。
|
||||||
|
- AC: [AC-ASA-02]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: RAG 实验室(双栏对比/调试联调)
|
||||||
|
|
||||||
|
> 页面导向:RAG 实验室主页面,突出“双栏对比视图”。
|
||||||
|
|
||||||
|
- [ ] (P3-01) RAG 实验室页面骨架:左侧参数面板(query、kbIds、检索参数、prompt 版本选择),右侧双栏结果区占位。
|
||||||
|
- AC: [AC-ASA-05]
|
||||||
|
|
||||||
|
- [ ] (P3-02) RAG 专用组件:实现 `RagRetrievalList`(召回片段列表:score/来源/片段)、`FinalPromptViewer`(最终 Prompt 只读展示,支持复制)。
|
||||||
|
- AC: [AC-ASA-05]
|
||||||
|
|
||||||
|
- [ ] (P3-03) 调试 API 联调:对接 `/admin/rag/experiments/run`,将返回的 `retrievalResults` 与 `finalPrompt` 绑定到双栏视图;处理 Loading/错误态。
|
||||||
|
- AC: [AC-ASA-05]
|
||||||
|
|
||||||
|
- [ ] (P3-04) 双配置对比模式(MVP):支持保留“上一次运行结果”作为对照(或同时运行两组参数,视后端能力),并在 UI 中标注差异。
|
||||||
|
- AC: [AC-ASA-06]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: 会话监控与详情(列表筛选/全链路详情)
|
||||||
|
|
||||||
|
> 页面导向:会话列表页 + 全链路详情弹窗。
|
||||||
|
|
||||||
|
- [ ] (P4-01) 会话监控列表页:实现多字段过滤(tenantId、sessionId、时间范围、状态/是否错误等)与分页,对接 `/admin/sessions`(若后端未提供,则先 Mock)。
|
||||||
|
- AC: [AC-ASA-07]
|
||||||
|
|
||||||
|
- [ ] (P4-02) 会话详情弹窗:点击列表行打开弹窗,对接 `/admin/sessions/{sessionId}`,展示消息流(Timeline/气泡流)与基础元信息。
|
||||||
|
- AC: [AC-ASA-07]
|
||||||
|
|
||||||
|
- [ ] (P4-03) Trace 展开视图:在详情中实现“检索命中/工具调用/错误信息”折叠面板,支持按消息节点展开查看。
|
||||||
|
- AC: [AC-ASA-07]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 待澄清(Open Questions)
|
||||||
|
|
||||||
|
- [x] (Q-01) ✅ 已确认:后端将补齐 `GET /admin/kb/documents` 列表接口。
|
||||||
|
- 影响 AC: [AC-ASA-01]
|
||||||
|
|
||||||
|
- [x] (Q-02) ✅ 已确认:后端将补齐 `GET /admin/sessions` 列表接口。
|
||||||
|
- 影响 AC: [AC-ASA-07]
|
||||||
|
|
||||||
|
- [x] (Q-03) ✅ 已确认:对比模式采用“前端串行调用两次 `/admin/rag/experiments/run` 接口”的方式实现。
|
||||||
|
- 影响 AC: [AC-ASA-06]
|
||||||
|
|
||||||
|
## Mock 支撑(在 Python 后端未完成前)
|
||||||
|
|
||||||
|
结论:**需要 Mock 支撑**,以便前端在后端未完成时并行开发页面与交互。
|
||||||
|
|
||||||
|
建议优先 Mock 覆盖(最小闭环):
|
||||||
|
- `/admin/kb/documents`(GET 列表,分页 + 筛选)
|
||||||
|
- `/admin/kb/documents`(POST 上传,返回 `jobId`)
|
||||||
|
- `/admin/kb/index/jobs/{jobId}`(GET 任务状态流转:pending -> processing -> completed/failed)
|
||||||
|
- `/admin/rag/experiments/run`(POST 实验结果:retrievalResults + finalPrompt)
|
||||||
|
- `/admin/sessions`(GET 列表,分页 + 筛选)
|
||||||
|
- `/admin/sessions/{sessionId}`(GET 详情:messages + trace)
|
||||||
|
|
@ -18,9 +18,123 @@ components:
|
||||||
description: "未认证(缺少或无效的认证信息)"
|
description: "未认证(缺少或无效的认证信息)"
|
||||||
Forbidden:
|
Forbidden:
|
||||||
description: "无权限(当前身份无权访问该资源)"
|
description: "无权限(当前身份无权访问该资源)"
|
||||||
|
schemas:
|
||||||
|
DocumentInfo:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
docId:
|
||||||
|
type: string
|
||||||
|
description: "文档ID"
|
||||||
|
kbId:
|
||||||
|
type: string
|
||||||
|
description: "知识库ID"
|
||||||
|
fileName:
|
||||||
|
type: string
|
||||||
|
description: "文件名"
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: "文档状态"
|
||||||
|
enum: [pending, processing, completed, failed]
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: "创建时间"
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: "更新时间"
|
||||||
|
SessionInfo:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sessionId:
|
||||||
|
type: string
|
||||||
|
description: "会话ID"
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: "会话状态"
|
||||||
|
enum: [active, closed, expired]
|
||||||
|
startTime:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: "开始时间"
|
||||||
|
endTime:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: "结束时间"
|
||||||
|
messageCount:
|
||||||
|
type: integer
|
||||||
|
description: "消息数量"
|
||||||
|
PageInfo:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
description: "当前页码"
|
||||||
|
pageSize:
|
||||||
|
type: integer
|
||||||
|
description: "每页大小"
|
||||||
|
total:
|
||||||
|
type: integer
|
||||||
|
description: "总记录数"
|
||||||
|
totalPages:
|
||||||
|
type: integer
|
||||||
|
description: "总页数"
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/admin/kb/documents:
|
/admin/kb/documents:
|
||||||
|
get:
|
||||||
|
summary: "查询文档列表"
|
||||||
|
operationId: "listDocuments"
|
||||||
|
tags:
|
||||||
|
- KB Management
|
||||||
|
x-requirements: ["AC-ASA-08"]
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/XTenantId"
|
||||||
|
- name: kbId
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: "知识库ID"
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [pending, processing, completed, failed]
|
||||||
|
description: "文档状态"
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 1
|
||||||
|
description: "页码"
|
||||||
|
- name: pageSize
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 20
|
||||||
|
description: "每页大小"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: "文档列表"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/DocumentInfo"
|
||||||
|
pagination:
|
||||||
|
$ref: "#/components/schemas/PageInfo"
|
||||||
|
'401':
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
'403':
|
||||||
|
$ref: "#/components/responses/Forbidden"
|
||||||
post:
|
post:
|
||||||
summary: "上传/导入文档"
|
summary: "上传/导入文档"
|
||||||
operationId: "uploadDocument"
|
operationId: "uploadDocument"
|
||||||
|
|
@ -172,6 +286,68 @@ paths:
|
||||||
$ref: "#/components/responses/Unauthorized"
|
$ref: "#/components/responses/Unauthorized"
|
||||||
'403':
|
'403':
|
||||||
$ref: "#/components/responses/Forbidden"
|
$ref: "#/components/responses/Forbidden"
|
||||||
|
/admin/sessions:
|
||||||
|
get:
|
||||||
|
summary: "查询会话列表"
|
||||||
|
operationId: "listSessions"
|
||||||
|
tags:
|
||||||
|
- Session Monitoring
|
||||||
|
x-requirements: ["AC-ASA-09"]
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/XTenantId"
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [active, closed, expired]
|
||||||
|
description: "会话状态"
|
||||||
|
- name: startTime
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: "开始时间"
|
||||||
|
- name: endTime
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: "结束时间"
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 1
|
||||||
|
description: "页码"
|
||||||
|
- name: pageSize
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 20
|
||||||
|
description: "每页大小"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: "会话列表"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/SessionInfo"
|
||||||
|
pagination:
|
||||||
|
$ref: "#/components/schemas/PageInfo"
|
||||||
|
'401':
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
'403':
|
||||||
|
$ref: "#/components/responses/Forbidden"
|
||||||
/admin/sessions/{sessionId}:
|
/admin/sessions/{sessionId}:
|
||||||
get:
|
get:
|
||||||
summary: "获取会话详情"
|
summary: "获取会话详情"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue