refactor(ECR-001): 接入 ESS 并完成结构对齐 Phase A–E

绑定 ESS 双轨治理,拆分超大 H5 页与 Go 引擎,抽出 membership 服务,
并将 star/fortune 重命名为 outlook(JSON 双写兼容);同时修复 /psy API 代理与首页 + 菜单层级。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-05 17:51:40 +08:00
co-authored by Cursor
parent 583133dd09
commit 19d3cd5945
75 changed files with 4199 additions and 2505 deletions
+65
View File
@@ -0,0 +1,65 @@
# CODE_REVIEW — ECR-001 Phase AE (+ ECR-002)
**Reviewer:** Cursor Agent (REVIEWER)
**Date:** 2026-08-05
**Decision:** **PASS**(可合入;见 Nits
## Scope reviewed
- Go`service/membership` 抽出 · `handler/report` / `httpserver` 接线 · `relation`/`star` 拆文件 · `fortune``outlook`
- H5Home/Synastry 拆分 · `baseURL`/`vite` 代理 · `+` 菜单 z-index
- 治理:ADR-0007 · LEGACY · go-services · ESS docs
## Evidence
| Check | Result |
|-------|--------|
| 公共 URL / envelope 未改 | PASS |
| Membership 仅经 router 注入,集成测试绿 | PASS(`go test ./internal/integration/` |
| 无残留 `star/fortune` / `package fortune` | PASS |
| JSON `fortune` 旧键保留 + `outlook` 双写 | PASScompat 策略正确) |
| relation/star 单测 | PASS |
| `build:h5` | PASS |
| Phase B 行为冻结(composable 迁移) | PASS(先前冒烟) |
## Findings
### Blockers
无。
### Should-fix(建议合入前或紧随 PR
无必须项。
### Nits(不阻断)
1. **`star/engine.go` 多次 `fort.AsMap()`**
summary/detail 各调用多次,建议 `m := fort.AsMap()` 复用,减分配(非正确性)。
2. **`ReportHandler.Membership` 无 nil 守卫**
生产路径始终由 `NewRouter` 注入;测试若手造 handler 会 NPE。可加防御或构造函数。
3. **`useSynastryPage` ~390 行**
贴近 coding 上限;后续可再抽 chart helpers(非本轮必须)。
4. **Synastry props 面偏宽**
可维护性 nit;可改为 provide/inject(后续)。
5. **JSON `lucky` 字段仍在 `outlook.Period`**
ECR-002 已声明兼容期;彻底 lexicon 清理需客户端迁移后再开 ECR。
6. **分支名未含 ECR-001**
ess-validate 仅 warning;合入时 commit message 宜带 `ECR-001`
## Risk
低。最大残留:旧客户端继续读 `fortune`;新键未使用也不影响。删除旧键前必须扫 H5/sdk。
## Gate
- [x] Architecture / layering PASS
- [x] Tests greenunit + integration + h5 build
- [x] No scope redesign
- [x] Ready to commit / ship Phase AE
**Decision: PASS**
+49
View File
@@ -0,0 +1,49 @@
# CODE_REVIEW — ECR-001 Phase B
**Reviewer:** Cursor Agent (REVIEWER)
**Date:** 2026-08-05
**Decision:** PASS(带人工冒烟)
## Evidence
| Check | Result |
|-------|--------|
| Scope 仅 Phase BHome/Synastry 拆分) | PASS |
| 无 API / OpenAPI / schema 变更 | PASS |
| 页面行数 ≤400 | Home 133 · Synastry 187 PASS |
| BirthDateInputs 绑定与组件 API 一致 | PASSyear/month/day + update:* |
| `build:h5` | PASS(先轮) |
| `homeCatalog` 单测 | PASS |
| 行为冻结 | 逻辑迁入 composable,未见故意改文案/路由 |
## Nits(不阻断)
1. `SynastryPage``v-else-if="loading"``!report` 时不可达——与重构前一致,landing 按钮文案承担 loading。
2. Synastry props/emits 面偏宽;后续可改为注入 composable 或 provide(非本 Phase)。
3. `useSynastryPage` 390 行贴近上限,Phase 后续可再抽 chart helpers。
## Smoke(本会话)
| 项 | 结果 |
|----|------|
| API healthz | PASS |
| Home UI(心情卡/金刚区/推荐) | PASS · 截图 `/tmp/yuxingu-smoke/home.png` |
| Synastry UI 结构 | PASS |
| Synastry `listProfiles` | **BLOCKED initially**`baseURL=/psy/api` 但 Vite 只代理 `/api`,返回 HTML 200 |
### Fix appliedreview 中发现,非 Phase B 引入)
1. `vite.config.ts``base: '/psy/'` + `/psy/api``8080/api` rewrite
2. `client.ts``baseURL` 从错误的 `/psy/api` 改为 `/psy`SDK 路径已含 `/api/v1`,避免 `/psy/api/api/v1`
冒烟后再验:`GET /psy/api/v1/profiles` → 200 JSON;合盘页无「接口返回异常」。
## Risk
低(拆分本身)。代理缺口已修;合盘需至少两档案才可生成结果。
## Gate
- [x] Ready for local smoke
- [x] Human/agent smoke:首页 OK;合盘页 UI OK(代理已修)
- [x] Decision **PASS**