Restructure into a three-tab app with Progress, goals, and Meditation
The UX redesign's first landing (spec in UX-REDESIGN.md): ContentView becomes a Today / Progress / Settings TabView, "Routine" replaces "Split" in every user-facing string and view name (code-level types keep their names), and workout starting moves to shared WorkoutStarter / StartedWorkoutNavigator plumbing. - New Progress tab: weekly goal streaks, workout trends, per-exercise weight progression, achievements, and the full history list (WorkoutLogsView -> WorkoutHistoryView). - Goals: stable categories workouts roll up to, managed from Settings. - New Meditation exercise + starter routine; timed sits record to Apple Health as Mind & Body sessions. Claude-Session: https://claude.ai/code/session_012qw2itfzKyEJ1HpsFt8Ex4
This commit is contained in:
@@ -26,7 +26,7 @@ struct WorkoutDocumentMapperTests {
|
||||
|
||||
@MainActor
|
||||
private func makeContext() throws -> ModelContext {
|
||||
let schema = Schema([Split.self, Exercise.self, Workout.self, WorkoutLog.self])
|
||||
let schema = Schema([Routine.self, Exercise.self, Workout.self, WorkoutLog.self])
|
||||
// cloudKitDatabase: .none matches WorkoutsModelContainer (see SeedLibraryTests).
|
||||
let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true, cloudKitDatabase: .none)
|
||||
return ModelContext(try ModelContainer(for: schema, configurations: [config]))
|
||||
@@ -63,7 +63,7 @@ struct WorkoutDocumentMapperTests {
|
||||
let context = try makeContext()
|
||||
let original = WorkoutDocument(
|
||||
schemaVersion: WorkoutDocument.currentSchemaVersion,
|
||||
id: "01WORKOUTROUNDTRIP00000001", splitID: "SPLIT-42", splitName: "Push Day",
|
||||
id: "01WORKOUTROUNDTRIP00000001", routineID: "RT-42", routineName: "Push Day",
|
||||
start: Self.start, end: Self.end, status: WorkoutStatus.completed.rawValue,
|
||||
createdAt: Self.created, updatedAt: Self.updated,
|
||||
logs: [
|
||||
@@ -97,8 +97,8 @@ struct WorkoutDocumentMapperTests {
|
||||
|
||||
// Spot-pin the load-bearing fields the whole-document `==` rolls up, so a future
|
||||
// regression names itself.
|
||||
#expect(rebuilt.splitID == "SPLIT-42")
|
||||
#expect(rebuilt.splitName == "Push Day")
|
||||
#expect(rebuilt.routineID == "RT-42")
|
||||
#expect(rebuilt.routineName == "Push Day")
|
||||
#expect(rebuilt.start == Self.start)
|
||||
#expect(rebuilt.end == Self.end)
|
||||
#expect(rebuilt.createdAt == Self.created)
|
||||
@@ -131,7 +131,7 @@ struct WorkoutDocumentMapperTests {
|
||||
let context = try makeContext()
|
||||
let original = WorkoutDocument(
|
||||
schemaVersion: WorkoutDocument.currentSchemaVersion,
|
||||
id: "01WORKOUTNOMETRICS0000001", splitID: nil, splitName: nil,
|
||||
id: "01WORKOUTNOMETRICS0000001", routineID: nil, routineName: nil,
|
||||
start: Self.start, end: nil, status: WorkoutStatus.inProgress.rawValue,
|
||||
createdAt: Self.created, updatedAt: Self.updated,
|
||||
logs: [log(id: "LOG-X", name: "Plank", order: 0, status: .inProgress, startedAt: Self.startedAt)],
|
||||
@@ -144,7 +144,7 @@ struct WorkoutDocumentMapperTests {
|
||||
|
||||
#expect(rebuilt == original)
|
||||
#expect(rebuilt.metrics == nil)
|
||||
#expect(rebuilt.splitID == nil)
|
||||
#expect(rebuilt.routineID == nil)
|
||||
#expect(rebuilt.end == nil)
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ struct WorkoutDocumentMapperTests {
|
||||
let context = try makeContext()
|
||||
let scrambled = WorkoutDocument(
|
||||
schemaVersion: WorkoutDocument.currentSchemaVersion,
|
||||
id: "01WORKOUTLOGORDER00000001", splitID: "S", splitName: "S",
|
||||
id: "01WORKOUTLOGORDER00000001", routineID: "S", routineName: "S",
|
||||
start: Self.start, end: Self.end, status: WorkoutStatus.completed.rawValue,
|
||||
createdAt: Self.created, updatedAt: Self.updated,
|
||||
logs: [
|
||||
@@ -184,7 +184,7 @@ struct WorkoutDocumentMapperTests {
|
||||
let context = try makeContext()
|
||||
let first = WorkoutDocument(
|
||||
schemaVersion: WorkoutDocument.currentSchemaVersion,
|
||||
id: "01WORKOUTREUPSERT00000001", splitID: "S", splitName: "S",
|
||||
id: "01WORKOUTREUPSERT00000001", routineID: "S", routineName: "S",
|
||||
start: Self.start, end: nil, status: WorkoutStatus.inProgress.rawValue,
|
||||
createdAt: Self.created, updatedAt: Self.updated,
|
||||
logs: [
|
||||
|
||||
Reference in New Issue
Block a user