|
|
|
@ -1,8 +1,54 @@ |
|
|
|
# 记忆中心(拾忆)设计与开发文档 |
|
|
|
|
|
|
|
> 版本:v0.2 日期:2026-09-04(v0.1 为 2026-08-31) |
|
|
|
> 版本:v0.3 日期:2026-09-05(v0.2 复核 09-04,v0.1 草案 08-31) |
|
|
|
> 范围:`apps/services`(后端)、`apps/client`(Flutter)、`apps/admin`(后台)、百炼 Agent 配置 |
|
|
|
> 状态:设计评审中,**未开工**(代码侧目前只有 tab 文案改名,见 §2.3) |
|
|
|
> 状态:**代码已落地**(一~三期的可自动化部分),剩余为需要人工决策/外部系统操作的项,见 §零 |
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
## 零、实施状态(v0.3,2026-09-05) |
|
|
|
|
|
|
|
一晚上把不需要决策的部分全部落地了。`go build` / `go vet` / `dart analyze` / |
|
|
|
`flutter build apk --debug` 全通过,新增 40 个测试。 |
|
|
|
|
|
|
|
### 已完成 |
|
|
|
|
|
|
|
| 分期 | 项 | 落点 | |
|
|
|
|---|---|---| |
|
|
|
| 零期 | `tabTodo` 补齐 41 语言(此前 38 个是坏的) | `core/translations/language/*.dart` | |
|
|
|
| 零期 | `i18n_audit.py` 补「缺失 key」检查 | 实测报出 7243 处历史缺失 | |
|
|
|
| 零期 | 引入 `timezone` + `flutter_timezone` | `pubspec.yaml` | |
|
|
|
| 零期 | 表常量 + 注销清理清单(含补上遗漏的 `useridverify`) | `comm/const.go`、`user/model_user.go` | |
|
|
|
| 一期 | `memory_item` / `memory_report` 表 + `memory` 模块 + 11 个接口 | `modules/memory/`、`proto/memory/` | |
|
|
|
| 一期 | 会议纪要 → 待办抽取第三路 | `modules/memory/meeting_extract.go`、`echomeet/tasks.go` | |
|
|
|
| 一期 | `MemoryService` + `MemoryItem` 模型 | `data/services/`、`data/models/` | |
|
|
|
| 一期 | 拾忆页换源、分类筛选、删 mock 与 44 个 demo key | `calendar_controller.dart` 等 | |
|
|
|
| 一期 | **写操作 UI 全套**(编辑层/勾完成/新增/下拉刷新/空态) | `memory_edit_sheet.dart`、`todo_scope_list.dart` | |
|
|
|
| 一期 | `SET_clock` 双写服务端(幂等键用指令 id) | `assistant_directive_service.dart` | |
|
|
|
| 二期 | `memory_upcoming` + 重复项按 tz 展开 | `modules/memory/remind.go` | |
|
|
|
| 二期 | 本地通知排期(id 命名空间/专用通道/权限降级) | `memory_reminder_scheduler.dart` | |
|
|
|
| 二期 | 每日弹窗 + TTS 播报 + 中断 | `memory_daily_sheet.dart` | |
|
|
|
| 三期 | `memory_report` + cron + 分布式锁 + worker + 超时补偿 | `modules/memory/report.go` | |
|
|
|
| 三期 | `stat_json` SQL 统计(明细截断) | `modules/memory/stats.go` | |
|
|
|
| 三期 | 报告弹窗 + 播报 + 确认 | `memory_report_sheet.dart` | |
|
|
|
| 三期 | **MCP 会话鉴权** + 3 个只读工具 | `modules/mcp/auth.go`、`tool_memory.go` | |
|
|
|
| 三期 | 存量 `DBTask` 迁移(幂等、失败不阻断) | `modules/memory/migrate_task.go` | |
|
|
|
|
|
|
|
### 实施中做的三个决策(原文档列为待确认,选了默认值,可推翻) |
|
|
|
|
|
|
|
1. **成本闸门选「活跃度阈值」而非额度**(待确认 1):`report_min_items: 3`, |
|
|
|
上周期不足 3 条记录不生成报告。理由见该条——既有额度全是「用户主动发起」语义, |
|
|
|
cron 主动生成扣用户额度说不通。 |
|
|
|
2. **多币种一期只做「分行不换算」**(待确认 4 相关):`stat_json.expenses` 按币种 |
|
|
|
分行,客户端与 MCP 都不做汇率换算。 |
|
|
|
3. **「上周」固定 ISO 周(周一起)**:`comm.MemoryWeekKey`,不做地区适配。 |
|
|
|
一个应用里「上周」必须只有一种含义。 |
|
|
|
|
|
|
|
### 仍需人工/外部操作(无法自动化) |
|
|
|
|
|
|
|
见 §十三。 |
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
## v0.2 修订说明 |
|
|
|
|
|
|
|
@ -1141,3 +1187,44 @@ mysql.Delete(comm.TableMemoryReport, "uid=?", uid) |
|
|
|
| 拾忆列表与花销卡片 | `apps/client/lib/modules/main_tab/views/widgets/todo_scope_list.dart` | |
|
|
|
| 本地通知(已有两处实例) | `apps/client/lib/core/utils/background_session_notifier.dart`、`apps/client/lib/modules/meeting/controllers/meeting_record_controller.dart` | |
|
|
|
| TTS 接口 | `apps/client/lib/data/services/tts_service.dart` | |
|
|
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
## 十三、剩余待办:需要人工或外部系统操作(v0.3) |
|
|
|
|
|
|
|
代码已就绪,但这些做不了,也不该由代码替你决定。 |
|
|
|
|
|
|
|
### A. 外部系统操作(必须有人去点) |
|
|
|
|
|
|
|
| # | 事项 | 位置 | 不做的后果 | |
|
|
|
|---|---|---|---| |
|
|
|
| A1 | **百炼后台补 `ADD_todo`/`ADD_idea`/`ADD_expense`/`CANCEL_clock` 四个工具** | 百炼控制台 | 语音只能定闹钟,说「记一笔花销」模型不下发任何指令却回「记好了」 | |
|
|
|
| A2 | **百炼后台摘掉 `SEND_message` / `MAKE_A_PHONE_CALL_phone_call`** | 同上 | 模型继续下发本版无法执行的指令 | |
|
|
|
| A3 | **`General-Meeting` zh-CN 模板第四节改造**(§7.1 的提示词) | 后台 → 会议模板(`meettemplates.vue`,已能按语言编辑) | 抽取那一路拿不到「负责人/截止时间」锚点,抽出来的待办大多只有任务内容 | |
|
|
|
| A4 | **`.env` 补 `GATEWAY_TOKEN_KEY` 到 mcp 服务** | `deploy/app/env/` | MCP 的用户数据类工具**一律拒绝服务**(这是刻意的失败方向,见 `auth.go`) | |
|
|
|
|
|
|
|
### B. 需要产品决策 |
|
|
|
|
|
|
|
| # | 决策 | 影响 | |
|
|
|
|---|---|---| |
|
|
|
| B1 | **`USE_EXACT_ALARM` 申不申请** | 不申请则「提前 5 分钟」实际是「提前 5~20 分钟之间」。申请需 Google Play 认可「应用核心功能是闹钟/日历」并单独提交说明。代码已做退化处理,两条路都能跑 | |
|
|
|
| B2 | **提醒送达率做不到 100%,预期要对齐** | 通知权限 48 小时合规冷却 + Android 14 精确闹钟 + 国内 ROM 杀后台,三条都不是代码能绕的 | |
|
|
|
| B3 | **拾忆页要不要走实名闸门** | 现在没拦。语音录入走 EMAI 已被拦,等于游客只能手动录——这个不对称是否可接受 | |
|
|
|
| B4 | **要不要给记忆中心埋点** | `analyze.writeEvent` 是固定 switch,加维度要同时改 console 看板列。目前一个埋点都没有 | |
|
|
|
| B5 | **数据导出** | 花销与灵感是用户资产,没有导出入口等于数据绑架。`memory_list` 已留分页参数 | |
|
|
|
|
|
|
|
### C. 已知偏差(写在代码注释里,不是 bug) |
|
|
|
|
|
|
|
| # | 偏差 | 说明 | |
|
|
|
|---|---|---| |
|
|
|
| C1 | 会议归属日期用 `creationtime`(上传时间) | `DBEchoMeetRecord` 上没有「会议实际发生日期」字段,也没有客户端时区。补录历史录音会算错。要做准得给表加 `meet_date` + `tz` 两列由客户端上报 | |
|
|
|
| C2 | 周报 cron 是容器固定的北京时间 | 纽约用户的周报在他本地周日中午生成,漏掉周日下半天。要做准得按用户 `tz` 分批触发(cron 每小时跑,只处理「本地刚过周一 00:30」的那批) | |
|
|
|
| C3 | 迁移来的 DBTask 丢失时区 | `trigger_time` 只有偏移没有 IANA 名,`tz` 留空按容器时区处理 | |
|
|
|
| C4 | i18n 新增 key 的 38 个语种是英文占位 | 已显式写入而不是留空——留空的话 GetX 静默回退英文,审计工具永远发现不了。现在 `i18n_audit.py` 会把它们列为「值等于英文基线」待翻译 | |
|
|
|
|
|
|
|
### D. 未做(超出本次范围) |
|
|
|
|
|
|
|
- 花销小票 OCR(§6.6):上传链路已就绪,缺 `uploadScenes` 加 `MemoryImages` 与识别调用点 |
|
|
|
- admin 后台排障页(分期表 #18) |
|
|
|
- `allhelp/summary.go` 的 doubao 硬编码(§12 待确认 8):新模块没复制这个写法,但存量那处仍绕过编排 |
|
|
|
|