syntax = "proto3"; option go_package = ".;pb"; // 记忆项分类(字符串常量,不做枚举——新增分类只加常量、不改表、不迁移; // 取值约束靠服务端白名单 comm.MemoryCategories,客户端对未知分类必须兜底成 todo 渲染) // alarm=闹钟 todo=待办 idea=灵感 expense=花销 // 记忆项状态 enum MemoryState { MemoryState_Pending = 0; // 待办/未完成 MemoryState_Done = 1; // 已完成 MemoryState_Dropped = 2; // 已废弃 } // 记忆项:一张表承载全部分类(拾忆页的唯一真相源) // // 字段类型说明(protobuf 没有 DECIMAL/DATE/DATETIME/null,逐个落地见设计文档 §3.2): // - 金额用 int64 存「分」,与 pay/结算模块同口径,绝不用 double // - happen_date 用 string + gorm type:date,值形如 2026-09-04 // - next_remind_at 用 int64 unix 秒,0 表示无 message DBMemoryItem { uint64 id = 1; //@go_tags(`gorm:"primaryKey;autoIncrement" json:"id"`) 主键自增 string uid = 2; //@go_tags(`gorm:"size:50;index:idx_mem_uid_date,priority:1;index:idx_mem_uid_cat,priority:1;uniqueIndex:idx_mem_uid_ck,priority:1" json:"uid"`) 用户ID string category = 3; //@go_tags(`gorm:"size:16;index:idx_mem_uid_cat,priority:2" json:"category"`) 分类 alarm/todo/idea/expense string source = 4; //@go_tags(`gorm:"size:16" json:"source"`) 来源 meeting/assistant/manual/device string source_id = 5; //@go_tags(`gorm:"size:64;index" json:"source_id"`) 会议记录id、端侧指令id等 string client_key = 6; //@go_tags(`gorm:"size:64;uniqueIndex:idx_mem_uid_ck,priority:2" json:"client_key"`) 幂等键(端侧指令id或本地uuid) // ⚠️ 服务端保证非空:客户端没传就现生成一个随机值。 // MySQL 的唯一索引对空串**不**像 NULL 那样放行重复, // 留空会让同一用户的第二条手动记录直接插入失败。 string title = 7; //@go_tags(`gorm:"size:200" json:"title"`) 主文案(所有分类通用) string detail = 8; //@go_tags(`gorm:"type:text" json:"detail"`) 补充说明 / 灵感正文 string happen_date = 9; //@go_tags(`gorm:"type:date;index:idx_mem_uid_date,priority:2;index:idx_mem_uid_cat,priority:3" json:"happen_date"`) 归属日期 YYYY-MM-DD,永不为空 string happen_time = 10; //@go_tags(`gorm:"size:5" json:"happen_time"`) HH:mm,无具体时间则空 bool date_certain = 11; //@go_tags(`gorm:"default:true" json:"date_certain"`) false=日期是推断的(如落在会议当天) string due_raw = 12; //@go_tags(`gorm:"size:64" json:"due_raw"`) 截止时间原文(「下周三前」) string tz = 13; //@go_tags(`gorm:"size:48" json:"tz"`) 录入时的客户端时区(IANA名),展开提醒按它算 string repeat_rule = 14; //@go_tags(`gorm:"size:16" json:"repeat_rule"`) once/daily/weekly/weekdays/weekend/monthly string repeat_raw = 15; //@go_tags(`gorm:"size:64" json:"repeat_raw"`) 重复规则原文(「每周一」) int32 weekday = 16; //@go_tags(`gorm:"default:0" json:"weekday"`) weekly 时 1-7 int64 amount_cents = 17; //@go_tags(`gorm:"default:0" json:"amount_cents"`) 花销金额(分),category=expense string currency = 18; //@go_tags(`gorm:"size:8" json:"currency"`) 货币码,默认 CNY string owner = 19; //@go_tags(`gorm:"size:64" json:"owner"`) 负责人原文(会议待办) MemoryState state = 20; //@go_tags(`gorm:"default:0;index" json:"state"`) 状态 int32 remind_ahead = 21; //@go_tags(`gorm:"default:5" json:"remind_ahead"`) 提前提醒分钟数,0=不提醒 int64 next_remind_at = 22; //@go_tags(`gorm:"default:0;index:idx_mem_remind,priority:1" json:"next_remind_at"`) 下一次提醒 unix 秒,0=无 bool user_edited = 23; //@go_tags(`gorm:"default:false" json:"user_edited"`) 用户改过 → 重新生成时不覆盖 int32 gen_round = 24; //@go_tags(`gorm:"default:0" json:"gen_round"`) 第几轮AI生成 string extra = 25; //@go_tags(`gorm:"size:2000" json:"extra"`) 扩展信息JSON int64 create_time = 26; //@go_tags(`gorm:"index" json:"create_time"`) int64 update_time = 27; //@go_tags(`json:"update_time"`) int64 finish_time = 28; //@go_tags(`gorm:"index" json:"finish_time"`) } // 周期报告生成状态 enum MemoryReportState { MemoryReportState_Pending = 0; // 待生成(入队) MemoryReportState_Processing = 1; // 生成中 MemoryReportState_Done = 2; // 完成 MemoryReportState_Failed = 3; // 失败 } // 周报/月报 // 唯一约束 (uid, period_type, period_key):同一周期只保留一条,重算按覆盖 message DBMemoryReport { uint64 id = 1; //@go_tags(`gorm:"primaryKey;autoIncrement" json:"id"`) string uid = 2; //@go_tags(`gorm:"size:50;uniqueIndex:idx_memrep_uid_period,priority:1;index" json:"uid"`) 用户ID string period_type = 3; //@go_tags(`gorm:"size:8;uniqueIndex:idx_memrep_uid_period,priority:2" json:"period_type"`) week/month string period_key = 4; //@go_tags(`gorm:"size:16;uniqueIndex:idx_memrep_uid_period,priority:3" json:"period_key"`) 2026-W35 / 2026-08 string period_start = 5; //@go_tags(`gorm:"type:date" json:"period_start"`) 周期起始日 YYYY-MM-DD string period_end = 6; //@go_tags(`gorm:"type:date" json:"period_end"`) 周期结束日 YYYY-MM-DD string stat_json = 7; //@go_tags(`gorm:"type:text" json:"stat_json"`) 结构化统计(服务端SQL算,不过LLM) string summary = 8; //@go_tags(`gorm:"type:text" json:"summary"`) AI生成的播报文案 string llm_svc_id = 9; //@go_tags(`gorm:"size:64" json:"llm_svc_id"`) 实际用的总结服务id(排障用,同echomeet口径) MemoryReportState state = 10; //@go_tags(`gorm:"default:0;index" json:"state"`) string error_msg = 11; //@go_tags(`gorm:"size:500" json:"error_msg"`) 失败原因 bool confirmed = 12; //@go_tags(`gorm:"default:false" json:"confirmed"`) 用户是否已确认 int64 confirm_time = 13; //@go_tags(`json:"confirm_time"`) int64 create_time = 14; //@go_tags(`gorm:"index" json:"create_time"`) int64 update_time = 15; //@go_tags(`json:"update_time"`) }