209021e7d2
- 新增 development/iterations/iteration-1/:15 份角色报告 + 进展看板(已完成/未闭环/下一步),作为双人协作的进度事实来源 - 新增 ADR-006:测试与交付容器化策略(Testcontainers / 交付 Docker 包 / 本机库仅个人联调) - Git 工作流规范补充:敏感信息只进忽略文件或 sample、测试数据不入库、测试代码限标准测试目录 - 门禁:mkdocs build --strict 通过(零警告)
148 lines
11 KiB
Markdown
148 lines
11 KiB
Markdown
# 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` —
|
||
|
||
```java
|
||
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` —
|
||
|
||
```java
|
||
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:文档未提、但与「可开工」相悖的其他事实
|
||
|
||
1. **patbond-api 零测试**(风险 #6 说了一半):`find` 全仓库不存在任何 `src/test` 目录、任何 `*Test*.java`。不是"测试少",是一个测试都没有。
|
||
2. **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 节的契约还全是"建议")。
|
||
3. **接口路径与规范不符**:现有接口是 `/auth/register`,文档 6.2 要求 `/api/v1/auth/register`——第一迭代要么改路径要么改文档,属于开工即遇的契约决策。
|
||
4. **patbond-common 强制传染依赖**(文档 4.1 提出原则但现状违反):`patbond-common/pom.xml:23-47` 直接依赖 `spring-boot-starter-amqp`(RabbitMQ)、`openfeign`、`loadbalancer`、`nacos-discovery/config`。本机没有 RabbitMQ,README 却把它列进技术栈;所有模块被动拖入这些依赖。
|
||
5. **patbond-flutter 工作区不干净**:`git status` 显示 `README.md` 有未提交修改(在运行步骤中加了一行 `flutter clean`)。"正式启动"时点上仓库状态未固化。
|
||
6. **target/ 残留指向外部主机 patbond.cn 的旧配置**(详见声明 4)——auth 那份是硬编码,无环境变量兜底。
|
||
7. **技术代际问题当场可见**:父 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** |
|
||
|
||
**开工前必须解决(按阻塞程度排序)**:
|
||
|
||
1. 安装并配置本地 Nacos(否则现有原型都无法端到端运行)。
|
||
2. 为当前用户建立 PostgreSQL 角色/库访问,验证 patbond 库 7 个 schema 是否真的已导入。
|
||
3. 将构建 JDK 切换/固定为 17(java-17-openjdk 已在 `/usr/lib/jvm/`,配 JAVA_HOME 或 Maven toolchain)。
|
||
4. 清理 `patbond-api` 各模块 `target/`,消除指向 `patbond.cn:8848` 的旧配置产物。
|
||
5. 安装 mkdocs(否则文档门禁不可执行)。
|
||
6. 提交或还原 `patbond-flutter/README.md` 的未提交修改,固化起点。
|