174 lines
14 KiB
Markdown
174 lines
14 KiB
Markdown
# Codebase Concerns
|
||
|
||
**Analysis Date:** 2026-03-27
|
||
|
||
## Tech Debt
|
||
|
||
**配置与凭据管理(严重级别:Critical):**
|
||
- Issue: 仓库内存在已提交的生产/测试环境敏感配置与直连外部基础设施的写法,配置边界没有被代码、脚本和部署文件统一约束。
|
||
- Files: `docker-compose.prod.yml`, `Makefile`, `pkg/config/defaults/config.yaml`, `scripts/verify_migration/main.go`, `scripts/verify_indexes/main.go`, `docs/deployment/deployment-guide.md`
|
||
- Impact: 凭据轮换成本高;泄漏后影响数据库、Redis、对象存储、短信网关、Gateway 与部署链路;开发、测试、生产边界容易串用。
|
||
- Supporting evidence:
|
||
- `docker-compose.prod.yml` 直接写入数据库、Redis、JWT、对象存储、Gateway、短信服务配置。
|
||
- `Makefile` 的 `DB_URL` 内嵌远程数据库连接串。
|
||
- `pkg/config/defaults/config.yaml` 为 `gateway.app_id`、`gateway.app_secret` 提供非空默认值,服务在未显式覆盖时仍会初始化 Gateway 客户端,见 `cmd/api/main.go:366-383`。
|
||
- `scripts/verify_migration/main.go` 与 `scripts/verify_indexes/main.go` 直接写死远程 PostgreSQL DSN。
|
||
- `docs/deployment/deployment-guide.md` 把 Registry 凭据与数据库连接示例直接写进文档。
|
||
- Fix approach: 把所有密钥迁移到部署平台 Secret/环境注入;默认配置只保留空值;脚本统一改为读取环境变量;把示例文档改成占位符而不是真实值。
|
||
- Suggested follow-up investigation topics:
|
||
- 盘点 `openspec/`, `docs/`, `scripts/` 中所有历史凭据残留。
|
||
- 审查 Gitea Secrets、Docker Registry、数据库、Redis、对象存储、短信网关、Gateway 的轮换计划。
|
||
- 检查 `.env`、`.env.local` 是否已在团队机器与 Runner 上扩散。
|
||
|
||
**支付与微信配置迁移未闭环(严重级别:High):**
|
||
- Issue: 设计已经切到 `tb_wechat_config` + `payment_config_id`,但代码与文档仍保留环境变量和单例支付实现,处于半迁移状态。
|
||
- Files: `docs/wechat-config-management/功能总结.md`, `internal/service/order/service.go`, `internal/service/recharge/service.go`, `internal/handler/callback/payment.go`, `docs/environment-variables.md`, `scripts/verify-wechat.sh`, `docker-compose.prod.yml`
|
||
- Impact: 多支付配置切换、旧订单验签、客户端支付发起、OAuth 配置一致性存在行为不一致风险;运维很难判断哪些配置源仍然生效。
|
||
- Supporting evidence:
|
||
- `docs/wechat-config-management/功能总结.md:232-238` 明确写着客户端支付发起仍是留桩,OAuth 仍从环境变量读取,且旧 `JUNHONG_WECHAT_PAYMENT_*` “可清理”。
|
||
- `internal/service/order/service.go:2107,2163,2356,2362` 与 `internal/service/recharge/service.go:271`、`internal/handler/callback/payment.go:66,143` 仍保留 TODO/留桩。
|
||
- `docs/environment-variables.md:36-69` 与 `scripts/verify-wechat.sh` 仍把微信支付环境变量当成必填启动前置条件。
|
||
- `docker-compose.prod.yml` 注释称“微信配置已迁移至数据库”,但部署文件仍维持部分旧式环境变量与其他支付相关外部配置模式。
|
||
- Fix approach: 明确单一配置源;把“已迁移”“留桩”“仍依赖环境变量”的边界写入运维文档;在代码层补齐动态加载或删除旧入口。
|
||
- Suggested follow-up investigation topics:
|
||
- 核实当前线上 OAuth 与支付分别读哪一套配置。
|
||
- 核查 `payment_config_id` 相关回调链路是否覆盖订单、资产充值、代理充值三条路径。
|
||
- 为未实现的客户端支付入口建立显式禁用清单。
|
||
|
||
**核心服务体量过大(严重级别:High):**
|
||
- Issue: 部分核心服务文件已经远超团队规范中的函数/文件规模要求,维护成本和回归风险高。
|
||
- Files: `internal/service/order/service.go`, `AGENTS.md`
|
||
- Impact: 改动难以局部验证;支付、幂等、库存/余额、回调逻辑耦合;新需求更容易引入回归。
|
||
- Supporting evidence:
|
||
- `AGENTS.md:371-375` 要求函数长度 ≤ 100 行,核心逻辑建议 ≤ 50 行。
|
||
- `internal/service/order/service.go` 的 TODO 已出现在 2107、2163、2356、2362 行,说明文件至少超过 2362 行。
|
||
- Fix approach: 按支付发起、支付回调、订单状态流转、幂等与锁、钱包扣款等职责拆分子服务/辅助组件。
|
||
- Suggested follow-up investigation topics:
|
||
- 统计 `internal/service/` 中超长文件与超长函数。
|
||
- 识别最常改动的热点段落与共享依赖。
|
||
|
||
## Known Bugs
|
||
|
||
**健康检查接口对故障返回 200 成功包裹(严重级别:High):**
|
||
- Symptoms: PostgreSQL 或 Redis 故障时,`/health` 仍通过 `response.Success` 返回成功包裹,只在 `data.status` 中标记 `degraded`。
|
||
- Files: `internal/handler/health.go`, `docker-compose.prod.yml`, `Dockerfile.api`, `debug-deployment.sh`
|
||
- Trigger: 数据库或 Redis Ping 失败。
|
||
- Workaround: 监控端必须解析响应体里的 `data.status` 与 `services.*.status`,不能只看 HTTP 状态码。
|
||
- Supporting evidence:
|
||
- `internal/handler/health.go:101-111` 注释与实现都明确“端点本身能响应即视为成功”。
|
||
- `docker-compose.prod.yml` 与 `Dockerfile.api` 的健康检查只执行 `wget --spider http://127.0.0.1:3000/health`,不会校验 JSON 内容。
|
||
- Suggested follow-up investigation topics:
|
||
- 确认当前容器健康检查、反向代理、告警系统是否只看 200。
|
||
- 评估是否需要新增 `readyz`/`livez` 区分活性与依赖可用性。
|
||
|
||
**API 路径文档与实际路由不一致(严重级别:Medium):**
|
||
- Symptoms: 文档仍混用 `/api/v1`、`/api/auth`、`/api/c/v1`,读者很难判断当前真实入口。
|
||
- Files: `README.md`, `internal/routes/routes.go`, `scripts/check-comment-paths.sh`
|
||
- Trigger: 新人按 README 试运行、按旧注释实现客户端、或依据文档回归接口。
|
||
- Workaround: 以 `internal/routes/routes.go` 为准核对真实挂载路径。
|
||
- Supporting evidence:
|
||
- `internal/routes/routes.go:21-39` 当前真实路由为 `/api/auth`、`/api/admin`、`/api/c/v1`、`/api/callback`。
|
||
- `README.md:577-583` 仍展示 `v1 := app.Group("/api/v1")` 的旧限流示例;`README.md:588-624` 仍以 `/api/v1/users` 讲解请求流。
|
||
- `scripts/check-comment-paths.sh` 只检查 `internal/handler/` 中残留 `/api/v1`,并不覆盖 `README.md`、`docs/`、`openspec/`。
|
||
- Suggested follow-up investigation topics:
|
||
- 扫描所有 `docs/`, `README.md`, `openspec/`, `specs/` 中的旧路径。
|
||
- 明确哪些旧路径仍需要兼容,哪些应统一下线。
|
||
|
||
## Security Considerations
|
||
|
||
**部署流水线绕过 TLS 校验(严重级别:High):**
|
||
- Risk: 工作流检出步骤通过 `GIT_SSL_NO_VERIFY=1` 跳过证书校验,供应链完整性依赖内网信任而不是证书验证。
|
||
- Files: `.gitea/workflows/deploy.yaml`
|
||
- Current mitigation: 注释说明是“内网自签名证书”。
|
||
- Recommendations: 为 Gitea/Registry 配置受信 CA;移除跳过校验;至少把跳过范围限制在明确的单一主机与受控 Runner。
|
||
- Supporting evidence:
|
||
- `.gitea/workflows/deploy.yaml:23-27` 设置 `GIT_SSL_NO_VERIFY=1` 后执行 `git clone`。
|
||
|
||
**对外/回调错误信息泄漏底层细节(严重级别:Medium):**
|
||
- Risk: 健康检查与富友回调把底层错误或内部状态直接返回给调用方,不符合统一错误暴露规范。
|
||
- Files: `internal/handler/health.go`, `internal/handler/callback/payment.go`, `AGENTS.md`
|
||
- Current mitigation: 有统一错误处理规范,但没有覆盖这两个特殊出口。
|
||
- Recommendations: 对外返回统一错误码/固定消息,把底层错误仅写日志。
|
||
- Supporting evidence:
|
||
- `AGENTS.md:124-129` 明确禁止直接暴露底层错误。
|
||
- `internal/handler/health.go:50-60,82-85` 直接返回 `err.Error()`。
|
||
- `internal/handler/callback/payment.go:178-191` 直接把 `err.Error()` 拼入富友回调失败响应。
|
||
|
||
## Performance Bottlenecks
|
||
|
||
**默认限流仍使用内存存储且默认关闭(严重级别:Medium):**
|
||
- Problem: 默认配置既不开启限流,也默认使用 `memory` 存储;多实例部署时无法形成统一配额。
|
||
- Files: `pkg/config/defaults/config.yaml`, `cmd/api/main.go`, `README.md`
|
||
- Cause: 配置更偏向本地开发便利,缺少生产默认值与环境级约束。
|
||
- Improvement path: 明确生产必须启用 Redis 存储限流;在部署文档里给出环境变量模板;增加启动日志或自检提示当前限流模式。
|
||
- Supporting evidence:
|
||
- `pkg/config/defaults/config.yaml:87-93` 默认 `enable_rate_limiter: false`、`storage: memory`。
|
||
- `cmd/api/main.go:236-278` 只有显式开启时才挂载限流,并根据配置选择 Redis 或内存存储。
|
||
|
||
## Fragile Areas
|
||
|
||
**OpenAPI 文档生成依赖手工双点维护(严重级别:Medium):**
|
||
- Files: `AGENTS.md`, `docs/api-documentation-guide.md`, `cmd/api/docs.go`, `cmd/gendocs/main.go`
|
||
- Why fragile: 新增 Handler 必须同时更新两个文件;流程靠人工记忆,历史上已经出现清单不一致并专门做过修复。
|
||
- Safe modification: 每次新增 Handler 时同时检查 `cmd/api/docs.go`、`cmd/gendocs/main.go` 与生成产物 `docs/admin-openapi.yaml`/`logs/openapi.yaml`。
|
||
- Test coverage: 未发现自动化校验这两份清单一致性的 CI 步骤。
|
||
- Supporting evidence:
|
||
- `AGENTS.md:53-65` 明确要求手工更新两个文件。
|
||
- `docs/api-documentation-guide.md` 多处把“忘记在两个文件中添加新 Handler”列为最常见问题。
|
||
- `.gitea/workflows/deploy.yaml` 中未见 `go run cmd/gendocs/main.go`、diff 校验或文档一致性检查。
|
||
|
||
**部署脚本与运行时约定已漂移(严重级别:Medium):**
|
||
- Files: `debug-deployment.sh`, `docker-compose.prod.yml`, `README.md`, `docs/deployment/deployment-guide.md`
|
||
- Why fragile: 诊断脚本仍假定旧环境变量名与外置配置文件存在,文档与当前嵌入式配置实现不完全一致。
|
||
- Safe modification: 先以 `docker-compose.prod.yml`、`pkg/config/defaults/config.yaml`、`cmd/api/main.go` 为准修正运维脚本,再统一更新部署文档。
|
||
- Test coverage: 未发现对诊断脚本、部署文档、健康检查语义的自动验证。
|
||
- Supporting evidence:
|
||
- `debug-deployment.sh:52-57` 仍 grep `DB_|CONFIG_ENV`,并尝试读取 `/app/configs/config.yaml`;当前配置前缀实际是 `JUNHONG_`,配置默认嵌入二进制,见 `README.md:651-689`、`pkg/config/defaults/config.yaml`。
|
||
- `docs/deployment/deployment-guide.md:302-305` 仍建议从 `/app/.env` 拼接迁移命令,但容器实际入口用环境变量构造 DSN,见 `docker/entrypoint-api.sh:8-17`。
|
||
|
||
## Scaling Limits
|
||
|
||
**CI/CD 质量闸门过窄(严重级别:High):**
|
||
- Current capacity: 当前工作流只做 clone、build、push、main 分支部署。
|
||
- Limit: 文档一致性、脚本检查、编译前规范、迁移安全、健康语义等问题都可能直接进入镜像与部署环境。
|
||
- Scaling path: 在 `.gitea/workflows/deploy.yaml` 前置独立质量作业,至少执行 `bash scripts/check-all.sh`、`go build ./...`、OpenAPI 生成/校验,并在部署前验证 compose 文件与镜像健康策略。
|
||
- Supporting evidence:
|
||
- `README.md:941-957` 声称脚本检查会在 CI/CD 自动执行。
|
||
- `.gitea/workflows/deploy.yaml` 未出现 `scripts/check-all.sh`、`go test`、`go vet`、`go build ./...`、OpenAPI 校验等步骤。
|
||
|
||
## Dependencies at Risk
|
||
|
||
**Go 版本与运行基础不统一(严重级别:Medium):**
|
||
- Risk: 版本声明分散在多个位置,升级与排障时容易出现“本地能过、容器不一致”的问题。
|
||
- Impact: 构建环境复现、依赖升级与 bug 排查成本上升。
|
||
- Migration plan: 约定单一权威版本源(如 `go.mod` + `.tool-versions`/`.go-version`),并让 Dockerfile、README、部署文档同步引用。
|
||
- Supporting evidence:
|
||
- `go.mod:3` 使用 `go 1.25.0`。
|
||
- `Dockerfile.api:4` 与 `Dockerfile.worker:4` 使用 `golang:1.25.6-alpine`。
|
||
- `README.md:884` 写的是 `Go 1.25.1`。
|
||
|
||
## Missing Critical Features
|
||
|
||
**缺少可执行的自动化质量/回归入口(严重级别:High):**
|
||
- Problem: README、历史设计与测试文档大量提到 `go test`、`IntegrationTestEnv`、`tests/integration/`,但仓库当前未发现对应测试文件或 `tests/` 目录。
|
||
- Blocks: 无法快速验证重构、支付回调、权限过滤、部署脚本变更;文档中的测试命令无法直接落地。
|
||
- Supporting evidence:
|
||
- `AGENTS.md:324-354` 当前规范明确禁止自动化测试,和 `README.md:712-756`、`docs/testing/test-connection-guide.md` 的测试要求形成正面冲突。
|
||
- 读取仓库根目录未发现 `tests/` 目录;`glob` 搜索 `tests/**/*_test.go` 与 `internal/**/*_test.go` 未返回结果。
|
||
- `docs/testing/test-connection-guide.md` 仍宣称“204 个测试总耗时 ~10.5 秒”并要求所有新测试遵循该规范。
|
||
|
||
## Test Coverage Gaps
|
||
|
||
**部署、配置迁移、运维脚本与文档一致性未见自动验证(优先级:High):**
|
||
- What's not tested: `docker-compose.prod.yml`、`debug-deployment.sh`、`scripts/migrate.sh`、OpenAPI 文档生成器双清单、README/部署文档与代码的同步性。
|
||
- Files: `.gitea/workflows/deploy.yaml`, `docker-compose.prod.yml`, `debug-deployment.sh`, `scripts/migrate.sh`, `cmd/api/docs.go`, `cmd/gendocs/main.go`, `README.md`
|
||
- Risk: 配置漂移、凭据泄漏、文档错误、健康检查误报、迁移行为变化都可能在上线后才暴露。
|
||
- Priority: High
|
||
- Suggested follow-up investigation topics:
|
||
- 设计最小化“文档/脚本一致性检查”而不是恢复完整自动化测试体系。
|
||
- 评估是否要为部署文件与文档生成引入静态检查或 smoke check。
|
||
|
||
---
|
||
|
||
*Concerns audit: 2026-03-27*
|