- Role & scope
- Independent · iPhone
- Built with
- Swift · SwiftUI · CloudKit · Swift Testing

Two kinds of history
Gym House pairs a strength-training log with a shared house of characters. Recording a workout advances the household, but someone may later need to correct their sets or change an entry to a rest day.
I separated the editable workout record from the rewards already credited to it. Revisions preserve the record’s identity and earned progress; a larger corrected workout can add the difference. The training history can become more accurate without taking away what the house has already earned.

When saves disagree
Progress is saved on the device, with backup to the user’s private iCloud account. The sync layer compares content fingerprints with the last shared save to decide whether either side has changed.
When both saves have diverged, the app asks which one to continue. Choosing replaces the other save, with a local recovery copy kept first. That is a deliberate tradeoff: the player reviews the conflict instead of the app attempting to merge interdependent workouts, relationships, and house state.
Check the interrupted paths
The sync tests exercise edits made while a fetch is in flight, failed uploads that must be retried, an Apple account changing during a request, and a conflict choice made stale by another device. These cases check the decisions around a backup, beyond a successful upload.
The implementation rechecks account identity and save revisions around network waits. This keeps the decision tied to the data being replaced. The tests establish specific behavior under those conditions; they are not a measurement of reliability across users’ devices.
What I take from this
Connecting a practical tool to a game means deciding what a correction is allowed to change. Making those rules explicit also makes it clearer when the app can reconcile progress itself and when the person needs to choose.