# 大鲸生活手账：跨设备接手说明

更新：2026-10-30。请先读本说明，再操作实际网站；以当前线上源代码与接口响应为准。

## 入口与边界
- 网站：https://daily.keepplaying.online/
- 本说明：https://daily.keepplaying.online/handoff.html
- 机器可读原文：https://daily.keepplaying.online/handoff.md
- 登录后下载源码及部署脚本：https://daily.keepplaying.online/api/cloud/handoff/source
- Cloudflare Pages 项目：dajing-daily；默认域名 dajing-daily.pages.dev。
- 主站 keepplaying.online 是独立项目 player-log-v1。修改手账时不得改动主站、主站 DNS 或现有数据库绑定。
- 使用 Asia/Shanghai 时区，日期键 YYYY-MM-DD。

## 必须先分清两种权限
1. 读写日程、手账、训练完成记录：使用网站口令登录后的会话即可。口令与 Keep Playing 相同，但不会写在本文、源码包或长期记忆中。
2. 修改网页代码、部署版本：需要 Cloudflare API token 或用户登录 Cloudflare。网站口令不能代替部署授权。

手机、云端聊天不会自动继承另一台电脑的登录态、文件或密钥。没有浏览器/HTTP 工具的会话不能直接操作接口；请用户切换到具备相关能力的 Work/Codex 环境。不要声称仅凭这份说明就已经获得权限。

## 日程与手账 API
前缀 https://daily.keepplaying.online/api/cloud
所有数据接口均需登录 Cookie。修改请求需包含：
- Origin: https://daily.keepplaying.online
- X-Dajing-Request: 1
- JSON 请求另带 Content-Type: application/json
浏览器同源请求自动携带 Origin；不要在前端脚本中手动设置它。跨站浏览器页面不能绕过同源限制。HTTP 客户端应使用 Cookie jar 保存登录返回的 Cookie，不打印会话内容。

- POST /login：{"password":"用户提供的口令"}，保存响应 Cookie。连续错误会限流，不猜口令。
- GET /session：返回 {ok:true/false}。
- GET /state：返回 {revision,data,updatedAt}。
- PUT /state：提交 {revision,data}，是整份文档的条件更新，不是局部 PATCH。
- POST /logout：清除会话。

安全更新步骤：GET 最新 state → 保存私密备份 → 深拷贝完整 data → 只改用户要求的字段 → PUT 原 revision 与完整 data → GET 验证。遇到 409 必须重新读取并重新合并，禁止用旧整份数据强行覆盖。不认识的字段全部保留。

主要数据：
- data.recurring：重复日程，id/title/start/end/days/category；days 使用 JS 星期编号（周日 0）。
- data.customCategories：自定义日程标签名称数组；内置标签包含艺术。保留自定义名称，跨设备新增标签取并集。
- data.oneOffs：临时日程，包含 date；时间可空。
- data.days[日期]：手账、打卡、反馈等。
- priorities：[{text,done}]；completedEvents：{日程id:布尔值}；skippedEvents：仅当天移除的固定日程 id。
- bright/notes：晚间文字；moods：多选心情。
- sport.types / sport.mins：历史命名，目前代表“关照身体”，包括冥想、按摩、艾灸、泡脚、休息等。不能一概当成运动，也不能据此自动增加/减少训练。
- coachLog：sessionKey/completed/feedback/resumeKey 等；没有标记完成就视为未完成。
- healthSupplement：本站补充草稿；healthPending：待重试提交；healthSubmissions：本站提交历史。
不要清空旧 health/healthBase 字段或改写历史数据。

## 健康补充渠道
- GET /health/YYYY-MM-DD：只检查连接，返回 connected，不返回其他渠道的档案内容。
- POST /health/YYYY-MM-DD：{id,notes,exercise,care}，id 为一次提交固定的唯一标识（如 UUID），notes/exercise 为字符串，care 可选。
- 只新增记录；重试使用同一 id。不能修改、删除、按日期覆盖现有 Health OS 记录。
- care 放关照身体记录；exercise 只放实际训练。
- 草稿自动随手账保存，但只有用户点击提交或明确授权提交后，才写健康档案。
- 此接口不接受旧 PUT 更新方式。

## 照片与发布到主站
- GET/PUT /photos/{id}：私有照片，id 只含字母数字下划线横线，最长 100；PUT 支持 JPEG/PNG/WebP，最大 8MB。
- 上传照片不等于自动发布。
- POST https://daily.keepplaying.online/api/keepplaying/logs：需要会话、同源修改请求头，multipart/form-data；photo 1–9 张，总大小 <=30MB，note <=160字，place <=80字，createdAt 毫秒时间戳，latitude/longitude 可选。
- 仅在用户明确要发布记录时执行；重试发布前先确认是否已成功，以免重复。

## 健身协作的真实状态
用户已选定：每次运动前在聊天里说“准备运动了，更新今天的训练”，使用现有 ChatGPT/Codex 订阅额度，不额外接收费 AI API，不开定时任务，不做手机推送。
先读取身体档案、近期完成记录及反馈，询问必要的当日状态，再安排。旧教练资料在聊天《制定健身计划》（ID 6ab7474e-6e9c-83ea-b538-fbaf830b75d5），需授权工具读该会话；不要假装云端自动带有照片或全部聊天记忆。
重要：目前网页展示依赖 index.html 内 coachPlanFor/coachByKey 的规则和模块，尚无“写任意 AI 训练计划”的专用接口。只向 state 塞入未知 plan 字段不会展示，renderCoachDay 还可能重算当天模块。接手者必须先检查并完善计划存储/展示，再声称已将个性化动作同步成功。不能把现有规则描述成每日 AI 复盘。

## 修改网页与部署
登录后下载源码包，解压目录内有 work/site、work/upload.py、work/cf.py、work/hash.cjs、package.json 和私有运维说明。
- index.html：界面和前端逻辑；_worker.js：Cloudflare Pages advanced-mode 后端。
- sw.js：缓存；manifest.webmanifest：桌面图标和 PWA 配置。
- 修改前备份当前部署与源码。源码包是制作时的快照，之后修改需重新生成。
- 保留 Pages 现有 JOURNAL_DB、JOURNAL_PHOTOS、AIRTABLE_TOKEN 绑定/secret，不建立替代空数据库。
- 在包目录执行 npm install（blake3-wasm 用于资源散列），设置环境变量 CLOUDFLARE_ACCOUNT_ID 和 CLOUDFLARE_API_TOKEN，然后执行 node work/hash.cjs、python3 work/upload.py。
- upload.py 使用 Pages 上传 API：获取上传 token、上传静态资源、提交 manifest 与 _worker.bundle，部署分支 main。
- 只向 dajing-daily 部署。不要改主站、DNS、Cloudflare 套餐或新增付费服务。
- 静态资源根目录文件都会上传；不要把任何 token、口令、真实记录、Cookie、个人照片备份放入 work/site。
- 源码包 handoff-source.zip 必须由 _worker.js 的私有下载路由保护；直接静态访问会被拦截。不得移除该防护。
- 修改后检查语法、相关行为和手机/电脑布局，确认 Cloudflare deploy success、HTTPS 200、实际资源更新。更新 sw.js 缓存版本以便客户端刷新。
- 更新接手说明与源码包时，以同次部署的新文件重打包，排除源码包自身，避免无限嵌套。

## 跨设备记忆
本文件不包含凭证，也不能把当前应用的长期记忆自动同步给所有独立聊天。把本链接加入你的 ChatGPT 项目资料或自定义指令，或在新会话发：“请先读取 https://daily.keepplaying.online/handoff.md，按说明接手我的生活手账”。
