作者分享用Claude Code作为日常协作工具开发Chngd的完整技术过程,核心经验是提交过滤比模型生成更影响输出质量。
我一直独立开发一个名为 Chngd 的托管变更日志工具,把 Claude Code 当作日常协作者,而不是自动补全工具来用。以下是实际构建过程中的技术细节,以及一个犯错经历——它反而成了目前最有价值的一课。
大多数变更日志工具都需要你手动编写,而 Chngd 试图省掉这一步:连接一个 GitHub 仓库,它就能根据你最近的提交和 PR 草拟一份面向客户的变更日志条目。你审核、编辑,然后发布。不会自动发布任何内容。
纸面上看,这个管道很简单:
chore:、ci:、test:、docs: 前缀,[skip changelog] 标记)过滤这一步比我预想的更重要。直接把原始提交日志发给模型,生成的变更日志读起来就像语法更好的提交日志。过滤掉内部提交(在模型看到之前),才是真正让输出读起来像客户会想要的东西的关键。
更偷懒的方案是 OAuth 加上个人访问令牌。构建起来更快,大概快半天。但我最终选择了 GitHub App,理由归结为一个问题:付费版实际上需要什么?
免费版是一个手动"立即同步"按钮。付费版通过 webhook 在推送时自动同步,并自动草拟(从不自动发布,那一步始终是人工操作)。这本质上是 GitHub App 的功能,而非 OAuth+PAT,因为每个仓库的 webhook 和安装范围的访问权限正是 GitHub Apps 的工作方式。先用 OAuth+PAT 构建,意味着以后要让每个现有用户重新连接。提前支付额外的设置成本,避免了上线后我最不想做的一次迁移。
这部分值得诚实写出来,而不是跳过。
我用 Supabase 做 Postgres 和 Auth,但所有实际的数据访问都通过 Drizzle 在服务端进行,而非通过 Supabase 的客户端库。正因如此,我把 Row-Level Security 当作一种不适用于我正在使用的模式的的东西,没有认真考虑它。
这是错的。Supabase 的 REST API(PostgREST)位于每个表的前面,无论你自己的服务器代码如何与数据库交互。公开的 anon key 被设计 baked 到客户端 JS 中,它本来就是公开的。在没有启用 RLS 的情况下,那个 anon key 可以毫无策略地读写任何表,完全独立于你的应用代码使用什么样的访问模式。
每个表都这样暴露了好几个星期,直到我差点错过的一个监控告警 catch 到它。我审查了篡改痕迹(未发现),在全部六张表上启用了 RLS,用直接 Postgres 查询和对 REST 端点用 anon key 进行 live curl 测试两种方式验证,并设置了 Slack 告警,这样以后的告警就不用依赖我查邮件。
教训:Supabase 中 RLS 默认关闭,"我不使用客户端库"不等于"这张表受保护"。如果你用 Supabase 作为 Postgres+Auth 配合服务端 ORM,今天就检查一下这个。代价只是一次迁移和几分钟时间。
已在 chngd.dev 上线,Stripe 计费从测试模式切换到正式模式,GitHub App 安装流程,可嵌入小组件,发布时邮件通知。独立构建和发布。如果对上述任何部分有疑问,尤其是 Claude 集成或 GitHub App 设置——如果有人正在权衡同样的选择——乐于回答。