Skip to content

✨ feat(timing): 实现提醒触发查询 - #178

Open
jing-gou wants to merge 7 commits into
1024XEngineer:mainfrom
jing-gou:dev/144-list-reminder-triggers
Open

✨ feat(timing): 实现提醒触发查询#178
jing-gou wants to merge 7 commits into
1024XEngineer:mainfrom
jing-gou:dev/144-list-reminder-triggers

Conversation

@jing-gou

@jing-gou jing-gou commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

结论

完成 #144TimingTaskService::ListReminderTriggers:支持任务、实例、日程、类型、状态和实际触发时间的组合查询,并返回稳定排序的分页结果。

本 PR 依赖开放 PR #171#143)。由于 GitHub 不允许把个人 fork 的 #171 分支作为本 PR 的 base,当前 diff 会包含其依赖提交;请先审 #171,再审本 PR 最后的提交 4cd7fe9

背景

父 Issue #137 要求逐个完成 TimingTask 的公开 Service,同时维持 Domain、Application 与 Port/Adapter 边界。本切片只读取已物化的提醒触发。

改动范围

  • 新增 ListTriggersFindInstance 最小 Store Port,并提供内存 fake。
  • 实现参数与资源校验、左闭右开时间过滤、组合过滤、稳定排序、分页、totalhas_more
  • 增加弱/强类型、全部触发状态、空结果、错误透传和分页的 Host 测试。
  • 未实现触发生成、消息投递、outbox 重试、SQLite/NVS Adapter 或索引优化。

接口与依赖影响

TimingTaskStorePort 增加两个只读方法;后续真实 Adapter 需实现相同行为合同。未新增跨组件依赖,未变更 Profile、协议或持久化格式。

TDD 与验证

  • RED:范围查询测试在原 kUnavailable 占位实现上失败。
  • GREEN:最小 Port、内存 fake 和查询实现使测试通过。
  • REFACTOR:查询隔离到独立翻译单元,公开 DTO 注释明确时间语义。
  • 本地 ./scripts/run_pre_submit_checks.sh 已通过:C++ Host 22/22、架构/Profile/Python 检查、IM Gateway 126/126。

已知风险、兼容与回退

生产 SQLite/NVS Adapter 尚未实现,当前证据仅覆盖 Host 内存 fake。该 PR 依赖 #171 先合入;其合入后应以最新 main 重新基线。回退方式为回退本 PR 的单个提交 4cd7fe9,即可恢复原有 kUnavailable 占位实现。

Refs #144
Refs #137
Refs #171

为提醒规则管理提供原子批量写入,避免逐条保存造成部分更新。

服务校验 weak/strong snooze、日程归属和准点 strong 唯一性;内存 fake 与主机测试覆盖成功、冲突和写入失败路径。

Host、架构、Profile、Python 检查及 Node 24 Gateway CI 已通过;本机缺少 GNU GCC,gcov 覆盖率由 CI 确认。

Closes 1024XEngineer#141
服务层基于旧快照校验后写入时,多个并发请求可能绕过准点强提醒唯一性。

Store Port 现在要求在同一原子写入边界复核该不变量;内存 fake 和 Store 合同测试覆盖第二个 writer 被拒绝的场景。

./scripts/run_checks.sh 已通过。

Refs 1024XEngineer#141
实现左闭右开时间范围内的用户可见 occurrence 查询,支持日程和状态过滤、排序与分页。通过 Store Port 查询任务和已物化实例,并在不引入 RFC 5545/IANA tzdb 的前提下展开基础周期规则,使用 modified/completed/skipped 例外覆盖基础 occurrence。

RED:ListCalendarView 合法范围测试在原 kUnavailable stub 上失败。GREEN:补充最小查询 Port 和内存 fake 后通过一次性、周期展开、例外覆盖、过滤分页及非法输入测试。REFACTOR:将查询实现独立到日历翻译单元。

Refs 1024XEngineer#143
…ar-view

# Conflicts:
#	tests/host/timing_task_service_test.cc
补充周、月、年周期展开,Store 查询失败、分页参数和过滤分支的公开 Service 测试,满足 C++ patch 覆盖率门禁。

Refs 1024XEngineer#143
周期规则使用 UTC 民用日期展开;对其他时区返回明确的不可用错误,避免静默产生错误的星期、月日和年月日匹配。补充 Host 失败路径测试。\n\nRefs 1024XEngineer#143
按任务、实例、日程、类型、状态和实际触发时间范围查询已物化提醒触发,支持稳定排序和分页。Store Port 增加只读触发和实例查询,未引入触发生成、消息投递或生产数据库实现。

RED:公开 Service 查询测试在 kUnavailable 占位实现上失败。GREEN:补齐最小查询 Port、内存 fake 和组合过滤实现。REFACTOR:将查询隔离为独立翻译单元并明确契约时间语义。

已通过完整提交前门禁;真实 SQLite Adapter 仍属后续范围。

Refs 1024XEngineer#144
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

@jing-gou

jing-gou commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Reference review: Codecov report

结论:不需要为该报告追加修复。

因此该 Codecov 评论提供的是可见性信息,不构成超出 #144 验收的补测理由;不新增代码或提交。

@jing-gou

jing-gou commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

@fennoai 你是资深后端/全栈架构师 + 嵌入式硬件工程师复合型专家,执行严格、客观、不留情面的代码仓库Review,请遵循下面所有评审规则,逐条输出审查结果,禁止敷衍、禁止只说空话、禁止笼统概括。
硬性约束:最终输出评审条目数量不少于20条,若直观可见问题不足,主动挖掘隐性架构隐患、软硬件兼容风险、长期运行潜在缺陷补足条目,不得简化评审内容。

评审维度

  1. 架构与模块设计
  • 模块职责是否清晰,是否存在循环依赖、职责混杂
  • 分层是否合理,是否违反单一职责原则、开闭原则
  • 接口抽象、依赖注入设计是否规范,有无硬编码耦合
  • 软件与硬件模块边界是否清晰,硬件相关逻辑是否侵入业务层
  1. 代码规范与可读性
  • 命名:变量、函数、类、文件命名是否语义清晰,禁止模糊命名、拼音命名
  • 注释:复杂逻辑、硬件时序、特殊寄存器配置必须注释;冗余注释、无效注释、过期注释需要指出
  • 代码格式、风格是否统一,是否存在大量魔法数字、魔法字符串,硬件参数无常量定义
  1. 性能隐患
  • 循环内IO、数据库重复查询、不必要的内存占用、低效算法
  • 资源是否释放(连接、句柄、定时器、文件流、硬件外设句柄)
  • 嵌入式场景:阻塞轮询、中断处理耗时过长、内存频繁分配释放
  1. 安全性检查【重点】
  • 输入校验、SQL注入、XSS、权限控制、敏感信息明文打印
  • 密钥、token、数据库地址、硬件访问口令是否硬编码提交到仓库
  • 外部指令下发至硬件驱动缺少权限校验,存在设备失控风险
  1. 健壮性 & 异常处理
  • 是否缺少异常捕获、错误分支处理
  • 参数判空、边界条件、失败重试逻辑是否完备
  • 硬件通讯异常(I2C/SPI/UART断线、设备无应答)缺少容错、恢复逻辑
  • 缺少硬件故障状态上报、故障隔离机制
  1. 硬件驱动 & 软硬件协同评审(新增专项)
  • 驱动代码与硬件原理图引脚定义是否匹配,无硬件版本兼容逻辑
  • 外设操作缺少电平保护、超时判断,存在烧毁外设芯片风险
  • 运动控制逻辑(如有)缺少软限位、急停、碰撞检测保护
  • 上下位机通讯协议:缺少校验和、重传、断线重连机制
  • 硬件参数(电流、电压、速度阈值)直接写死代码,无统一配置入口
  1. 测试覆盖
  • 是否缺少单元测试、边界用例
  • 核心业务逻辑、硬件驱动逻辑无测试直接合并风险
  • 缺少硬件异常工况、极限压力场景测试用例
  1. 工程规范
  • 无用代码、注释掉的废弃代码是否大量遗留
  • 依赖包版本风险、冗余依赖、存在已知漏洞依赖
  • 配置区分环境(开发/样机/生产),环境配置是否混写
  • 固件、上位机、3D模型、原理图版本号不统一,无关联管理
  1. 可维护性 & 扩展性
  • 新增需求是否需要大面积修改原有代码
  • 是否存在大量重复代码,缺少公共封装
  • 硬件型号迭代时,软件需要大规模改动,缺少适配抽象层

输出要求

  1. 问题分级:🔴严重阻塞(必须修改才能合并/上机测试) / 🟡建议优化(不阻塞但强烈建议重构) / 🟢可选改进
  2. 每条问题固定格式:【文件路径+代码位置】问题描述 + 风险说明 + 可直接落地的修改方案
  3. 条目数量强制≥20条;问题较少时区分表层问题与隐性长期风险,拆分为独立条目逐条列出,禁止多条问题合并为一条
  4. 最后汇总三部分:
    ① 整体仓库风险总结
    ② 优先级整改清单(阻断项优先)
    ③ 长期架构、软硬件协同优化方案
  5. 如果存在架构层面缺陷,单独提炼顶层设计问题,不要只局限单行代码
  6. 不要美化结论,发现隐患直接指出,客观评估风险等级;不使用“建议考虑”这类温和模糊表述,明确写出故障后果(程序崩溃、硬件烧毁、机构失控、数据泄露等)

现在开始对提供的仓库代码/PR变更、硬件资料、结构模型进行评审

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two calendar-view regressions stand out: one-off tasks now depend on instance storage, and persisted instances are surfaced as exceptions unconditionally.

return Result<CalendarView>::Failure(ErrorCode::kUnavailable, "周期日历展开暂仅支持 UTC 时区");
}

const auto instances = store_.ListInstances(task.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fetch runs for every active task before you know whether the task is recurring. For one-off tasks, ListInstances is unused, so a transient instance-store failure now aborts the whole calendar read even though the task could still be rendered from task.start_at alone.

.actual_trigger_at = instance.actual_trigger_at,
.status = instance.status,
.is_recurring = task.recurrence.frequency != RecurrenceFrequency::kNone,
.is_exception = true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every persisted instance is marked as is_exception=true, even when it has no override fields. That makes normal materialized occurrences indistinguishable from real exceptions in the calendar response.

@fennoai

fennoai Bot commented Aug 6, 2026

Copy link
Copy Markdown

严格 Review 结果

结论:不建议直接合并到生产路径。Host 测试能通过,但当前 Store Port 和 Service 实现把查询下推、分页、权限/可见性、边界值语义都留给未来适配器或调用方,嵌入式长期运行风险明显。本次未发现 PR 中包含硬件资料、结构模型、原理图或驱动改动,因此引脚、电平、电流、电机限位等硬件项无法实物级核验。

问题清单

  1. 🔴严重阻塞【components/voicelife_timing/include/voicelife/timing/timing_task_store.h:63】ListTriggers() 只暴露“返回全部未删除触发”的接口。风险:真实 SQLite/NVS/Flash 适配器只能全表扫描再把所有记录搬到 RAM,提醒历史增长后会导致查询卡死、看门狗复位或内存耗尽。修改方案:把 ReminderTriggerQuerylimitoffset/cursor、排序字段下推到 Store Port,返回已过滤分页结果和 total/has_more
  2. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:69】Service 每次先 store_.ListTriggers() 再分页。风险:page_size <= 100 不能限制读取量,恶意或异常查询仍读取全量数据,形成嵌入式设备上的本地 DoS。修改方案:删除服务层全量读取,改为 store_.ListReminderTriggers(query),由数据库索引执行过滤和分页。
  3. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:55】按 schedule_id 查询先 ListTasks() 全量扫描任务。风险:任务数增加后一次日程查询退化为任务全表扫描 + 触发全表扫描;Flash/SQLite 上会放大 IO 和功耗。修改方案:新增 FindTaskIdsByScheduleId(schedule_id) 或让触发表冗余 schedule_id 并建立索引。
  4. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:87】所有匹配结果都进入 std::sort 后才分页。风险:大结果集 O(n log n) 排序和二次拷贝会阻塞主循环/业务线程。修改方案:排序下推到持久化层;内存 fake 可只模拟合同,不应决定生产合同。
  5. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:96】result.size() 强转为 int。风险:历史触发超过 INT_MAXtotal 溢出为负数或错误值,分页边界随后失真。修改方案:将分页 total/page/page_size 改为 int64_t/size_t,并在适配器层限制最大可报告值。
  6. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:97】没有限制 page 上限。风险:超大页码仍触发全量扫描排序,接口可被低成本调用拖垮。修改方案:定义最大页码或改为 cursor/keyset pagination,超过上限直接 kInvalidArgument
  7. 🔴严重阻塞【components/voicelife_timing/include/voicelife/timing/timing_task_contracts.h:167】使用 0 作为未提供时间范围的哨兵。风险:Unix 时间戳 0 是合法边界,无法表达 [0, x) 或跨 epoch 查询;序列化调用方也无法区分“未传”和“传 0”。修改方案:把 range_start/range_end 改为 std::optional<int64_t> 或增加显式 has_range
  8. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:16】TriggerSortBy 非法枚举值落入默认实际触发时间排序。风险:外部反序列化传入未知枚举时不会报错,调用方得到错误排序且难以发现协议兼容问题。修改方案:新增 IsKnownTriggerSortBy/IsKnownSortOrder 校验,未知枚举返回 kInvalidArgument
  9. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:91】SortOrder 只判断是否等于 ascending,其他非法值全部按 descending 处理。风险:协议污染或内存错误会静默改变结果顺序。修改方案:显式 switch 校验 kAscending/kDescending,默认分支返回参数错误。
  10. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:40】按 task_id 只校验任务存在,不校验 status/deleted_at。风险:已终止或软删除任务的提醒触发仍可能被查询返回,造成历史数据误展示或越权可见。修改方案:读取任务后拒绝 deleted_at != 0,并明确 terminated 任务是否可查;若不可查则过滤或返回 kNotFound
  11. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:59】schedule_id 关联任务集合没有过滤任务生命周期。风险:已删除/终止任务仍被加入 schedule_task_ids,随后其触发可被日程查询返回。修改方案:只加入 active 且未删除任务,或在 Store 查询中统一执行可见性条件。
  12. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:46】同时传 task_idinstance_id 时只分别存在性校验,不校验实例是否属于该任务。风险:资源组合错误被伪装成空结果,调用方无法区分参数冲突和无触发记录,后续权限判断也容易接错。修改方案:FindInstance 成功后校验 instance.task_id == query.task_id,不匹配返回 kConflict
  13. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:54】同时传 schedule_idtask_id 时不校验任务是否属于该日程。风险:跨日程参数错误返回空页,API 语义与“资源校验”描述不一致。修改方案:已有 task 时直接比对 task.schedule_id,不匹配返回 kConflict
  14. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:54】同时传 schedule_idinstance_id 时不校验实例所属任务是否归属该日程。风险:跨资源查询可能掩盖调用方 bug,也给后续多租户/权限控制留下漏洞。修改方案:通过实例的 task_id 查任务并校验 schedule_id,或下推到带 join 的 Store 查询。
  15. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:64】不存在的 schedule_id 返回 kNotFound,而 ListCalendarView 对不存在日程返回空结果。风险:同一模块两个 list API 语义冲突,前端/上位机适配会出现分支不一致。修改方案:统一 list 查询语义;若日程服务无法验证日程存在,则不存在关联任务应返回空页。
  16. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:100】返回完整 ReminderTrigger,其中包含 payload。风险:payload 可能承载语音文本、用户内容或下游指令,缺少脱敏/投影会造成敏感信息泄露。修改方案:为列表接口定义轻量 DTO,默认不返回 payload;需要详情时走带权限校验的单条查询。
  17. 🟡建议优化【components/voicelife_timing/include/voicelife/timing/timing_task_store.h:60】“可见/未删除”的 Store 合同只约束触发记录,未定义任务、实例、租户、用户或日程可见性。风险:不同适配器会实现出不同结果,安全边界无法审计。修改方案:把可见性条件写成可测试合同:触发未删除、所属实例未删除、所属任务未删除、租户/用户匹配。
  18. 🟡建议优化【tests/host/support/timing_fakes.h:140】测试 fake 的 AddTrigger 不检查 task_id/instance_id/reminder_rule_id 是否存在。风险:测试可构造生产中不应存在的孤儿触发,导致服务逻辑缺少外键/关系异常覆盖。修改方案:fake 增加严格模式,默认拒绝孤儿触发;确需构造脏数据时使用显式 AddCorruptTriggerForTest
  19. 🟡建议优化【tests/host/support/timing_fakes.h:121】fake 的 ListTriggers 只按 deleted_at 过滤,不模拟真实索引、分页和故障场景。风险:当前测试证明不了真实适配器的查询合同、索引使用和边界性能。修改方案:增加 Store contract 测试,覆盖组合过滤、排序、分页、删除级联、错误透传和大数据分页。
  20. 🟡建议优化【tests/host/timing_task_service_reminder_triggers_test.cc:83】测试只覆盖正常时间范围,没有覆盖 range_start=0、负时间戳、极大时间戳。风险:当前 0 哨兵缺陷不会被测试发现。修改方案:新增 [0, 1)[-10, 10)INT64_MAX-1 的参数和结果测试。
  21. 🟡建议优化【tests/host/timing_task_service_reminder_triggers_test.cc:117】分页测试只覆盖小页码。风险:超大 page、超过总数页、total 边界和 has_more=false 的稳定性没有证据。修改方案:新增 page 很大、page 正好最后一页、空结果页的断言,并覆盖不会溢出。
  22. 🟡建议优化【tests/host/timing_task_service_reminder_triggers_test.cc:121】排序测试只覆盖 created_at 倒序,未覆盖 planned_trigger_at、非法枚举和主键相同排序键的降序 tie-break。风险:协议新增字段时排序回归会直接影响分页稳定性。修改方案:补齐三种 sort key、两种 order、非法枚举和相同 sort key 的测试。
  23. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_rules.cc:14】channel/source 只校验非空。风险:后续下游按字符串路由硬件语音通道或 IM 通道时,未知通道会触发错误投递、重复重试或设备无响应。修改方案:定义枚举或 allowlist,例如 voice/im/system_default/user_defined,未知值直接 kInvalidArgument
  24. 🟡建议优化【components/voicelife_timing/src/timing_task_service_reminder_rules.cc:20】强提醒 max_snooze_countsnooze_interval_minutes 只有正数校验,没有上限。风险:异常配置可能产生多年级别推迟时间或后续乘法溢出,导致提醒永久丢失。修改方案:定义业务上限并用常量集中管理,例如最大推迟次数、最大单次推迟分钟数。
  25. 🟡建议优化【components/voicelife_timing/src/timing_task_service_calendar.cc:147】ListCalendarView 没有 page_size 上限。风险:调用方可请求超大页面,日历展开结果被一次性拷贝返回,嵌入式 RAM 风险直接暴露。修改方案:与提醒触发保持一致,定义统一分页上限常量并测试。
  26. 🔴严重阻塞【components/voicelife_timing/src/timing_task_service_calendar.cc:95】周期日历展开按天遍历整个查询范围。风险:传入多年范围会在单次请求中执行海量循环,导致主线程长时间阻塞。修改方案:限制最大查询跨度,并对周/月/年规则按周期跳转生成,而不是逐日扫描。
  27. 🟡建议优化【components/voicelife_timing/src/timing_task_service_calendar.cc:163】只要结果集中任一周期任务不是 UTC,整个 ListCalendarView 返回 kUnavailable。风险:一个暂不支持的任务会毒化同一范围内其他可展示任务,用户日历整页失败。修改方案:在注册阶段拒绝当前不能展开的非 UTC 周期任务,或查询时跳过并返回部分结果告警字段。
  28. 🟢可选改进【components/voicelife_timing/src/timing_task_service_reminder_triggers.cc:34】所有参数错误合并成同一错误文案。风险:调试上位机/IM 网关参数时无法快速定位是缺过滤、时间范围、页码还是 page_size。修改方案:拆分校验分支,返回具体错误消息,并在测试中断言错误码即可、日志记录细粒度原因。

整体仓库风险总结

当前实现满足 Host 内存 fake 的功能验证,但生产级查询边界没有建立:过滤、排序、分页、可见性和索引没有进入 Store 合同,应用层全量扫描会在长期运行设备上累积成 RAM、Flash IO、功耗和看门狗风险。安全方面,列表接口缺少调用方/租户/投影控制,payload 直接出现在列表 DTO 中,后续接 IM/语音/硬件通道时会扩大数据泄露和错误路由风险。硬件专项方面,本 PR 未提交原理图、引脚表、驱动或结构模型,无法确认软硬件协同安全;不能把本次 Host 通过等价为可上机结论。

优先级整改清单

  1. 先改 Store Port:把组合过滤、排序、分页、可见性下推到真实查询合同,并补 Store contract 测试。
  2. 立即修复时间范围哨兵、非法枚举、任务/实例/日程关系校验、生命周期过滤和 payload 投影。
  3. ListReminderTriggersListCalendarView 增加页码、页大小、查询跨度和结果总量上限。
  4. 补齐边界测试:0 时间戳、负时间戳、极大时间、非法枚举、孤儿触发、软删除任务/实例、跨资源组合、超大分页。
  5. 在进入硬件联调前提交硬件资料版本、通道 allowlist、故障上报和超时/重试策略,否则不能证明不会出现设备无响应或错误投递。

长期架构与软硬件协同优化方案

把 TimingTask 查询建成“应用服务编排 + Store 索引查询 + DTO 投影”的三层合同:Service 负责参数和资源关系校验,Store 负责索引化过滤分页,Adapter 负责 SQLite/NVS/Flash 的事务和索引。提醒通道不要继续使用裸字符串,改成枚举或注册表,并在硬件/语音/IM 适配层集中做 allowlist、超时、重试、故障状态上报。硬件资料必须和固件版本绑定:引脚、外设电平、通信协议校验和、断线重连、异常状态码都要进入仓库并纳入测试或仿真,否则后续上机风险不可控。

验证

  • 已执行:./scripts/run_host_tests.sh,22/22 通过。
  • 已执行:git diff --check 06484ca9250179937ee6533060bb04172914f856...4cd7fe984feaed750ae6e9f0a55bdc9afb2063ee,无输出。
  • 未完成:./scripts/run_pre_submit_checks.sh 因环境缺少 clang-format 在格式检查阶段停止。

View job run

@jing-gou

jing-gou commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

参考审查:fennoai review 的范围与验收核对

结论:#144 不需要改代码,因此不会向本 PR 增加提交。

范围依据

继承日历代码的行级意见

  1. timing_task_service_calendar.cc:167 - 不按原意见采纳;[Timing] 实现 ListReminderTriggers 提醒触发查询 #144 不修改。 即使是单次任务,ListInstances() 仍会被使用:已持久化 occurrence 可经 ToOccurrence 提供 statusactual_trigger_at 和覆盖字段,并替代基础 occurrence 返回。父 Issue [Timing] 实现 ListCalendarView 日历视图查询 #143 的验收要求已物化例外覆盖基础规则,因此不能将实例存储失败视为无关,否则会丢弃要求返回的数据。这是继承的 [Timing] 实现 ListCalendarView 日历视图查询 #143/✨ feat(timing): 实现 ListCalendarView 日历视图查询 #171 代码;若要改变其契约,应在该 PR 中讨论。
  2. timing_task_service_calendar.cc:119 - 不是 [Timing] 实现 ListReminderTriggers 提醒触发查询 #144 的问题;若将来引入普通 Runner 物化,则转由 [Timing] 实现 ListCalendarView 日历视图查询 #143 处理。 [Timing] 实现 ListCalendarView 日历视图查询 #143 只要求合并已物化的 modified/completed/skipped 例外;[Timing] 完善定时任务模块核心业务能力 #137 明确排除了后台预生成 Runner。该意见没有给出当前范围内必须返回的普通物化 occurrence,因此不足以证明现有 [Timing] 实现 ListCalendarView 日历视图查询 #143 契约被违反。改变 is_exception 的含义需要单独的日历契约决策,不能夹带进提醒触发查询。

编号意见逐项判断

1-4、6、19 - 本切片不采纳。 Store 端过滤/分页/排序、索引和大历史数据性能属于生产 Adapter/索引设计;#144#137 已明确排除。当前最小 Port/fake 正是允许的纵向切片。
5 - 不采纳。 totalpagepage_size 是既有的 int 公开 DTO 字段。理论上超过 INT_MAX 的结果数量不构成 #144 已证实的缺陷;扩大公开契约需要单独兼容性决策。
7、20 - 暂缓,不改 #144 支持 epoch 零点或负时间戳,需要将该 DTO 与仓库中广泛使用的零值表示“未提供”的惯例,改为 optional/显式 presence 语义。#144 只规定成对的左闭右开范围,并未要求时间域迁移。
8-9 - 不采纳。 这是进程内 C++ Service API;#144/#137 未引入传输或反序列化层。未知枚举的协议校验应在未来的 REST/Gateway 边界处理,该边界属于明确范围外。
10-11 - 不采纳。 ListTriggers 的明确契约是“未删除的触发记录”;#144 没有重定义按任务生命周期处理历史触发的可见性。过滤已终止/软删除任务的历史记录会无需求地改变查询语义。
12-14 - 不采纳。 多个过滤条件是逻辑与。现有资源之间不匹配时,返回稳定空页是有效结果;#144/#137 没有要求新增 kConflict 的关系校验契约。
15 - 拒绝,因为它与 #144 相悖。 #144 明确要求不存在资源返回明确错误。ListCalendarView 对不存在日程过滤返回空日历,是独立的 #143 契约,不能覆盖此要求。
16-17 - 不采纳。 payload 投影、调用方授权、租户与可见性策略,在 #137/#144 中均没有领域或传输模型。此处增加会形成跨模块策略工作,超出本切片。
18 - 不采纳。 内存 fake 是已声明 Port 的最小测试替身,Port 没有外键/数据完整性契约。严格/脏数据模式属于后续 Store 合同,不是 #144 的验收条件。
21-22 - 不作为必需工作采纳。 Host 测试已覆盖 #144 指定的 weak/strong、全部状态、空结果、时间范围、分页/稳定排序、无效参数、不存在资源与 Store 失败透传。极端页码和穷举排序可以作为后续补测建议,但没有发现 #144 行为失败。
23-24 - 范围外。 这些是 #141 的提醒规则校验问题,而非触发查询。
25-27 - 范围外。 这些是 #143 的日历实现问题;#143 本身也排除了生产性能优化和完整 recurrence 工作。
28 - 仅可选改进。 #144 要求明确的错误,当前已返回 kInvalidArgument;更细粒度的错误文字不是验收要求。

两条日历意见应在 #171/#143 基于其最新依赖头继续评估。#144 的实现保持在已接受的查询契约内,不修改继承的日历/规则行为。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant