Skip to content

✨ feat(schedule): 查询最近十五分钟日程操作 - #175

Closed
HuXiaohui424 wants to merge 3 commits into
1024XEngineer:mainfrom
HuXiaohui424:dev/X-query-record-operation
Closed

✨ feat(schedule): 查询最近十五分钟日程操作#175
HuXiaohui424 wants to merge 3 commits into
1024XEngineer:mainfrom
HuXiaohui424:dev/X-query-record-operation

Conversation

@HuXiaohui424

@HuXiaohui424 HuXiaohui424 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

结论

本 PR 实现 ScheduleService::query_recent_schedule_operation(),返回当前设备用户在当前时间往前 15 分钟内的全部日程操作,并提供确定性的倒序结果。请 Reviewer 重点判断 15 分钟闭区间、取消 10 条限制、同秒排序规则,以及设备单用户 mock 与未来真实用户隔离的边界是否合理。

本 PR 依赖 #174。由于 #174 尚未合并且其 head 位于 fork,本分支暂时包含 #174 的提交;建议先合并 #174,再合并本 PR。

Refs #176

变更

  • 实现 ScheduleService::query_recent_schedule_operation()
  • 新增纯查询辅助函数,筛选闭区间 [now - 15min, now] 内的全部操作。
  • operated_at 倒序排列,同秒记录按 operation_id 倒序排列。
  • 移除 mock 存储的 10 条容量裁剪,保证 15 分钟内超过 10 条时仍完整返回。
  • 沿用 ✨ feat(schedule): 实现日程操作记录接口 #174OperationRecord::previous,返回操作前完整 Schedule 快照。
  • 当前 mock 按设备单用户处理,并为真实 Store 按用户和时间窗口查询保留 TODO。
  • 新增 schedule_recent_operation_test,覆盖空结果、窗口边界、未来记录、倒序、重复查询和超过 10 条的场景。
  • 调整 schedule_operation_test,验证 mock 存储不再按记录条数裁剪。

明确未包含:

  • 未注册 MCP Tool,未实现外部 JSON 序列化。
  • 未引入用户 ID、会话身份或多用户存储契约。
  • 未接入 SQLite 或其他真实持久化适配器。
  • 未实现撤销操作和已撤销状态过滤。
  • 未将操作记录自动接入日程创建、修改或删除流程。

架构与兼容

不新增 Port、Profile、外部协议或组件依赖方向。公共结果结构未增加字段,继续返回 QueryRecentScheduleOperationResult#174 定义的 OperationRecord;仅将查询注释从“最近十条”修正为“最近十五分钟内”。

mock 存储由固定 10 条容量改为不按条数裁剪,这是为了满足“返回 15 分钟内全部操作”的查询契约。真实存储接入后,应在 Store 层按当前用户和时间窗口过滤,并保持相同的排序语义。

验证

  • ./scripts/run_pre_submit_checks.sh
  • 远端 CI 的工作流、格式、IM Gateway、主机测试、架构、ESP-IDF 和 CodeQL 均通过;依赖图已启用时依赖审查也通过,未启用时已记录跳过原因
  • ESP-IDF 对应 Profile 构建
  • 真机或外部服务验证(不适用:本 PR 为纯日程领域逻辑和进程内 mock,无外部服务交互)

证据:

  • 使用 Homebrew LLVM 18.1.8 格式化全部修改过的 C/C++ 文件。
  • CLANG_FORMAT=<llvm@18>/bin/clang-format RUFF=/Users/mac/.local/share/uv/tools/ruff/bin/ruff ./scripts/check_format.sh 通过,16 个相关文件均已格式化。
  • ./scripts/run_host_tests.sh -L schedule 通过,7/7 日程测试通过。
  • ./scripts/run_pre_submit_checks.sh 完整通过:23 个主机测试、29 个 Python 测试和 126 个 IM Gateway 测试通过,公共 API 文档、架构、双端契约、esp32s3-dev Profile 与 idf.py build 均通过。

TDD 记录

  • RED:新增 schedule_recent_operation_test 后,基线缺少 query_recent_schedule_operation() 定义,且 ✨ feat(schedule): 实现日程操作记录接口 #174 的 mock 会将超过 10 条的场景裁剪,无法满足查询契约。
  • GREEN:实现 15 分钟过滤和倒序查询,移除 10 条容量裁剪后,空结果、时间边界、未来记录、超过 10 条及重复查询测试通过。
  • REFACTOR:将时间窗口过滤和排序拆到 schedule_operation_query_helpers 纯函数,通过显式 now 消除测试对系统时间和 sleep 的依赖;同秒使用操作 ID 倒序保证结果稳定。

风险与回退

  • 当前操作记录仅保存在进程内,设备重启后会丢失;当前用户也仅按设备单用户语义模拟。
  • 撤销状态尚未建模,因此本接口只按 15 分钟时间窗口判断候选记录;后续实现撤销时需补充已撤销记录的处理规则。
  • mock 不再按条数裁剪,长时间高频写入会增加进程内存占用;真实 Store 接入后应使用带用户条件的时间窗口查询和存储清理策略。
  • 如需回退,可回退提交 6db8b1d✨ feat(schedule): 实现日程操作记录接口 #174 的操作记录接口可独立保留。

@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@HuXiaohui424 HuXiaohui424 self-assigned this Aug 6, 2026
@HuXiaohui424 HuXiaohui424 added the MiniSpec 规格粒度-小改动的精简规格 label Aug 6, 2026
@HuXiaohui424 HuXiaohui424 linked an issue Aug 6, 2026 that may be closed by this pull request
17 tasks
@HuXiaohui424
HuXiaohui424 deleted the dev/X-query-record-operation branch August 6, 2026 07:45
@HuXiaohui424
HuXiaohui424 restored the dev/X-query-record-operation branch August 6, 2026 07:46
@HuXiaohui424 HuXiaohui424 reopened this Aug 6, 2026
@HuXiaohui424

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 commented Aug 6, 2026

Copy link
Copy Markdown

严格 Review 结果

按固定范围 06484ca9250179937ee6533060bb04172914f856...6db8b1dec1e5adc96c227cb479c8a866ac2a5c1c 审查。已跑 ./scripts/run_host_tests.sh -L schedule,7/7 通过。未发现本 PR 直接改动 GPIO/I2C/SPI/UART/电机/电源等硬件驱动代码,也未看到随 PR 提供的原理图、结构模型或硬件版本资料;硬件专项只能基于嵌入式运行风险审查,不能确认引脚/电气/机构匹配。

审查条目

  1. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_operation_mock_data.cc:13】进程全局 std::deque<OperationRecord> 无任何容量、TTL 或清理策略,且 PR 明确移除 10 条裁剪。风险:设备长期运行或外部工具高频记录操作会持续吃 RAM,ESP32-S3 类设备最终触发内存耗尽、任务崩溃或看门狗复位。**修改方案:**恢复有界存储策略,但按“15 分钟窗口”裁剪而不是按 10 条裁剪;写入前后删除 operated_at < now - 15min 的记录,并设置最大记录数/最大字节数双阈值,超限返回明确错误或丢弃过期数据。

  2. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_operation_mock_data.cc:28】【components/voicelife_schedule/src/schedule_operation_mock_data.cc:31】NextOperationId()++operations.push_back() 没有互斥保护。风险:MCP 请求、语音任务、提醒任务并发调用时发生 C++ 数据竞争,可能产生重复 ID、deque 内部结构破坏、进程崩溃。**修改方案:**在 mock store 内增加 std::mutex,让 ID 分配、写入、复制读取在同一锁内完成;真实 Store 接入时使用数据库自增主键和事务。

  3. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_operation_mock_data.cc:36】读取全量操作时也没有锁,与写入并发会边遍历边修改 deque。风险:查询最近操作可能读到撕裂数据,严重时迭代器失效导致崩溃。修改方案:LoadMockScheduleOperations() 使用同一把 mutex 复制快照;或提供 QueryMockScheduleOperationsSince(earliest, now) 在锁内过滤后返回。

  4. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_service.cc:242】record_schedule_operation() 允许调用方直接提交任意 schedule_id,不校验日程是否存在、是否属于当前设备用户、是否由真实 create/update/delete 流程产生。风险:外部工具一旦接入,任何客户端都能伪造可撤销操作记录,后续撤销会删除/恢复错误日程,属于权限与数据完整性漏洞。**修改方案:**不要把记录操作作为任意可调用业务入口;改为在 create/update/delete 成功落库的同一事务内由服务内部写操作记录,或至少注入 ScheduleStore 校验目标日程和用户权限。

  5. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_operation_helpers.cc:46】【components/voicelife_schedule/src/schedule_operation_helpers.cc:49】只校验 create 是否带 previous、update/delete 是否缺 previous,没有校验 previous->id == command.schedule_id。风险:可以为日程 A 写入日程 B 的快照,撤销时恢复/覆盖错误对象,造成用户数据串改。**修改方案:**对 update/delete 强制 previous->id == schedule_id,并在测试中加入 mismatch 用例。

  6. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_operation_helpers.cc:30】previous 内部字段完全不校验,包括 id <= 0、非法 ScheduleStatusend_time <= start_time。风险:操作记录可持久化非法领域快照,后续 undo 或 JSON 落库会把坏数据重新写回业务表,直接破坏日程数据一致性。**修改方案:**复用/抽出完整 Schedule 校验函数,对 previous 执行 ID、标题、时间区间、状态枚举校验;非法快照返回 kInvalidArgument

  7. 🔴严重阻塞:【components/voicelife_schedule/src/schedule_service.cc:275】query_recent_schedule_operation() 没有用户、会话、设备上下文参数。风险:真实 Store 接入前后都没有接口层隔离边界,查询会天然返回全局操作记录,多用户/多会话设备上会泄露他人日程标题、地点、备注。**修改方案:**在命令/服务上下文中引入 user_idaccount_id,Store 查询必须包含用户条件;mock 也要显式单用户实现,避免接口契约以后再破坏。

  8. 🟡建议优化:【components/voicelife_schedule/src/schedule_service.cc:279】查询先 LoadMockScheduleOperations() 复制全量,再过滤,再排序全量窗口。风险:配合无界存储后,单次查询从 O(k) 退化为 O(n log n) 且复制所有历史快照,用户频繁打开“撤销列表”会造成 CPU 峰值和内存抖动。**修改方案:**改成 Store 层按 (user_id, operated_at between earliest and now) 查询并 ORDER BY operated_at DESC, id DESC;mock 也在锁内倒序扫描,只复制窗口内记录。

  9. 🟡建议优化:【components/voicelife_schedule/src/schedule_service.cc:276】【components/voicelife_schedule/src/schedule_operation_mock_data.cc:10】使用 system_clock 判定 15 分钟窗口。风险:设备 RTC 未同步、NTP 校时、用户改系统时间会让刚记录的操作变成“未来记录”被排除,或过期操作重新进入窗口。**修改方案:**记录时同时保存 wall-clock 时间和单调时间戳;撤销窗口用单调时钟判定,展示/持久化才使用 wall-clock。

  10. 🟡建议优化:【components/voicelife_schedule/include/voicelife/schedule/schedule_types.h:51】OperationRecord::previousJsonDocument 改为 Schedule,公共领域类型直接绑定当前 Schedule 结构。风险:Schedule 新增字段时会隐式改变操作记录 ABI/序列化负担,历史记录 JSON 兼容和跨版本回放会变脆。**修改方案:**定义独立 ScheduleSnapshot/OperationSnapshot,包含版本号和撤销需要的最小字段;存储适配器按版本序列化/反序列化。

  11. 🟡建议优化:【components/voicelife_schedule/include/voicelife/schedule/schedule_commands.h:61】命令层也暴露完整 Schedule previous,调用方必须构造完整领域对象。风险:外部边界被迫了解内部字段,未来 Schedule 字段迭代会导致所有记录操作调用点大面积修改。**修改方案:**让记录命令只传操作类型和 schedule_id,由服务从 Store 读取操作前快照;如果必须外部传入,改为稳定的 snapshot DTO。

  12. 🟡建议优化:【components/voicelife_schedule/src/schedule_service.cc:248】schedule_eventprevious->event 是两份可互相矛盾的数据,服务不定义谁是事实来源。风险:列表展示和撤销执行可能使用不同标题,用户看到“撤销 A”实际恢复 B,造成误操作。**修改方案:**update/delete 的 schedule_eventprevious.event 派生;create 的标题从实际创建成功的 Schedule 派生,不接受调用方重复传入。

  13. 🟡建议优化:【components/voicelife_schedule/src/schedule_service.cc:242】记录操作与日程 create/update/delete 没有事务边界,也没有被这些流程自动调用。风险:日程修改成功但操作记录失败会无法撤销;操作记录成功但日程修改失败会出现幽灵撤销项。**修改方案:**在持久化 Store 中实现“修改日程 + 写 OperationRecord”的单事务 API;失败时整体回滚。

  14. 🟡建议优化:【components/voicelife_schedule/include/voicelife/schedule/schedule_service.h:47】注释写“可撤销操作”,但数据模型没有 undone_at/undone_by/is_undone,查询也不排除已撤销记录。风险:撤销一次后仍会出现在列表中,重复撤销可能造成数据回滚到错误状态。**修改方案:**为 OperationRecord 增加撤销状态字段;查询条件排除已撤销记录;undo 成功后同事务标记记录已撤销。

  15. 🟡建议优化:【components/voicelife_schedule/src/schedule_operation_query_helpers.cc:9】15 分钟窗口写死在 helper 内,没有命名业务常量或配置入口。风险:MCP 文档、服务注释、撤销实现、测试之间未来容易出现 10/15/30 分钟不一致。**修改方案:**在一个公共 schedule operation 配置头中定义 constexpr auto kRecentOperationWindow = std::chrono::minutes{15};,服务、helper、测试、文档全部引用。

  16. 🟡建议优化:【components/voicelife_schedule/src/schedule_operation_helpers.cc:11】【components/voicelife_schedule/src/schedule_service.cc:20】kMaximumEventLength = 100 在两个翻译单元重复定义。风险:后续修改创建日程上限时忘记同步操作记录上限,导致同一标题创建成功但记录失败,撤销链断裂。**修改方案:**抽出 kMaximumScheduleEventLength 到共享 validation/config 头,所有创建/修改/记录路径复用。

  17. 🟡建议优化:【components/voicelife_schedule/src/schedule_operation_mock_data.h:15】mock 存储头文件位于 src,但 host tests 通过 private include 直接调用 LoadMockScheduleOperations() 检查内部状态。风险:测试和实现细节耦合,后续替换 Store 会导致测试大面积重写,无法稳定验证公共契约。**修改方案:**测试优先通过 ScheduleService 公共查询断言;确需白盒能力时提供 test-only fixture/reset 接口,并用编译开关隔离。

  18. 🟡建议优化:【components/voicelife_schedule/src/schedule_operation_mock_data.cc:13】mock store 没有 reset/fixture 生命周期控制。风险:同一测试进程内新增用例或未来并行 runner 复用进程时,前一个用例的操作记录污染后一个用例,出现随机失败。**修改方案:**增加 ResetMockScheduleOperationsForTest(),测试入口显式清理;生产编译不导出该接口。

  19. 🟡建议优化:【components/voicelife_schedule/test/schedule_recent_operation_test.cc:63】服务级测试只写入“当前时间”的记录,过期和未来记录只覆盖了纯 helper。风险:ScheduleService 的系统时钟取值、mock 读写、过滤串联路径没有覆盖边界,真实 bug 可能被 helper 单测掩盖。**修改方案:**给服务注入 Clock/Store 测试替身,构造过期、边界、未来记录后通过公共服务方法验证结果。

  20. 🟡建议优化:【components/voicelife_schedule/test/schedule_operation_test.cc:45】测试未覆盖 previous 与 schedule_id 不一致、previous 时间区间非法、previous 状态非法等关键负例。风险:当前数据完整性漏洞不会被 CI 捕获,undo 接入后会扩大为用户数据破坏。**修改方案:**补充上述 invalid previous 用例,并要求 record_schedule_operation() 返回 kInvalidArgument

  21. 🟢可选改进:【components/voicelife_schedule/src/schedule_operation_mock_data.cc:27】TODO 只说替换为原子 INSERT,但没有写明用户过滤、窗口索引、撤销状态索引。风险:后续 Store 实现可能只按时间查全表,继续保留泄露和性能问题。**修改方案:**把 TODO 扩展为明确契约:WHERE user_id = ? AND operated_at BETWEEN ? AND ? AND undone_at IS NULL ORDER BY operated_at DESC, operation_id DESC,并要求索引 (user_id, operated_at DESC, operation_id DESC)

  22. 🟢可选改进:【components/voicelife_schedule/CMakeLists.txt:4】业务组件直接把 mock operation store 编进 ESP-IDF component。风险:样机/生产固件如果误用 mock 存储,会在设备内存中累积操作记录且重启丢失,调试现象与真实持久化完全不同。**修改方案:**通过 profile/feature flag 区分 mock 与真实 Store,生产 profile 禁止链接 mock store;缺少真实 Store 时服务返回明确 kUnavailable

  23. 🟢可选改进:【components/voicelife_schedule/src/schedule_operation_query_helpers.cc:16】排序 tie-breaker 依赖 id 单调递增,但这个性质只存在当前进程内 mock,真实 Store/导入数据/时钟回放没有在类型契约中声明。风险:跨库迁移或恢复备份后同秒顺序不稳定,撤销列表抖动。**修改方案:**在 OperationRecord Store 契约中明确 operation_id 全局单调;否则增加 sequence 字段作为排序键。

  24. 🟢可选改进:【components/voicelife_schedule/test/schedule_recent_operation_test.cc:67】没有压力测试“15 分钟内大量操作 + 大 previous 快照”。风险:在嵌入式设备上,std::vector/std::deque/std::string 的频繁分配会造成堆碎片和延迟尖峰。**修改方案:**增加 host 压测/基准用例,至少覆盖数千条记录和最大长度标题/notes;生产路径设定内存上限并监控失败返回。

  25. 🟢可选改进:【components/voicelife_schedule/include/voicelife/schedule/schedule_service.h:53】undo_schedule_operation() 已声明,但本 PR 新查询接口返回“可撤销”记录时没有把“撤销不可用”状态反映到结果。风险:上层 UI/MCP 可能展示可撤销列表,用户点击后才发现功能不存在,形成错误产品契约。**修改方案:**在 undo 实现完成前,把文档改为“最近操作记录”而不是“可撤销操作”;或同步实现 undo 并补齐幂等/重复撤销测试。

顶层设计问题

当前 PR 把“操作记录”设计成独立可写的公共业务能力,并用进程全局 mock 存储承接真实 Store 的职责。这会把权限校验、用户隔离、事务一致性、撤销状态、容量治理全部推迟到未来,导致现在的接口形状已经不利于真实落库。正确边界应是:日程写操作在同一事务内产生日志;查询只读当前用户、未撤销、时间窗口内记录;撤销在同一事务内恢复快照并标记日志已撤销。

① 整体仓库风险总结

本 PR 的纯筛选 helper 本身逻辑清晰,闭区间和同秒倒序测试覆盖到了;但服务级实现仍是全局 mock、无锁、无界、无用户上下文。对后端一致性和嵌入式长稳运行而言,主要风险不是算法写错,而是接口边界过早暴露了不可信写入和无限内存增长。硬件驱动层未被本 PR 直接触碰,未发现直接烧毁外设或机构失控代码路径;但无界堆增长和并发数据竞争会造成固件级崩溃/复位,同样阻断上机长期测试。

② 优先级整改清单

阻断项优先:先修全局 mock store 的互斥与容量/TTL 清理;再补用户/设备上下文和 Store 查询契约;随后禁止外部伪造操作记录,把记录写入并入 create/update/delete 事务;最后校验 previous 快照完整性和 schedule_id 一致性。

强制补测:增加 previous mismatch/非法 previous、并发写读、过期记录服务级过滤、15 分钟内大批量记录、重复撤销状态过滤用例。

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

建立 ScheduleOperationStore Port,提供 AppendInTransactionQueryRecentByUserMarkUndone 三类原子能力;SQLite/真实持久化层必须有用户条件、时间窗口索引、撤销状态字段和容量清理任务。嵌入式 profile 下禁止生产固件链接无界 mock store,所有可增长内存结构必须有最大记录数/最大字节数/过期清理策略。时间窗口判断拆成 wall-clock 展示与 monotonic 有效期两套语义,避免 RTC 校时破坏撤销窗口。

@HuXiaohui424
HuXiaohui424 marked this pull request as ready for review August 6, 2026 09:02

@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 high-risk issues remain in the new operation-history path; details are inline.


/** @brief 返回进程内的操作记录集合。 @return 可变的操作记录集合。 */
std::deque<OperationRecord>& MockOperations() {
static std::deque<OperationRecord> operations;

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 process-global deque and the adjacent ID counter are shared by all callers, but neither the append path nor the read path takes a lock. Concurrent schedule writes/queries can race, corrupt the history, or duplicate IDs; there is also no prune/reset path, so the store grows without bound on long-running firmware.

QueryRecentScheduleOperationResult ScheduleService::query_recent_schedule_operation() const {
const DateTime now = std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now());

// TODO(#121):真实存储接入用户上下文后,由存储层按当前用户和十五分钟时间窗口查询。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 The TODO here notes user scoping is still missing, but the public API has no parameter for user/device identity. As written, query_recent_schedule_operation() can only return the process-global history, so once this is backed by a real store it will mix and potentially expose other callers' operations instead of 'the current user's recent operations'.

@HuXiaohui424
HuXiaohui424 marked this pull request as draft August 6, 2026 09:16
@HuXiaohui424 HuXiaohui424 linked an issue Aug 6, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

MiniSpec 规格粒度-小改动的精简规格

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Query] 实现最近十五分钟日程操作查询 [Schedule] 完善日程模块核心业务能力

1 participant