Bodyspace: from a legacy vendor codebase to a 14-package monorepo
Took over a legacy vendor codebase and rebuilt it as a Clean Architecture Melos monorepo with ~12k lines of tests, 6 Codemagic workflows, Shorebird OTA patching, PostHog and Crashlytics.
- Client
- Bodyspace
- Role
- Sole developer
- Period
- 2024 — now
- Platforms
- iOS · Android
01 · Context
A pass and class-booking app, inherited from a vendor
Bodyspace sells gym passes and vouchers and takes class bookings through one app on the App Store and Google Play. In February 2024 RSApps took over the codebase the previous vendor had built and became the app's only developer.
02 · Problem
No structure, no tests, no safety net
The inherited app was a single package with no layers: every API call lived in one class, the only test was Flutter's unmodified template, and there was no CI and no crash reporting. Checkout was not finished, and the code still targeted Dart 2.
03 · What I did
Stabilised first, then rebuilt as a monorepo
In the first months RSApps restructured the app in place, moved it to BLoC, go_router, GetIt and secure storage, got Przelewy24 payments working and added Crashlytics. It then rebuilt the app as a Clean Architecture Melos monorepo and released it in February 2026.
- 4 apps and 14 packages, ~59k lines of Dart: sealed-class Cubits, GetIt DI and typed go_router navigation
- ~12k lines of automated tests
- 6 Codemagic workflows: staging builds, store releases from version tags, Shorebird patches and version flags
- PostHog analytics and feature flags, Crashlytics, and a forced-update gate driven by those flags
- Przelewy24 payments, an offline-first cart, group-class booking, gym-machine control by QR code, account deletion and consent management
04 · Result
Routine releases, urgent fixes without store review
A release now starts from a version tag, and CI builds it and publishes it to both stores. Urgent fixes can ship as Shorebird patches without waiting for store review, and PostHog and Crashlytics show what happens in production. The theming is brand-based, and a second client's app on the same platform is in progress: the start of a white-label, multi-brand product.