# R1.3.10 PostgreSQL 后端统一验证入口任务报告

## 交付结果

- 产品分支：`feat/r1310-test-postgres`。
- 产品提交：
  - `ebe829b feat: expose backend verification result`。
  - `a806570 fix: serialize PostgreSQL verification tests`。
- 产品 PR：[pikainc/pikaoa#12](https://github.com/pikainc/pikaoa/pull/12)。
- 执行记录：[pikainc/pikaoa#10](https://github.com/pikainc/pikaoa/issues/10)。

## 入口契约

- `scripts/verify-backend.sh` 是单一非交互验证入口，`make verify-backend` 是默认 Make 包装。
- 入口依次执行：
  - `go test -p 1 -count=1 ./...`。
  - `go vet ./...`。
  - `make build`。
- 全仓 integration package 共用专用测试 Job 注入的一个 PostgreSQL DSN，并且会各自执行 migrate。
  - `-p 1` 固定 package 并发为 1，避免并发迁移和数据库状态竞争。
  - `-count=1` 禁用 Go test cache，确保每次 Job 都真实执行。
- 阶段开始、完成和失败写入 stderr，避免长任务无输出；stdout 最终只输出一个 JSON 文档。
- PostgreSQL 只披露 `PIKAOA_TEST_DATABASE_URL` 是否为非空，不读取、打印、拼接或记录 DSN 内容。
- 默认无 DSN 时，其他阶段继续运行，最终明确输出 `dsnPresent=false`、`integration=skipped`。
- `--require-postgres` 模式缺少 DSN 时，在运行任何子命令前返回：
  - exit 2。
  - `postgres_test_database_required`。
  - `integration=not_run`。
- DSN 存在时通过环境继承给 Go 测试；全仓测试成功后输出 `integration=passed`。

## 测试与迁移治理

- fixture 通过 PATH 注入假的 `go` 和 `make`，验证：
  - 默认 skipped。
  - require-postgres 缺失 typed failure。
  - DSN presence 传递和无泄露。
  - Go 调用参数精确包含 `test -p 1 -count=1 ./...`。
- 迁移测试使用嵌入文件系统动态枚举 `migrations/*.sql`，校验：
  - 文件名符合五位编号和稳定名称；
  - 文件按版本严格递增；
  - 每个嵌入文件可读取；
  - 每个迁移具有 Goose Up 和 Down 段；
  - `LatestVersion()` 等于嵌入文件中的动态最高版本。
- 测试不再包含 `latest == N` 或迁移数量硬编码，并行模块新增保留编号时不需要修改共享 latest 断言。

## 验证证据

- `env -u PIKAOA_TEST_DATABASE_URL go test -count=1 ./internal/verifybackend`：fixture 通过。
- `env -u PIKAOA_TEST_DATABASE_URL ./scripts/verify-backend.sh`：
  - exit 0。
  - 全仓 Go package 按顺序重新执行。
  - Go test、vet 和 build 均 passed。
  - 最终 JSON 披露 `integration=skipped`。
- `env -u PIKAOA_TEST_DATABASE_URL ./scripts/verify-backend.sh --require-postgres`：
  - exit 2。
  - typed code 为 `postgres_test_database_required`。
- fixture 使用不可用伪 DSN，只验证环境传递；stdout、stderr 和调用记录均不包含伪 DSN。
- `git diff --check`：通过。

## 边界与风险

- 本轮没有连接真实 PostgreSQL、数据库集群或 Kubernetes，没有启动 host server。
- 本轮没有修改业务模块、迁移 SQL、身份/RBAC、CI/CD、Web 或运行配置。
- `integration=passed` 的真实运行证据仍必须由 YAML-first 专用测试 Job 注入测试 DSN 后产生。
  - 本任务只交付可供该 Job 调用的入口。
  - PR 暂不合并。
  - 后续吸收并行模块迁移后再在专用测试集群运行。
- 并行伙伴、附件、合同和发票 PR 都可能修改 `internal/migrate/migrate_test.go`。
  - 合并冲突时必须保留动态枚举逻辑。
  - 不得恢复最新版本号或迁移数量硬编码。
