Skip to content

收口:资料只走资料库相对路径 - #230

Merged
taekchef merged 29 commits into
mainfrom
codex/library-relative-only
Aug 16, 2026
Merged

收口:资料只走资料库相对路径#230
taekchef merged 29 commits into
mainfrom
codex/library-relative-only

Conversation

@taekchef

Copy link
Copy Markdown
Collaborator

背景

这是项目体检最终收尾(#228 / 2df3708)的 follow-up,不是新产品任务。

Codex 复审后确认:此前问题根源不是再加固外部文件恢复,而是「长期引用资料库外文件」这套旧模型本身没有必要。

关闭 #229

实际改动

  • 默认资料库:~/Documents/魏碑资料库/{通用资料,通用笔记}
  • 顶层课程文件夹自动补 .weibei/course.json文稿笔记;重命名文件夹后 courseID 仍来自 course.json
  • 最终条目存储只保留 common(relativePath) / courseOwned(courseID, relativePath) / bundledSample
  • 运行时 URL 由资料库根 + 相对路径计算,不再持久化 urlPath / 书签 / lastKnownPath
  • 外部导入复制进对应目录,原文件不动;同名同内容复用,同名不同内容保留两份
  • 课程中建笔记写入 课程/笔记,课程外写入 通用笔记
  • 整库不可访问时不批量清登记;单文件删除只去掉对应资料
  • 新 workspace 不再写入 courseItemMemberships
  • 删除 ImportedFileRecovery、旧 gone-import 恢复测试和对应 SelfCheck

未做

  • 不迁移当前测试数据(已清空)
  • 不加固书签 / 备用地址 / 外部重绑
  • 未整段删除课程可携带状态里的历史 sharedReference 编码(不再作为新资料挂载模型使用)
  • 符号链接共享入口仍有旧函数残留,新导入/建笔记路径不再走它

共享文件占用

  • Sources/WeiBei/Stores/WorkspaceStore.swift — 本任务占用,随本 PR 合并释放
  • Sources/WeiBeiSelfCheck/main.swift — 本任务占用,随本 PR 合并释放

负责人:codex/library-relative-only / #229

验证

  • 本地:swift build -c debug --product WeiBei
  • 本地:WeiBeiSelfCheck 通过
  • 本地:WeiBeiWebEditorCheck 通过
  • 本地:WeiBeiPiCheck 通过
  • 本地无完整 Xcode,XCTest 以本 PR CI 为准

轻量冒烟

自动检查覆盖首次结构、复制导入、相对路径存储和 gone-item。真实 App 体验仍由用户在最终候选包上完成。

Delete the long-lived outside-library file model. Persist only
common, courseOwned, and bundledSample storage with relative paths.
Import copies into the library; gone items drop when the library is
available. First launch can create ~/Documents/魏碑资料库.

Closes #229
Keep course-folder discovery in WorkspaceStore so it can update
courses, and finish leftover courseOwned / shared / cleanup type errors.
Keep StudyItem storage on relativePath, but do not rename the portable
export shared-material fields. That accidental rename broke XCTest
compilation.
Common items are globally visible to course search by relative path.
Old workspace items are found by stable item ID, not a persisted
absolute path.
Old snapshots keep their item IDs. Import copies notes into the library,
so tests look them up by file name instead of the original outside path.
A resume point may point at a globally visible common item. Course
search reports the current course instead of a multi-course mount list.
Do not require migrated file: IDs or persisted absolute paths after the
library-relative storage cut.
Removing a course must not require the old shared-item mount table.
Note links keep the same stable item IDs.
Empty relativePath after portable apply broke course files, resume,
and notes. Rebuild memberships from storage, resolve file: IDs for
existing identity repair, and keep urlPath decode-only.
Old snapshots may still contain urlPath. New encodes must omit it.
A common library item is the workspace original. An older course
portable snapshot may restore membership, but must keep the current
file digest and metadata.
Portable restore must not replace a common item that already lives in
the library. Old snapshots can still be found by file name if their
item ID was repaired.
Runtime URL refresh must leave the item unbound when the file at the
relative path has a different digest. Conflicting drafts stay as two
items.
New saves still omit the mount table. Old snapshots that already stored
memberships must keep both conflicting course entries on reopen.
Rebind must keep entry identity. Complementary memberships can still
dedupe when the same file identity is persisted.
No library is not the same as an inaccessible library. A file: item
whose path is gone is unregistered. Course import no longer deletes
the external original.
WorkspaceFixture has no makeDirectory helper.
Blank notes follow the course workspace, not the sidebar-active
course. Bare storage names like "笔记.md" are leftover file:
items, not library-relative paths, so they must not resolve under
the library root or they get dropped on reload.
Opening a course file must refresh inode identity when the
library-relative path still exists. Resume fixtures now place
common materials under 通用资料/ so they resolve as real
library-relative paths instead of leftover bare filenames.
The remaining CI red was old-model coverage: migrate that deletes
the original, symlink sharing, and resume fixtures that only
survived if a file could be mounted in many courses. Common notes
stay valid for a course resume without that mount.
Import now requires a library, so rootless leftover fixtures cannot
register files. Resume samples live under 通用资料/通用笔记 so they
resolve after restart without a course root.
通用资料 and 通用笔记 are global. Resume and open-in-course must
not require a leftover multi-course membership.
Opening 通用资料 is not enough. The reading location and resume
point must be stored for the current course without requiring a
leftover multi-course membership.
通用资料 can remember a per-course reading position. A selected
通用笔记 must not leak into another course's resume point.
A selected 通用资料 must not attach to a chat-only course just
because that course became active.
A deleted file while the library is available is gone. Chat history
stays. The old temporarily-unavailable bookmark path is closed.
Import is copy-in. Moving the original or treating a missing library
file as a bookmark target is the old external-file model.
Those cases still look up notes by the old external path and
recovery journal. The library-relative suite already covers
copy-in and resume.
@taekchef
taekchef marked this pull request as ready for review August 16, 2026 14:59
@taekchef
taekchef merged commit 76b92a4 into main Aug 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant