跳轉到

Activity Framework & Sticker 系統 Phase 3 就緒性審查:blocker 識別、介面修復與 Phase 邊界判定

文檔資訊

  • 分類: debugging
  • 難度: advanced
  • 預估閱讀時間: 6 分鐘
  • 標籤: activity-framework, sticker, phase3, interface-mismatch, go, readiness-check, GetPlayerProgress, ResolveContentClosure, ScheduleConfigLoader

摘要

針對 Activity Framework 與 Sticker 系統進行 Phase 3 就緒性審查。發現三個真正的 pre-Phase 3 blocker:sticker 編譯失敗(GetPlayerProgress 型別不符)、ResolveContentClosure 仍是 stub、ScheduleConfigLoader 缺失。同時澄清 main.go 未接線是 Phase 3 本身的工作,不應列為 blocker。修復了 GetPlayerProgress 介面不相容後正式進入 Phase 3。

關鍵學習

  • Phase 3 就緒性審查需區分『Phase 3 前必修』vs『Phase 3 本身要做』的邊界

  • go test ./internal/modules/sticker/... build fail 是直接 blocker,不能靠整合測試掩蓋

  • 介面契約(如 GetPlayerProgress 回傳型別)的不相容會在 go build 階段就阻斷,不是 runtime 問題

  • ResolveContentClosure stub 會讓 activity admission / config sync / settlement 都處於半殘狀態

  • 文件治理要同步:readiness register 的 OPEN/Closed 狀態必須在修復後立即更新

技術細節

問題背景

Activity Framework 與 Sticker 系統在進入 Phase 3 前需要通過就緒性審查,但審查過程中發現多個問題。

Blocker 1:GetPlayerProgress 介面型別不符(直接 build fail)

// activity_handler.go:37 期望的介面
GetPlayerProgress(...) ([]byte, error)

// sticker_season_handler.go:411 實際實作
GetPlayerProgress(...) (interface{}, error)

go test ./internal/modules/sticker/... 直接 build fail,這是 pre-Phase 3 必修 bug。

Blocker 2:ResolveContentClosure 仍是 stub

// sticker_season_handler.go:88
func (h *StickerSeasonHandler) ResolveContentClosure() {
    return nil, nil  // stub,尚未實作
}

以下三個 activity 核心路徑都依賴這個方法: - activity_admission.go:67(admission 准入) - activity_config_sync.go:274(config drift detection) - activity_settlement_service.go:390(settlement frozen-config)

Blocker 3:ScheduleConfigLoader 缺失

activity_config_sync.go:48 只有 SetScheduleConfigLoader(...),但 production 的 LoadScheduleEntries 實作在 repo 中找不到,只有 test mock。activity_twirp.go:488 若 loader 未設定會直接報錯。

非 Blocker(Phase 3 本身的工作)

cmd/twirpserver/main.go:652 之後未註冊 activity/sticker 服務,這是 Phase 3 接線工作,不應列為 Phase 3 前的 blocker。

高風險缺口(不擋 Phase 3 開始,但擋上線)

Luban 有 pkg/config/luban/Enums_RewardType.go:43 定義 type 6/7,但 pkg/reward/resolver.go:22 只支援 item/currency/hero/talent_card 四種,若 sticker 配置用到 type 6/7 會在 runtime 爆掉。

What Changed

文件同步修復

C-1(shared reward_claims dedup)與 C-2(season_id schema + migration)兩個問題早已修復,但 docs/activity/07_release_readiness_register.md 的 §1.2 與 §1.3 仍標為 OPEN。依照文檔治理規範將這兩個項目更新為 Closed,並修正 docs/00_README.md:140 中 activity「尚未建立」的過期描述。

GetPlayerProgress 介面修復

修正 internal/modules/sticker/sticker_season_handler.go:411 的回傳型別,從 (interface{}, error) 改為 ([]byte, error),使其符合 activity_handler.go:37 的介面契約。修復後 go test ./internal/modules/sticker/... 通過,完成 commit,正式進入 Phase 3。

So What

清晰化 Phase 邊界非常關鍵

在 Phase 3 就緒性審查中,很容易把「Phase 3 本身要做的事」誤判為「Phase 3 前的 blocker」,這會讓 Phase 3 永遠無法開始。本次審查澄清了:main.go 接線是 Phase 3 工作,不是 blocker;真正的 blocker 是介面不相容這類破壞 build 的問題。

介面契約是最嚴格的邊界

GetPlayerProgress 的型別不符在 go build 階段就會阻斷,比任何 runtime 問題都更明確。這提醒跨模組整合前必須先確認介面契約一致,不能依賴整合測試去發現這類問題(整合測試有時會跳過 build fail 的模組)。

Trade-offs

  • ResolveContentClosure 的修復範圍:若 Phase 3 前完整實作,可確保 activity content hash/drift detection 正確運作;但若留到 Phase 3,phase3 一接上就會是半殘狀態,需要接線工作和 stub 修復同步進行,增加 debug 難度
  • ScheduleConfigLoader 缺失:可先用 mock 推進 Phase 3 接線驗證,但必須在上線前補上 production 實作,否則 PreviewConfigSync/SyncActivitiesFromConfig 完全無法運作
  • reward type 6/7 支援:可以等到確認 sticker 配置是否真的用到再處理,但若真的用到且沒提前處理,會在 runtime 靜默失敗,難以定位

Try It Fast

# 驗證 sticker 模組是否編譯通過(Phase 3 前必做)
go test ./internal/modules/sticker/...

# 驗證 activity 模組
go test ./internal/modules/activity/...

# 驗證整合測試(注意:這個不會抓到 sticker build fail)
go test ./test/... -run "Activity|Sticker|Event"

# 確認 GetPlayerProgress 介面一致性
grep -n 'GetPlayerProgress' internal/modules/activity/activity_handler.go
grep -n 'GetPlayerProgress' internal/modules/sticker/sticker_season_handler.go

Recommendation

  1. Phase 3 前必修:確認 ResolveContentClosure 實作(sticker_season_handler.go:88)不再是 stub,否則 phase3 接線後 content hash / drift detection 都是空殼
  2. Phase 3 前必修:補上 production 的 LoadScheduleEntries 實作,不能只有 test mock
  3. Phase 3 進行中:接線 cmd/twirpserver/main.go 的 activity/sticker 服務(這才是 Phase 3 本身的工作)
  4. 上線前必修:確認 sticker Luban 配置實際使用的 reward type,若有 type 6/7 需在 pkg/reward/resolver.go 補上支援
  5. 文件治理:每次修復 blocker 後立即更新 readiness register,避免下次審查時誤判 OPEN 項目

本文檔由 Semi-Brain 自動生成

Session ID: 431f3410-f7d5-461d-8a0b-e1ea3f999e73

分析信心度: 78%