there should be a service for logging workouts, it should update/create a new workout for a user: POST /workout, body params:{ userId: string, workoutType: WorkoutType, metrics: JSON (including metrics like time, number of repetitions or distance)} where metrics is an ENUM with values like {swimming, running,...}. and it should save in the db the data and the date it was logged. maybe it could also compute using an AI how many calories were burned and any other metrics needed.
it should fetch the data for a user:
GET /stats/:{userId} the stats for a specific user and
GET /history/:{userId} a history with all the workouts ordered chronologically for a user.
for syncing across devices we should leverage websockets for real time communication so the users will be able to access the stats with all their devices, eg smart watch, smart phone, etc. they should be used right after logging the workouts. on the same endpoint the message is sent to websocket POST /workout and there should be a listener in the service that whenever a message arrives to the websocket, it will consume it and update the metrics across the other devi
firstly we'll need a DNS, the request will reach the DNS which will translate the domain to an IP address and return it.
A CDN would be helpful to get the static elements like the JS files faster and to show the website quicker.
in order to handle many requests we could add a Load Balancer which firstly receives the request and forwards it to the API Gateway. by doing this we can easily scale up the servers in case of higher traffic.
the api gateway will handle the authentication and the rate limiting, to prevent abusive calls.
workout service is the one handling the business logic, it writes to db, for fetching user history and metrics it firstly checks in cache and in case it is missing, it uses the readonly DB replicas.
the websocket gateway relieves the heavy write to DB and also handles real time communication by forwarding the messages to queues. in case of need we could also add a load balancer and scale up the websocket gateways
a message queue would be useful here to decouple the write operations for workouts which then delegates the work to workers.
in order not to lose any data during offline activities, they could be pushed to a message queue which when the system goes back online, will consume the messages and update the db and cache accordingly.
workers will then emit a sync event and sync all other devices
for bulk imports the service should use the websocket gateway and message queues and asynchrnously handle them in order not to block incoming requests
in case of offline events, messages will be pushed to queues along with idempotency keys so they get handled only once even if they are duplicated. when the system is back online, all the messages from queues will be consumed, the idempotency keys will be checked and eventually only one operation will get through with its idempotency key unique
Api gateway can call the analytics service on each call.
also workout service might call an AI Gateway to compute calories burnt or any other operations, to decouple the massive workload we could use message queues
the db will have a user table which will store: userId, name, userName and any additional info
a device table which stores: deviceId, userId, deviceDetails;
workout table: workoutId, deviceSourceId, details, distance, type, calories
regarding stale data: write operations will invalidate the cache. the other devices receive real time updates through websockets, they dont poll, they get updates pushed to them. read replicas may remain stale for milliseconds but they will get updated on write operations
for notifications a service will be used which is called after a worker finishes its job, to ensure the entire event is completed and commited. analytics can be directly called from api gateway and use a queue in order not to block the main actions from completing (calling workout service, etc)
when a workout is logged, the user will send a request, load balancer will hit it first and route it to api gateway, now async the analytics queue will do its job using a message queue, while in the meantime the gateway will forward the request to workout service.
from the service when users log workouts, they send the details to ai gateway which will compute calories burnt for example and write it to db in an async mode. also the workout service will write the changes to the db and update the replicas and invalidate the caches.
in order to also notify all the other devices for a specific user, the call will be forwarded to websocket gateway along with an idempotency key, then get published to a queue and workers will handle it and emit the sync event whilst invalidating the cache and updating it.
for fetching history and stats for users, the workout service will read from read replicas. this might slow down write operations but it is a trade off for fast reading for users