拥有 17 年经验的解决方案架构师。从 2026 年 3 月到 2026 年 7 月,我是某个海湾国家国家港口社区系统身份与单点登录层的唯一动手开发者——该平台是其港口与物流部门的前端系统。目前已在生产环境中上线。

我想准确说明“唯一”,因为这很重要:其他人员对两个代码仓库都有提交——CI、自动化测试、少量修复以及下游集成工作。我撰写了约 80% 的后端提交和约 70% 的前端提交。没有任何其他人对核心系统进行过动手功能开发。这是真实情况。

来自 git log --numstat 的实际数据量:

  • 602 次提交,跨 1,423 个文件更改约 184,000 行代码
  • 后端:383 个 Java 文件 / 约 21k 行代码,19 个控制器,83 个 REST 端点
  • 前端:152 个 TS/HTML 文件 / 约 15.3k 行代码,62 个 Angular 组件
  • 6 个外部集成,每个都有真实适配器和模拟适配器
  • 4 个环境,通过 2 次独立渗透测试并完成修复

我在 4 月向领导层提交的书面估算是:没有 AI 工具的情况下,需要 3–4 名工程师用 3 个月时间完成。

架构

六边形架构(端口与适配器)+ CQRS。领域包中零 Spring 或 JPA 导入——可 grep 验证,返回为空。这是检验六边形架构是否真正落地而非口号的实际标准,大多数声称使用六边形架构的代码库都无法通过此检查。

domain/         纯领域层——模型、值对象、事件、端口。不含框架导入。
application/    用例层——命令(写入)和查询(读取)、DTO、组装器。
dataprovider/   适配器层——JPA 实体、Spring Data 仓库、SOAP 客户端。
web/            入站适配器——控制器、DTO、映射器、JWT 过滤器、SAML 处理器。

进入全屏模式 退出全屏模式

每个功能都配对 XxxCommand/XxxCommandImpl(事务性写入)和 XxxQuery/XxxQueryImpl(只读)。每个外部依赖都通过端口封装,Spring profile 选择真实或模拟适配器——这意味着 QA 和 UAT 可以在不依赖政府系统在线的情况下运行完整的端到端流程。而这些系统经常处于离线状态。

一个值得借鉴的 JPA 细节:@Version 乐观锁配合先查找再更新的保存模式,专门用来避免 Spring Data 的 null 版本即新实体行为导致的主键重复错误。这个错误很容易出现,调试起来非常痛苦。

用户生命周期是一个真正的状态机(PENDING_VERIFICATION → ACTIVE → LOCKED/INACTIVE),使用状态模式实现,因此无效转换会在领域层直接失败,而不是在 UI 中用分散的 if 语句进行防护。

值得一读的四个问题

1. Java 的 X.509 解析器拒绝了政府证书

AVA not a sequence——一种格式错误但在现实世界中常见的编码,JDK 的严格解析器直接拒绝。我改用 BouncyCastle 的 X.509 工厂编写了一个手动元数据解析器。

后来部委在生产环境中轮换了签名证书,系统再次宕机。于是我让证书支持热重载,并在失败时自动刷新。它在二十天后再次轮换——这次系统自我修复,没有触发任何告警。

2. 间歇性 500 错误,大家都归咎于网络

测试人员在印度,服务器在阿曼,因此“这是延迟问题”成为共识。

我进行了核实。配置的超时时间是 60 秒。印度到阿曼的实际往返延迟是 100–250 毫秒——大约短 240 倍。即使出现严重退化,也不可能产生 60 秒的延迟。而且 500 或 503 错误是由服务器生成的,在它已经接受连接之后,因此从定义上讲这不是网络路径问题。

政府 API 本身就不稳定。这个结论支持采用带退避的重试策略,而不是花几周时间追查一个虚构的网络问题。

在同一个集成中还埋藏着一个问题:他们的生产 API 对有效工作许可返回 "WORKING",而不是 "Active"。一个字符串不匹配就静默阻止了所有真实用户注册。

3. 可能在支付过程中产生竞争的三个时钟

10 分钟发票过期、约 2 分钟前端轮询窗口,以及 60 秒后端对账任务。缓慢的 3-D Secure 确认可能超出前端的耐心等待时间,即使支付成功

修复方案是两个独立于浏览器是否仍然打开的后端调度器作为安全网,加上两条独立的最终化路径——银行的服务器到服务器回调(权威路径,即使用户关闭标签页也能工作)和 SPA 的轮询(回退路径)——都通过单一的幂等性守卫进行 funnel,确保无论哪条路径获胜,下游同步都只触发一次。

相关且更愚蠢的问题:浏览器直接 GET 银行支付端点会静默丢弃 POST 请求体。修复方案是使用后端渲染的自动提交表单,这样浏览器根本不会 GET 该端点。

4. Chrome 阻止 XHR 的 TLS 重新协商,但不阻止导航

所有 API 调用都以 net::ERR_FAILED 失败,而 SAML 重定向却完美工作。

这种不对称性导致问题代价高昂——一个认证重定向成功但后续所有 API 调用都失败的系统,看起来完全像是后端认证错误。实际上这是基础设施配置问题。

没人警告你的返工

两个代码仓库共经历 16 个不同的还原和重建周期。两个最突出的例子:

  • 下游令牌交换握手在一个下午经历了四种不同协议——两步式、服务 JWT bearer、app_secret bearer、无认证头——随后在接下来的几天里又被还原两次,最终才确定为单步交换。
  • 一个业务线规范化规则:一天内通过四个 PR 构建了四种策略,当对方确认他们的 API 需要完全按照存储的值时,当天全部还原,从 main 中完全移除,两周后又以第三种方式重建。

这些都不是 AI 或我的错。这是与需求尚未确定的团队进行集成时必然发生的情况。

Claude 实际帮助的地方,以及没有帮助的地方

它编写了大部分代码。不仅仅是脚手架——适配器对、数十个功能的 CQRS 命令和查询实现、JPA 映射约定、Angular 组件、集成客户端的大部分内容。这种压缩是单人覆盖 3–4 人工作量的全部原因。

它没有发现上述四个问题中的任何一个。每个问题都始于知道应该怀疑什么。证书失败表现为通用的 SAML 错误。500 错误被房间里的每个人自信地误诊。时钟竞争在测试中从未出现。TLS 错误表现为认证问题。

你无法通过提示来修复你尚未正确识别的问题——你描述的是你已经解释过的症状,而解释本身就是工作。

还有一个没人提到的版本:我在五个月中多次达到模型使用限制。速率限制是一个真实的时间表约束,而不是脚注。

我会做 differently 的事情

后端的测试覆盖率约为 23% 指令覆盖率。这个数字很低,我不会粉饰它。如果有第二名工程师,我会更早投资于自动化覆盖率,并让有人在实现之前审查下游集成协议,而不是通过四轮现场返工才发现不匹配。

很乐意深入讨论其中任何内容。