1. 页面概览
1.1 是什么
数据源页面(FoundryDataSourcesPage.vue)负责 Foundry 产品与外部数据库的连接管理。它是 V5 Stage 1(B1-6)「数据源路由解耦」的产物:此前 datasources 表与 CRUD 路由仅存在于 AIP 服务(18080),而 Foundry 是独立进程 + 独立库,AIP 停机时 Foundry 侧数据源页直接 404。B1-6 后 Foundry 后端(18081)自持 /datasources 全套路由,数据源 CRUD、连接测试、元数据导入不再经由 AIP——AIP 停机时本页仍完全可用。
页面核心能力有四:新建 / 编辑数据源(连接参数管理,密码后端打码回显 ****)、测试连接(按请求体完整连接配置真实建连验证)、导入元数据(读取外部表结构入库,可选 AI 生成表/列业务描述)、删除数据源。其中「导入元数据」是任务化操作:后端 15 秒窗口内完成则直接返回结果(快路径),超时返回 202 受理 {task_id, status:'running', type},前端在结果弹窗内轮询进度条直到终态(success / failed / cancelled)。
页面依赖 platform/datasource 平台包的服务能力,在 foundry 库建表(AutoMigrate 见 bootstrap.go)并注册全套路由,响应统一套 foundry 风格 {code:0, data:{...}} 包装,数据在 res.data.data。API 走独立实例 foundryDsApi.js(baseURL /api/v1 → Vite 代理 → Foundry 18081),不修改 client.js / aipClient.js。
1.2 核心价值
| 价值点 | 说明 |
|---|---|
| 路由解耦 | Foundry 自持 /datasources,AIP 停机不影响数据源页可用性 |
| 连接测试 | 按请求体完整连接配置真实建连,结果 JSON 弹窗展示,配置错误即时暴露 |
| 元数据导入任务化 | 15s 快路径 + 202 受理轮询进度条,大库导入不卡死页面 |
| AI 描述生成 | 导入时可勾选「AI 生成描述」,调 LLM 为表/列生成业务描述(较慢) |
| 密码打码 | 编辑回显 ****,密码留空提交表示不改,避免明文泄漏 |
| 支撑数据域 | 数据源是数据集拉数 / 同步引擎 / 质量画像 / 语义查询的连接底座 |
1.3 一句话总结
数据源页面把"连接外部数据库"变成可创建、可测试、可导入元数据、可维护的自助服务。
2. 访问入口
2.1 路由与菜单
| 项 | 值 |
|---|---|
| 路由 path | /foundry/datasources |
| 路由 name | FoundryDataSources |
| meta.title | Foundry 数据源 |
| 侧边栏入口 | FoundryLayout 侧边栏「数据源」(位于「SQL 工作台」之后、「数据血缘」之前) |
| 前端源码 | action/web/src/views/FoundryDataSourcesPage.vue |
| API 客户端 | action/web/src/api/foundryDsApi.js |
路由注册见 action/web/src/router/index.js:
{ path: 'datasources', name: 'FoundryDataSources', component: FoundryDataSourcesPage, meta: { title: 'Foundry 数据源', requiresAuth: true } },
侧边栏入口见 action/web/src/views/FoundryLayout.vue 的 menuItems 数组 { path: '/foundry/datasources', label: '数据源' }。
2.2 认证与权限
- 路由
requiresAuth: true:未登录访问被前端路由守卫拦截跳转登录页。 - 后端 API 全部挂在 protected 组:
authMiddleware校验Authorization: Bearer <token>,token 缺失/非法返回 401{"code":"AUTH_ERROR","error":"..."}。 - Token 类型:
aip_token(localStorage 键名aip_token)。foundryDsClient 请求拦截器自动读取并附带Bearer ${token}(跨产品统一 SECRET_KEY 互认);401 响应由拦截器统一处理:移除aip_token/aip_username,不在登录页则跳转/login。 - 角色限制:本页 API 未做细粒度角色门禁,任何登录用户均可操作;创建/更新/删除会记录操作者(
dsCurrentUser,缺省 anonymous)。 - 404 排错提示:若访问
/foundry/datasources404,检查 Foundry 后端(18081)是否启动、registerDatasourceRoutes是否在 protected 组挂载、以及前端 Vite 代理/api → 18081是否配置。
2.3 端口与 API 前缀
- Foundry 后端端口:18081。
- API 前缀:
/api/v1(foundryDsApi.js baseURL 为/api/v1,Vite 代理/api→ 18081)。 - 任务轮询接口:
/api/v1/system/tasks/:id(Foundry 侧任务路由挂/system前缀)。 - 与 AIP 的差异:AIP 数据源接口前缀为
/aip-api/v1(18080),本页固定走/api/v1(18081),切勿混用导致 404。
3. 界面布局
+--------------------------------------------------------------+
| Foundry 数据源 [☑ 导入时 AI 生成描述(调用 LLM,较慢)] [新建数据源] |
+--------------------------------------------------------------+
| [alert 操作结果提示条(可关闭)] |
+--------------------------------------------------------------+
| [新建/编辑表单卡片(showCreateForm 时显示)] |
| 数据源名称* | 数据库类型* | 主机地址 | 端口 | 数据库名 | 用户名 | 密码 | 描述 |
| [创建数据源/更新数据源] [取消] |
+--------------------------------------------------------------+
| [数据源列表卡片] |
| ID | 名称 | 类型 | 描述 | 连接信息 | 操作 |
| [测试连接] [导入元数据/导入中...] [编辑] [删除] |
+--------------------------------------------------------------+
| [结果弹窗(modal,resultModal.visible 时显示)] |
| 测试连接结果 / 导入元数据结果 / 导入元数据(任务 xxx) |
| 进行中:进度条 + 百分比 · 任务执行中... <pre>JSON 结果</pre> |
+--------------------------------------------------------------+
各板块职责:
- 页头:标题「Foundry 数据源」+ 右侧「导入时 AI 生成描述(调用 LLM,较慢)」开关 + 「新建数据源 / 收起表单」按钮。
- 操作结果提示条:创建/更新/测试/导入/删除结果以 alert 呈现(alert-success / alert-error / alert-info),右侧「关闭」按钮清空。
- 新建 / 编辑表单:同一张表单承载创建与编辑两种模式(
editingId区分),标题随之切换「新建数据源」/「编辑数据源」。 - 数据源列表:表格展示 ID、名称、类型、描述、连接信息(
host:port/database),行内四个操作按钮;加载中显示「加载中...」,空列表提示「暂无数据源,请点击"新建数据源"添加。」。列表按服务端分页每页 10 条展示(请求GET /datasources?page=&page_size=),底部提供「上一页 / 第 N / M 页(共 K 条)/ 下一页」,其中总数 K 来自响应data.total;下方一行提示说明「服务端分页:本页按 page/page_size(默认 10/页,上限 100)请求,总数来自响应 total」。 - 结果弹窗:测试连接与导入元数据共用一个 modal;任务化导入进行中展示进度条与进度百分比,最终以 JSON 文本(
<pre class="code-block">,最大高度 400px 可滚动)呈现结果。
4. 交互元素详解
4.1 页头与列表
| 元素 | 位置 | 含义 | 必填/默认 | 操作效果 | 触发的后端调用 |
|---|---|---|---|---|---|
| 「导入时 AI 生成描述(调用 LLM,较慢)」开关 | 页头左侧 | 导入元数据时是否调用 LLM 生成表/列业务描述 | 默认关闭 | 绑定 aiGenerate,导入时作为 query 参数 | POST /api/v1/datasources/:id/import-metadata?ai_generate_descriptions=true/false |
| 「新建数据源」/「收起表单」按钮 | 页头右侧 | 展开/收起新建表单 | — | 切换 showCreateForm | 无 |
| 「测试连接」按钮 | 列表操作列 | 按请求体完整连接配置真实建连测试 | 导入中禁用 | 弹出「测试连接结果」JSON | POST /api/v1/datasources/:id/test |
| 「导入元数据」/「导入中...」按钮 | 列表操作列 | 导入外部表结构到平台元数据 | 导入中禁用并显示「导入中...」 | 弹窗展示结果或进度条轮询 | POST /api/v1/datasources/:id/import-metadata?ai_generate_descriptions=... |
| 「编辑」按钮 | 列表操作列 | 将数据源填入表单进入编辑模式 | — | 密码留空、标题切「编辑数据源」,并按类型回填默认端口(端口为空时) | PUT /api/v1/datasources/:id |
| 「删除」按钮 | 列表操作列 | 删除数据源 | — | confirm 二次确认后删除 | DELETE /api/v1/datasources/:id |
| 「上一页 / 下一页」分页 | 列表底部 | 服务端分页翻页 | 首页/末页按钮禁用 | changeDsPage(p) 重新请求第 p 页(每页 10 条,page=p&page_size=10) | GET /api/v1/datasources?page=&page_size= |
| 分页提示 | 列表底部 | 常驻说明「服务端分页:本页按 page/page_size(默认 10/页,上限 100)请求,总数来自响应 total」 | — | 无交互,纯提示 | 无 |
4.2 新建 / 编辑表单
| 字段 | 含义 | 必填/默认 | 操作效果 | 触发的后端调用 | |
|---|---|---|---|---|---|
| 数据源名称 | 数据源显示名 | 必填,placeholder 如 sales_data_warehouse | 写入 dsForm.name | POST /api/v1/datasources 或 PUT /api/v1/datasources/:id | |
| 数据库类型 | 连接类型下拉 | 必填,占位「请选择」;选项:PostgreSQL / MySQL / SQLite / SQL Server / Oracle / ClickHouse;@change 触发 onTypeChange 类型联动 | 写入 dsForm.type(值为 POSTGRESQL/MYSQL/SQLITE/SQLSERVER/ORACLE/CLICKHOUSE) | 同上 | |
| 主机地址 | 数据库主机 | 可空,placeholder 按类型动态:SQLITE 显示「SQLite 无需主机」,其余 localhost | 写入 dsForm.host → payload 中 connection_config.host | 同上 | |
| 端口 | 连接端口 | 可空,type=number,placeholder 按类型动态(POSTGRESQL 5432 / MYSQL 3306 / SQLSERVER 1433 / 其他「按类型自动填充」);切换类型时若端口为空则回填默认端口,已填则保留用户输入 | 写入 dsForm.port → connection_config.port(空提交为 0) | 同上 | |
| 数据库名 | 目标库名 | 可空,placeholder chatbi_forge_dev | 写入 dsForm.database → connection_config.database | 同上 | |
| 用户名 | 连接账号 | 可空,placeholder postgres | 写入 dsForm.user → connection_config.user | 同上 | |
| 密码 | 连接密码 | 编辑时留空表示不改,后端回显 **** | 写入 dsForm.password → connection_config.password(编辑留空则提交空串,后端保留原密码) | 同上 | |
| 描述 | 数据源业务描述 | 可空,textarea rows=2 | 写入 dsForm.description → connection_config.description | 同上 | |
| 「创建数据源」/「更新数据源」/「提交中...」按钮 | 表单底部 | 提交创建或更新 | 提交中禁用并显示「提交中...」 | POST /api/v1/datasources 或 PUT /api/v1/datasources/:id | 同上 |
| 「取消」按钮 | 表单底部 | 重置并收起表单 | — | 调用 resetForm() | 无 |
4.3 结果弹窗
| 元素 | 含义 |
|---|---|
| 标题 | 测试连接结果 / 导入元数据结果 / 导入元数据(任务 task_id 前 8 位...) |
| 进度条 | taskRunning=true 时显示,宽度按 progress × 100%,下方 百分比 · progressMessage |
| JSON 内容 | <pre class="code-block"> 展示 JSON.stringify(payload, null, 2),最大高度 400px 可滚动 |
| 「关闭」按钮 | 关闭弹窗并 stopPolling();点击遮罩(@click.self)同样关闭 |
5. 后端关联
5.1 API 客户端
foundryDsApi.js 为独立 axios 实例(B1-6 数据源路由解耦专用):
- baseURL:
/api/v1 - timeout:30000(30 秒)
- 请求拦截器:从 localStorage 读
aip_token,附加Authorization: Bearer ${token} - 响应拦截器:401 时移除
aip_token/aip_username并跳转/login
导出函数:
| 函数 | 请求 |
|---|---|
listDataSources() | GET /datasources → data.data_sources |
getDataSource(id) | GET /datasources/:id |
createDataSource(payload) | POST /datasources(201) |
updateDataSource(id, payload) | PUT /datasources/:id |
deleteDataSource(id) | DELETE /datasources/:id → data.deleted |
testDataSource(id, payload) | POST /datasources/:id/test(body 同创建:完整连接配置) |
importMetadata(id, aiGenerate=false) | POST /datasources/:id/import-metadata?ai_generate_descriptions=true/false |
getTask(taskId) | GET /system/tasks/:id |
5.2 端点表
| 方法 | 路径 | 请求体 | 响应要点 |
|---|---|---|---|
| GET | /api/v1/datasources | — | {code:0, data:{data_sources:[...]}}(skip/limit 后端取 0/100) |
| POST | /api/v1/datasources | {name, type, connection_config:{host,port,user,password,database,description,active}} | 201 {code:0, data:ds} |
| GET | /api/v1/datasources/:id | — | {code:0, data:ds} |
| PUT | /api/v1/datasources/:id | {name, type, connection_config:{...}}(全字段更新语义) | {code:0, data:ds} |
| DELETE | /api/v1/datasources/:id | — | {code:0, data:{deleted:true}} |
| POST | /api/v1/datasources/:id/test | 完整连接配置(body 同创建) | {code:0, data:{...连接测试结果}} |
| POST | /api/v1/datasources/:id/import-metadata | query: ai_generate_descriptions | 200 快路径 data={...结果字段, task_id};202 data={task_id, status:'running', type:'foundry_import_metadata'} |
| GET | /api/v1/system/tasks/:id | — | data={id,status,progress,message,result,error,...} |
5.3 响应结构
数据源列表响应:
{
"code": 0,
"data": {
"data_sources": [
{
"id": 1,
"name": "sales_data_warehouse",
"type": "POSTGRESQL",
"connection_config": {
"host": "localhost", "port": 5432, "user": "postgres",
"password": "****", "database": "chatbi_forge_dev",
"description": "销售数仓", "active": true
}
}
]
}
}
导入元数据 202 受理响应:
{ "code": 0, "data": { "task_id": "task-uuid", "status": "running", "type": "foundry_import_metadata" } }
任务轮询响应(GET /system/tasks/:id):
{
"code": 0,
"data": {
"id": "task-uuid", "type": "foundry_import_metadata",
"status": "success", "progress": 1.0, "message": "元数据导入完成",
"result": { "tables": 12, "columns": 108 }, "error": "", "finished_at": "..."
}
}
5.4 关联模块表
| 后端包 | 职责 |
|---|---|
platform/datasource | DataSourceService(CRUD/TestDataSourceConnection)+ MetadataGenerationService(GenerateMetadataFromDataSource)+ ConnectorCacheService |
products/foundry/server(datasource_handlers.go) | Foundry 侧数据源全套路由、任务化提交、{code:0,data} 包装 |
platform/task | 异步任务系统:foundry_import_metadata 任务类型、进度上报、终态判定 |
platform/connector | 连接器工厂(allow-list 白名单:默认仅放行 MYSQL/SQLSERVER/POSTGRESQL) |
products/foundry/server(server.go) | registerDatasourceRoutes 挂 protected 组、task.RegisterRoutes 挂 /system、bootstrap AutoMigrate |
5.5 关键机制
数据源路由解耦(B1-6):Foundry 独立进程 + 独立库,datasources 表在 foundry 库经 bootstrap AutoMigrate 建立;复用 platform/datasource 服务构造(NewDataSourceServiceWithCache 带 5 分钟连接缓存)。AIP 停机不影响本页。
导入元数据任务化:importMetadata handler 将 GenerateMetadataFromDataSource 包进 TaskManager.Submit(type=foundry_import_metadata,payload 含 data_source_id / ai_generate),15s 窗口内完成保持旧同步响应语义(结果字段 + task_id),超时返回 202 {task_id, status:'running', type};taskMgr 为 nil 或 Submit 失败时降级同步直执行。前端 handleImportMetadata 判断:payload.status === 'running' && payload.task_id 则弹窗进度条 + pollTask 轮询(1.5s,POLL_INTERVAL_MS=1500),否则直接 showResult 展示快路径结果。
任务轮询(pollTask):pollTimer 用 setTimeout 链式调用而非 setInterval;单次轮询失败(catch)不中断、继续 setTimeout(tick, 1500) 重试;弹窗关闭(resultModal.visible=false)即 stopPolling;终态 success 时展示 {task_id, status:'success', result} 并 fetchDataSources 刷新列表,failed/cancelled 时展示 {task_id, status, error: task.error || task.message || '任务未成功'}。
密码打码回显:后端对密码字段回显打码为 ****;编辑时前端把密码留空(dsForm.password = ''),提交空串表示不改动(后端保留原密码)。
类型校验与连接器白名单:创建/更新时后端校验 name 必填、type 必填且为合法枚举(大小写不敏感);type 白名单含 POSTGRESQL/MYSQL/SQLSERVER/SQLITE/ORACLE/CLICKHOUSE/SNOWFLAKE/REDSHIFT/BIGQUERY/DATABRICKS/TRINO/DB2/OCEANBASE/TIDB。但能否真正建连取决于 connector 工厂 allow-list 授权(默认仅放行 MYSQL/SQLSERVER/POSTGRESQL,其余需 AllowAdvancedTypes 显式授权)。
6. 核心流程详解
6.1 新建 / 编辑数据源
- 点击「新建数据源」展开表单(
showCreateForm = true)。 - 填写数据源名称(必填)、数据库类型(必填)、主机/端口/数据库名/用户名/密码/描述。
- 点击「创建数据源」(
submitting=true显示「提交中...」):组装 payload{name, type, connection_config:{host, port, user, password, database, description, active:true}},POST /datasources。 - 成功提示「数据源创建成功」,
resetForm()收起表单并fetchDataSources刷新列表。 - 编辑模式:点「编辑」
startEdit(ds)把数据源字段回填表单(editingId = ds.id,密码置空),标题切「编辑数据源」,并调用onTypeChange()按类型回填默认端口(仅当端口为空时);点「更新数据源」PUT /datasources/:id,成功提示「数据源更新成功」。 - 类型联动:在两个模式下共用同一逻辑——切换「数据库类型」时,若端口为空则填入该类型默认端口(POSTGRESQL 5432 / MYSQL 3306 / SQLSERVER 1433;SQLITE 无端口不预填),端口占位提示同步切换。
6.2 测试连接
- 点击行内「测试连接」。
- 前端组装 payload:
{name: ds.name, type: ds.type, connection_config: ds.connection_config || {}}(body 需完整连接配置,后端按 body 建连测试,而非仅用库内记录)。 POST /datasources/:id/test→ 成功showResult('测试连接结果', JSON.stringify(resp?.data ?? resp, null, 2))弹窗展示;失败走 alert「测试连接失败:错误详情」。
6.3 导入元数据(任务化主流程)
- 可选:打开「导入时 AI 生成描述(调用 LLM,较慢)」开关(绑定
aiGenerate)。 - 点击行内「导入元数据」(按钮变为「导入中...」,
importingId = ds.id期间本行测试/导入按钮禁用)。 importMetadata(ds.id, aiGenerate)带 queryai_generate_descriptions=true/false发请求:
- 200 快路径:
payload.status !== 'running'→showResult('导入元数据结果', JSON.stringify(payload, null, 2))直接展示结果字段(含 task_id); - 202 受理:
payload.status === 'running' && payload.task_id→ 弹窗标题「导入元数据(任务 {task_id 前 8 位}...)」、taskRunning=true显示进度条、progressMessage='任务已受理,等待执行...',启动pollTask(task_id)。
- 轮询循环(1.5s setTimeout 链):
getTask(taskId)→ 更新progress(0~1)/progressMessage;status==='success'→ 展示结果 JSON、stopPolling、fetchDataSources刷新;status==='failed'||'cancelled'→ 展示错误 JSON、stopPolling;否则继续下一轮。 finally中importingId = null恢复按钮。
6.4 删除数据源
confirm('确定要删除数据源"xxx"吗?此操作不可撤销。') 二次确认后 DELETE /datasources/:id,成功提示「数据源"xxx"已删除」并刷新列表。
7. 权限与安全
7.1 认证
- JWT Bearer 认证(
aip_token);401 统一跳转登录页。 - 后端
authMiddleware双路径:lfk_前缀走 API Key 校验,否则走securityService.ParseToken解析 JWT;成功注入user_id/username/roles。
7.2 数据级安全
- 数据源
connection_config中的密码是敏感凭证:后端响应回显打码****,前端编辑表单密码始终置空、留空提交表示不改,避免明文在浏览器与日志中扩散。 - 连接器工厂 allow-list:默认仅放行 MYSQL/SQLSERVER/POSTGRESQL,其余类型需显式授权(
AllowAdvancedTypes("SQLITE")等),从连接层限制可访问的数据库类型。 - 请求体大小限制:
decodeJSON用http.MaxBytesReader限制 body 大小(1MB),防超大请求。
7.3 写操作防护
- 创建/更新/删除记录操作者(
dsCurrentUser,缺省 anonymous);平台auditService注入数据源服务记录审计事件。 - 删除有前端
confirm二次确认。 - 更新采用全字段更新语义(Python 对齐),type 需为合法枚举,非法类型返回 400
INVALID_REQUEST。
8. 常见问题与排错
8.1 测试连接失败
- 现象:点击「测试连接」后 alert 提示「测试连接失败:...」,或弹窗 JSON 显示连接错误。
- 原因:连接参数错误、目标主机/端口不可达、数据库认证失败、或数据库类型未被 connector 工厂 allow-list 放行(默认仅 MYSQL/SQLSERVER/POSTGRESQL)。
- 排查步骤:
- 读取 alert 或弹窗中的具体错误文本,区分网络不可达 / 认证失败 / 类型不支持;
- 核对表单中的 host/port/database/user/password 与目标库实际配置是否一致(注意测试连接按请求体配置建连,若编辑后未保存,请求体用的仍是列表里的 connection_config);
- 若报类型不支持,确认该类型是否在 connector 工厂 allow-list(默认仅 MYSQL/SQLSERVER/POSTGRESQL,SQLite 等需
AllowAdvancedTypes显式授权); - 用数据库客户端手工连接一次,排除库侧问题(账号锁、白名单 IP 等)。
8.2 导入元数据后 RAG / 查询仍按旧表名命中
- 现象:导入元数据成功,但后续数据查询 / 数据集创建时提示的表名与实际库表不符,或残留旧表名误导检索。
- 原因:元数据导入需要按
table_schema_id清理旧 columns/tables(AGENTS.md 常见坑:导入元数据前需清理旧 columns/tables,防止残留表名误导 RAG);若数据源表结构变更后未重新导入,元数据停留在旧快照。 - 排查步骤:
- 确认本次导入任务终态为 success,且 result 中 tables/columns 数量符合预期;
- 在目标数据库确认表结构确实已变更(如删表/改列);
- 重新点击「导入元数据」触发全量重建(
GenerateMetadataFromDataSourceregenerateAll 传 false,但导入逻辑会按 table_schema_id 清旧后重建); - 若检索侧仍有旧表名,检查 RAG 向量库是否需要重建索引(元数据入库后需触发对应索引刷新)。
8.3 导入元数据任务一直转圈 / 进度条不动
- 现象:导入元数据后弹窗进度条长时间停在某百分比,或「任务已受理,等待执行...」不变。
- 原因:任务仍在执行中(大库表多耗时久),或任务系统 worker 繁忙、或任务提交失败走降级同步执行但页面还在轮询旧 task_id。
- 排查步骤:
- 观察进度百分比与 message 是否在变化——在变说明任务在推进,耐心等待(AI 描述生成较慢);
- 不变则打开 DevTools Network 看
GET /system/tasks/:id响应 status 是否仍为 running/queued; - queued 长期不变说明 worker 未取走——检查后端日志是否有「异步任务提交失败,降级同步执行」告警;
- 确认弹窗标题中的 task_id 与 Network 中请求的 task_id 一致(避免旧轮询残留);必要时关闭弹窗重新点击「导入元数据」。
8.4 勾选 AI 生成描述但导入报错
- 现象:打开「导入时 AI 生成描述(调用 LLM,较慢)」后导入元数据失败。
- 原因:Foundry 侧 LLM 服务未装配(
foundryMetaSvc用NewMetadataGenerationServiceWithCache(db, nil, ...)传 nil 表示 LLM 不可用)——ai_generate_descriptions=true时元数据导入明确报错(诚实降级)。 - 排查步骤:
- 查看错误文本是否为"LLM 服务未配置 / 不可用"类;
- 若需要 AI 描述,先配置 LLM 网关(.env 中的 deepseek / dashscope key)并重启 Foundry;
- 不需要 AI 描述时取消勾选后重新导入,确认普通导入正常。
9. 已知缺陷与边界
| 缺陷/边界 | 说明 |
|---|---|
| LLM 未装配时 AI 描述不可用 | ai_generate_descriptions=true 时元数据导入明确报错(诚实降级),需先配置 LLM 网关 |
| 双凭证推迟 | 只读/写回双凭证建模推迟至 S5 Markings 批次评估,本批以独立数据源记录满足"解耦" |
| 连接器 allow-list 限制 | 默认仅放行 MYSQL/SQLSERVER/POSTGRESQL,SQLite/Oracle/ClickHouse 等需 AllowAdvancedTypes 显式授权 |
| 列表服务端分页(已修复 2026-09-14) | 后端列表已支持 page/page_size(默认 1/10,page_size 上限 100),skip=(page-1)*page_size 透传 GetAllDataSources,并在响应补 total(DatasourceDeps.CountDataSources 以 data_sources 表 COUNT 注入);前端改为服务端分页:翻页即重新请求,total 用于总页数与计数,不再受 100 条上限约束(单页上限 100) |
| 类型回显联动为默认端口 | 类型下拉已做联动:切换/编辑时按类型回填默认端口(端口为空才填)、占位提示与 SQLite 主机提示随类型变化;未联动数据库名/用户名等类型专属默认值 |
| 导入任务 result 仅展示 | 快路径/轮询结果以 JSON 文本展示,不做图表化或落库状态梳理 |
| 更新为全字段语义 | PUT 时 name/type 必填,漏传会 400;密码留空表示不改(后端特殊处理) |
10.2 后端文件
action/products/foundry/server/datasource_handlers.go(Foundry 侧数据源路由与任务化 handler)action/platform/datasource/(DataSourceService / MetadataGenerationService / ConnectorCacheService)action/platform/task/models.go、rest.go、manager.go(异步任务系统)action/products/foundry/server/server.go(registerDatasourceRoutes 接线与 bootstrap)
10.3 项目文档
action/wiki/upgrade-v5/dev-story/stage-1.md(B1-6 数据源路由解耦设计)action/wiki/changelog/2026-08-29-2-v5-stage1.md(Stage 1 变更记录)action/wiki/frontend-intro-v5/markdown/foundry/index.md(页面索引)
10.4 相邻页面
- 数据集(datasets) — 数据源拉数/登记为平台数据集
- 数据同步(sync) — 数据源作为 platform_ds 来源被抽取
- 数据血缘(lineage) — 数据源元数据导入参与血缘链路
- SQL 工作台(sql-workbench) — 基于数据源连接的数据查询
- 数据质量(quality) — 基于数据源的数据质量画像