Files
ctms/docs/project-notifications.md
Cheng Zhou 3e77127687
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
功能(提醒):统一项目提醒中心与桌面通知链路
增加通用提醒状态、数据库迁移和定时同步,覆盖风险时效、文件回执、项目里程碑、访视窗口与协作申请。

新增网页端和桌面端提醒中心、真实投递诊断与固定隐私通知正文,并补齐登录来源聚合、测试和说明文档。
2026-07-16 16:50:34 +08:00

73 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目提醒中心
## 产品边界
项目提醒是既有业务状态面向明确收件人的可操作投影,不是独立任务、日历或聊天系统。源业务记录和业务审计始终是权威数据;提醒的阅读、桌面投递均不能替代 AE 上报、问题关闭、文件回执、审批或其他业务动作。
当前范围只包括已认证在线客户端:
- 网页端和桌面端共用当前项目的通用提醒 Feed。
- 顶栏铃铛展示摘要,`/project/notifications` 提供当前提醒、未读和待处理筛选。已经解决或因权限变化失效的提醒不再向客户端返回。
- 桌面系统通知是用户主动开启的可选投递渠道,只显示不含项目、文件、受试者或风险详情的通用文案。
- 不提供离线提醒、本地业务权威数据、个人自由定时任务、短信、即时通讯或浏览器 Push。
- 管理员权限监控告警、登录会话提醒和客户端更新“稍后提醒”不进入业务提醒中心。
## 状态模型
`notifications` 是收件人级通用提醒表:
- `read_at`:用户已经看过提醒。
- `resolved_at`:源业务已经完成、关闭、失效,或一次性信息通知已经被阅读。
- `requires_action`:区分业务待办和一次性信息通知。
- `due_at`:用于展示业务截止时间;业务规则仍以源记录为准。
- `source_type``source_id``source_version``dedupe_key`:用于来源追踪、幂等同步、阶段升级和自动关闭。
阅读待处理提醒不会写入 `resolved_at`。业务动作完成后由对应服务即时关闭提醒,定时同步还会对遗漏或权限变化进行对账。一次性信息通知在首次阅读时归档。
桌面投递状态继续保存在 `desktop_notification_deliveries`,但通过 `notification_id` 关联通用提醒。投递成功只记录 `delivered_at`,不自动标记业务提醒已读或已处理;提醒升级或重新打开时可以重新进入桌面投递队列。
桌面客户端每 60 秒执行一次在线投递检查:先确认本机系统权限,再读取当前账号的服务端订阅,随后领取待投递提醒、调用系统通知并确认实际成功投递的提醒。任一系统通知调用失败时不会确认该条提醒;网络或投递失败采用指数退避,最长 15 分钟。用户可在“设置 → 通知”查看本次客户端运行期间的最近检查、最近投递和当前链路状态,并主动执行一次真实业务提醒检查。
## 当前规则
| 来源 | 收件人 | 触发和升级 | 自动关闭 |
|---|---|---|---|
| 协作编辑申请 | 文件所有者、文件管理者 | 申请创建 | 申请批准或拒绝 |
| 协作申请结果 | 申请人 | 申请批准或拒绝 | 申请人阅读后归档 |
| 文件分发与回执 | 指定用户、指定角色、中心联系人 | 新分发;3 天内到期;逾期 | 用户完成接收回执、分发关闭或权限失效 |
| AE 上报时效 | 具备 AE 读取权限且在中心范围内的项目成员 | 3 天内到期;逾期;按数量增加重新提醒 | 数量归零或权限失效 |
| 监查问题整改 | 具备监查问题读取权限且在中心范围内的项目成员 | 3 天内到期;逾期;按数量增加重新提醒 | 数量归零或权限失效 |
| 项目里程碑 | 里程碑负责人 | 7 天内到期;逾期;日期或状态变化重新提醒 | 完成、负责人变化或日期移出提醒窗口 |
| 受试者访视窗口 | 具备访视更新权限的有效项目成员;CRA 仅限负责中心 | 窗口开始前 3 天、窗口进行中;错过窗口后升级 | 录入实际访视、取消访视、受试者结束、中心停用或权限/中心范围失效 |
所有规则都要求当前有效项目成员和对应业务权限。系统管理员不会仅因平台权限而批量接收所有项目提醒;需要作为有效项目成员或明确业务收件人进入提醒范围。
日期型 AE、里程碑和访视窗口规则按 `Asia/Shanghai` 业务日计算,带时区的截止时间统一按 UTC 存储和比较。若未来引入项目级时区,应由项目配置替代固定业务时区,不能使用浏览器本地时区驱动服务端规则。
访视提醒按访视记录生成并可跳转到对应受试者详情,但提醒标题和正文不包含受试者编号、姓名、中心名称或其他可识别信息。收件人资格以 `visits:update` 及其前置权限为准,避免仅具备只读权限的 PV、QA、CTA 等角色被动接收受试者访视提醒。
## 同步与诊断
服务端启动提醒同步任务,默认每 300 秒对所有有效项目成员执行幂等同步;间隔通过 `NOTIFICATION_SYNC_INTERVAL_SECONDS` 配置,允许 603600 秒。PostgreSQL advisory lock 防止多个后端进程重复执行全量任务。
用户读取 Feed 时还会执行一次当前用户轻量对账,用于弥补短时任务失败。单个成员同步失败不会中断其他成员;失败写入 `ctms.notifications` 日志。提醒创建、更新和自动关闭本身不替代源业务审计。
## 桌面隐私边界
系统通知固定为:
- 标题:`CTMS 待办提醒`
- 正文:`有新的业务提醒待查看`
系统通知 API 不接受动态标题或正文。项目名、文件名、版本、受试者、AE、监查问题等详情只允许在完成 token 校验和项目权限确认后的应用内 Feed 中展示;访视提醒即使在应用内 Feed 也不直接显示受试者标识,只通过受控详情路径访问。
## 系统通知授权边界
系统权限和服务端订阅是两个独立条件:
- 首次开启时,客户端先请求操作系统授权;只有操作系统返回已授权,才开启当前账号的服务端订阅。
- 用户在操作系统中撤销权限后,服务端订阅可以仍然保持开启,但客户端不会领取提醒,设置页会明确显示“系统权限已拒绝”。
- macOS 或 Windows 已拒绝权限时,系统通常不会再次展示授权框。设置页分别引导用户前往“系统设置 → 通知 → CTMS”或“设置 → 系统 → 通知 → CTMS”,返回后通过“重新检测权限”恢复链路。
- “发送测试通知”只验证本机通知能力,不访问业务提醒队列;“立即检查业务提醒”会走服务端订阅、领取、系统投递和确认的真实路径。
- CTMS 不申请打开任意 URL、执行系统命令或读取操作系统通知内容的额外 Tauri 权限。授权引导仅展示设置路径,避免为便利入口扩大桌面原生能力边界。