feat: add reviewed chunks and atomic index publication #8

Merged
saint merged 1 commits from kronecker/feat/backend-chunk-index-versions AGit into dev 2026-10-16 13:11:17 +08:00
Collaborator

当前知识审核和关键词检索已有记录版本,但缺少可复核的持久化切分和独立的发布边界。本改动保存已审核知识的原文 chunks、出处/版本快照及索引版本,并将构建和发布分开;资料变化或发布失败时不把旧快照当作当前依据。

任务与依赖

  • T05:持久化 chunks 与文本索引版本;独立任务 Issue 仍待具备 Gitea 写入认证后补建,本 PR 与任务板保留验收记录。
  • 分支 feat/backend-chunk-index-versions,目标 dev;新增提交 2722a59。
  • 叠加待审 PR #7(f9827fe,认证)并继承 PR #6(关键词)。用户已授权无需等待合并继续开发;没有自行批准或合并这些 PR。
  • 迁移链 0003_retrieval_runs → 0004_auth_sessions → 0005_chunk_indexes。若前置 PR 先合入,本 PR 差异会自动收敛;请按依赖审阅。

实现与接口

  • 新增 index_versions、chunks、index_state、index_publications。保存构建配置、目录修订、语料指纹、片数、原文起止偏移/内容哈希、知识及父资料版本与出处。
  • POST /api/indexes 构建 ready 快照;POST /api/indexes/{id}/publish 携带 expected_generation 显式切换。GET 接口查询版本/当前指针/chunks/逐次发布记录,均支持相应分页。
  • 所有索引管理接口要求服务端 admin;写入沿用 Cookie、明确 Origin 与会话 CSRF。新增前端类型和请求封装,未改页面。
  • unicode-window-v1 保留原知识正文,默认 500 字符/重叠 80,长度 100–2000、重叠不超过一半;只读有效且完整核验的知识。沿用 5000 条/200 万字符语料预算,每版本最多 20000 chunks,超限明确拒绝。
  • 构建、发布与知识/来源/文档应用写入共用状态行锁。目录写入先取锁并递增修订;发布同时核对代数、目录修订与当前语料指纹,旧构建拒绝发布。
  • 发布事务原子切换旧/新状态、指针和历史;构建/发布的校验或数据库写入失败完整回滚,旧版本保留。资料变化后 is_current=false,历史 chunk 不改写;空语料可作为明确撤回后的新快照发布。
  • 修正真实重启测试发现的发布时间表示差异,索引和发布记录统一 UTC 输出。

实际验证

  • ruff check .、ruff format --check .:通过。
  • pytest -q:91 passed,隔离 PostgreSQL 16 + pgvector。覆盖原文重建/偏移/哈希/出处、审核与关联失效、重复构建、过期与代数冲突、实际行锁竞争、真实数据库约束导致的构建/发布回滚、旧数据迁移/降级保留,以及原认证/知识/关键词回归。
  • 默认应用生命周期真实 HTTP:重启后当前指针、chunks 与发布历史一致;原会话/知识/检索持久化用例继续通过。
  • frontend npm run build:通过。新增内容隐私检查通过,作者和提交者使用项目通用身份。

升级、回滚与限制

  • 停止旧后端,安装依赖并备份后 alembic upgrade head,再启动;所有后端实例须统一升级,当前版本要求 0005_chunk_indexes。
  • 备份后可配合旧后端 alembic downgrade 0004_auth_sessions,仅撤回四张新增索引表,保留用户、会话、知识和检索记录;索引历史恢复依赖备份。
  • 文本版本不是向量/ANN 索引。现有 POST /api/retrieval 仍按知识条目运行原关键词基线,不读取新 chunks;Embedding、RRF、RAG 仍属后续阶段。
  • 全局锁与同步构建面向当前有限语料,构建期间会短暂阻塞目录写入;后台/增量流程、保留策略和前端页面待后续实现。
  • Docker、真实浏览器端验收仍待完成;所有自动化资料为占位数据,不是论文实验结论。完整字段、并发与维护边界见 docs/INDEX_API.md。
当前知识审核和关键词检索已有记录版本,但缺少可复核的持久化切分和独立的发布边界。本改动保存已审核知识的原文 chunks、出处/版本快照及索引版本,并将构建和发布分开;资料变化或发布失败时不把旧快照当作当前依据。 ## 任务与依赖 - T05:持久化 chunks 与文本索引版本;独立任务 Issue 仍待具备 Gitea 写入认证后补建,本 PR 与任务板保留验收记录。 - 分支 feat/backend-chunk-index-versions,目标 dev;新增提交 2722a59。 - 叠加待审 PR #7(f9827fe,认证)并继承 PR #6(关键词)。用户已授权无需等待合并继续开发;没有自行批准或合并这些 PR。 - 迁移链 0003_retrieval_runs → 0004_auth_sessions → 0005_chunk_indexes。若前置 PR 先合入,本 PR 差异会自动收敛;请按依赖审阅。 ## 实现与接口 - 新增 index_versions、chunks、index_state、index_publications。保存构建配置、目录修订、语料指纹、片数、原文起止偏移/内容哈希、知识及父资料版本与出处。 - POST /api/indexes 构建 ready 快照;POST /api/indexes/{id}/publish 携带 expected_generation 显式切换。GET 接口查询版本/当前指针/chunks/逐次发布记录,均支持相应分页。 - 所有索引管理接口要求服务端 admin;写入沿用 Cookie、明确 Origin 与会话 CSRF。新增前端类型和请求封装,未改页面。 - unicode-window-v1 保留原知识正文,默认 500 字符/重叠 80,长度 100–2000、重叠不超过一半;只读有效且完整核验的知识。沿用 5000 条/200 万字符语料预算,每版本最多 20000 chunks,超限明确拒绝。 - 构建、发布与知识/来源/文档应用写入共用状态行锁。目录写入先取锁并递增修订;发布同时核对代数、目录修订与当前语料指纹,旧构建拒绝发布。 - 发布事务原子切换旧/新状态、指针和历史;构建/发布的校验或数据库写入失败完整回滚,旧版本保留。资料变化后 is_current=false,历史 chunk 不改写;空语料可作为明确撤回后的新快照发布。 - 修正真实重启测试发现的发布时间表示差异,索引和发布记录统一 UTC 输出。 ## 实际验证 - ruff check .、ruff format --check .:通过。 - pytest -q:91 passed,隔离 PostgreSQL 16 + pgvector。覆盖原文重建/偏移/哈希/出处、审核与关联失效、重复构建、过期与代数冲突、实际行锁竞争、真实数据库约束导致的构建/发布回滚、旧数据迁移/降级保留,以及原认证/知识/关键词回归。 - 默认应用生命周期真实 HTTP:重启后当前指针、chunks 与发布历史一致;原会话/知识/检索持久化用例继续通过。 - frontend npm run build:通过。新增内容隐私检查通过,作者和提交者使用项目通用身份。 ## 升级、回滚与限制 - 停止旧后端,安装依赖并备份后 alembic upgrade head,再启动;所有后端实例须统一升级,当前版本要求 0005_chunk_indexes。 - 备份后可配合旧后端 alembic downgrade 0004_auth_sessions,仅撤回四张新增索引表,保留用户、会话、知识和检索记录;索引历史恢复依赖备份。 - 文本版本不是向量/ANN 索引。现有 POST /api/retrieval 仍按知识条目运行原关键词基线,不读取新 chunks;Embedding、RRF、RAG 仍属后续阶段。 - 全局锁与同步构建面向当前有限语料,构建期间会短暂阻塞目录写入;后台/增量流程、保留策略和前端页面待后续实现。 - Docker、真实浏览器端验收仍待完成;所有自动化资料为占位数据,不是论文实验结论。完整字段、并发与维护边界见 docs/INDEX_API.md。
Kronecker added 3 commits 2026-10-16 08:45:05 +08:00
saint merged commit b232031ffe into dev 2026-10-16 13:11:17 +08:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: saint/border-red-post-nalati#8