# 晨风书屋工作记录

> 更新日期：2026-07-12
> 本文记录可复核的工程、数据和发布事实，不记录任何 Secret 值。

## 1. 项目沿革

### 2026-05-25 至 2026-06-02：P22 本地版本

- 建立 15 列书架、CLC 分类、ISBN 查询、搜索、统计、重排和封面功能。
- 数据最初保存在 IndexedDB，DeepSeek Key 曾由浏览器本地管理。
- V1.12.6 稳定两步比例分配，V1.12.15 修复 OpenLibrary 占位图。
- 这些机制只保留为历史，不再作为当前架构和安全方案。

### 2026-06-28：V2 云端迁移

- 书目从 IndexedDB 迁到服务器 SQLite。
- 新增 Flask REST API、访客只读与管理员管理模式。
- 管理员会话改用当前标签页保存，但早期版本的密码仍缺少服务端有效校验。

### 2026-06-30：并入 P09

- 原 `P22_HomeLibrary` 源码、API 和资料合并到 `P09_PersonalWebsite`。
- P09 成为唯一源码源，旧 P22 不再维护。
- 发布统一纳入 `sync-website.sh`。

## 2. 2026-07-12 数据治理与功能迭代

### V2.1.0：旧备份兼容和导入保护

- 兼容 V1 CSV、V2 JSON 和常见 IndexedDB 包装备份。
- 对桌面旧名备份 `晨风书舍_2026-07-12.csv` 做本地全量预检。
- 文件 SHA-256：`ee28b121e8166b52be9d2ad44fbe14a140b935744d5d9d9ae2a156cf6dec4a36`。
- 记录 912 条，位置有效，无重复位置；861 条含 ISBN，同 ISBN 多册按真实数据保留。
- 导入改为前端预检、服务器复检、SQLite 快照和单事务替换。
- 新增 `sync-website.sh --library-only`，限制发布范围并排除正式数据库。

### V2.2.0：手机录入、主题和分类代理

- 增加手机摄像头 EAN-13 扫描，扫码后必须人工确认。
- 手机浏览器支持管理员登录、录入、编辑、导入导出和统计。
- 增加深浅双主题与浏览器主题偏好。
- 增加书架位置唯一索引、冲突错误码和重排两阶段事务。
- DeepSeek Key 从浏览器迁到服务器独立 Secret，分类接口只返回建议。
- 管理员密码与 DeepSeek Key 分离，不进入 Git、网站、SQLite、导出、日志或备份。

### V2.2.1：认证与生产数据保护

- 修复任意密码都能打开管理界面的问题，先调用服务器 `/auth/verify`。
- 错误密码返回 401；刷新时重新验证当前标签页会话。
- API 统一禁用缓存，页面刷新重新读取服务器最新数据。
- 发布前后检查 SQLite 完整性和记录数基线，正式数据库不在发布白名单内。
- 修正深浅主题文字对比度、footer 名称和顶部服务器状态表达。

### V2.3.0：封面、标签和条件备份

- 修复“补封面”仅当前页面显示、刷新后丢失的问题。
- 增加封面专用批量事务接口，只更新 `cover`。
- 封面查询改为服务器豆瓣元数据优先、OpenLibrary 回退。
- “修正”每轮最多 10 本，成功项记录 `corrected=true`。
- L9 标签迁移到服务器 `settings` 表，并纳入导出和备份。
- 增加每天 22:00 的逻辑指纹检查，仅数据变化时创建备份。

相关提交：

| 提交 | 内容 |
|:---|:---|
| `e232b19` | 手机扫码与数据保护 |
| `2fb5a0b` | DeepSeek 服务器代理 |
| `720b3f1` | 管理员认证与服务器数据保护 |
| `a8d8bf0` | 动态提示与 footer 位置修复 |
| `4929673` | 管理员 Secret 一次性安装 |
| `f8fbc1c` | 封面、标签持久化和条件备份 |
| `f02f88b` | 条件备份脚本与 cron 所有权门禁 |
| `8f06295` | 发布所有权检查引号修复 |

## 3. 正式环境基线

2026-07-12 V2.3.0 功能发布完成后的已知状态：

```text
URL: https://chenningbo.com/library/
主站版本: v1.7.1
晨风书屋版本: V2.3.0
发布标识: v1.7.1_20260712_172631
Git HEAD: 8f06295
```

数据库检查：

```text
数据库: /var/www/data/home_library.db
integrity: ok
total: 912
distinct_ids: 912
duplicate_positions: 0
blank_titles: 0
with_isbn: 861
covers: 0
corrected: 0
settings_table: 1
```

`covers=0` 与 `corrected=0` 表示功能已验证但未擅自对 861 本书执行大规模补封面或分类改写。后续批量操作仍应由管理员明确触发并观察外部来源质量。

## 4. 不可变数据基线

导入后的 912 本数据已固化：

```text
/root/backups/chenningbo/baselines/
library_baseline_20260712_165605_912books_v1.6.2.tar.gz
SHA-256: 99e3c5920f55ba0eab1422904ca5457cb097e71c88bb92c89e43f2d106f7f8a1
immutable: yes
secret_entries: 0
```

该基线是恢复依据，不是日常写入数据库。日常数据继续在正式 SQLite 中实时更新。

## 5. 条件备份上线记录

```text
脚本: /root/backup-library-if-changed.sh
cron: /etc/cron.d/chenningbo-library-backup
时间: 每天 22:00
脚本权限: root:root 0755
cron 权限: root:root 0644
```

首份条件备份：

```text
/root/backups/chenningbo/library-daily/
home_library_20260712_172406_346731606_912books.tar.gz
SHA-256: 2bf861bc0fb3bb6d562d1499f0029a24ee71b0f4ede9dd596d4ad8d38d72aba7
```

验证结果：首次 `CREATED`，第二次无变化 `SKIPPED unchanged`；解压后 SQLite 完整性为 `ok`，记录 912，`settings` 表存在，归档不含 Secret。

## 6. 测试记录

本地自动化：

```text
Flask API: 14/14
Playwright: 6/6
旧备份兼容: 通过
条件备份创建/跳过/恢复: 通过
Python 编译: 通过
Shell 语法: 通过
git diff --check: 通过
```

外部来源抽测：

- 20 个现有 ISBN 样本中，豆瓣封面元数据命中 19 个。
- OpenLibrary 单独命中 3 个，用于回退覆盖。
- 生产封面查询受保护接口返回 HTTP 200。
- 国图分类接口生产抽测 1 本返回 HTTP 200 与有效 CLC。

公网浏览器：

```text
Desktop: 1440 x 900
Mobile: 390 x 844
页面总数: 912
footer: v2.3.0
服务器状态: 正常
控制台错误: 0
失败请求: 0
```

实体手机摄像头、真实扫描枪、连续扫描、多设备并发和 DeepSeek 代表性分类质量仍需按 `TEST_REPORT.md` 的实体设备清单持续验证。

## 7. 2026-07-12 文档治理

- 在编辑前创建完整 Git bundle：`backup_20260712_173154_pre_library_work_record.bundle`。
- bundle SHA-256：`020206df74b2f240af812a814d217c20eba1f90672fe83f3a3a4da0008017ca5`。
- bundle 可恢复到 `8f06295`，`git bundle verify` 确认为完整历史。
- 新建需求、现行方案、代码架构、API、版本管理、工作记录和遗留路线图。
- 将旧 P22 书架规则和版本里程碑归并到当前文档与 CHANGELOG。
- 删除会把 IndexedDB、本地 Key、旧云备份误解为现行架构的过期资料。
- 文档清理严格限定在晨风书屋资料；不修改其他模块内容。

## 8. 接手检查清单

1. 确认 Git 分支、工作区和本地/服务器版本。
2. 阅读本目录 README 所列的需求、架构、数据、发布、测试和遗留问题。
3. 不读取 Secret 内容，只验证服务配置存在与权限是否符合门禁。
4. 功能修改前创建本地备份；发布前由脚本创建服务器恢复点。
5. 写入型测试只用临时 SQLite，禁止以生产库作为自动化测试数据库。
6. 只使用 `sync-website.sh --library-only`，发布后检查数量不能减少。
