hectorqin
|
be219e5090
|
docs: align library write model and deployment guidance
|
2026-09-22 16:49:06 +08:00 |
|
cnb.dQC5J6ohAGA
|
ca68a03e5d
|
merge: 解决 auto/init-server-scaffold-81b3 与 main 的冲突
两个分支各自演进:一侧引入格式注册表、H5 客户端与 Android 外壳,另一侧
引入漫画目录书与逐页取图。冲突集中在扫描器、metadata、library 路由和 web
客户端,逐项按「两边能力都要保留」的原则合并。
合并后修复了 4 个被冲突掩盖的真实缺陷:
- scanner 同时保留了两套目录书实现,类型检查与测试均无法通过;改为统一
走格式注册表,目录书在文件遍历之前发现,其内容不再重复入库。
- /manifest 的 files 对漫画目录书返回的是文件夹路径,客户端无法逐页取图;
改为由 manifest 派生真实页路径。
- 单个文件端点只认 book_files 行,漫画目录书的每一页都 404;改为目录书
额外认领其目录下的路径,并修正路径归一化使穿越尝试仍被拒绝。
- 目录书判定只看图片数量,会把夹着一本书的目录整体吞掉;改为注册表驱动
的判定,含书籍文件的目录始终是书架。
同时修复了 web 端两套测试运行器互相无法执行对方用例的问题(vitest 与
node:test 混跑会静默跳过),以及 web 侧 5 处类型错误。
Ref: #9
|
2026-09-16 18:04:11 +08:00 |
|
CodeBuddy
|
0a17174fb8
|
fix(server): 让解析器修复能真正到达已入库的书
改 EPUB 读取时发现两个连在一起的坑,都会静默留疤:
1. `spineLength()` 用内存里的 zip 打开,但里面调用的 `readPackage` 又要求
从文件读,于是每本 epub 的 page_count 都是 null 且不报错。
`null` 同时也是"这个格式本来就报不出页数"的合法答案,下游无法区分。
2. 更麻烦的是:即使修好 1,已入库的书也修不回来。变更检测基于内容哈希,
而解析器修复不改变任何字节,扫描恰好会跳过最需要重读的那些文件。
于是坏结果永久留存——这正是这个 bug 在真实书库里的表现。
修法是给解析结果带上版本号:`book_files.parse_version` 记录是哪一版解析器
写下的,`PARSE_VERSION` 一旦提升就强制重解析一次。自部署用户不会按时升级,
所以版本得跟着数据行走,不能只活在进程里。
配套:schema 加一段可重复执行的增量迁移(SQLite 不支持 ADD COLUMN IF NOT
EXISTS,靠 duplicate column 错误判断已执行过),旧库能原地升级。
新增的日志出口 `lib/log.ts` 是因为扫描器和解析器跑在定时器里,没有请求
可以借 logger;静默正是 1 得以存在的原因。
|
2026-09-16 14:48:35 +08:00 |
|
cnb.dQC5J6ohAGA
|
2233b295bb
|
feat: 初始化自部署书库服务端
按产品设计 v0.2 落地服务端,覆盖第一版范围中的扫描、元数据、权限与同步。
核心决策:
- 书籍主键用 dc:identifier + 内容哈希,不用文件路径。
重命名/移动不丢进度,副本自动合并,重新编码的文件保持独立。
- 库目录只读挂载,写操作全部落到 DATA_DIR。
启动时断言 DATA_DIR 不在 BOOKS_DIR 内,路径解析统一走 resolveInside
拦截逃逸,扫描不跟随符号链接。
- 元数据优先级:手动修改 > 内嵌 > provider > 文件名解析。
手动修改独立成表,扫描永远碰不到,可单字段撤销。
- 中文文件名解析采取保守策略,无证据时不猜测作者方向。
- 离线合并用 LWW,笔记删除写墓碑,批次单事务。
- 无原生编译依赖:node:sqlite 与 scrypt 均为内置模块。
交付:
- Fastify + TypeScript 服务端,Docker 单容器
- 27 个自动化测试用例全部通过
- AGPL-3.0,README 做到一条命令跑起来
- CNB 流水线:typecheck / test / build
|
2026-09-16 14:07:25 +08:00 |
|