ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Claude Code实战:从零搭建宠物生命周期管理App全记录

Claude Code实战:从零搭建宠物生命周期管理App全记录

这段时间我把 Claude Code 用在了实处——从零搭建一个宠物生命周期管理 App。目标很简单:帮养宠家庭把疫苗记录、驱虫提醒、体重变化、就医档案这些零散信息统一管起来,给每只宠物建立一份从领养到老去的完整档案。这篇文章不打算写成工具说明书,而是把从项目立项、需求拆解、数据建模,到让 Claude Code 一步步生成代码、调试部署的完整过程记录下来,包括踩过的坑和现在回头看会换种做法的决定。想用 AI 辅助开发真正接手业务项目的朋友,这份实录应该能帮你省掉不少试错时间。

先交代一下背景:我不是第一次接触 AI 编程工具,但之前大多停留在「让 AI 补个小函数、修个 bug」的层面。这次我给自己定的目标是全程用 Claude Code 干活——需求梳理让它参与、代码让它写、报错让它解,我只做架构判断和最终把关。项目选的是典型业务系统:实体清晰、规则明确、交互不复杂,正好是这类工具最擅长的领域。整个流程走下来,Claude Code 大概承担了七成左右的编码工作,剩下的三成是需求边界澄清、逻辑校验和那些只有人才能想得到的边界情况。

1. 为什么选宠物生命周期管理:需求边界与应用场景判断

1.1 宠物生命周期管理到底要管理什么

先把这个 App 的业务范围划清楚。市面上宠物类应用不少,但大多集中在社交、电商、遛狗打卡这类「流量型」功能上,真正把宠物从幼年到老年的健康数据管好的产品反而少见。养宠家庭的真实痛点很具体:疫苗本纸质版容易丢、驱虫日期靠脑子记、体重变化没有连续记录、生病的化验单和处方笺散落在各个医院。

所以这个项目的核心价值就四个字:数据沉淀。具体拆成五个功能模块:

  • 宠物档案:名字、品种、生日、性别、是否绝育、领养日期、头像。
  • 疫苗与驱虫记录:疫苗名称、接种时间、下一针时间、接种医院、备注。
  • 体重与成长记录:每次称重的体重值、记录时间、备注,用于生成成长曲线。
  • 健康档案:症状、诊断、用药、手术等事件,按时间线排列。
  • 提醒中心:基于疫苗记录和驱虫记录自动生成待办,到期未完成就高亮提醒。

这套功能从技术角度看并不高深,本质是标准 CRUD 加一个日期计算引擎。但它的业务逻辑比表面看起来要细:不同疫苗的间隔周期不一样,幼宠第一年的免疫程序和成年后的加强针完全不同,驱虫也分体内体外、不同产品有不同频率。这些规则恰恰是 AI 写代码时最容易出错也最需要人来定义清楚的地方。

1.2 为什么这种业务系统正好是 AI 的主场

我不是第一次尝试用 AI 写完整项目,之前也试过让它做数据处理脚本和简单的内部工具。做完这个宠物项目之后,我对「什么样的活适合交给 AI」有了更明确的判断标准。

适合的,是那些模式成熟、边界清晰、业界有大量先例的代码。增删改查接口、数据表设计、表单校验、列表渲染,这类代码在训练语料里到处都是,Claude Code 生成起来又快又稳,基本不用我盯。宠物档案、体重记录、健康档案这几个模块,本质上就是教科书级别的资源管理模型,AI 一次生成的路由和页面代码,落地后稍作调整就能跑通。

不适合的,是强实时交互、强创新、强一致性要求的部分。比如实时推送提醒这类功能,牵扯到长连接和离线消息,AI 生成的方案往往偏理论化,真要上线还得人来设计基础设施。还有那种需要精细视觉设计的页面,AI 给出的样式总有点「模板味」,需要人工调。所以项目启动前我先划了一条线:凡是业务规则明确、输出形态固定的功能,全部交给 Claude Code 生成;凡是设计判断和异常处理,我自己兜底。

1.3 先给「从零到一」定个性:不是全自动,是半自动流水线

很多文章把 AI 编程工具描述成「你说需求它出应用」的神器,我这次的实际体验没那么玄乎,但也足够高效。用一个词概括就是「流水线式辅助开发」:我把每个阶段要做什么拆成清晰的任务单元,Claude Code 负责执行,我负责验收和纠偏。

打个比方,这有点像带一个能力很强但缺乏常识判断的实习生。你让它写一个「查询宠物列表的接口」,它交出来的代码基本能用;但你如果只说「帮我做一个宠物 App」,它会给你一个四不像的东西——功能倒是全,但数据库设计可能有缺陷,模块之间的逻辑也对不上。所以「从零搭建」真正的功夫,不在敲代码,而在把模糊想法翻译成机器能理解、人也看得懂的任务说明书。下一章就详细讲这部分。

2. 开工前的需求拆解:把模糊想法翻译成 AI 能执行的任务

2.1 用结构化描述替代口语需求:我写的初始提示词

Claude Code 最怕的不是复杂需求,而是模糊需求。我早期用它写过一个小工具,输入是「帮我做一个记账的页面」,结果它返回了一个既有月度报表又带预算规划的「全家桶」,里面一半功能我用不上,另一半实现方式不是我想要的。

这次我学乖了,写需求之前先建了一个项目需求文档,把每一条功能都明确到「谁能用、能干什么、输入是什么、输出是什么」。然后我把第一段提示词写成了这样:

你是这个项目的资深后端开发。我们正在做宠物生命周期管理 App,技术栈为 Node.js + Express + SQLite。 请基于下面的数据模型,生成完整的数据库初始化脚本(建表 SQL),要求: 1. 所有外键必须带 ON DELETE CASCADE; 2. 时间字段统一用 TEXT 存储 ISO 格式日期; 3. 每个表都要有 created_at 字段; 4. 表名和字段名统一用 snake_case。 数据模型如下: - pets:宠物基础档案,字段包括 name、species(cat/dog/other)、breed、gender、birthday、adopted_date、avatar_url、neutered - vaccine_records:疫苗与驱虫记录,字段包括 pet_id、vaccine_name、vaccinated_at、next_due_at、vet_name、note - weight_records:体重记录,字段包括 pet_id、weight_kg、recorded_at、note - health_records:健康事件,字段包括 pet_id、record_type、title、content、happened_at - reminders:提醒任务,字段包括 pet_id、kind、due_date、completed

这段提示词看着啰嗦,但每个信息都有用。「资深后端开发」是角色设定,能让模型调用更专业的代码范式;技术栈点名能避免它自作主张引入其他框架;明确约束条件能防止生成结果跑偏;表结构直接给出则省掉了它「发挥想象力」的空间。经验是:给 AI 的约束越具体,返工次数越少。

2.2 数据模型先行:五张核心表的关联关系设计

数据模型是这个项目的骨架,也是我唯一坚持自己主导的部分。原因很简单:数据库表一旦落地,后面所有代码都围着它转,改成本极高。让 AI 从零设计表结构当然也可以,但它很容易设计出「一张大表装所有字段」的方案,或者漏掉外键约束。我的做法是先把业务对象列出来,再让 AI 补充细节和索引。

最终定下来的五张表如下:

表名用途关键字段
pets宠物基础档案name、species、birthday、adopted_date、neutered
vaccine_records疫苗与驱虫记录vaccine_name、vaccinated_at、next_due_at
weight_records体重与成长数据weight_kg、recorded_at
health_records就医与健康事件record_type、title、happened_at
reminders提醒任务kind、due_date、completed

表关系是典型的一对多:一只宠物对应多条疫苗记录、多条体重记录、多条健康事件,所以从 pet 表出发的三张记录表都通过pet_id外键关联。reminders 表单独拎出来是有讲究的——它需要支持「已完成 / 未完成」的状态切换,如果在疫苗记录表上直接加状态字段,会影响原始数据的纯净度。把「提醒」和「记录」分开,记录永远只反映历史事实,提醒则反映当前待办,这是业务建模里很重要的一条原则。

表结构定稿后,我又让 Claude Code 补了索引和外键定义。它很快给出了带复合索引的脚本,比如在reminders(due_date, completed)上建索引,方便「今天该提醒什么」的查询,这部分确实帮我省了不少事。

2.3 技术栈定调:为什么选这个组合而不是别的

技术选型直接决定 AI 生成代码的效率和可维护性。我在立项时对比了三种方案:

方案优点缺点结论
原生 App(iOS/Android)体验好、能调系统能力双端开发成本高,AI 生成代码难度大不选
小程序生态好、触达快平台审核约束多,部分能力受限备选
Web App(PWA)跨平台、开发效率高、AI 语料丰富离线能力和系统调用受限选了

最终选了React + Vite 前端 + Node.js Express 后端 + SQLite 数据库的组合。理由有三条。第一,全栈 JavaScript 让 AI 只需要切换上下文而不用换语言范式,生成质量更稳定。第二,SQLite 作为本地文件型数据库,零配置、好迁移,对单机应用是性价比最高的选择,没必要为一个中小型工具上 PostgreSQL 集群。第三,这个组合在训练语料里占比极高,Claude Code 对它最熟悉,遇到问题时的解决方案也最成熟。

至于「App」这个词,我把它实现为一个移动端适配良好的 PWA 页面,可以添加到手机桌面,体验上接近原生应用。如果后续真要上架应用商店,前端代码可以大部分复用,后端接口也不需要重写。

3. 主干搭建实战:项目骨架生成与核心 API 落地的完整过程

3.1 第一次会话:让 AI 先生成目录结构和数据库脚本

任务拆解之后,第一步我让 Claude Code 完成三件事:初始化项目目录、生成数据库建表脚本、搭出后端入口文件。这三个任务放在一次会话里做,因为相互依赖且范围明确。

目录结构方面,Claude Code 给的方案很标准:

pet-app/ ├── server/ # 后端 │ ├── db.js # 数据库连接与初始化 │ ├── routes/ # 路由文件 │ ├── app.js # Express 入口 │ └── schema.sql # 建表脚本 ├── client/ # 前端 │ ├── src/ │ ├── pages/ │ └── components/ └── README.md

数据库这块我比较较真,让它把建表脚本写完整再交给我审。成品基本符合预期,外键约束、默认值、索引都有了。只发现一个隐患:所有日期字段用的是TEXT类型,这在 SQLite 里是常规做法,但要求所有写入端必须统一传YYYY-MM-DD格式,否者排序和比较会出问题。我随即在需求文档里加了一条约定:所有日期在 API 层做格式校验,非 ISO 格式直接返回 400。这个约定后来避免了很多隐蔽 bug。

3.2 宠物档案模块:从生成路由到跑通前端联调

数据库就绪后,我让 Claude Code 按模块推进。第一个做的是宠物档案模块,因为它是其他所有模块的父表,必须先跑通。这一段的提示词我拆得比较细:

请生成 pets 模块的全部后端代码: 1. GET /api/pets 返回宠物列表,支持按 species 筛选; 2. POST /api/pets 创建宠物,校验 name、species、birthday 必填; 3. GET /api/pets/:id 返回宠物详情,包含它的最近 5 条体重记录; 4. PUT /api/pets/:id 更新宠物; 5. DELETE /api/pets/:id 删除宠物,级联删除关联记录。 所有接口用 JSON 响应,错误码遵循 REST 惯例。

Claude Code 在几分钟内生成了对应的路由文件和数据库操作函数。我大致浏览了一下,结构没毛病,但有一个细节它漏了:创建宠物时没有对 birthday 做「不能是未来日期」的校验。这种业务规则光靠通用编程范式是推不出来的,必须人来补充。我直接在提示词里追加了一句要求,它立刻改了。

前后端联调这一步,老实说比写代码还费劲。React 页面组件由 Claude Code 生成,逻辑不复杂:一个列表页、一个详情页、一个表单弹窗。但联调时发现 API 返回的字段名和前端表单的 state 命名对不上——它后端用了adopted_date,前端表单却用了adoptDate。这种低级不一致靠人眼扫很难发现,跑一遍交互就暴露出来了。后来我在前端提示词里明确要求「字段名一律使用后端 API 的 snake_case」,这个问题就再没犯过。

3.3 现阶段最典型的「AI 幻觉」:我没盯着看就翻车的地方

整个项目做下来,Claude Code 一共出现过四次比较明显的「幻觉」,也就是生成看似合理但实际有问题的代码。这里列两个最有代表性的。

第一次是虚构 API。它在一个文件里写了db.prepare(...),但其实我们用的 SQLite 驱动方法名不是这个——Claude Code 根据自身的知识库「脑补」了一个其他语言的 API 风格。代码静态看完全没毛病,一运行直接报TypeError: db.prepare is not a function。这种问题没法靠审查发现,只能靠跑测试。

第二次是正则表达式误伤。它给手机号校验写了一条特别复杂的正则,结果测试时发现合法的座机号被拦了,非法的号码反而能通过。我直接把校验规则简化成「非空 + 长度 6 到 20」,够用就好。这种过度设计在 AI 生成代码里很常见——它追求「看起来严谨」,但没考虑业务实际需要什么样的严谨。

总结下来,AI 幻觉的规律是:越冷门的 API 越容易编错,越复杂的规则越容易做过头。应对手段就是两条:关键函数一定写单元测试,复杂的校验规则一定先跑真实用例验证。

4. 核心功能逐个实现:疫苗提醒、成长曲线与健康档案

4.1 疫苗与驱虫提醒:不是简单加日期的活

疫苗提醒是这个 App 最核心的业务功能,也是最不能全交给 AI 的部分。表面上看,逻辑不过是「上次接种日期 + 间隔周期 = 下次接种日期」,但实际规则比这复杂得多。

幼宠第一年的免疫程序通常是「三针联苗 + 狂犬」,每针间隔 3 到 4 周;成年后变成每年一针加强。驱虫更是分体内、体外,不同品牌的产品间隔周期从一个月到三个月不等。所以不能只存一个「下次接种日期」,还要把「疫苗类型」和「间隔周期」作为业务规则存下来。

Claude Code 的代码生成这部分我只让它做一件事:根据vaccinated_at和间隔月数计算next_due_at,计算函数我给它写了明确规则:

function buildNextDueDate(lastDate, intervalMonths) { const d = new Date(lastDate + 'T00:00:00'); const next = new Date(d.getFullYear(), d.getMonth() + intervalMonths, d.getDate()); return next.toISOString().slice(0, 10); }

注意两个细节。第一,new Date之前先拼T00:00:00,否则在不同时区的设备上解析纯日期字符串会偏移一天;第二,用setFullYear与setMonth的这套写法,天然处理了「1月31日加一个月该落到哪一天」的溢出问题——JavaScript 会把 2 月 31 日自动进位成 3 月 2 日或 3 月 3 日,比手动算安全得多。这个函数虽然短,但承载了全 App 的提醒正确性,值得认真对待。

4.2 成长曲线:把体重数据变成一眼能看懂的变化趋势

体重记录模块的思路和前两个模块一样:记录表负责存数据,页面负责展示。真正花心思的是成长曲线的实现方式。

前置服务是一名宠物医生朋友给的建议——幼宠的体重增长曲线是不是正常,比某一次的体重绝对值更有参考意义。所以我在体重记录表里每一条都存了recorded_at和weight_kg,前端拿到数据后按时间排序,画出一条折线图。Claude Code 在图表这块没有让我失望,它用开源图表库直接生成了一张带坐标轴、数据点和最轻最重标注的曲线图,十几分钟就搞定。

这个模块的坑在数据录入环节。宠物主人称重的时间不固定,容易漏记、记错,而且体重数据可能出现异常值,比如把克当成千克输入。我在录入表单里加了两层防护:一是体重范围校验(0.1 到 100 千克),二是「相比上次变化超过 30% 时弹出确认提示」。后者是人想出来的业务规则,AI 不会主动替你设计,但它能很好地帮你实现。

4.3 健康档案与事件时间线:把零散就医记录串成一条线

健康档案模块设计成事件式的。每次就诊、每次用药、每次手术都是独立事件,带record_type字段区分类型,用happened_at排序后自然形成一条时间线。这种设计比传统的「病历夹」模式更好用,因为它让主人可以跳着看某一类事件——比如只看疫苗相关的记录,而不用翻完整本记录。

Claude Code 在这个模块的贡献主要是把时间线 UI 写得比较规整:左侧一列圆点代表事件,右侧是事件详情卡片,类型用不同颜色区分。数据层面没费什么劲,因为它只是套用了前面宠物档案模块的模式。

不过这个模块引出一个新需求:附件上传。就医记录经常伴随化验单照片,我让 Claude Code 增加了一个简单的文件上传接口,把图片存到本地uploads目录,数据库只记录路径。它实现得中规中矩,但我提醒自己——本地存储方案在未来多用户部署时肯定要改,现在先不折腾。

5. 质量关卡:AI 写出来的代码必须过的三道门槛

5.1 AI 代码审查清单:最常见的三类问题与处理方式

Claude Code 把代码交出来之后,我从来不会直接合入主干。吃过几次亏之后,我总结了一张审查清单,按问题出现的频率排序:

问题类型典型表现处理方式
逻辑幻觉用了不存在的库 API、错误的方法名跑一遍单测,以运行结果为准
边界遗漏空值、非法格式、极端日期没处理补边界测试用例
结构膨胀每个相似功能都生成一大段重复代码要求抽取公共方法、复用组件
数据一致性删除主表时漏掉级联操作检查外键约束和 DELETE 逻辑

四个问题里,「结构膨胀」最隐蔽也最影响长期维护。Claude Code 在生成第二个、第三个相似模块时,往往直接把上一份代码拷过来改改,虽然能用,但项目的重复代码会越来越多。我的做法是在需求文档里明确要求「公共查询函数抽到单独文件」,同时自己定了一条规矩:每个模块生成后,看一眼代码重复率,超过两处就要求它重构。

5.2 哪些功能必须手动验证,不能只靠 AI 自测

Claude Code 自己也提供了测试工具,能跑通接口返回正确数据,但这远远不够。有些业务逻辑必须用手工用例过一遍,我整理了一张「强制人工验收」清单:

  • 日期相关:跨年、跨月、闰年 2 月 29 日接种后的下一个到期日;
  • 空数据状态:新用户没有任何记录时,列表页和图表页不能白屏;
  • 级联删除:删除一只宠物后,它的体重、疫苗、健康记录是否全部消失;
  • 非法输入:体重填了负数、日期填了 2026 年、疫苗名称为空,系统都要给出友好提示;
  • 时间线排序:多条同一天的记录,展示顺序是否稳定。

这五项里每一项我都真实跑过。其中「空数据状态」那项,AI 生成的页面确实漏了——它默认列表有数据,一旦数据库为空,前端直接报 undefined 错误。这也是 AI 编程的共性盲区:它擅长处理「正常情况」,对「什么都没有」的情况常常忽略。人工验收恰恰补上了这块。

5.3 上下文窗口管理:让 Claude Code 始终记住该记的事

用 Claude Code 做大型项目,最需要管理的不是代码,而是它的「记忆」。每个会话的上下文窗口有限,项目一旦铺开,它很容易忘记前面约定的字段命名规则、错误码规范、组件风格。

我的做法是项目根目录放一个CONVENTIONS.md,把反复用到的约定写进去——包括日期格式、字段命名规范、接口错误码结构、页面组件风格。每开始一个新模块的会话,我第一句话就是让它先读这个文件。效果立竿见影:跨模块的命名不一致、代码风格漂移问题大幅减少。

另外,每次会话结束时我会让它生成一段「当前进度摘要」,包含已完成的功能、未完成的部分、遗留的坑。下个会话开始时把摘要贴给它。这套流程跑顺之后,Claude Code 连续多天的工作基本无缝衔接,很少出现「它忘了上一轮做了什么」的情况。

6. 跑通之后的迭代方向:从能用走向好用

6.1 下一阶段功能优先级怎么排

当前版本已经能在本地完整跑通:宠物档案增删改查、疫苗驱虫记录、体重曲线、健康档案、提醒中心都上线了。但我很清楚,离「好用」还有距离。按投入产出比排,下一阶段优先级如下:

  1. 多宠物支持:现在一只宠物是全部数据的前提,现实中大部分用户有两三只猫狗,这个需求最迫切。
  2. 云端同步:本地 SQLite 数据一旦换设备就没了,这是 PWA 方案的硬伤。考虑引入云数据库做同步,但这事牵扯账号体系和网络缓存,工程量不小。
  3. 疫苗本导出:做成一个可打印的 PDF 免疫记录页,去看医生时直接出示,这个功能实用价值很高,实现成本却很低。
  4. 日常行为记录:饮食量、饮水量、排便情况这些日常数据,对早期发现健康问题很有用,但录入负担也大,需要设计成轻量打卡模式。

我建议同类项目在规划迭代时也按这个思路排序:先补核心场景的缺口,再做锦上添花。数据导出这类低成本高感知的功能,比一个花哨的交互动效更值得先做。

6.2 几件让我开发效率明显提升的小事

做到这一步,累计的代码量已经接近万行,而实际投入的「人时」远低于传统开发方式。有几点经验值得单独拎出来说。

第一,把常用提示词沉淀成模板。同样是「生成一个 CRUD 模块」,我第一次写了 200 字的提示词,后来越写越精简,最后变成一张包含角色、技术栈、约束、验收标准的模板表。新模块直接套,基本不用动脑。

第二,每次让 AI 干活前,先明确验收标准。这不是阿里的繁琐,而是减少来回拉扯的最有效手段。「生成一个列表页」和「生成一个列表页,要求包含搜索框、分页器、加载状态三要素」是两种完全不同的效率。

第三,在让 AI 改动旧代码前,先让它解释现有代码的意图。有一次我想给疫苗模块加一个「补打提醒」功能,如果直接让 AI 改,它大概率会叠床架屋地再加一块逻辑。我先问它现有的提醒状态是怎么流转的,它分析完给出的改造建议比我预想的方案简洁得多——直接复用已有状态位。

第四,也是最重要的一条:别把 AI 当计算器用。它生成代码再快,判断业务价值、权衡技术债务、决定什么时候该重构,这些事它做不了。我的定位始终是「我做架构师和验收人,它做码农」,这个分工让整个项目既快又不失控。

回头看这个宠物生命周期管理 App 的开发全程,最大的收获不是那几千行代码,而是摸索出了一套「需求结构化拆解 + AI 按模块生成 + 人工仿真验收」的流水线工作法。现在再让我从零起一个新项目,不管是内部工具还是面向用户的业务系统,我都有底气说:这套流程能跑,而且跑得挺顺。如果你也正在尝试用 AI 工具做完整项目,我的建议是先别贪大,找一个像宠物管理这样业务边界清晰的选题,把流程跑通,你会回来感谢自己的。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进