1. 页面概览
1.1 是什么
数据集(DatasetPage.vue,路由 /foundry/datasets)是 LightFoundry「数据目录」的核心页面,承载 V5 Stage 1 B1-1 数据集能力。页面把「外部数据源查询 / 上传文件 / 管道产物 / 对象快照」统一收编为版本化编目的一等公民——每个数据集有 fd_datasets 主表记录(rid/uri/source_type/schema_json/row_count/current_version/status),行数据按数据集独立建动态表 ds_<rid文件安全名>,列随 schema_json 动态创建。
页面上你可以:新建数据集(platform_ds:提交一条查询 SQL,后端立即执行并落数、推断 schema);上传文件(CSV/JSON,multipart 上传建数据集);列表过滤(仅活跃/全部/仅归档);详情抽屉(Schema 列定义 / 行数据预览 50 行 / 版本历史 + 发布版本 / 基础画像);软删归档。页面描述明确其定位:「数据接入 → 数据集 → 管道 → 对象 链路的地基:外部查询/上传文件统一版本化编目。」
1.2 核心价值
| 维度 | 说明 |
|---|---|
| 数据接入统一编目 | platform_ds 查询 / CSV/JSON 上传 / 管道产物 / 对象快照四类来源统一进入数据集目录 |
| 版本化 | 发布版本 = 当前 schema + 行数快照入 fd_dataset_versions,current_version++(指针推进,不拷贝数据),分支/回滚语义即切换指针 |
| 质量画像 | 详情抽屉「基础画像」Tab:每列 null 率 / distinct / top5(number 列附 avg),聚合 SQL 下推计算 |
| 安全落地 | 行数据表 DDL 只允许白名单标识符(列名 ^[a-z][a-z0-9_]*$),全部行值参数化绑定防注入 |
| 来源可视化 | source_type 徽标区分 platform_ds(蓝)/upload(绿)/pipeline_output(橙)/object_snapshot(紫) |
| 血缘打点 | 创建/上传成功自动打血缘边(datasource/upload → dataset),可在「数据血缘」页追溯 |
1.3 一句话总结
2. 访问入口
2.1 路由与菜单
- 路由:
/foundry/datasets - 路由名称:
FoundryDatasets - 菜单位置:Foundry 左侧边栏「数据集」(FoundryLayout 菜单「数据集成」区块)
- 源码文件:
action/web/src/views/DatasetPage.vue(约 628 行);API 客户端action/web/src/api/datasetApi.js
2.2 认证与权限
- 需要登录:是(路由
meta.requiresAuth = true) - 登录方式:AIP 统一登录;
datasetApi.js独立 axios 实例(模式对齐 client.js:baseURL/api/v1+ Beareraip_token+ 401 清理凭证跳/login),不改动 client.js - 页面无角色限制;数据集
owner由后端注入当前登录用户(handler 层currentUserID),显式传值优先 - 404 排错:访问
/foundry/datasets404,确认 Foundry 后端(18081)已启动且路由已注册(router/index.js第 305-309 行)
2.3 端口与 API 前缀
- 后端端口:18081(Foundry)
- API 前缀:
/api/v1(datasetApi.js) - 请求超时:列表/详情等 60 秒;上传文件单独放宽到 120 秒(大文件传输)
3. 界面布局
┌──────────────────────────────────────────────────────────────┐ │ ① 页头:「数据目录 · 数据集」+ 一句话说明 │ │ ② 操作结果提示条(alert 成功/失败,可「关闭」) │ │ ③ 工具栏:「新建数据集(数据源查询)」+「上传文件」 │ │ [状态下拉:仅活跃/全部/仅归档] [刷新] │ │ ④ 新建表单卡片(platform_ds:名称/数据源ID/查询SQL/描述) │ │ ⑤ 上传对话框(遮罩 + 居中弹窗:名称/文件/描述) │ │ ⑥ 数据集列表卡片(表格) │ │ └─ 名称(+描述)/来源/行数/大小/版本/状态/Owner/更新时间/操作 │ │ ⑦ 详情抽屉(右滑 860px) │ │ ├─ 头部:名称+来源+状态+RID+uri+物理表+[关闭] │ │ ├─ 操作条:版本说明输入 + [发布版本] [刷新] │ │ ├─ Tab:[Schema] [预览] [版本历史] [基础画像] │ │ └─ 各 Tab 内容卡片 │ └──────────────────────────────────────────────────────────────┘
各板块职责:
- ① 页头:标题与定位说明(
page-desc)。 - ② 提示条:全局反馈通道,
showAlert(msg, type)驱动,带「关闭」按钮。 - ③ 工具栏:左侧两个建数据集入口(新建=查询、上传=文件),右侧状态过滤 + 刷新。
- ④ 新建表单:
showCreateForm控制;提交platform_ds立即拉数请求。 - ⑤ 上传对话框:
drawer-mask遮罩 +upload-dialog居中卡片;点遮罩空白处也可关闭。 - ⑥ 列表:
fetchDatasets加载;空列表提示「暂无数据集,请"新建数据集"或"上传文件"。」;行内「详情」「删除」(仅 active 可删)。 - ⑦ 详情抽屉:
openDetail加载详情 + 预览 + 版本历史三份数据;Tab 懒加载。
4. 交互元素详解
4.1 工具栏与列表
| 位置 | 元素 | 含义 | 默认值/必填 | 操作效果 | 触发的后端调用 |
|---|---|---|---|---|---|
| 工具栏 | 「新建数据集(数据源查询)」 | 展开/收起新建表单 | — | 切换 showCreateForm | 无 |
| 工具栏 | 「上传文件」 | 展开/收起上传对话框 | — | 切换 showUploadForm | 无 |
| 工具栏 | 状态下拉 | 列表状态过滤 | 默认 仅活跃;选项 仅活跃/全部/仅归档 | change 即刷新 | GET /datasets?status= |
| 工具栏 | 「刷新」 | 手动刷新列表 | — | fetchDatasets() | GET /datasets?status= |
| 列表列 | 名称 | 名称 + 描述(cell-sub,无描述显示 -) | — | 只读 | — |
| 列表列 | 来源 | src-badge 徽标(src-platform_ds/src-upload/src-pipeline_output/src-object_snapshot) | — | 只读 | — |
| 列表列 | 行数 / 大小 | row_count / fmtSize(size_bytes)(B/KB/MB 智能换算) | — | 只读 | — |
| 列表列 | 版本 | current_version > 0 ? 'v'+n : '未发布' | — | 只读 | — |
| 列表列 | 状态 | status-badge(status-active/status-archived) | — | 只读 | — |
| 列表列 | Owner / 更新时间 | owner / fmtTime(updated_at)(T 替换 + slice 19) | — | 只读 | — |
| 列表行 | 「详情」 | 打开详情抽屉 | — | openDetail(d) 并发加载详情/预览/版本 | GET /datasets/:id + GET /datasets/:id/preview + GET /datasets/:id/versions |
| 列表行 | 「删除」 | 软删归档(仅 status=active 显示) | confirm 提示「确认删除数据集「xx」?(软删归档,可在"仅归档"过滤中查看)」 | 归档后刷新列表 | DELETE /datasets/:id |
4.2 新建表单(platform_ds)
| 位置 | 元素 | 含义 | 默认值/必填 | 操作效果 | 触发的后端调用 |
|---|---|---|---|---|---|
| 表单 | 数据集名称 * | name | 必填,占位 如 orders_daily | 文本输入 | — |
| 表单 | 数据源 ID(ds_id)* | 来源数据源 id | 必填,占位 如 1 | 文本输入 | — |
| 表单 | 来源查询 SQL * | 立即执行的查询 | 必填,默认 SELECT * FROM orders LIMIT 1000;hint「建议带 LIMIT;查询立即执行,结果落平台行数据表并推断 schema。」 | 文本域 | — |
| 表单 | 描述 | 数据集描述 | 可空 | 文本输入 | — |
| 表单 | 「创建」/「创建中...」 | 提交 | busy 时禁用 | 成功 alert「数据集创建成功」并刷新列表 | POST /datasets(body {name, description, source_type:'platform_ds', source_ref:{ds_id, query}}) |
| 表单 | 「取消」 | 关闭表单 | — | showCreateForm=false | 无 |
4.3 上传对话框
| 位置 | 元素 | 含义 | 默认值/必填 | 操作效果 | 触发的后端调用 |
|---|---|---|---|---|---|
| 对话框 | 数据集名称(留空则用文件名) | name | 可空 | 文本输入 | — |
| 对话框 | 文件 * | 上传文件 | 必填;accept=".csv,.json"(仅 CSV/JSON) | onFileChange 记录文件 | — |
| 对话框 | 描述 | 描述 | 可空 | 文本输入 | — |
| 对话框 | hint | 「CSV 首行为表头;空字段按 NULL 处理;XLSX 本版降级不支持,请另存为 CSV。」 | — | 提示文案 | — |
| 对话框 | 「上传」/「上传中...」 | 提交 | busy || !uploadForm.file 时禁用 | 成功 alert「上传成功,数据集已创建」并刷新列表 | POST /datasets/upload(multipart:name 可空 + file 必填,timeout 120s) |
| 对话框 | 「取消」/遮罩点击 | 关闭 | — | showUploadForm=false | 无 |
4.4 详情抽屉
| 位置 | 元素 | 含义 | 操作效果 | 触发的后端调用 |
|---|---|---|---|---|
| 抽屉头 | 来源/状态徽标 + RID + uri + 物理表 | 数据集元信息 | 只读 | — |
| 抽屉头 | 「关闭」 | 关闭抽屉 | closeDetail() | 无 |
| 操作条 | 版本说明(可空) | publish changelog | 文本输入 | — |
| 操作条 | 「发布版本」 | 发布当前快照 | 成功 alert 已发布版本 v<version> 并刷新详情与版本历史 | POST /datasets/:id/versions/publish(body {changelog}) |
| 操作条 | 「刷新」 | 重载详情 | refreshDetail()(重新 openDetail) | 详情三接口 |
| Tab | Schema | 列定义表 | 只读;空表提示「无 schema(登记型数据集,行数据由管道/同步写入)」 | 详情接口已带 schema |
| Tab | 预览 | 行数据预览(前 50 行) | 懒加载;NULL 显示为「NULL」 | GET /datasets/:id/preview?limit=50 |
| Tab | 版本历史 | 版本快照列表 | 懒加载;空提示「尚未发布版本(发布后将当前 schema+行数快照入版本)」 | GET /datasets/:id/versions |
| Tab | 基础画像 | 列画像 | 懒加载;「重新计算」按钮触发 | GET /datasets/:id/profile |
4.5 详情 Tab 细节
| Tab | 列/字段 | 说明 |
|---|---|---|
| Schema | # / 列名 / 类型 / 可空 | 列名 cell-code、类型 type-tag、可空 是/否(本版统一 true) |
| 预览 | 动态列 + 行 | preview.columns 为表头、preview.rows 为行数组;单元格 null 渲染「NULL」;空表提示「暂无行数据」 |
| 版本历史 | 版本 / 行数 / 说明 / 操作人 / 时间 | 当前版本行带「当前」蓝色 cur-tag |
| 基础画像 | 总行数/物理表/生成于 + 每列 列/类型/Null 率/Distinct/Avg/Top5 | null_rate*100 保留 1 位小数 + (null_count);avg 保留 2 位小数(非 number 列显示 -);top5 为 value ×count 标签;profile.note 展示降级说明 |
5. 后端关联
5.1 API 客户端
action/web/src/api/datasetApi.js:
- baseURL
/api/v1、timeout60000(上传单独120000)、Beareraip_token、401 清理跳登录 - 导出函数:
listDatasets(status,limit,offset)、createDataset(payload)、uploadDataset(name,file)、getDataset(id)、updateDataset(id,payload)、deleteDataset(id)、publishVersion(id,changelog)、listVersions(id)、previewDataset(id,limit=50)、profileDataset(id)
5.2 端点表
| 方法 | 路径 | 请求要点 | 超时 |
|---|---|---|---|
| GET | /datasets | query: status(空=active / archived / all)、limit、offset | 60s |
| POST | /datasets | {name, description, source_type, source_ref{ds_id,query}, owner} | 60s |
| POST | /datasets/upload | multipart:file 必填 + name 可空;上限 32MB | 120s |
| GET | /datasets/:id | 无 | 60s |
| PUT | /datasets/:id | {name?, description?} 指针语义 | 60s |
| DELETE | /datasets/:id | 无(软删 archived,幂等) | 60s |
| POST | /datasets/:id/versions/publish | {changelog}(可空,空 body 也允许) | 60s |
| GET | /datasets/:id/versions | 无(version 倒序) | 60s |
| GET | /datasets/:id/preview | query: limit(默认 50,服务端钳制 500) | 60s |
| GET | /datasets/:id/profile | 无 | 60s |
5.3 响应结构
统一 {code: 0, data: ...};失败 {code, error}(dataset 包自包含 okData/errorResponse,模式对齐 server 包)。
列表:
{ "code": 0, "data": { "datasets": [ { "id": "...", "rid": "rid.foundry.dataset.xxx", "uri": "dataset://foundry/rid.foundry.dataset.xxx", "name": "orders_daily", "source_type": "platform_ds", "row_count": 1000, "size_bytes": 20480, "current_version": 1, "status": "active", "owner": "admin" } ], "total": 1 } }
详情:
{ "code": 0, "data": { "dataset": { "...": "..." }, "schema": [ { "name": "order_id", "type": "number", "nullable": true } ], "table": "ds_dataset___foundry_rid_foundry_dataset_xxx", "source_ref": { "ds_id": "1", "query": "SELECT * FROM orders LIMIT 1000" } } }
版本发布:
{ "code": 0, "data": { "version": 2 } }
预览:
{ "code": 0, "data": { "columns": ["order_id", "amount"], "rows": [[1, 99.5], [2, 120]] } }
基础画像:
{ "code": 0, "data": { "dataset_id": "...", "table_name": "ds_...", "row_count": 1000, "generated_at": "...", "columns": [ { "name": "amount", "type": "number", "null_count": 5, "null_rate": 0.005, "distinct": 300, "avg": 88.75, "top5": [ { "value": "99.5", "count": 12 } ] } ], "note": "" } }
5.4 关联模块表
| 后端包/文件 | 职责 |
|---|---|
products/foundry/dataset/rest.go | 全部数据集端点(RegisterRoutes 挂 protected 组)+ 自包含 okData/errorResponse |
products/foundry/dataset/models.go | Dataset / DatasetVersion(表 fd_datasets / fd_dataset_versions)+ SourceRef/ColumnDef + RowTableName + AutoMigrate |
products/foundry/dataset/service.go | Create(platform_ds 拉数)/ Upload(CSV/JSON 解析)/ Get/List/Preview/Profile/PublishVersion/Update/Delete/DeleteRows |
products/foundry/lineage | 血缘打点(datasource/upload → dataset 边,允许 nil) |
platform/connector | platform_ds 拉数用连接器(ConnectorProvider 注入) |
platform/resource | 资源 URI 生成与 FileSafeName(行表名安全化) |
5.5 关键机制
- 来源类型(
source_type):platform_ds(source_ref{ds_id, query},创建即拉数)、upload({filename},上传落盘)、pipeline_output({pipeline_id},登记型,落数由管道/同步引擎写入)、object_snapshot({object_id},登记型)。 - 状态机:
active → archived;Delete 软删置 archived(幂等),列表按 status 过滤(空=仅 active、archived=仅归档、all=全部)。 - 版本发布:
PublishVersion把当前 schema_json + row_count 快照入fd_dataset_versions(UNIQUE(dataset_id, version)),current_version++(指针推进,不拷贝数据);并发发布冲突(唯一索引)时重试最多 3 次;已归档数据集禁止发布。 - 上传解析:CSV 走 encoding/csv(首行表头、空字段 NULL、类型按全量数据推断 number/bool/text)、JSON 走 encoding/json(对象数组或
{"rows":[...]},列=键并集按首现顺序);XLSX 显式拒绝(诚实标注降级);原始文件落盘data/foundry/datasets/<FileSafeName(uri)>/。 - 安全红线:列名白名单
^[a-z][a-z0-9_]*$(上传表头/JSON 键非法即拒绝,不做静默改写);行数据表 DDL 只允许白名单标识符,全部行值参数化绑定;类型 text/number/date/bool/json 映射物理类型。 - 预览/画像额度:预览 limit 默认 50、服务端钳制 500;登记型数据集(无行表)预览返回空结果。
- 画像计算:Profile 单条 SQL 下推(null/distinct 汇总 + 逐列 top5),number 列附 avg;
note字段承载降级/空数据说明(诚实标注)。
6. 核心流程详解
6.1 新建数据集(platform_ds 立即拉数)
- 工具栏点「新建数据集(数据源查询)」展开表单;
- 填数据集名称(必填)、数据源 ID(必填)、来源查询 SQL(必填,默认
SELECT * FROM orders LIMIT 1000,建议带 LIMIT)、描述(可选); - 点「创建」→
POST /datasets,body{name, description, source_type:'platform_ds', source_ref:{ds_id, query}}; - 后端
Create:校验来源 → 经 ConnectorProvider 连接ds_id数据源执行query→ 从结果推断 schema(列名归一化后过白名单)→ 动态建行数据表ds_<rid安全名>→ 参数化逐行落数 → 更新 row_count/size_bytes → 打血缘边(datasource → dataset); - 前端 alert「数据集创建成功」,关闭表单并刷新列表;新数据集出现在列表(来源徽标 platform_ds)。
6.2 上传文件建数据集
- 工具栏点「上传文件」打开对话框(点遮罩空白也可关闭);
- 数据集名称可留空(留空用文件名),选文件(
accept=".csv,.json"仅 CSV/JSON,必填),描述可选; - 点「上传」→
uploadDataset(name, file):FormData 构造name(非空才 append)+file,POST /datasets/upload(multipart,timeout 120s); - 后端
Upload:读文件(超 32MB 报「上传文件超过大小上限(32MB)」)→ 按扩展名分派 CSV/JSON 解析(非法列名拒绝)→ schema 推断 → 建行表参数化落数 → 原始文件落盘data/foundry/datasets/<FileSafeName(uri)>/→ 打血缘边(upload → dataset); - 前端 alert「上传成功,数据集已创建」并刷新列表(来源徽标 upload)。
6.3 查看详情与质量画像
- 列表点「详情」→
openDetail并发加载详情 / 预览 / 版本历史; - 抽屉 Tab 默认 Schema:查看列定义(#/列名/类型/可空);
- 切「预览」:行数据预览前 50 行(懒加载,
drawerTabwatch 在无数据时补拉),NULL 显示「NULL」; - 切「版本历史」:查看各版本 vN + 「当前」标记;
- 切「基础画像」:懒加载
GET /datasets/:id/profile;可点「重新计算」手动重算(loadProfile);表格展示每列 Null 率(含 null_count)/Distinct/Avg/Top5 高频值,顶部汇总总行数、物理表名与生成时间;note非空时展示降级说明。
6.4 发布版本
- 详情抽屉操作条「版本说明(可空)」输入 changelog(可空);
- 点「发布版本」→
POST /datasets/:id/versions/publish(body{changelog}); - 后端
PublishVersion:校验未归档 → 快照当前 schema_json+row_count 入版本表(version = current_version+1)→ 事务内推进current_version→ 并发冲突重试最多 3 次; - 前端 alert
已发布版本 v<version>,随后refreshDetail+loadVersions刷新;列表「版本」列显示v<新版本>,版本历史出现该条并带「当前」标记。
6.5 软删归档与恢复查看
- 列表「删除」(仅 active 显示)→ confirm(提示软删归档)→
DELETE /datasets/:id; - 后端 Delete 置
status=archived(幂等,已归档视为成功); - 前端 alert「数据集已归档」;若详情抽屉正打开该数据集则自动关闭;刷新列表后该行消失;
- 查看归档:工具栏状态下拉切「仅归档」,列表展示 archived 数据(无「删除」按钮,可再「详情」查看历史)。
6.6 上传失败分支(XLSX)
选 .xlsx 文件时浏览器 accept 过滤即无法选择;若强行上传,后端 Upload 对 XLSX 显式拒绝并明示(本版未引入 excelize,降级只支持 CSV/JSON)。请先在 Excel 另存为 CSV 再上传。
7. 权限与安全
- 认证:AIP 统一登录;
datasetApi.js拦截器附带 Bearer token,401 清理凭证跳登录。 - 数据级安全:数据集
owner记录创建人(后端注入当前用户);列表/详情按登录态访问,具体行级/列级安全由下游消费方(管道/对象/SQL 工作台)执行时注入;数据集本身不设独立 RLS。 - 上传/拉数防护:上传文件大小上限 32MB(服务端
maxUploadBytes强制);JSON 请求体上限 2MB;列名白名单^[a-z][a-z0-9_]*$准入闸,非法列名直接拒绝(不做静默改写,防注入语义可测);行数据表 DDL 只允许白名单标识符;全部行值参数化绑定,杜绝 SQL 注入。 - 写操作防护:删除有
confirm二次确认;创建/上传/发布/删除均busy置位防连点;删除为软删(可恢复查看),发布为指针推进(不破坏历史数据)。
8. 常见问题与排错
8.1 上传报「上传失败:缺少上传文件字段 file」或「上传文件超过大小上限(32MB)」
- 现象:选好文件点「上传」,alert 报缺少 file 字段或超上限。
- 原因:multipart 请求缺
file字段(FormData 未拼上,常见于未选文件就提交);或文件超过 32MB 服务端上限。 - 排查步骤:① 确认已通过文件选择器选中文件(
uploadForm.file非空,否则「上传」按钮禁用);② 确认文件后缀为.csv/.json(accept 过滤);③ 文件 >32MB 时压缩/拆分后上传,或改用「新建数据集(数据源查询)」走 SQL 拉数;④ DevTools Network 检查POST /datasets/upload的 FormData 是否含file。
8.2 上传 CSV 报列名非法(表头含大写/中文/空格)
- 现象:上传后 alert「上传失败:...非法列名...」。
- 原因:列名白名单
^[a-z][a-z0-9_]*$——表头必须小写字母开头、仅小写字母/数字/下划线;含大写、中文、空格、特殊字符的列名直接拒绝(服务端不静默改写)。 - 排查步骤:① 用文本编辑器检查 CSV 首行表头;② 把列名统一为小写/下划线(如
customer_name而非Customer Name);③ 另存为 UTF-8 编码(避免 BOM 干扰,服务端有 trimBOM 处理但建议避免);④ 重新上传。
8.3 发布版本后列表「版本」列不更新
- 现象:点「发布版本」成功提示
已发布版本 v2,但列表版本仍显示 v1。 - 原因:发布成功后
refreshDetail与loadVersions刷新的是抽屉内数据;列表列数据来自fetchDatasets(列表接口),发布操作不会自动重拉列表。 - 排查步骤:① 点击工具栏「刷新」按钮重拉
GET /datasets;② 或重新进一次列表页;③ 确认版本发布成功(详情抽屉版本历史有 v2 且带「当前」标记)。
8.4 详情抽屉「预览」无数据或报错
- 现象:切「预览」Tab 显示「暂无行数据」,或 alert「加载预览失败」。
- 原因:登记型数据集(pipeline_output/object_snapshot,无行数据表)预览返回空结果属正常;platform_ds/upload 有行数据却为空时,可能行表缺失或查询失败。
- 排查步骤:① 看来源徽标:登记型(橙/紫)空结果属正常;② 检查 DevTools Network 中
GET /datasets/:id/preview响应是否 500(行表不存在时服务端返回空而非报错);③ 确认创建时 SQL 确实返回了行(建议带 LIMIT);④ 预览 limit 默认 50、服务端钳制 500,需要更多行请用 SQL 工作台。
8.5 基础画像为空的可能原因
- 现象:「基础画像」Tab 显示「尚未计算,点击"重新计算"。」或表格「无列画像数据」。
- 原因:profile 懒加载未触发(首次切 Tab 时
profile为 null 会触发loadProfile,但若请求失败被静默 alert);登记型数据集无行表,画像返回空 columns。 - 排查步骤:① 点「重新计算」按钮手动触发
GET /datasets/:id/profile;② 检查响应是否有note字段(降级说明);③ 确认数据集有行数据(先看预览);④ 若一直失败,查看后端日志中 Profile 的 SQL 执行错误。
9. 已知缺陷与边界
| 缺陷/边界 | 说明 | 影响 |
|---|---|---|
| XLSX 不支持 | 本版未引入 excelize,上传显式拒绝 XLSX | 需另存为 CSV |
| 上传 32MB 上限 | maxUploadBytes 服务端强制 | 大文件需拆分 |
| 列名白名单严格 | ^[a-z][a-z0-9_]*$,非法列名拒绝 | 中文/大写表头需改名 |
| 行表无主键约束 | ColumnDef.Nullable 本版统一 true,行表不设主键 | 无唯一性约束 |
| 版本不可回滚 UI | 版本机制支持指针切换,但页面无「回溯/回滚」操作入口 | 回滚需 API/后续版本 |
| 预览上限 500 | 服务端钳制 preview limit 500 | 大表预览受限 |
| 登记型无预览 | pipeline_output/object_snapshot 无行表,预览空 | 属设计行为 |
| 删除不可恢复 | 软删后无「恢复」入口(需 API 改 status) | 归档只能查看 |
注:列表无分页已于 2026-09-06 修复(列表前端本地分页展示,支持第 X/Y 页与每页条数切换)。
注:发布后列表不刷新已于 2026-09-06 修复(发布成功后同步刷新列表,行上 current_version 版本列即时更新)。