Tachigo Extension — 導航架構 + 功能 MVP 設計
狀態:定稿 v4(已通過三輪 Codex review,第三輪結論「可開工」,尚未 commit / push)
日期:2026-05-16
相關:discussion #710、plans/ocean-mining-character-system-phase1.md
v3 變更摘要:第二輪 Codex review 指出
claim與redeem一樣需要 wallet + 上鏈(claim_service.go做 on-chain mint)。經對照程式碼驗證屬實。已新增 後端 PR、補上 $TACHI 交易帳本與兌換 idempotency 設計、修正開機分流 UX、 釐清流式佈局的拆分範圍。完整處置見第 11 段。
1. 背景與目標
apps/extension 目前是以 demo state 驅動的原型:畫面用扁平的 DemoScreen
字串 enum 切換,資料來自 loadDemoState / saveDemoState(chrome storage 假資料)。
本設計做兩件事:
- 導航骨架:把扁平 screen enum 重構成兩層導航(全螢幕 scene + 疊層 overlay), 讓後續十幾個畫面能逐張掛上、不互相牽動。
- 功能 MVP:把核心循環接成真實後端——Twitch 登入(自動建 tachigo 帳號)→ 實際挖礦累積點數 → claim 成 $TACHI → 用 $TACHI 換 Tachiya 商城折價券。汰除 demo state。
MVP 定位是「最簡可用版本,先做內部測試」:只用螃蟹單一角色、無進化、無其他角色。
運行型態(已拍板):MVP 只支援 Twitch 站內 extension,登入一 律走
onAuthorized extension JWT。standalone(popup / sidepanel)與手機端置後,
MVP 不做 OAuth redirect 登入路徑。
設計尺寸(已拍板):採流式響應式佈局,不寫死 px——寬度設計基準 360、
下限 320(吃得下 Twitch Panel 型 extension)、上限約 430(大尺寸手機);
高度永遠流式(min-height + 內容可捲動)。實作用 % / flex / clamp()。
這樣同一份程式碼在 Twitch panel、瀏覽器側邊欄、手機 360–430 都不需重切。
MVP $TACHI 經濟(已拍板):claim 與 redeem 在 MVP 皆走 DB-only 路徑, 不需 Web3 wallet、不上鏈。on-chain mint / burn 是後續迭代,不在 MVP。
非目標:#710 海洋角色系統不在 MVP,獨立 track 排在 MVP 之後;本設計只負責「預留位置」。
2. 現況
apps/extension/src/app/App.tsx:扁平DemoScreen = 'login'|'loading'|'hud'|'claim'|'coupon'|'raffle', 條件渲染,底部一排 永遠 render 的 dev 導航鈕(非 dev-only)。frame 寫死 320。- 既有畫面元件:
LoginScreen、LoadingScreen、MarioHUD(挖礦主頁,capybara)、ClaimPanel、CouponShopPanel、RaffleResultPanel、LanguageSwitcher。 →ClaimPanel仍是 demo CPC→TCG 換算;CouponShopPanel用 demo catalog。 →LoginScreen/MarioHUD/ClaimPanel等內部都寫死width: 320(不只 App frame)。 - 既有 hooks:
useTwitch(onAuthorizedJWT → 後端換 token;目前把所有 login 失敗都壓成Backend unavailable,未區分 identity 未分享 / JWT 無效)、useHeartbeat、useClickBoost、useTPoint、useRaffleResult。 - 後端(
services/api/internal/)關鍵事實(已對照程式碼確認):extension_service.goLoginWithExtension:不會建帳號,查不到ProviderTwitch連結回ErrUserNotFound;claims.UserID為空(未分享 identity)回ErrInvalidExtJWT。auth_service.goupsertOAuthUser(OAuth callback 路線):會 find-or-create user。users.email/username皆可為 nil。auth_providers(provider, provider_id)的 unique index 主要在 migration 建立,AutoMigrate 未必明確建出(須確認 fresh DB)。claim_service.goClaim:resolveWalletAddress→MintBroadcastOnChain→WaitMintReceiptOnChain→ 寫tachi_balances.balance。需 wallet + 上鏈 mint。spend_service.goRedeem:resolveWalletAddress+BurnOnChain。需 wallet + 上鏈 burn。models/tachi_balance.goTachiBalance:單列 aggregate(UserID uniqueIndex+Balance), 無 $TACHI 交易流水、無 coupon 兌換記錄。- 路由:
/extension/auth/login、/extension/watch/*、/api/v1/users/me/points/claim、/api/v1/spend/redeem。
- 前端
redeemCoupon()繞過runWithAuthRecovery、手動塞Authorization: Bearer ${token}。 - Figma
Tachigo Prototype v1:01 主視覺、02 登入、02-1 註冊、02-2 忘記密碼、 03 角色選擇、04 挖礦主頁、05 claim、06 coupon market。
3. 設計決策:兩層導航(不引入 router)
- A(採用)兩層導航:
scene狀態機 +overlayStack疊層。自訂NavigationProvider(context + reducer),不引入 router lib。 - B Hash router:Twitch Extension iframe 無有意義 URL / history,疊層無法乾淨對應 route。
- C 擴充扁平 enum:無疊層、無 stack、無返回,面板長到 10+ 會腐爛。
採用 A:貼合無 URL 環境、輕量、返回鍵語意清楚、好持久化、好測試。
4. 畫面盤點
Scenes(全螢幕流程)
| scene | 對應 | 現況 | MVP? |
|---|---|---|---|
entry | 程式入口主視覺(press-to-enter) | 🆕 新增 |