feat(space): 共享工作区增量3b —— KB 知识库按 Space 共享(存储 re-key)
把 3a 的 Space 作用域推到 KB 层:KB/Doc/DocLink owner→space_id,作用域键 owner/name→space_id/name,同空间成员共享知识库(检索/入库/文库/双链/图谱)。 后端: - store: KB/Doc/DocLink 加 space_id,唯一索引 (owner,*)→(space_id,*),owner 降级创建人; 查询全改 space 作用域;SaveDoc/ListVault/GetDocByID/DeleteDocByID/ReplaceDocLinks/ ResolveInboundLinks/ListLinks 改 space;tenantIDForSpace 补异步入库租户 - MigrateKBSpaces 启动迁移(space_id 回填 + 唯一索引换新,同 Agent 顺序坑规避) - scopedKB owner/name→space_id/name;IngestJob 契约加 SpaceID;enqueueIngest/runIngest 穿 space;MinIO 对象键改 space/kb/doc(避免跨空间同名撞键,老键不透明不迁) - KB 写路由(create/ingest/ingest_file/note/delete)挂 RequireSpaceRole(member):viewer 只读 - 存储层重灌迁移端点 POST /admin/migrate-kb-storage(异步):为存量文档入队新 space 作用域的重灌作业(复用 JetStream 入库 worker 池),先删旧键;避免同步重嵌撑爆 HTTP 超时 桌面端: - KbView 收 spaceId(变则重拉库)+spaceReadOnly(viewer 禁建库/入库/文件/笔记);VaultPanel 同 验证(gateway+mcp-go+Milvus/Neo4j/embedding 全栈): - PG 迁移: 20/21 KB + 50/54 doc 回填 space_id(4 未迁=pre-多租户 owner='wt' 空租户遗留, 正确跳过),唯一索引 idx_kb_sn/idx_doc_skn 换新、旧索引删除 - KB 共享: member 见共享库 / viewer 建库·入库 403 / 切回个人空间隔离(看不到) - 全向量链路: RagA 入库(真 dashscope embedding)→ RagB(空间member)检索命中 RagA 内容 - 存储重灌: 端点异步入队 49 作业(worker 池背压处理),重灌后老文档在新 space 键可检索 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -65,14 +65,14 @@ func New(db *store.Postgres, cache *store.Redis, bus *nats.Bus, blobStore *blob.
|
||||
p.PUT("/memory", h.SetMemory) // 偏好记忆登记(→ mcp-go memory_upsert)
|
||||
p.GET("/memory", h.ListMemory) // 列出当前用户偏好(记忆面板)
|
||||
p.DELETE("/memory", h.DeleteMemory) // 软删一条偏好(?key=)
|
||||
p.GET("/kb/list", h.KbList) // 当前用户的知识库列表(owner 隔离)
|
||||
p.POST("/kb/create", h.KbCreate) // 新建知识库
|
||||
p.POST("/kb/ingest", h.KbIngest) // 文本入库
|
||||
p.POST("/kb/ingest_file", h.KbIngestFile) // 文件入库
|
||||
p.POST("/kb/search", h.KbSearch) // 检索台
|
||||
p.GET("/kb/list", h.KbList) // 当前空间的知识库列表(共享工作区)
|
||||
p.POST("/kb/create", middleware.RequireSpaceRole(db, store.RoleMember), h.KbCreate) // 新建知识库:空间只读 viewer 拦下
|
||||
p.POST("/kb/ingest", middleware.RequireSpaceRole(db, store.RoleMember), h.KbIngest) // 文本入库:viewer 拦下
|
||||
p.POST("/kb/ingest_file", middleware.RequireSpaceRole(db, store.RoleMember), h.KbIngestFile) // 文件入库:viewer 拦下
|
||||
p.POST("/kb/search", h.KbSearch) // 检索台(读,全员)
|
||||
p.GET("/kb/vault", h.KbVault) // 文库列表
|
||||
p.GET("/kb/doc", h.KbDoc) // 取单篇文档
|
||||
p.DELETE("/kb/doc", h.KbDeleteDoc) // 级联删文档(三库+MinIO+PG)
|
||||
p.DELETE("/kb/doc", middleware.RequireSpaceRole(db, store.RoleMember), h.KbDeleteDoc) // 级联删文档:viewer 拦下
|
||||
|
||||
// Prompt 控制面(平台级配置:建版本 → 激活 → 控制面热下发各服务)
|
||||
p.GET("/prompts", h.PromptList) // 列出全部版本 + 可配键
|
||||
@@ -80,7 +80,7 @@ func New(db *store.Postgres, cache *store.Redis, bus *nats.Bus, blobStore *blob.
|
||||
p.POST("/prompts/activate", middleware.Audit(db), h.PromptActivate) // 激活某版本 → 广播热更新(审计)
|
||||
p.POST("/prompts/deactivate", middleware.Audit(db), h.PromptDeactivate) // 撤销激活 → 回退代码默认(热,审计)
|
||||
p.GET("/kb/links", h.KbLinks) // 某库双链
|
||||
p.POST("/kb/note", h.KbSaveNote) // 新建/编辑笔记
|
||||
p.POST("/kb/note", middleware.RequireSpaceRole(db, store.RoleMember), h.KbSaveNote) // 新建/编辑笔记:viewer 拦下
|
||||
p.GET("/kb/graph", h.KbGraph) // 知识图谱三元组
|
||||
p.GET("/agents", h.AgentList) // 当前空间的编排列表(共享工作区,含创建人)
|
||||
p.POST("/agents", middleware.RequireSpaceRole(db, store.RoleMember), h.AgentSave) // 保存/更新编排:空间只读 viewer 拦下
|
||||
@@ -127,6 +127,7 @@ func New(db *store.Postgres, cache *store.Redis, bus *nats.Bus, blobStore *blob.
|
||||
admin.GET("/status", h.AdminStatus) // 服务状态:基建/服务探活 + MCP 工具注册
|
||||
admin.GET("/overview", h.AdminOverview) // 系统级聚合:全平台用户/任务/评测/模型态/提示词态/健康
|
||||
admin.GET("/usage", h.AdminUsage) // 用量/积分/成本:全平台按天趋势 + 租户排行 / 单租户余额
|
||||
admin.POST("/migrate-kb-storage", h.MigrateKBStorage) // 增量3:存量 KB 三库 owner/kb→space/kb 重灌(一次性)
|
||||
admin.GET("/audit", h.AuditList) // 敏感操作审计流(倒序,翻页)
|
||||
admin.GET("/guardrail-events", h.GuardrailEvents) // 护栏命中安全事件流(倒序,翻页)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user