- 新增 development/iterations/iteration-1/:15 份角色报告 + 进展看板(已完成/未闭环/下一步),作为双人协作的进度事实来源 - 新增 ADR-006:测试与交付容器化策略(Testcontainers / 交付 Docker 包 / 本机库仅个人联调) - Git 工作流规范补充:敏感信息只进忽略文件或 sample、测试数据不入库、测试代码限标准测试目录 - 门禁:mkdocs build --strict 通过(零警告)
11 KiB
Patbond 第一迭代 Reality Check 报告
- 核实人:TestingRealityChecker(Reality Checker agent)
- 核实日期:2026-09-03
- 核实对象:
patbond-api、patbond-flutter、patbond-doc(位于/home/lx/workspace/patbond/) - 参照文档:
patbond-doc/docs/development/development-plan.md第 2 节(当前基线)、第 11 节(当前已知风险) - 方法:只读核查(源码阅读、grep、wc、ls、git 只读命令、版本检查),未启动任何服务、未修改任何文件、未运行构建
总体结论:NEEDS WORK。文档对现状的描述罕见地诚实、准确(未发现夸大),但本机环境存在两个硬阻塞(无 Nacos、数据库不可访问验证),且默认 JDK 与团队基线不符。当前三仓不构成任何端到端链路,「正式启动第一版」只能理解为"启动开发计划",而非"存在可运行的第一版"。
声明 1:patbond-api 有 6 个接口;用户仅存内存;token 不可验证
结论:CONFIRMED(三点全部属实)
接口共 6 个,逐一定位:
| # | 接口 | 证据 |
|---|---|---|
| 1 | POST /auth/register |
patbond-api/patbond-auth/src/main/java/com/patbond/patbond/auth/controller/AuthController.java:24-27 |
| 2 | POST /auth/login |
同上文件 :29-32 |
| 3 | POST /internal/users |
patbond-api/patbond-user/src/main/java/com/patbond/patbond/user/controller/UserController.java:27-30 |
| 4 | POST /internal/users/verify-password |
同上文件 :32-35 |
| 5 | GET /internal/users/{id} |
同上文件 :37-40 |
| 6 | GET /internal/users/by-username/{username} |
同上文件 :42-45 |
全仓库仅这两个 Controller,无其他 @RestController。
用户仅存内存:patbond-user/.../service/UserService.java:21-23 —
private final AtomicLong idGenerator = new AtomicLong(1);
private final Map<Long, UserRecord> usersById = new ConcurrentHashMap<>();
private final Map<String, UserRecord> usersByUsername = new ConcurrentHashMap<>();
无任何 Repository、DataSource、JDBC/JPA 依赖或 PostgreSQL 连接配置。服务重启即丢失全部用户。密码确实用 BCrypt 加密(UserService.java:24,35),这是原型中唯一像样的安全措施。
token 不可验证:patbond-auth/.../service/AuthService.java:47-56 —
private AuthTokenResponse buildToken(Long userId, String username, String nickname) {
return new AuthTokenResponse(
"Bearer",
UUID.randomUUID().toString().replace("-", ""),
LocalDateTime.now().plusHours(2),
...
token 是随机 UUID 字符串,生成后不存储、无签名、无校验端点、无 refresh/logout 接口。所谓"2 小时过期"只是响应里的一个展示字段,服务端无法执行。文档风险 #2 属实。
连带核实:风险 #1(API 用 Long 用户 ID)属实——UserController.java:38 @PathVariable Long id;风险 #3(/internal/users/** 无访问控制)属实——UserController 无任何鉴权注解,全仓库无 Security 配置类、无 Filter/Interceptor(源码共 15 个 Java 文件,逐一核对)。
声明 2:patbond-flutter 无网络层、无登录页;测试仅一个导航冒烟测试
结论:CONFIRMED
无网络层:patbond-flutter/pubspec.yaml 依赖仅 cupertino_icons: ^1.0.8 和 shared_preferences: ^2.5.4,没有 http、dio 或任何网络包。grep -rniE "\bhttp\b|dio|HttpClient|Uri\.parse|login" lib 在 14 个 Dart 文件中零命中(唯一命中是 pets_page.dart:652 的 radio_button_unchecked 图标名,属误匹配)。
无登录页:lib/ 全部文件为 app/、core/theme/、data/demo_data.dart、features/{create,home,main,pets,post,profile,services}、models/、state/、widgets/——没有任何 auth/login feature。数据全部来自 lib/data/demo_data.dart。
测试仅一个:test/ 目录只有 widget_test.dart 一个文件,内含一个 testWidgets('Patbond renders the main navigation', ...),断言五个 Tab 文案和写死的演示文案("北京 · 朝阳区"、"28°C 晴")。这正是文档风险 #6 所述的"一个导航冒烟测试"。
声明 3:patbond_postgresql.sql 包含 7 个 schema、36 张表
结论:CONFIRMED
文件:/home/lx/workspace/patbond/patbond-doc/docs/database/patbond_postgresql.sql(1950 行,91 KB)。
grep -icE "^\s*CREATE SCHEMA"= 7:platform、identity、media、pet_health、community、creation、marketplace—— 与文档第 3 节的 schema 表完全一致。grep -icE "^\s*CREATE TABLE"= 36,分布:identity 5、media 1、pet_health 9、creation 3、community 8、marketplace 7、platform 3。
注意:文件在磁盘上属实,但"已导入本地数据库"这半句无法验证(见声明 5 的 PostgreSQL 项)。
声明 4:application.yml 只有 .sample,干净检出无法直接启动
结论:CONFIRMED——且发现一个文档未提的隐患
patbond-auth/src/main/resources/与patbond-user/src/main/resources/各自只有application.yml.sample,无application.yml(ls -la核实)。patbond-api/.gitignore明确忽略patbond-*/src/main/resources/application.yml并保留.sample;git status工作区干净。因此干净检出后 Spring Boot 无配置文件可读,无法直接启动。风险 #5 属实。Readme.md只写了mvn compile,完全没提"复制 sample"这一步,佐证"无法按 README 直接启动"。
隐患(文档未提):本地 target/classes/ 里残留着旧版真实配置的编译产物:
patbond-user/target/classes/application.yml:server-addr: "${NACOS_SERVER_ADDR:patbond.cn:8848}"patbond-auth/target/classes/application.yml:硬编码server-addr: http://patbond.cn:8848/nacos,连环境变量覆盖都没有
这两份与 .sample(默认 127.0.0.1:8848)内容不一致(diff 核实)。若有人在不清理的情况下直接跑旧产物,服务会去连外部主机 patbond.cn:8848。target/ 已被 gitignore,不影响干净检出,但本机开工前应清理。
声明 5:环境检查(JDK 17 / Maven / Flutter / PostgreSQL / Nacos)
结论:PARTIAL——五项中两项有问题,一项无法验证
| 组件 | 要求(文档 5.1) | 实际 | 判定 |
|---|---|---|---|
| JDK | 17,"不要使用更高版本代替基线" | 默认 JDK 26(java -version → openjdk 26.0.2.1);java-17-openjdk 已安装但非默认(archlinux-java status) |
PARTIAL:可用但需手动切换/设 JAVA_HOME |
| Maven | 3.9+ | 3.9.16(但运行在 Java 26 上,mvn -v 显示 runtime: java-26-openjdk) |
满足,注意 JDK 绑定 |
| Flutter | 满足 pubspec sdk: ^3.12.2 |
Flutter 3.44.6 stable,Dart 3.12.2 | 满足 |
| PostgreSQL | 16+,"现有本地库作为开发数据源" | 服务端 18.6 正在运行(pgrep 见 /usr/bin/postgres -D /var/lib/postgres/data;psql/pg_ctl 18.6) |
版本满足;但当前 OS 用户 lx 无数据库角色(psql -ltq → FATAL: role "lx" does not exist),无法验证 patbond 库和 7 个 schema 是否真的已导入。"已导入本地数据库"一说 UNVERIFIED |
| Nacos | 必需(auth 经 Nacos 发现 user) | 完全缺失:无二进制(command -v nacos 空)、无 /opt/nacos、无 systemd 单元、无运行进程 |
FAILED——硬阻塞 |
Nacos 缺失的影响是致命的:UserClient.java:12 是 @FeignClient(name = "patbond-user"),auth 必须经服务发现才能调用 user。没有 Nacos,连现有的登录原型都无法在本机端到端跑通。
声明 6:文档未提、但与「可开工」相悖的其他事实
- patbond-api 零测试(风险 #6 说了一半):
find全仓库不存在任何src/test目录、任何*Test*.java。不是"测试少",是一个测试都没有。 - mkdocs 未安装:
mkdocs: 未找到命令。文档第 9 节把mkdocs build --strict列为 CI 最低门禁,本机现在跑不了。同时mkdocs.yml导航只挂了index.md和development-plan.md,database/patbond_postgresql.sql不在导航中——docs/实际只有 3 个文件,第 1 节列出的 api/architecture/testing/operations 目录均不存在(文档自己声明"出现对应文档时创建",一致,但意味着 OpenAPI 契约为零,第 6 节的契约还全是"建议")。 - 接口路径与规范不符:现有接口是
/auth/register,文档 6.2 要求/api/v1/auth/register——第一迭代要么改路径要么改文档,属于开工即遇的契约决策。 - patbond-common 强制传染依赖(文档 4.1 提出原则但现状违反):
patbond-common/pom.xml:23-47直接依赖spring-boot-starter-amqp(RabbitMQ)、openfeign、loadbalancer、nacos-discovery/config。本机没有 RabbitMQ,README 却把它列进技术栈;所有模块被动拖入这些依赖。 - patbond-flutter 工作区不干净:
git status显示README.md有未提交修改(在运行步骤中加了一行flutter clean)。"正式启动"时点上仓库状态未固化。 - target/ 残留指向外部主机 patbond.cn 的旧配置(详见声明 4)——auth 那份是硬编码,无环境变量兜底。
- 技术代际问题当场可见:父 POM 锁定 Spring Boot 2.7.18 / Spring Cloud 2021.0.9(
pom.xml),而本机默认 JDK 26——Boot 2.7 在 JDK 26 上编译运行风险很高,风险 #8 的"先升级还是先交付"不是远虑,是第一次mvn compile就会撞上的问题(本次核查按约定未运行构建验证)。
最终判定
| 项 | 判定 |
|---|---|
| 文档第 2 节「当前基线」 | 准确,无夸大 |
| 文档第 11 节「已知风险」#1-#6 | 逐条核实属实 |
| 声明 1(API 6 接口/内存用户/假 token) | CONFIRMED |
| 声明 2(Flutter 无网络层/登录页,单测试) | CONFIRMED |
| 声明 3(7 schema / 36 表) | CONFIRMED(导入状态 UNVERIFIED) |
| 声明 4(配置只有 sample) | CONFIRMED |
| 声明 5(环境) | PARTIAL:Maven/Flutter 就绪;JDK 17 需切换;PostgreSQL 在跑但当前用户无访问角色;Nacos 缺失 |
| 能否立即开工 | NEEDS WORK |
开工前必须解决(按阻塞程度排序):
- 安装并配置本地 Nacos(否则现有原型都无法端到端运行)。
- 为当前用户建立 PostgreSQL 角色/库访问,验证 patbond 库 7 个 schema 是否真的已导入。
- 将构建 JDK 切换/固定为 17(java-17-openjdk 已在
/usr/lib/jvm/,配 JAVA_HOME 或 Maven toolchain)。 - 清理
patbond-api各模块target/,消除指向patbond.cn:8848的旧配置产物。 - 安装 mkdocs(否则文档门禁不可执行)。
- 提交或还原
patbond-flutter/README.md的未提交修改,固化起点。