docs: 基本完成初版数据库设计

This commit is contained in:
R524809
2026-10-15 10:09:34 +08:00
parent 63a6993276
commit e6ded00a4c
41 changed files with 2597 additions and 180 deletions
+9 -5
View File
@@ -230,7 +230,7 @@ apps/server/ # 以下路径相对于 doodle-store
1. 小程序调用 `wx.login()` 获取一次性 code。
2. 服务器用配置的 AppID/AppSecret 调用微信 `code2Session`,取得可信 OpenID,UnionID 可为空。
3. 按当前 AppID + OpenID 查找迁入用户,沿用原 `users._id`;确实不存在时才新建。
3. 使用配置的单一小程序 AppID 验证登录,按可信 OpenID 查找迁入用户,沿用原 `users._id`;确实不存在时才新建。
4. 签发有期限的应用登录凭证。首期可用 JWT,建议初始有效期 24 小时;过期后通过微信静默登录续用,暂不增加独立刷新令牌体系。
5. 每次用户请求核对账户有效状态;角色从服务端配置/数据取得。注销立即使旧凭证失效。
@@ -247,7 +247,7 @@ Web 用户不会凭现有小程序 OpenID 自动变成同一账户。跨端身
- 数据库对 `(userId, exportId)` 建唯一键,下载记录和 `worksheets.downloads + 1` 在同一事务内完成。重试只返回已有结果,不再次加数。
- API 上报失败不能把已保存的图片判定为保存失败。新版可用小型本地补报队列重试同一个 exportId;补报不再次递增本地配额或发送 export_success。队列绑定原 userId,换账户不代报,注销时清除。
- 服务端接收的是客户端成功回报,无法独立证明图片已进入手机相册;本次不把该回报设计成支付凭据。
- 收藏唯一键为 `(userId, worksheetId)`;确实新增/删除关系时才更新 likes。重复请求不增减;注销删除收藏时同步处理受影响计数。
- 收藏统一保存功能和内容目标,按资源 ID 是否为空分别去重。只有功能收藏的真实增删才更新 likes;内容收藏不增减功能计数。旧接口限定资源 ID 为 NULL,重复请求不增减;注销清理两种关系但只扣功能贡献。
- 展示计数与真实计数分开:展示可沿用真实值 + `likes_seed`/`downloads_seed`,分析和管理原始查询不加 seed。迁移期间不改变已有推荐的种子参与规则。
- 常规重新发布题型不能将真实计数重置为 0。显式统计修订保留管理员入口,但记录操作者及前后值。
@@ -273,17 +273,19 @@ Web 用户不会凭现有小程序 OpenID 自动变成同一账户。跨端身
| `page_configs` | `page_configs` | `current` ID、JSON 结构、版本、时间保留;所有嵌套文件引用转换 |
| `settings` | `settings` | 包括 `homeAutoRefresh.enabled`,先盘点全部线上配置 |
新增必要辅助表:文件迁移/引用表 `assets`、任务执行记录 `job_runs`、管理审计记录 `admin_audit_logs`。它们用于迁移与运行,不代表已有业务集合。
新增必要辅助表:文件迁移/引用表 `assets`、任务执行记录 `job_runs`、管理审计记录 `admin_audit_logs`。它们用于迁移与运行,不代表已有业务集合。另新增 worksheet_resources 和 worksheet_resource_assets,用于一份内容关联多份线框/参考素材,再新增 worksheet_grades 支持多适用年级,共 13 张表。categories 继续管理内容分类,年级菜单组合查询 worksheet_grades;旧 grade 仅保留兼容,需审核后写入年级映射,不按年龄自动回填。功能与内容分别记录首次发布时间及下载量;新 isNew 按时间派生,功能 isHot 保留为运营推荐,旧累计下载不分摊资源。worksheet 增加生成方式、renderer_key 和共用配置;现有 ID/path/previewImg 保持兼容,下载和收藏增加可空的内容条目 ID;旧收藏保持功能目标,新内容收藏不影响功能 likes。详见 [Worksheet 数据库设计说明](./v3.5/Worksheet数据库设计说明.md)。
主键采用足够长度的字符串,保留大小写语义,不重新生成所有 ID。业务字段用结构化列,tags/页面配置/扩展配置用 JSON;导入前保留完整原始导出,未识别字段进入迁移报告,不能默默丢弃。
主要索引:用户 `(miniAppId, openid)` 唯一;收藏 `(userId, worksheetId)` 唯一及 `(userId, createdAt)`;下载 `(userId, exportId)` 唯一及用户/题型时间索引;题型分类/状态/排序索引。空 exportId 规范为 NULL,历史多条无 ID 下载不得互相冲突。
主要索引:用户 `openid` 唯一(首期仅接入一个小程序,AppID 由服务端配置);收藏以内容 ID 是否为空区分功能/内容,分别采用 `(userId, worksheetId) WHERE worksheetResourceId IS NULL` 与 `(userId, worksheetResourceId) WHERE worksheetResourceId IS NOT NULL` 部分唯一索引,保留 `(userId, createdAt)` 列表索引;下载 `(userId, exportId)` 唯一及用户/题型时间索引;题型分类/状态/排序索引。空 exportId 规范为 NULL,历史多条无 ID 下载不得互相冲突。
资源收藏使用统一 favorites;新增 `PUT/DELETE /me/favorites/resources/:worksheetResourceId`,旧按 worksheetId 的路由及 CloudBase 桥只操作资源 ID 为 NULL 的功能关系。列表/数量显式 target=worksheet/resource/all,默认 worksheet;资源收藏的独立预览及跳转由新版客户端接入。注销删除两种收藏,仅功能收藏扣减 likes。
### 6.2 导入与审计规则
1. 完整分页导出实际集合,记录每个集合总数、主键清单、时间范围和校验摘要;不可只导出首批 100 条。
2. 规范 BSON/JSON 日期为同一 UTC 时间,数据库和 API 时间一致;业务日与任务时区明确使用 Asia/Shanghai。空值与 0 区分,禁止因默认值覆盖已有数据。
3. 先导分类和用户,再导题型、收藏、下载、配置及设置。脚本可重复执行、按主键 upsert,并支持 dryRun;生产切换后不允许再次用旧导出覆盖新写入。
3. 先导分类和用户,再导题型、收藏、下载、配置及设置。题型导入后,根据审核过的 worksheetId → grades 映射写入 worksheet_grades;不从旧 grade 或年龄自动生成适用范围。脚本可重复执行、按主键 upsert,并支持 dryRun;生产切换后不允许再次用旧导出覆盖新写入。
4. 检测重复 OpenID、重复收藏、重复 exportId、失联关联、非法状态/年龄、缺失图片和未知字段。异常输出逐项报告,不以“跳过错误”当成功。
5. 原用户已经注销而留下的收藏/下载记录应隔离归档,不能重建已注销用户。题型缺失时保留历史 worksheetId 和记录,列表 LEFT JOIN 返回空详情,不能整个历史接口报错。
6. 收藏去重、异常隔离等转换明确写进审计报告:原始数 = 正常导入数 + 合并重复数 + 隔离数。不得无说明要求转换后条数与原始条数相同。
@@ -471,3 +473,5 @@ AI 主要承担接口/模型初稿、SQL 转换、数据脚本、小程序调用
- [pnpm 工作区](https://pnpm.io/workspaces):Monorepo、内部包引用及工作区锁文件。
- [pnpm 筛选命令](https://pnpm.io/filtering):按应用、依赖关系执行开发与检查任务。
- `doodle-mini` 仓库依据:`cloudfunctions/*/index.js`、`miniprogram/app.ts`、`utils/auth.ts`、`favorites.ts`、`downloadLogs.ts`、`downloadPrint.ts`、`base/pageMixin.ts`、`pages/profile/profile.ts`、`core/font/*` 及上述管理页面。
资源收藏是新增能力,原 CloudBase 收藏函数不能直接承接。若确需回到旧数据库,应先明确新增内容及收藏关系的存储和旧查询隔离方案并演练,不能把资源收藏压成功能收藏;优先回滚 API 版本并继续使用新主库。