運動應用程式:用戶端架構規格
Artifact這是第 3 集「為應用程式賦予智慧」和第 4 集「無程式碼應用程式實作計畫」中使用的構件。您可以參考這份規格,瞭解前端檢視畫面、可重複使用的 UI 元件、用戶端狀態管理,以及淺顯易懂的測試案例。
登入即可存取這個構件
登入 Google 開發人員個人檔案,即可查看及複製「Build It!」系列中使用的完整構件。
須具備開發人員設定檔
您不符合建立開發人員設定檔的資格。請通知 Workspace 管理員啟用這項功能。
建立開發人員設定檔
免費建立 Google 開發人員個人檔案,即可解鎖所有 Build It! 提示和構件。
加入 Builder Central 即可解鎖
一鍵領取免費的 Builder 會員徽章,即可解鎖所有 Build It! 提示和構件。
狀態:準備進行規劃會議 (與客戶規劃助理共同草擬)
助理文件:資料架構規格
架構目標:以乾淨、可維護、模組化且可測試的方式,重新建構 AI Studio 智慧健身原型的前端。
0. 核心技術堆疊和工程標準
- 執行階段架構:Next.js (App Router、React 19) + 漸進式網頁應用程式 (PWA) 離線資產快取。
- 樣式架構:Tailwind CSS v4 + Tailwind Variants (用於確定性元件樣式) + Lucide React (圖示)。
- 客戶州/省:
- Zustand (本機工作階段):管理不穩定的健身房狀態 (
useActiveSessionStore)、碼錶計時器、有效組數緩衝區,以及預先計算的步驟順序。已同步到localStorage,用於手機鎖定復原。 - TanStack Query (伺服器狀態):管理 Firestore 文件快取、背景重新驗證,以及
weekly_plans、user_profiles、prs和workout_logs的樂觀更新。
- Zustand (本機工作階段):管理不穩定的健身房狀態 (
- 圖表視覺化:Recharts (使用自訂深色健身模式符記設定樣式)。
- 驗證:Firebase 驗證,使用不記名權杖驗證標頭傳遞至所有伺服器端點。
1. 前端原則和設計原則
- 健身優先的人體工學設計:專為運動時單手操作設計,即使手上有汗也能輕鬆使用。寬大的輕觸目標 (至少 48x48dp)、高對比度易讀性,以及最少的輸入需求。
- 樂觀 UI 和離線韌性:記錄組數、啟動休息計時器和切換運動項目時,UI 必須立即回應 (<16 毫秒)。背景同步處理會處理伺服器持續性,並傳送至
POST /api/workouts/log,不會封鎖使用者。 - 嚴格區分關注點:Dumb/Presentational 元件會接收資料,並使用 props 發出事件;智慧容器檢視畫面會管理商業邏輯、狀態儲存庫和 API 協調。
- 分階段變更使用者體驗:AI 教練 (
POST /api/coach/chat) 生成的提案會顯示為互動式分階段預覽資訊卡,並提供明確的「接受計畫」和「修改」控制項,讓您在提交變更前確認應用程式狀態。 - 行為導向品質:每個頁面、元件和互動都搭配淺顯易懂的測試案例,明確定義預期行為。
2. 應用程式導覽和檢視區塊階層
| 路徑 | 檢視表名稱 | 主要目的 | 內含重要元件 |
|---|---|---|---|
/ |
根目錄重新導向 | 立即重新導向至 /today。 |
(路由器重新導向) |
/today |
今日訓練活動預覽 | 預設檢視。自動解析為當天星期幾,並顯示今天的訓練預覽。 | <BackButton />、<WorkoutHeader />、<CoachNoteCard />、<WorkoutExerciseSummary />、<WorkoutBlock />、<ExerciseCard />、<EmptyDayPlaceholder />、<ModifyWithCoachCard /> |
/workouts/:day |
每日訓練預覽 | 顯示一週中特定日期的訓練預覽畫面 (例如 /workouts/monday、/workouts/thursday)。 |
<BackButton />、<WorkoutHeader />、<CoachNoteCard />、<WorkoutExerciseSummary />、<WorkoutBlock />、<ExerciseCard />、<EmptyDayPlaceholder />、<ModifyWithCoachCard /> |
/workout/active |
使用中活動時段追蹤工具 | 高強度健身執行畫面 (組數、次數、計時器)。底部導覽列會持續顯示。 | <ActiveSessionStickyHeader />、<ActiveExerciseCardHeader />、<CoachTipCard />、<CurrentSetTargetCard />、<SetNavigationRow />、<ExerciseSetsTable />、<ActiveRestTimerDock />、<SessionExerciseOverview />、<ActiveSessionControlsDock />、<SwapExerciseModal />、<FinishConfirmationModal /> |
/week |
訓練時間表/週檢視畫面 | 完整的 7 天時間表總覽,包含每週總量/時間匯總資料。 | <WeekHeader />,<WeeklyStatsSummary />,<DayScheduleCardList />,<DayScheduleCard />,<ModifyWeekWithCoachCard /> |
/coach |
AI 教練對話 | 提供對話式指導,並附上情境方塊和分階段訓練提案。 | <CoachHeader />、<ChatMessageList />、<ChatBubble />、<StagedProposalCard />、<ContextualPromptsBar />、<ChatInputDock />、<ContextBanner />、<ChatInputBar />、<SpeechToTextButton /> |
/progress |
進度與數據分析 | 歷來訓練記錄、個人最佳成績和訓練量圖表。 | <ProgressHeader />、<PRShowcaseBanner />、<VolumeProgressChartCard />、<AllTimeStatsGrid />、<WorkoutHistorySection />、<HistorySessionCard />、<EmptyHistoryPlaceholder /> |
/settings |
使用者個人資料和偏好設定 | 設備設定檔、通知和 3 層記憶體管理。 | <SettingsHeader />、<UserProfileCard />、<EquipmentSelectorCard />、<EquipmentToggleChip />、<PreferencesGroup />、<MemoryTierViewerCard />、<MemoryItemCard />、<AccountActionsGroup /> |
/exercises/:exerciseId |
運動百科全書詳細資料 | 可深層連結的練習指南 (例如 /exercises/incline-db-bench-press),內含影片和表單提示。 |
<BackButton />,<ExerciseVideoPlayer />,<TargetMusclesCard />,<HowToPerformCard />,<FormTipsCard /> |
3. 網頁和檢視畫面規格
檢視畫面:DailyWorkoutView (/today和/workouts/:day)
- 用途:顯示特定日期的預定訓練計畫,包括訓練重點、時間長度、目標肌肉負荷分布、教練附註、直組區塊和超級組區塊。如果沒有預定訓練,則會顯示乾淨的空白狀態。
- 視覺元素:
- 上衣:
<BackButton label="Back to Week" targetRoute="/week" />。 - 標題:單行標題 (
"Today"或星期幾),包含條件式"✓ Completed"徽章、時間長度藥丸 ("⏱ 50 min") 和目標肌肉強度百分比長條。 - 教練筆記:情境建議資訊卡,包含圖示和綠色邊框。
- Body:使用
<WorkoutExerciseSummary />的可捲動運動區塊清單 (一般組或超級組,附border-left: 3px solid #a3e635和🔁 SUPERSET BLOCK徽章)。 - 空白狀態:
<EmptyDayPlaceholder message="Nothing scheduled for this day" />。 - 底部頁尾動作:
<ModifyWithCoachCard />(導向/coach?day=:day)。
- 上衣:
查看:WeekScheduleView (/week)
- 用途:顯示完整的 7 天訓練計畫總覽,包括高層級的每週訓練量/時間指標、精選的訓練日清單 (嚴格篩除未排定訓練/休息日),以及直接使用 AI 教練全面調整每週計畫的捷徑。
- 視覺結構:
<WeekHeader />、3 欄<WeeklyStatsSummary />(總時間、總量、頻率)、使用<DayScheduleCard variant="normal" />的排定日期清單 (當天有螢光綠TODAY徽章),以及<ModifyWeekWithCoachCard />(導向/coach?context=week)。
查看:CoachChatView (/coach)
- 用途:Gemini 訓練員代理的對話式指導中心。提供激勵和策略訓練建議、支援語音轉文字聽寫功能,並透過明確的接受控制項,提供人工介入迴路分階段訓練調整。
- 視覺剖析:
<CoachHeader />、可捲動的<ChatMessageList />(<ChatBubble />和<StagedProposalCard />)、條件式<ContextualPromptsBar />,以及固定的<ChatInputDock />(<ContextBanner />搭配[✕]關閉 +<ChatInputBar />+<SpeechToTextButton />)。
查看:ExerciseDetailView (/exercises/:exerciseId)
- 目的:提供可深層連結的百科全書條目,包括自動循環播放的靜音示範影片 (
<ExerciseVideoPlayer />)、主要與次要目標肌肉徽章 (<TargetMusclesCard />)、依序排列的逐步操作說明 (<HowToPerformCard />),以及姿勢提示 (<FormTipsCard />)。
查看:ActiveWorkoutView (/workout/active)
- 用途:高強度健身執行和設定記錄畫面。管理即時訓練碼錶狀態、目前設定目標、次數/重量輸入、即時勾號完成 (<16 毫秒)、自動超級組交替、休息計時器倒數 (含觸覺/音訊)、動作切換,以及最終持續性至
POST /api/workouts/log。 - 視覺結構:
<ActiveSessionStickyHeader />、<ActiveExerciseCardHeader />、<CoachTipCard />、<CurrentSetTargetCard />、浮動<ActiveRestTimerDock />(+30s、Skip)、<SetNavigationRow />、<ExerciseSetsTable />(+ Add Set)、<SessionExerciseOverview />、固定<ActiveSessionControlsDock />([⇄ SWAP EXERCISE]+[▶ START WORKOUT]/[⏸ PAUSE]/[▶ RESUME])、<SwapExerciseModal />和<FinishConfirmationModal />。
查看:ProgressView (/progress)
- 用途:追蹤運動進展、慶祝近期個人記錄 (
<PRShowcaseBanner />)、透過互動式 Recharts (<VolumeProgressChartCard />搭配4W | 3M | 1Y切換鈕) 呈現每週/每月運動量趨勢、顯示<AllTimeStatsGrid />,以及封存過去完成的健身課程 (<WorkoutHistorySection />/<HistorySessionCard />)。
查看:SettingsView (/settings)
- 用途:管理運動員個人資料 (
<UserProfileCard />)、裝備庫存 (<EquipmentSelectorCard />/<EquipmentToggleChip />)、訓練偏好設定 (<PreferencesGroup />,適用於LBS / KG、觸覺回饋、音效),並提供透明的使用者管理功能,以及刪除 AI 教練 3 層活動記憶 (<MemoryTierViewerCard />/<MemoryItemCard />) 的功能。
4. 可重複使用的元件目錄和介面
應用程式中重要的 TypeScript 元件屬性合約:
// src/components/workout/WorkoutExerciseSummary.tsx
interface WorkoutExerciseSummaryProps {
blocks: Array<{
label?: string;
category?: string;
exercises: Array<{
exercise_id: string; // Canonical slug (e.g. 'incline-db-bench-press')
name: string; // Denormalized display name (e.g. 'Incline DB Bench Press')
target_sets: number;
target_reps: string | number;
rest_seconds?: number;
}>;
}>;
activeExerciseId?: string;
onSelectExercise?: (exerciseId: string) => void;
}
// src/components/week/DayScheduleCard.tsx
interface DayScheduleCardProps {
dayName: string;
dayShort: string;
subtitleLabel?: string;
isToday?: boolean;
title: string;
focusBadge: string;
durationMin: number;
volumeLbs?: number;
targetMuscles: string[];
variant?: 'normal' | 'condensed';
onPress: (dayName: string) => void;
}
// src/components/coach/StagedProposalCard.tsx
interface StagedProposalCardProps {
proposalId: string;
type: 'UPDATE_DAY' | 'UPDATE_WEEK';
targetDay?: string;
summaryDiff: string;
proposalData: any;
isApplied?: boolean;
onAccept: (proposalId: string, data: any) => void;
onModify: (summaryDiff: string) => void;
}
// src/components/workout/CurrentSetTargetCard.tsx
interface CurrentSetTargetCardProps {
setNumber: number;
targetWeightLbs: number;
targetReps: number;
isCompleted: boolean;
onWeightChange: (weight: number) => void;
onRepsChange: (reps: number) => void;
onToggleComplete: () => void;
}5. 用戶端狀態管理和資料流程矩陣
5.1 延遲和載入政策:雙速引擎
- 健身房樂觀 UI (<16 毫秒):健身房觸覺動作 (勾選組數、增加重量/次數、切換分頁和切換設備) 會在 16 毫秒內更新本機狀態並重新轉譯。使用者在舉重時,不會受到載入指標的干擾。
- 非同步作業的明確載入旋轉圖示和指標:
- AI 教練對話 (
POST /api/coach/chat):提交即時通訊訊息後,對話串會立即顯示動畫教練思考旋轉泡泡,直到 Gemini 傳回回覆或健身提案。 - 初始冷啟動和網路同步:擷取
weekly_plans或historical_workouts時,檢視容器會顯示骨架載入器和高對比載入旋轉圖示。 - 提交健身資料 (
[Finish]):當課程酬載提交至 Cloud Firestore 中的POST /api/workouts/log時,完成確認模式會顯示載入中的旋轉圖示。
- AI 教練對話 (
5.2 用戶端商店架構和網域邊界
| 商店層 | 狀態網域和重要屬性 | 保留和快取政策 | 協調後端合約 |
|---|---|---|---|
useActiveSessionStore (Zustand) |
sessionState (unstarted、running、paused)、elapsedSeconds、currentStepIndex、steps: WorkoutStep[]、loggedExercises。 |
每秒同步至 localStorage,手機鎖定/重新整理時可完美復原。 |
將完成的酬載提交至 POST /api/workouts/log。 |
useWeeklyPlanQuery (TanStack Query) |
目前 7 天的訓練課表、每日訓練物件、超級組區塊、完成狀態 (scheduled、completed)。 |
在 TanStack Query (staleTime: 5 min) 中快取;在啟動時預先擷取。 |
使用者輕觸 [Accept Plan] 接受POST /api/coach/chat的提案後,即會提交。 |
useCoachChatStore (Zustand + TanStack) |
依時間順序排列的訊息泡泡、activeContext、提示詞方塊、isCoachTyping: boolean、分階段提案。 |
使用即時訂閱 (onSnapshot) 與 Firestore 每週聊天 bucket 同步。 |
將查詢調度至 POST /api/coach/chat。 |
useProgressQuery (TanStack Query) |
歷來訓練封存、個人記錄板 (/users/{userId}/prs)、歷來訓練量匯總、時間範圍篩選器 (4W、3M、1Y)。 |
在 TanStack Query (staleTime: 10 min) 中快取。 |
完成訓練課程後立即更新。 |
useUserProfileStore (TanStack Query) |
裝備清單、單位 (LBS/KG)、音效/觸覺回饋切換、3 層生活記憶 (基本、生理、情境)。 |
在 TanStack Query 中快取,並與 Firestore user_profiles 雙向同步。 |
使用POST /api/coach/chat的memory_mutations自動更新。 |
useExerciseLibraryQuery (TanStack Query) |
靜態百科全書項目、影片網址、主要/次要肌肉、步驟、姿勢提示。 | 積極快取優先,存留時間無限 (staleTime: Infinity)。 |
從不可變更的 Firestore exercises 集合讀取。 |
5.3 預先計算的活動時段步驟圖
export interface WorkoutStep {
stepIndex: number; // 1-based index (e.g. 1 to 13)
totalSteps: number; // Total sets in the session
blockIndex: number; // Index of block in day plan
blockType: 'straight' | 'superset';
exerciseId: string; // Canonical slug
exerciseName: string; // Display name
setNumber: number; // Set index for this exercise (1, 2, 3...)
targetWeightLbs: number; // Target weight in lbs
targetReps: string | number; // Target reps (e.g. "8-10")
restSecondsAfter: number; // Prescribed rest duration
isCompleted: boolean; // Completion checkmark status
actualWeightLbs?: number; // User entered weight
actualRepsCompleted?: number; // User entered reps
}5.4 端對端資料流程和變異矩陣
| 使用者觸發條件 | 來源檢視表 | 用戶端儲存庫已變更 | UI 延遲/載入狀態 | 後端協調 | 復原/失敗處理 |
|---|---|---|---|---|---|
輕觸「[✓] 完成設定」 |
/workout/active |
useActiveSessionStore |
<16ms (樂觀) |
本機工作階段緩衝區已更新,不需等待網路。 | 本機記憶體寫入,具備可靠的本機持續性。 |
輕觸 [Finish Workout] |
/workout/active |
useActiveSessionStore、useWeeklyPlanStore、useProgressStore |
同步處理時,按鈕會顯示載入旋轉圖示 | 提交至 POST /api/workouts/log。將 Firestore 日標示為 completed。 |
如果離線,則會將酬載排入本機同步緩衝區,並在重新連線後重試。 |
輕觸 [Accept Plan] |
/coach |
useWeeklyPlanStore、useCoachChatStore |
Instant UI 圖章 ("✓ Plan Applied") |
將 proposal.data 提交至 Firestore weekly_plans。 |
如果網路連線失敗,系統會顯示浮動式通知,提醒使用者,且按鈕仍可點選,方便使用者重試。 |
| 在 Chat 中傳送訊息 | /coach |
useCoachChatStore、useUserProfileStore |
樂觀泡泡附加 + Coach 思考旋轉圖示 | 來電POST /api/coach/chat。提交作業傳回 memory_mutations。 |
將旋轉圖示替換為「無法傳送。輕觸即可重試。」 |
| 切換設備方塊 | /settings |
useUserProfileStore |
即時切換 (<16ms) |
將背景寫入作業調度至 Firestore user_profiles。 |
如果寫入失敗,則會還原方塊選取項目,並顯示錯誤浮動式訊息。 |
刪除 AI 記憶項目「[🗑]」 |
/settings |
useUserProfileStore |
立即刪除 (<16ms) |
將刪除異動作業調度至 Firestore user_profiles。 |
還原回憶集錦項目,並在刪除失敗時通知使用者。 |
6. 端對端使用者歷程和淺顯易懂的測試矩陣
- 套件 1:應用程式殼層、導覽和路徑處理 (測試 1.1 至 1.6:根啟動重新導向、持續性停駐、有效工作階段快速返回、無效星期備用、未知路徑 404 備用、無效運動深層連結備用)。
- 套件 2:每日訓練檢視畫面和區塊算繪 (測試 2.1 至 2.7:動態日期標題解析、特定日期路徑和返回按鈕、單一與超級組區塊處理、空白日期預留位置、已完成訓練戳記、中央播放按鈕的純導覽、使用教練情境附件修改)。
- 套件 3:週排程檢視畫面和日排程資訊卡 (測試 3.1–3.6:每週統計資料算繪、僅限排程日期篩選器、今日視覺摘要、日資訊卡導覽、修改週導覽、精簡變化版本算繪)。
- 測試套件 4:教練對話和階段式變更 (測試 4.1 至 4.7:即時通訊訊息串算繪、內容橫幅附加和關閉、提示詞方塊預先填入、語音聽寫切換、階段式變更隔離、提案接受和提交、每週全面提案預覽和提交)。
- 套件 5:運動詳細資料和百科全書 (測試 5.1 至 5.5:運動詳細資料算繪、自動循環靜音播放、影片暫停切換、主要與次要肌肉標記、歷史記錄返回瀏覽和備用)。
- 套件 6:活動訓練追蹤工具和記錄 (測試 6.1–6.7:未開始的初始狀態和手動開始、暫停和繼續碼錶、觸覺組記錄和勾號切換、超級組步驟交替、交換運動模式和替換、完成確認和伺服器同步、重新載入時恢復工作階段狀態)。
- 套件 7:進度與歷來數據分析 (測試 7.1 至 7.5:進度資訊主頁總覽算繪、PR 展示橫幅顯示、圖表時間範圍切換、空白記錄狀態、輕觸過往工作階段記錄)。
- 套件 8:使用者設定、裝備和 AI 記憶 (測試 8.1 至 8.4:設定檢視畫面算繪、裝備切換更新、單位切換、AI 記憶項目刪除)。