The basic mechanics for user activity are already handled by the app:
-
Each user has its own globally unique
user identifier
assigned by the app; -
Every time a user opens the app on his device, a new user session is started;
-
Each new session is assigned a
session identifier
(generated by the app) when it starts; -
Each session identifier is guaranteed to be unique for that user, but may not be unique across different users.
Immediately after a session is started and its identifier generated, the app sends an "activity" event (i.e. an HTTP request)
to the API you are implementing through the following endpoint:
-
The request body is a JSON-encoded object with the following keys:
•
user_id
(string): the globally unique identifier of the user that opened the app;•
session_id
(string): the identifier of the user's new session;
-
the number of unique users seen in that time period. Unique means if a user opens the app more than once in that time period, it is only counted once.
-
the number of sessions seen in that time period;
-
the average number of sessions per user in time period.
The endpoint for this is:
-
Requests must include the
start_date
(inclusive) andend_date
(inclusive) query parameters to filter the data:• dates are specified in the
YYYY-MM-DD
format (e.g. January 23rd 2016 is written as 2016-01-23); -
Requests may also include an optional
user_id
query parameter to filter the response to a single user identifier; -
The response body should be a JSON-encoded string with the following format:
•
unique_users
(integer): number of unique users in the given time period;•
num_sessions
(integer): number of sessions in the given time period (or all time if no period is passed);
-
Your code should start an HTTP web server that exposes the two endpoints described above and handles the requests accordingly;
-
Your code must be written in either JavaScript or CoffeeScript and should compile and run on a standard Node.js environment;
-
This API must be built without using any pre-existing database management systems:
• That means no SQL, SQLite, MongoDB, Elastic, Redis, Memcache, etc.;
-
Your system should be fault-tolerant:
• If the process is killed it can be restarted with no (or minimal) loss of data;
-
Your system should be able to store and query the user activity events for the next 5 years;
-
The mobile app has about 1 million active daily users, that number is not expected to change in the next 5 years;
-
Each user opens the app twice a day on average, generating two new sessions and the corresponding activity events;
Example requests (notice the timestamps):
[2015-10-04T16:33:44] POST /activity { user_id: 4, session_id: 1 } -> 200 OK
[2015-10-05T02:42:18] POST /activity { user_id: 4, session_id: 2 } -> 200 OK
[2015-10-05T02:48:18] POST /activity { user_id: 4, session_id: 2 } -> 200 OK
[2015-10-05T10:37:29] POST /activity { user_id: 4, session_id: 3 } -> 200 OK
[2015-10-05T19:03:14] POST /activity { user_id: 5, session_id: 1 } -> 200 OK
[2015-10-06T23:33:20] POST /activity { user_id: 6, session_id: 1 } -> 200 OK
[2015-10-07T01:24:52] POST /activity { user_id: 4, session_id: 6 } -> 200 OK
[2015-10-08T00:00:01] GET /stats?start_date=2015-10-05&end_date=2015-10-06 ->
{
num_sessions: 4,
unique_users: 3,
avg_sessions_per_user: 1.33
}
[2015-10-09T00:00:01] GET /stats?start_date=2015-01-01&end_date=2015-12-31 ->
{
num_sessions: 6,
unique_users: 3,
avg_sessions_per_user: 2
}