Skip to content

集合:情绪打卡(checkins)

字数
1426 字
阅读时间
7 分钟

1. 目的与使用场景

  • 记录用户每日情绪打卡、任务回执等高敏数据,支撑今天页心情轮、情绪趋势、周报与微建议算法。被今天页、心情随笔清单回执、护心周报云函数使用。

2. Schema 定义

字段类型必填默认值约束/校验说明索引权限
_idstring-TCB 自动主键PKP1
_openidstring-TCB 自动创建者 openidIDXP2
user_idstring-指向 users._id用户指针FKP2
mood_scorenumber-0-100情绪分值IDXP3
mood_tagsarray[]字符串数组场景/人物/地点标签-P3
scene_tagsarray[]字符串数组场景标签-P3
primary_emotionstring-枚举主情绪类别IDXP3
risk_levelstringL1枚举风险等级IDXP3
context_notestring-长度 ≤ 280文本感受摘要-P3
input_typestringmood_card枚举来源入口IDXP2
related_task_idstring-指向 tasks._id关联任务FKP2
energy_levelnumber-0-5能量指数IDXP3
attachmentsarray[]附件数组图片/语音引用-P3
mood_wheel_snapshotobject-心情轮数据心情轮占比-P3
checkin_datedate-ISO 日期打卡日期IDXP2
suggestion_idsarray[]建议ID数组当次建议列表-P2
checkin_countnumber1≥1当日打卡次数-P2
createdAtdate-服务端时间创建时间IDXP1
updatedAtdate-服务端时间更新时间IDXP1
createdBystringminiapp-创建渠道-P1
updatedBystringminiapp-最近更新渠道-P1
is_deletedbooleanfalse-软删标记IDXP2

枚举值

  • primary_emotion: joy(喜悦), calm(平静), anxious(焦虑), low(低落), anger(愤怒), other(其他)
  • risk_level: L1(一般), L2(关注), L3(需要干预), L4(紧急危机)
  • input_type: mood_card(情绪卡片), task_receipt(任务回执), night_mode(晚安模式), manual(手动)

3. 索引与唯一约束

  • 单字段索引:user_idcheckin_daterisk_level
  • 复合索引:[user_id, checkin_date desc][user_id, risk_level, createdAt desc]
  • 唯一性约束:支持同日多次打卡,以[user_id, checkin_date, checkin_count]保证唯一性
  • 设计理由与查询覆盖说明:今天页与趋势图需按用户查询最近记录;周报生成依赖日期倒序读取;风险等级用于预警和干预;支持同日多次打卡记录情绪变化。

4. 访问控制(TCB 权限)

json
{
  "read": "_openid == auth.openid || auth.role in ['counselor']",
  "write": "_openid == auth.openid || auth.role in ['ops','counselor']"
}

角色说明:本人可读写;辅导员可在危机干预时补录;运营仅在授权后可代为编辑。

  1. 关系与级联

引用:

  • user_idusers
  • related_task_idtasks
  • suggestion_idssuggestions

删除策略:

  • 用户注销时软删并脱敏 context_note;相关任务回执保留引用但标记 related_checkin_id=null

反范式字段:

  • mood_wheel_snapshot 存储计算结果以减少前端计算;更新时由云函数刷新。
  1. 数据生命周期与合规
  • 留存时长:保留 3 年供纵向分析,超过时段匿名化(仅留 mood_score/mood_tags 聚合)。
  • 匿名化:脱敏 context_note、移除附件。
  • 用户请求导出时提供加密 CSV;删除时软删并触发清理函数。
  • 审计字段:createdAtupdatedAtcreatedByupdatedByinput_type
  1. API/云函数契约映射 | 接口/函数 | 读/写 | 使用字段 | 过滤条件 | 排序/分页 | 备注 | | /api/moods/today | 读 | mood_score, mood_tags, primary_emotion, checkin_date, mood_wheel_snapshot, risk_level | user_id = auth.uid 当日 | - | 今天页展示 | | /api/moods/trend | 读 | mood_score, mood_tags, checkin_date, risk_level | user_id = auth.uid,时间范围 | checkin_date asc | 趋势图 | | 任务回执云函数 taskReceipt | 写 | mood_score, context_note, related_task_id, input_type | - | - | 来自任务闭环 | | /api/checkins (草案) | 写 | mood_score, mood_tags, scene_tags, energy_level, risk_level | - | - | 直连情绪打卡 | | 风险监测服务 riskMonitor | 读 | mood_score, risk_level, context_note | risk_level in ['L3','L4'] | createdAt desc | 风险预警 |

  2. 示例文档(≥3条)

json
{
  "_id": "ck_20240406_a",
  "_openid": "oAbcd123",
  "user_id": "usr_001",
  "mood_score": 72,
  "primary_emotion": "calm",
  "mood_tags": ["校园", "自习室"],
  "context_note": "专注学习但略累",
  "input_type": "mood_card",
  "checkin_date": "2024-04-06",
  "suggestion_ids": ["sg_001","sg_004"],
  "createdAt": "2024-04-06T09:00:00Z",
  "updatedAt": "2024-04-06T09:00:00Z"
}
{
  "_id": "ck_20240406_b",
  "_openid": "oAbcd456",
  "user_id": "usr_002",
  "mood_score": 45,
  "primary_emotion": "anxious",
  "mood_tags": ["室友", "噪音"],
  "context_note": "室友打游戏有点吵",
  "input_type": "mood_card",
  "energy_level": 2,
  "checkin_date": "2024-04-06",
  "createdAt": "2024-04-06T13:10:00Z",
  "updatedAt": "2024-04-06T13:12:00Z"
}
{
  "_id": "ck_20240407_task",
  "_openid": "oAbcd123",
  "user_id": "usr_001",
  "mood_score": 80,
  "primary_emotion": "joy",
  "context_note": "完成冥想任务感觉放松",
  "input_type": "task_receipt",
  "related_task_id": "task_305",
  "checkin_date": "2024-04-07",
  "createdAt": "2024-04-07T20:05:00Z",
  "updatedAt": "2024-04-07T20:05:00Z"
}
  1. 常用查询样例(≥3条)
javascript
// 近 7 天情绪趋势
const trend = await db.collection('checkins').where({
  user_id: auth.uid,
  checkin_date: db.command.gte('2024-03-31')
}).orderBy('checkin_date', 'asc').get();

// 查找任务回执对应的打卡
const receipt = await db.collection('checkins').where({ related_task_id: taskId }).limit(1).get();

// 辅导员查看近 24 小时情绪分值低于 40 的记录
const alerts = await db.collection('checkins').where({
  mood_score: db.command.lt(40),
  createdAt: db.command.gte(new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString())
}).orderBy('createdAt', 'desc').limit(100).get();
  1. 边界与错误码
  • 重复打卡:同日已有记录时返回 E_DUP_CHECKIN,提示改为更新。
  • 并发更新:采用事务写入,冲突返回 E_CONFLICT 并附带最新版本。
  • 越权:非本人修改返回 E_FORBIDDEN 并记录审计。
  1. 变更影响评估
  • 调整 mood_score 精度需同步埋点事件 mood_checkin_submit 参数。
  • 新增字段需更新周报生成器与数据仓库导出。
  1. 假设与待确认
  • 假设 auth.uid 为 users 集合 _id,由登录云函数写入;待确认 TCB 环境是否启用自定义登录。
  • 待确认情绪附件是否需要单独 COS bucket 分类加密。

贡献者

The avatar of contributor named as Cai Hongyu Cai Hongyu

文件历史

撰写