← [ BACK_TO_NOTES ]

MemoFlow · Reminder / Routine 开发笔记

按版本记录循环提醒、Profile 场景、Protocol 与 Scheduler 协作的设计。

#blog #growing #dev

Reminder 模块目标

我想要一个专门管理日常行为提醒的模块,例如喝水、站起来活动、休息眼睛和定时吃饭。它和 Task 不一样:用户不需要每次都背负“必须勾选完成”的任务负担,提醒的重点是帮助形成日常习惯。

V1.0.0

第一版采用 ReminderTemplate + ReminderGroup。每个模板保存提醒内容和重复时间;Group 则把多个提醒组合成一个生活场景。

例如工作时启用“喝水、活动、休息眼睛”,玩游戏时启用另一组提醒。组要能统一开启和暂停,但有时也希望某个成员独立控制,所以先考虑两种启用模式:

  • Group 模式: 成员跟随组的开关。
  • Individual 模式: 成员使用自己的开关。

还想加一个总开关,避免用户休息时必须逐个关闭所有提醒。这里的难点是有效启用状态与用户手动设置的状态不同,不能只用一个布尔值覆盖全部信息。

v1.1.0

现在需要把分组和单个提醒的操作接到 Vue 界面上。Reminder Card 从 Store 获取数据,用户修改启用状态后,卡片应该马上显示正确值。

遇到的问题是:组件如果一直持有旧的 Group 对象,IPC 更新 Store 后,显示值可能没有同步。可以选择只传 Group ID,再从 Store 查最新对象;或者保留对象作为输入,但实际显示始终从 Store 的权威状态派生。

这也提醒我,不能让组件自己保存另一份“是否启用”的结果。组开关、成员开关和临时暂停是不同来源的事实,页面只计算当前有效状态。

V2.0.0

希望把 Reminder 从简单的循环提醒扩展为更完整的 Routine Coach。

原来一个 ReminderGroup 既负责分类、批量启停,又影响每个成员的长期配置,职责有些混合。现在把它们拆成:

  • RoutineDefinition: 一项提醒或习惯的长期配置,例如“每 30 分钟站起来”。
  • RoutineProfile + ProfileMembership: “工作”“游戏”等场景及成员关系;Profile 影响成员是否可以生效,但不接管 Definition 本身。
  • TemporaryOverride: 临时暂停、稍后提醒或短期修改间隔,过期后恢复长期规则。

这样用户切换 Profile 时,不用把每个 Routine 的原始启用状态改来改去。一个 Routine 还可以属于多个 Profile,场景门控与自身配置分开处理。

v2.1.0

不是所有习惯都适合写成一个 Cron 或间隔数字。现在将触发方式分开考虑:

  • WallClock: 每天固定时间或按墙上时钟计算的间隔;需要可靠的后台调度。
  • ActiveUsage: 只有用户真实使用设备达到一定时长才提醒;必须依赖 Desktop 的设备活动能力,不能在 Web 上假装可以获取相同数据。
  • ProtocolSession: 如 50/10 或 Pomodoro,有工作、休息和暂停等连续阶段,应该是一个明确的状态机,而不是两个互不关联的定时器。

这版先把长期规则、设备能力和连续会话分开,让无法支持的端明确提示能力限制。

V3.0.0

Routine 本身应该拥有“什么时候该提醒、这次是否发生过”的业务事实,但不需要再次维护一个独立的定时器引擎。

WallClock 的实际唤醒交给统一 Scheduler;Routine 更新配置、Profile 或临时 Override 时,使用 SchedulingPort.reconcile 重新同步调度意图。Scheduler 管唤醒、重试与租约,Notification 负责把结果送给用户。

这样停用一个 Routine 的正确动作,是修改 Routine 的权威状态并更新调度投影,而不是在界面里直接删除某条 Worker Job。也需要区分Routine 已触发、调度执行完成和桌面通知已展示,它们并非同一件事。

创建于 2026/3/5 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本