智能健身应用:客户端架构规范
宇宙文物这是第 3 集“为应用赋予智慧”和第 4 集“无代码应用实现计划”中使用的工件。您可以将此规范作为前端视图、可重用界面组件、客户端状态管理和简明英语测试用例的参考。
登录即可访问此制品
使用您的 Google 开发者资料登录,即可查看和复制“Build It!”系列中使用的完整工件。
必须提供开发者资料
您不符合创建开发者资料的条件。请通知您的 Workspace 管理员启用此功能。
创建开发者资料
创建免费的 Google 开发者资料,解锁所有 Build It! 提示和工件。
加入 Builder Central 即可解锁
一键领取免费的 Builder 会员徽章,即可解锁所有 Build It! 提示和工件。
状态:已准备好进行规划会议(正在使用 Client Planning Companion 起草)
配套文档:数据架构规范
架构目标:对 AI Studio 智能健身原型进行干净、可维护、模块化且可测试的前端重建。
0. 核心技术栈和工程标准
- 运行时框架:Next.js(App Router、React 19)+ 渐进式 Web 应用 (PWA) 离线资源缓存。
- 样式架构:Tailwind CSS v4 + Tailwind Variants(用于确定性组件样式)+ Lucide React(图标)。
- 客户端状态划分:
- Zustand(本地会话):管理不稳定的健身房状态 (
useActiveSessionStore)、秒表计时器、活动组缓冲区和预先计算的步序。已同步到localStorage,用于手机锁定恢复。 - TanStack Query(服务器状态):管理 Firestore 文档缓存、后台重新验证以及
weekly_plans、user_profiles、prs和workout_logs的乐观更新。
- Zustand(本地会话):管理不稳定的健身房状态 (
- 图表可视化:Recharts(使用自定义深色健身模式令牌设置样式)。
- 身份验证:Firebase Authentication,其中不记名令牌身份验证标头会传递到所有服务器端点。
1. 前端原则和设计原则
- Gym-First Ergonomics:专为在锻炼期间用汗湿的手进行单手触控操作而设计。宽大的点按目标(至少 48x48dp)、高对比度易读性,以及尽可能减少输入需求。
- 乐观界面和离线弹性:记录组数、启动休息计时器和切换练习等操作必须在界面中即时响应(<16 毫秒)。后台同步会处理服务器与
POST /api/workouts/log的持久性,而不会阻塞用户。 - 严格分离关注点:哑组件/展示组件使用属性接收数据并发出事件;智能容器视图管理业务逻辑、状态存储区和 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: Scrollable list of exercise blocks using
<WorkoutExerciseSummary />(straight sets or supersets withborder-left: 3px solid #a3e635and🔁 SUPERSET BLOCKbadge). - 空白状态:
<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 组件 prop 协定:
// 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 延迟时间和加载政策:双速引擎
- 健身房场景下的乐观界面 (<16ms):健身房场景下的触觉操作(勾选组数、增加重量/次数、切换标签页和切换器械)会在 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 每周聊天存储桶同步。 |
将查询分派到 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) |
静态百科条目、视频网址、主要/次要肌肉、步骤、动作要领。 | 具有无限 TTL 的激进缓存优先 (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 端到端数据流和变更矩阵
| 用户触发器 | 源视图 | 客户端存储区已更改 | 界面延迟时间/加载状态 | 后端协调 | 回滚/失败处理 |
|---|---|---|---|---|---|
点按 [✓]“完成设置” |
/workout/active |
useActiveSessionStore |
<16ms(乐观) |
本地会话缓冲区已更新;无需等待网络。 | 本地内存写入,具有可靠的本地持久性。 |
点按 [Finish Workout] |
/workout/active |
useActiveSessionStore、useWeeklyPlanStore、useProgressStore |
按钮在同步时显示“正在加载”旋转图标 | 提交到 POST /api/workouts/log。将 Firestore 日期标记为 completed。 |
如果处于离线状态,则将载荷排入本地同步缓冲区,并在重新连接后重试。 |
点按 [Accept Plan] |
/coach |
useWeeklyPlanStore、useCoachChatStore |
即时界面图章 ("✓ 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:应用 Shell、导航和路线处理(测试 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 记忆项删除)。