Case study
Elite Progress
A remote strength-coaching platform that connects a mobile app for clients with a web admin panel for coaches in one system — training plans, set logging, real-time chat, and subscription payments. Built for personal trainers coaching clients remotely and their athletes, replacing scattered spreadsheets, messaging apps, and manual package billing.
I was responsible for the full build of the product: architecture, backend, both client apps, and deployment.
The app in action
Screenshots of key mobile and coach panel screens.
Problem
Trainers coaching clients remotely typically juggle several disconnected tools: a spreadsheet for the training plan, a messaging app to stay in touch with the client, separate notes for strength progress and body weight, manual tracking of package payments. This approach doesn't scale:
- a client's training history is scattered and hard to analyze,
- information gets lost in chat threads, the coach loses context on a client,
- there's no single place for progress data (weights, RPE, 1RM, body weight, calories),
- package access and payments are managed manually, outside the system.
As the client base grows, this way of working starts producing errors and eating into time the coach should spend analyzing training, not on admin work.
Solution
Elite Progress replaces that toolset with a single platform offering two role-tailored interfaces, tied together by a shared backend:
Mobile app (client)
Logs every set (weight, reps, RPE, media), shows the current training block and history, real-time chat with the coach, metrics, and a self-assessment review at the end of each block.
Web panel (coach)
All clients in one place, a training block builder, log analysis against the plan, messaging, and formal block completion.
Shared backend
One API contract for both clients, subscription payments (Stripe), cloud media storage, real-time chat.
The result: the coach gets a full picture of every client without switching between tools, and the client has one place to log training and reach their coach.
Scope of responsibility
Key features
Training plan
Full hierarchy: block, week, session, exercise, set — with the option to duplicate the previous block as a starting point for the coach.
Offline-first logging
Clients can log sets even without a connection; data syncs automatically once they're back online, with no duplicates.
Real-time chat
Coach–client messaging built on SignalR, integrated with the specific user's context in the admin panel.
Subscriptions & payments
Three packages (Starter/Momentum/Peak) with recurring billing via Stripe and feature gating based on the active package.
Coach operations panel
Training block builder, log analysis against the plan, review tracking, and reports (activity, compliance, strength/weight trends).
Architecture
User interface (mobile/web) → API (REST + real-time hub) → database (SQL Server) → external integrations (auth, payments, media, notifications).
flowchart LR
subgraph Clients
A[Mobile app
React Native + Expo
client/athlete]
B[Web panel
Angular
coach]
end
subgraph Backend
C[REST API + SignalR Hub
ASP.NET Core .NET 8]
end
D[(SQL Server
EF Core)]
subgraph External integrations
E[Firebase Auth]
F[Stripe
subscriptions]
G[Google Cloud Storage
media]
H[Expo Push
notifications]
end
A -- HTTPS / WebSocket --> C
B -- HTTPS / WebSocket --> C
C --> D
C --> E
C --> F
C --> G
C --> H
Technical challenges
Offline-first data sync
The mobile client needs to let athletes log training without a connection and sync
it safely later. Solution: a local log queue with a unique client-generated
identifier (clientId) and a last-write-wins strategy — the backend
checks the clientId to see if the log already exists, so retries after a
dropped connection never create duplicates.
Secure payments & webhook handling
A client's subscription must always stay consistent with Stripe's state, even though events arrive asynchronously via webhooks. The backend verifies the webhook signature, buffers the request, and only updates the subscription state once the event is confirmed.
Roles and package-based feature gating
Two independent front ends must consistently respect the same access rules: user role and active subscription package determine which features are visible. The rules live in a single place on the API side — so there's never two sources of truth for permissions.
Results
The product is pre-launch, so the numbers below are measurable technical facts about scope — no invented business metrics.
Technologies
| ASP.NET Core (.NET 8) | Backend REST API, modular monolith with 9 domain modules |
|---|---|
| Entity Framework Core + SQL Server | Training data model, code-first migrations |
| SignalR | Real-time coach–client chat |
| React Native + Expo | Client mobile app (iOS/Android), offline-first workout logging |
| Angular + ng-zorro-antd | Coach operations panel: block builder, reports, log analysis |
| Firebase Authentication | Email/password, Google, and Apple sign-in — the single source of identity |
| Stripe | Recurring subscriptions, checkout, payment-status webhooks |
| Google Cloud Storage | Media storage via signed-URL uploads |
| Google Cloud Run | API container hosting, production deployment |
| Docker / Docker Compose | Local development environment (database + API) |
| i18next | Full mobile internationalization (PL/EN), backend error-code translation |
| Vitest | Unit tests for domain logic on mobile |