昨天在前端把運動紀錄的體驗做了優化,包含日曆、快速自訂動作、重量輸入的計算機。今天要把這些功能「落地」到後端,才能真正把資料存起來,未來還能做分析。
對健身紀錄來說,資料不只是「今天做了幾下 bench press」,而是要能支援未來的各種分析:
所以資料結構必須 既能記錄細節,又能彈性擴充。
我這邊用 Mongoose 來舉例:
// workout-log.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Types } from 'mongoose';
@Schema({ timestamps: true })
export class WorkoutLog extends Document {
@Prop({ type: Types.ObjectId, ref: 'User', required: true })
userId: Types.ObjectId;
@Prop({ type: String, required: true })
exerciseName: string; // e.g. Bench Press, Squat
@Prop({ type: String, enum: ['strength', 'cardio', 'stretch'], required: true })
category: string;
@Prop([
{
set: { type: Number, required: true },
reps: { type: Number, required: true },
weight: { type: Number }, // 可選,跑步就不需要
note: { type: String },
},
])
sets: {
set: number;
reps: number;
weight?: number;
note?: string;
}[];
@Prop({ type: Date, required: true })
date: Date;
}
export const WorkoutLogSchema = SchemaFactory.createForClass(WorkoutLog);
👉 這樣的設計,一筆紀錄可以包含多組 set/reps,非常貼近實際健身的紀錄方式。
POST /workouts
Content-Type: application/json
{
"exerciseName": "Bench Press",
"category": "strength",
"sets": [
{ "set": 1, "reps": 10, "weight": 60 },
{ "set": 2, "reps": 8, "weight": 65 }
],
"date": "2025-09-28"
}
GET /workouts?date=2025-09-28
GET /workouts/user/:userId
PATCH /workouts/:id
DELETE /workouts/:id
flowchart LR
A[使用者輸入紀錄] --> B[前端 UI]
B --> C[呼叫 API /workouts]
C --> D[後端 Controller]
D --> E[Service 處理邏輯]
E --> F[(MongoDB)]
F --> E
E --> D
D --> C
C --> B
B --> A
前端的 UI 只是「輸入器」,真正有價值的是背後的資料。
今天的 Schema + API 設計就是這個系統的基礎,未來無論要做 AI 分析、進度追蹤或排行榜,都是靠這些紀錄才能實現。