Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
Merge pull request #58 from mjrousos/Issue54-PreserveCart
Browse files Browse the repository at this point in the history
Merge anonymous carts upon login
  • Loading branch information
mjrousos authored Jun 6, 2017
2 parents d572916 + 8ac2c6e commit 05ccd70
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 9 deletions.
29 changes: 20 additions & 9 deletions apigateway/routes/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,29 @@ router.get('/', function stickerRouteCart(req, res) {

router.use(bodyParser.json());

// TODO this enables carts for unauthenticated users, passing the uuid
// generated by the client to the session service as the user's id.
// Moving the user's unauthenticated cart to one stored with their
// permanent id upon login is unimplemented.
router.use((req, res, next) => {
// the client passes the uuid in the query string for GET
// requests, in body JSON for PUT
var sessionId = req.query.token || req.body.token;
if (!req.user) {
req.user = { id: req.query.token || req.body.token };
// If the user is unauthenticated, use
// the session uuid generated by the client as a
// temporary 'user id'
req.user = { id: sessionId };
next();
} else {
// If the user is authenticated, pass the client's
// session uuid so that any items that were added
// to the cart prior to the user authenticating can
// be merged into the user's cart.
request.put(`${CART_URL}/transfer/${sessionId}`, {
headers: { stickerUserId: req.user.id },
json: true
}, (error, response) => {
if (error) {
console.error(error);
}
next();
});
}

next();
});

router.get('/api/items', function getCart(req, res) {
Expand Down
1 change: 1 addition & 0 deletions sessionService/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
addToCartAsync: cart.addToCartAsync,
clearCartAsync: cart.clearCartAsync,
getCartAsync: cart.getCartAsync,
mergeCartsAsync: cart.mergeCartsAsync,
removeFromCartAsync: cart.removeFromCartAsync,
addItemToHistoryAsync: history.addItemToHistoryAsync,
getHistoryAsync: history.getHistoryAsync,
Expand Down
13 changes: 13 additions & 0 deletions sessionService/data/sources/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ exports.addToCartAsync = (userId, itemId) => {
});
}

exports.mergeCartsAsync = (destUserId, userIds) => {
return new Promise((resolve, reject) => {
var args = [cartKey(destUserId)].concat(userIds.map(userId => cartKey(userId)));
redisClient.sunionstore(args, (error, result) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}

exports.removeFromCartAsync = (userId, itemId) => {
return new Promise((resolve, reject) => {
redisClient.srem([cartKey(userId), itemId], (error, result) => {
Expand Down
24 changes: 24 additions & 0 deletions sessionService/routes/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,28 @@ router.put('/:item_id', async (req, res) => {
}
});

// Transfers one user's cart items to another user's cart
// (useful for when a user begins a session with a temporary
// un-auth'd user ID and then later logs in)
router.put('/transfer/:oldUserId', async (req, res) => {
try {
// If the old user has cart items, transfer them to
// the current user's cart.
if ((await dataAccess.getCartAsync(req.params.oldUserId)).length > 0) {
// Merge the two carts
await dataAccess.mergeCartsAsync(req.userId, [req.userId, req.params.oldUserId]);

// Once the carts are merged, it doesn't make sense to leave the partial
// cart for the original anonymous user.
await dataAccess.clearCartAsync(req.params.oldUserId);
}

// Return the user's current cart items (after merging, if necessary)
await sendItems(req.userId, res);
} catch (error) {
console.error(error);
res.sendStatus(500);
}
});

module.exports = router;

0 comments on commit 05ccd70

Please sign in to comment.