1. 项目缘起与整体设计思路1.1 为什么选宠物生命周期管理这个方向宠物生命周期管理这个选题乍一听像是又一个记录猫猫狗狗日常的普通工具但真正拆开来看它覆盖的是一个跨度极长、状态变化极多的数据模型。一只宠物从被领养、日常喂养、疫苗接种、驱虫、体检、发情、配种、怀孕、生产到老年慢性病管理最后到离世与纪念这条时间线上每一个节点都对应着不同的数据结构、提醒逻辑和展示形态。我之所以拿它当练手项目恰恰是因为它足够不规整——如果只是做一个待办清单AI 生成一遍就完事了根本压不出真实项目里那些边界情况。用 AI 辅助从零搭建核心价值不在于让 AI 帮我写代码而在于把整个项目的骨架、数据流、状态机、提醒调度这些容易在早期想漏的东西在动手写第一行代码之前就摊开在桌面上。我见过太多人一上来就让 AI 帮我写一个宠物 App结果生成一堆互相矛盾的页面改到第三轮就彻底失控。所以这个项目的设计思路是先让 AI 当架构师再让 AI 当程序员最后让 AI 当测试员三个阶段严格分开每个阶段的产出都要人工过一遍。1.2 技术选型背后的取舍逻辑这个项目我最终定的是Flutter SQLite本地 可选云同步的组合。为什么不用纯 Web因为宠物提醒类应用的核心场景是到点推送Web 端在后台提醒这块天然吃亏。为什么不用原生双端因为一个人做项目双端维护成本直接翻倍Flutter 一套代码跑两端配合本地数据库离线可用这对养宠人群特别重要——很多人带宠物去医院时信号并不好。数据库层面宠物生命周期数据的特点是读多写少、关联查询多、时间序列明显。SQLite 配合一张主表加若干张事件表足够撑起单用户几万条记录。如果你后期想加多设备同步再引入一层轻量同步协议即可不必一上来就上重型后端。AI 在这个环节的作用是帮我做方案对比。我会把三四个候选技术栈丢给 AI让它列出每个方案在离线能力、开发速度、后期扩展、学习成本四个维度的打分然后我自己拍板。注意AI 给的打分只能当参考真正决定的是你对项目的预期寿命——如果这个项目你只打算做两周那就选你最熟的那套别为了技术先进去踩新坑。1.3 项目模块的整体切分整个 App 我切成了六个核心模块这个切分是让 AI 先按用户旅程列一遍我再按数据耦合度重排的结果模块核心职责数据特征宠物档案基础信息、品种、生日、绝育状态单条主记录低频修改健康事件疫苗、驱虫、体检、用药时间序列高频追加提醒调度到期提醒、周期提醒、自定义依赖事件表需去重成长记录体重曲线、照片、里程碑半结构化体积大繁育管理发情周期、配种、孕检、生产状态机驱动逻辑最复杂纪念与归档离世记录、回忆相册只读为主情感属性强这个表格看着简单但它是整个项目的宪法。后面所有页面、所有接口、所有 AI 生成的代码都必须能映射回这六块之一。一旦发现某段逻辑放不进任何一块要么是模块切分有问题要么是这个需求本身就不该做。我在实操中最大的体会就是AI 很擅长在既定框架内填内容但极不擅长帮你发现框架本身的漏洞所以框架必须人来定。2. 核心细节解析与实操要点2.1 用 AI 生成数据模型时的关键约束让 AI 设计数据表最容易出的问题是它给你设计得太完整——把所有可能字段都塞进去结果表结构臃肿后期迁移痛苦。我的做法是给 AI 加三条硬约束第一每张表字段不超过 12 个超了就拆表。第二所有时间字段统一用 UTC 毫秒时间戳存储展示层再转本地时区这条能避免 90% 的跨时区 bug。第三状态字段必须用枚举而非字符串比如宠物状态只允许active / pregnant / nursing / senior / deceased这五个值AI 生成时如果写了别的值直接打回。以健康事件表为例我最终定下来的结构是这样的CREATE TABLE health_event ( id INTEGER PRIMARY KEY AUTOINCREMENT, pet_id INTEGER NOT NULL, event_type TEXT NOT NULL, -- vaccine/deworm/checkup/medication event_name TEXT NOT NULL, occurred_at INTEGER NOT NULL, -- UTC 毫秒 next_due_at INTEGER, -- 可空用于周期提醒 dosage TEXT, vet_name TEXT, notes TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL );这里有个细节值得说next_due_at我特意做成可空字段而不是单独建一张提醒表。原因是提醒本质上是事件的派生属性如果单独建表就要处理两张表的一致性一旦事件被删除提醒表里的孤儿记录会非常难清理。把下次到期时间挂在事件上提醒调度模块只需要扫这张表就行逻辑简单得多。这个取舍是我踩过一次坑之后才想明白的——第一版我确实建了独立提醒表结果删除事件时忘了级联测试阶段出现了宠物已经没了但还在提醒打疫苗的诡异现象。2.2 状态机的设计繁育模块为什么最难六个模块里繁育管理是唯一一个真正需要状态机的。一只母犬/母猫的发情周期大致是静默期 → 发情前期 → 发情期 → 发情后期 → 静默期如果配种成功还要进入妊娠期 → 分娩期 → 哺乳期。每个状态之间的转换有明确的时间窗口和生理特征一旦状态判断错了后面的提醒全乱。我让 AI 先画状态转换图用文字描述不用图表然后我逐条核对。AI 第一版给的转换条件里把发情期持续天数写成了固定 9 天这明显不对——不同品种差异很大。我改成发情期持续 5 到 14 天由用户手动标记开始和结束AI 才把逻辑改对。这件事说明AI 对领域知识的掌握是平均化的它给的是统计意义上的常见值但真实项目需要的是可配置的区间。状态机的实现我用了一个简单的枚举加转换表enum EstrusState { anestrus, proestrus, estrus, diestrus, pregnant, nursing } const validTransitions { EstrusState.anestrus: [EstrusState.proestrus], EstrusState.proestrus: [EstrusState.estrus, EstrusState.anestrus], EstrusState.estrus: [EstrusState.diestrus, EstrusState.pregnant], EstrusState.diestrus: [EstrusState.anestrus, EstrusState.pregnant], EstrusState.pregnant: [EstrusState.nursing, EstrusState.anestrus], EstrusState.nursing: [EstrusState.anestrus], };每次状态变更前先查这张表非法转换直接拒绝并记录日志。这个日志在后期排查为什么提醒没触发时救了我好几次——有一次用户反馈妊娠提醒没出来一查日志发现是状态从estrus直接跳到了nursing中间漏了pregnant属于非法转换被拦截了问题定位只花了五分钟。2.3 提醒调度的去重与补偿机制提醒这块我踩的坑最多。最初的想法很简单每天扫一遍所有事件把next_due_at落在今天的挑出来推送。但实际跑起来发现两个问题一是同一天多次触发因为 App 每次启动都扫一遍二是错过补偿用户三天没打开 App第四天打开时前三天该提醒的全丢了。解决方案是引入一张轻量的提醒日志表CREATE TABLE reminder_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_id INTEGER NOT NULL, scheduled_at INTEGER NOT NULL, fired_at INTEGER, status TEXT NOT NULL -- pending/fired/missed/skipped );调度逻辑改成先生成未来 30 天的待触发记录pendingApp 启动时检查所有scheduled_at now且状态为 pending 的记录统一标记为 fired 并推送如果超过 24 小时未触发则标记为 missed 并合并成一条你有 N 条错过的提醒。这样既解决了重复触发又解决了补偿问题。注意生成未来记录时一定要设上限我一开始设了 365 天结果一只老年犬的每日用药提醒直接生成了 365 条记录数据库瞬间膨胀。后来改成周期提醒只生成未来 30 天滚动补充问题解决。3. 实操过程与核心环节实现3.1 从零到可运行 Demo 的完整步骤我把整个搭建过程拆成了七个阶段每个阶段都有明确的 AI 参与方式和人工验收标准。这套流程我跑过三遍基本可以稳定复现。第一阶段需求澄清人工为主AI 辅助。我先自己写一份 500 字的需求草稿然后让 AI 帮我列出这份需求里没写清楚的地方。AI 通常会问出二三十个问题我挑出真正影响架构的十个来回答剩下的记进待定清单。这一步千万别跳过我见过太多人直接开写写到一半发现多宠物怎么切换这种基础问题没想清楚。第二阶段数据模型设计AI 为主人工审核。把澄清后的需求丢给 AI让它输出完整的建表语句和字段说明。审核时重点看三件事字段是否冗余、外键关系是否清晰、时间字段是否统一。这一步的产出直接决定了后面所有代码的质量。第三阶段项目骨架搭建AI 生成人工调整。让 AI 生成 Flutter 项目的目录结构我一般会要求它按 feature-first 组织也就是每个模块一个文件夹里面放自己的 model、view、controller。这样后期删模块特别方便不会牵一发动全身。第四阶段核心页面实现AI 生成人工联调。先做宠物档案页因为它是所有其他页面的入口。AI 生成的页面通常能跑但样式很丑我会让它先保证功能样式后面统一调。第五阶段提醒调度实现人工为主。这块逻辑复杂AI 生成的代码我基本要重写一半。核心是前面说的提醒日志表加补偿机制。第六阶段繁育状态机实现人工为主。同上状态转换表必须人工核对。第七阶段测试与打磨AI 辅助生成测试用例。让 AI 针对每个模块生成边界测试用例比如宠物生日设为未来日期会怎样、同一天添加两条相同疫苗记录会怎样这些用例能挖出不少隐藏 bug。3.2 关键参数的计算与选择过程项目里有几个参数是需要实际算的不能拍脑袋。第一个是体重曲线的采样频率。宠物成长记录里体重是最重要的指标之一但采样太密用户嫌烦太疏又看不出趋势。我的做法是幼年期0 到 12 月建议每周一次成年期每月一次老年期每两周一次。这个频率是根据宠物生长曲线的变化率定的——幼年期体重变化快需要高频采样才能拟合出准确曲线。第二个是提醒提前量。疫苗提醒提前几天推我试过提前 1 天、3 天、7 天三个值最后定的是提前 7 天推第一次提前 1 天推第二次。原因是宠物疫苗通常需要预约提前 7 天给用户留出安排时间提前 1 天做最后提醒。这个值不是拍脑袋是我在测试群里问了二十多个养宠的人得出的经验值。第三个是照片压缩参数。成长记录里照片体积最大原图一张 3 到 5 MB存几百张手机就爆了。我最终定的压缩策略是长边限制 1920 像素JPEG 质量 80这样一张照片大约 300 到 500 KB肉眼几乎看不出差别。这个参数是拿几张典型照片反复压出来的质量 80 是清晰度和体积的平衡点再低就能看出噪点了。3.3 实操现场一次完整的 AI 协作记录我拿添加疫苗记录这个功能举例完整走一遍 AI 协作流程。第一步我给 AI 的指令是基于 health_event 表实现一个添加疫苗记录的页面需要包含疫苗名称、接种日期、下次到期日期、接种机构、备注五个字段日期选择器用系统原生的保存后返回上一页并刷新列表。第二步AI 生成了页面代码我跑起来发现两个问题一是日期选择器默认值是今天但用户可能补录历史记录应该允许选过去日期二是保存后没有刷新列表因为 AI 用的是局部状态没通知父页面。这两个问题都很典型AI 生成的代码往往能跑但不好用。第三步我针对这两个问题给 AI 追加指令日期选择器允许选择过去一年内的日期默认今天保存成功后通过回调通知父页面刷新。AI 这次改对了。第四步我自己加了一层校验接种日期不能晚于今天下次到期日期必须晚于接种日期。这两条 AI 没主动加但属于业务常识必须人工补。第五步让 AI 生成这个页面的测试用例它给出了八条我补充了三条边界情况日期为空、疫苗名称为空、下次到期日期早于接种日期最终十一条用例全部通过。这个过程说明一个道理AI 生成的代码是及格线人工补的是业务线。及格线保证能跑业务线保证好用。两者缺一不可。4. 常见问题与排查技巧实录4.1 高频问题速查表项目做完之后我整理了一份问题速查表都是实际踩过的坑按出现频率排序问题现象根本原因解决方法提醒重复推送每次启动都全量扫描引入 reminder_log 表去重提醒丢失无补偿机制启动时检查 missed 记录并合并推送状态转换异常缺少合法性校验加转换表非法转换记日志照片加载卡顿原图直接加载压缩到长边 1920质量 80数据库膨胀周期提醒生成过多只生成未来 30 天滚动补充时区显示错误存储未统一 UTC存储用 UTC展示转本地多宠物数据串了查询未带 pet_id所有查询强制带 pet_id 条件删除宠物后残留数据未做级联删除删除时事务内清理所有关联表这张表我建议每个做类似项目的人都存一份因为这些问题几乎必然会遇到提前知道能省大量调试时间。4.2 独家避坑技巧第一个技巧AI 生成的 SQL 一定要手动跑一遍 EXPLAIN。AI 写的查询经常缺索引数据量小的时候看不出来一旦记录上千条就明显卡顿。我养成的习惯是每张表建完后把 AI 生成的典型查询拿去 EXPLAIN 一下看有没有全表扫描。宠物事件表我加了(pet_id, occurred_at)的联合索引查询速度直接提升了一个数量级。第二个技巧所有涉及金额、剂量、体重的字段用整数存最小单位。比如体重存克而不是千克剂量存微克而不是毫克。浮点数在数据库里做比较和求和会有精度问题我一开始用浮点存体重结果两条 5.5 千克的记录加起来显示 11.000000001虽然不影响使用但看着难受。改成整数存克之后所有计算都是精确的。第三个技巧给 AI 的指令里永远带上不要做什么。比如实现提醒功能不要用第三方推送库不要依赖网络不要生成超过 30 天的记录。AI 很听话你说不要它就不做你不说它就可能给你引入一堆依赖。这个技巧能大幅减少后期清理依赖的时间。第四个技巧每个模块做完立刻写一份模块说明哪怕只有三行。因为项目做到后期你自己都会忘记某个字段为什么这么设计。这份说明可以直接让 AI 根据代码生成你审核一遍即可成本极低但收益极高。4.3 关于 AI 协作节奏的个人体会做了这个项目之后我最大的感受是AI 适合做宽度人适合做深度。让 AI 铺开一个模块的所有页面、所有字段、所有基础逻辑速度极快但每个模块里真正决定成败的那几个关键决策——状态机怎么设计、提醒怎么去重、数据怎么压缩——必须人来拍板。我试过完全放手让 AI 做繁育模块结果它给的状态转换逻辑自相矛盾返工花的时间比一开始自己设计还多。另一个体会是指令要短、要具体、要带验收标准。我早期给 AI 的指令都是帮我实现宠物管理功能这种大而空的话AI 生成的东西往往跑偏。后来改成实现宠物档案的编辑页面包含名称、品种、生日、绝育状态四个字段保存后返回列表页并刷新生日不能晚于今天生成质量立刻上了一个台阶。指令越具体AI 的产出越接近可用状态。最后一个体会是关于测试。AI 生成的测试用例覆盖的是正常路径边界情况基本靠人补。我现在的习惯是AI 生成测试用例后我自己再想三个如果用户乱来会怎样的场景补进去。这个习惯帮我提前发现了至少五个上线后才会暴露的 bug比如用户把宠物生日设成 2099 年、用户在同一天添加两条完全相同的疫苗记录、用户在妊娠期把状态改回静默期。这个项目后续还可以这样扩展把本地 SQLite 换成带同步能力的方案支持多设备把提醒从本地推送升级成可选的云端推送把成长记录的照片做成时间轴相册。但这些都是后话核心骨架搭稳了扩展只是往上加模块的事。