chore(ECR-001,ECR-003): 关闭结构对齐并清理 outlook JSON 旧键
正式关闭 ECR-001/002;删除 fortune 双写与 lucky 字段,H5 改读 outlook/boost。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -78,8 +78,11 @@ func TestFlowStarDeepAccess(t *testing.T) {
|
||||
if sum["headline"] == nil || sum["headline"] == "" {
|
||||
t.Fatalf("missing headline: %#v", sum)
|
||||
}
|
||||
if sum["fortune"] == nil || sum["planets"] == nil {
|
||||
t.Fatalf("expected fortune+planets in star summary: %#v", sum)
|
||||
if sum["outlook"] == nil || sum["planets"] == nil {
|
||||
t.Fatalf("expected outlook+planets in star summary: %#v", sum)
|
||||
}
|
||||
if sum["fortune"] != nil {
|
||||
t.Fatal("legacy fortune key must be removed (ECR-003)")
|
||||
}
|
||||
reportID := rep["id"].(string)
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ func BuildWith(opts BuildOpts) (Output, error) {
|
||||
}
|
||||
fort := outlook.Build(chart, asOf)
|
||||
daily := fort.Daily
|
||||
fortMap := fort.AsMap()
|
||||
|
||||
planetsOut := make([]map[string]any, 0, len(chart.Planets))
|
||||
for _, p := range chart.Planets {
|
||||
@@ -114,10 +115,8 @@ func BuildWith(opts BuildOpts) (Output, error) {
|
||||
},
|
||||
"planets": planetsOut,
|
||||
"aspects_preview": aspectPreview,
|
||||
// "fortune" kept for client compat; prefer "outlook" (ECR-002).
|
||||
"fortune": fort.AsMap(),
|
||||
"outlook": fort.AsMap(),
|
||||
"transits": fort.AsMap()["transits"],
|
||||
"outlook": fortMap,
|
||||
"transits": fortMap["transits"],
|
||||
"daily_soft": map[string]any{
|
||||
"title": daily.Title, "focus": daily.Focus, "tip": daily.Tip,
|
||||
"energy": daily.Score, "note": daily.Label, "score": daily.Score, "label": daily.Label,
|
||||
@@ -152,9 +151,9 @@ func BuildWith(opts BuildOpts) (Output, error) {
|
||||
section("年运详解", fort.Yearly.Tip+" "+fort.Yearly.Caution, []string{
|
||||
fmt.Sprintf("综合分 %d(%s)", fort.Yearly.Score, fort.Yearly.Label),
|
||||
fmt.Sprintf("感情 %d · 事业 %d · 财务 %d · 心情 %d", fort.Yearly.Dims["love"], fort.Yearly.Dims["career"], fort.Yearly.Dims["money"], fort.Yearly.Dims["mood"]),
|
||||
fort.Yearly.Lucky,
|
||||
fort.Yearly.Boost,
|
||||
}),
|
||||
section("一生运势", fort.Lifetime.Tip, []string{fort.Lifetime.Caution, fort.Lifetime.Lucky}),
|
||||
section("一生运势", fort.Lifetime.Tip, []string{fort.Lifetime.Caution, fort.Lifetime.Boost}),
|
||||
section("关系互动", pack.RelationDeep, pack.RelationBullets),
|
||||
section("事业与学习节奏", pack.CareerDeep, pack.CareerBullets),
|
||||
section("成长方向", pack.GrowthDeep, pack.GrowthBullets),
|
||||
@@ -171,8 +170,7 @@ func BuildWith(opts BuildOpts) (Output, error) {
|
||||
"behavior_pattern": pack.SunDeep,
|
||||
"relation_style": pack.RelationDeep,
|
||||
"growth_direction": pack.GrowthDeep,
|
||||
"fortune_detail": fort.AsMap(), // compat
|
||||
"outlook_detail": fort.AsMap(),
|
||||
"outlook_detail": fortMap,
|
||||
}
|
||||
return Output{Summary: summary, Detail: detail}, nil
|
||||
}
|
||||
|
||||
@@ -25,8 +25,11 @@ func TestBuildDeterministic(t *testing.T) {
|
||||
if a.Summary["sun_sign"] == nil || a.Detail["sections"] == nil {
|
||||
t.Fatal("missing fields")
|
||||
}
|
||||
if a.Summary["sign_cards"] == nil || a.Summary["fortune"] == nil || a.Summary["planets"] == nil {
|
||||
t.Fatal("missing sign_cards, fortune or planets")
|
||||
if a.Summary["sign_cards"] == nil || a.Summary["outlook"] == nil || a.Summary["planets"] == nil {
|
||||
t.Fatal("missing sign_cards, outlook or planets")
|
||||
}
|
||||
if a.Summary["fortune"] != nil {
|
||||
t.Fatal("legacy fortune key must be removed (ECR-003)")
|
||||
}
|
||||
if a.Summary["aspects_preview"] == nil {
|
||||
t.Fatal("missing aspects_preview")
|
||||
@@ -66,18 +69,30 @@ func TestBuildWithBirthTimeChangesRise(t *testing.T) {
|
||||
_ = b.Summary["rise_sign"]
|
||||
}
|
||||
|
||||
func TestBuildFortuneScores(t *testing.T) {
|
||||
func TestBuildOutlookScores(t *testing.T) {
|
||||
birth := time.Date(1990, 5, 12, 0, 0, 0, 0, time.UTC)
|
||||
out, err := BuildWith(BuildOpts{Birth: birth, Name: "测", AsOf: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fort, ok := out.Summary["fortune"].(map[string]any)
|
||||
bundle, ok := out.Summary["outlook"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("fortune missing")
|
||||
t.Fatal("outlook missing")
|
||||
}
|
||||
daily, ok := fort["daily"].(map[string]any)
|
||||
daily, ok := bundle["daily"].(map[string]any)
|
||||
if !ok || daily["score"] == nil {
|
||||
t.Fatal("daily score missing")
|
||||
}
|
||||
if daily["lucky"] != nil {
|
||||
t.Fatal("legacy lucky key must be removed")
|
||||
}
|
||||
if daily["boost"] == nil {
|
||||
t.Fatal("boost missing")
|
||||
}
|
||||
if out.Detail["fortune_detail"] != nil {
|
||||
t.Fatal("legacy fortune_detail must be removed")
|
||||
}
|
||||
if out.Detail["outlook_detail"] == nil {
|
||||
t.Fatal("outlook_detail missing")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/yuxingu/digital-psychology/apps/api/internal/star/natal"
|
||||
)
|
||||
|
||||
// Period is one fortune block.
|
||||
// Period is one outlook block (daily…lifetime).
|
||||
type Period struct {
|
||||
Key string `json:"key"`
|
||||
Title string `json:"title"`
|
||||
@@ -17,7 +17,7 @@ type Period struct {
|
||||
Label string `json:"label"`
|
||||
Dims map[string]int `json:"dims"`
|
||||
Tip string `json:"tip"`
|
||||
Lucky string `json:"lucky"`
|
||||
Boost string `json:"boost"` // soft accent tip (was lucky; ECR-003)
|
||||
Caution string `json:"caution"`
|
||||
Focus string `json:"focus"`
|
||||
}
|
||||
@@ -40,7 +40,7 @@ type Bundle struct {
|
||||
Transits []Transit `json:"transits"`
|
||||
}
|
||||
|
||||
// Build returns fortune for natal chart as of asOf (date matters).
|
||||
// Build returns period outlook for natal chart as of asOf (date matters).
|
||||
func Build(chart natal.Chart, asOf time.Time) Bundle {
|
||||
if asOf.IsZero() {
|
||||
asOf = time.Now()
|
||||
@@ -118,7 +118,7 @@ func lifetime(chart natal.Chart) Period {
|
||||
"money": 48 + (seed*5)%42, "mood": 55 + (seed*7)%35,
|
||||
},
|
||||
Tip: tip, Focus: "人生阶段",
|
||||
Lucky: "长期复盘 · 边界清晰",
|
||||
Boost: "长期复盘 · 边界清晰",
|
||||
Caution: "避免把阶段标签当成宿命;可调整节奏与选择。",
|
||||
}
|
||||
}
|
||||
@@ -197,7 +197,7 @@ func period(key, title string, seed int, sun, moon float64, chart natal.Chart, f
|
||||
"love": love, "career": career, "money": money, "mood": mood,
|
||||
},
|
||||
Tip: tips[i], Focus: focuses[i%len(focuses)],
|
||||
Lucky: luckyFrom(seed),
|
||||
Boost: boostFrom(seed),
|
||||
Caution: cautionFrom(seed, chart),
|
||||
}
|
||||
}
|
||||
@@ -205,19 +205,19 @@ func period(key, title string, seed int, sun, moon float64, chart natal.Chart, f
|
||||
func scoreLabel(s int) string {
|
||||
switch {
|
||||
case s >= 85:
|
||||
return "大吉"
|
||||
return "高能"
|
||||
case s >= 75:
|
||||
return "吉"
|
||||
return "顺畅"
|
||||
case s >= 65:
|
||||
return "中平偏吉"
|
||||
return "偏顺"
|
||||
case s >= 55:
|
||||
return "平稳"
|
||||
default:
|
||||
return "需谨慎"
|
||||
return "宜缓行"
|
||||
}
|
||||
}
|
||||
|
||||
func luckyFrom(seed int) string {
|
||||
func boostFrom(seed int) string {
|
||||
colors := []string{"红色", "金色", "蓝色", "绿色", "紫色", "白色"}
|
||||
nums := []string{"3", "6", "7", "8", "9"}
|
||||
return colors[seed%len(colors)] + " · 数字 " + nums[seed%len(nums)]
|
||||
@@ -256,6 +256,6 @@ func (b Bundle) AsMap() map[string]any {
|
||||
func periodMap(p Period) map[string]any {
|
||||
return map[string]any{
|
||||
"key": p.Key, "title": p.Title, "score": p.Score, "label": p.Label,
|
||||
"dims": p.Dims, "tip": p.Tip, "lucky": p.Lucky, "caution": p.Caution, "focus": p.Focus,
|
||||
"dims": p.Dims, "tip": p.Tip, "boost": p.Boost, "caution": p.Caution, "focus": p.Focus,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user