Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/cart api #60

Merged
2 commits merged into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/constants/errorMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const INVALID_TOKEN = 'Invalid token !';
export const NOT_FOUND_GENERIC = 'Not found !';
export const INVALID_OTP = 'Invalid or expired OTP !';
export const ADD_CART_FAILED = 'Failed to add some models';
export const DELETE_CART_FAILED = 'Failed to delete some models';
export const MODEL_NOT_FOUND = 'This model does not exist';
export const DELETE_MODEL_FAILED = 'Model deletion failed';
export const UPDATE_MODEL_FAILED = 'Model update failed';
Expand Down
4 changes: 2 additions & 2 deletions src/dtos/in/addCart.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { Static, Type } from '@sinclair/typebox';
export const AddCartInputDto = Type.Object({
models: Type.Array(
Type.Object({
id: Type.String(),
quantity: Type.Number()
id: Type.String({ description: 'The id of the model to add to cart' }),
quantity: Type.Number({ minimum: 1, description: 'The number to add to cart' })
})
)
});
Expand Down
9 changes: 9 additions & 0 deletions src/dtos/in/delCart.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Static, Type } from '@sinclair/typebox';

// See https://github.com/sinclairzx81/typebox

export const DelCartInputDto = Type.Object({
models: Type.Array(Type.String(), { description: 'A list of model ids to delete from the cart' })
});

export type DelCartInputDto = Static<typeof DelCartInputDto>;
1 change: 1 addition & 0 deletions src/dtos/in/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
export * from './addCart.dto';
export * from './auth.dto';
export * from './defaultModel.dto';
export * from './delCart.dto';
export * from './order.dto';
export * from './paypal.dto';
export * from './register.dto';
Expand Down
76 changes: 58 additions & 18 deletions src/handlers/cart.handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Handler } from '@interfaces';
import { AddCartInputDto } from '@dtos/in';
import { AddCartInputDto, DelCartInputDto } from '@dtos/in';
import { prisma } from '@repositories';
import { ADD_CART_FAILED } from '@constants';
import { ADD_CART_FAILED, DELETE_CART_FAILED } from '@constants';
import { GetCartResultDto } from '@dtos/out';

const get: Handler<GetCartResultDto> = async (req, res) => {
Expand Down Expand Up @@ -36,23 +36,25 @@ const add: Handler<string, { Body: AddCartInputDto }> = async (req, res) => {
const { models } = req.body;

try {
await models.forEach((model) =>
prisma.cart.upsert({
create: {
model_id: model.id,
user_id: user_id,
quantity: model.quantity
},
update: {
quantity: model.quantity
},
where: {
user_id_model_id: {
await Promise.all(
models.map((model) =>
prisma.cart.upsert({
create: {
model_id: model.id,
user_id: user_id
user_id: user_id,
quantity: model.quantity
},
update: {
quantity: model.quantity
},
where: {
user_id_model_id: {
model_id: model.id,
user_id: user_id
}
}
}
})
})
)
);

return 'Added successfully';
Expand All @@ -61,7 +63,45 @@ const add: Handler<string, { Body: AddCartInputDto }> = async (req, res) => {
}
};

const del: Handler<string, { Body: DelCartInputDto }> = async (req, res) => {
const user_id = req.userId;
const { models } = req.body;

try {
await Promise.all(
models.map((model_id) =>
prisma.cart.delete({
where: {
user_id_model_id: {
model_id,
user_id
}
}
})
)
);

return 'Deleted successfully';
} catch (e) {
return res.badRequest(DELETE_CART_FAILED);
}
};

const delAll: Handler<string> = async (req) => {
const user_id = req.userId;

await prisma.cart.deleteMany({
where: {
user_id
}
});

return 'Reset cart successfully';
};

export const cartHandler = {
get,
add
add,
del,
delAll
};
30 changes: 28 additions & 2 deletions src/routes/apis/cart.plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AddCartInputDto } from '@dtos/in';
import { AddCartInputDto, DelCartInputDto } from '@dtos/in';
import { GetCartResultDto } from '@dtos/out';
import { cartHandler } from '@handlers';
import { verifyToken, verifyUserRole } from '@hooks';
Expand All @@ -24,13 +24,39 @@ export const cartPlugin = createRoutes('Cart', [
url: '',
onRequest: [verifyToken, verifyUserRole(UserRole.CUSTOMER)],
schema: {
summary: 'Add a model to the current user (based on jwt)',
summary: 'Add some models to the cart of the current user (based on jwt)',
body: AddCartInputDto,
response: {
200: Type.String(),
400: Type.String()
}
},
handler: cartHandler.add
},
{
method: 'DELETE',
url: '',
onRequest: [verifyToken, verifyUserRole(UserRole.CUSTOMER)],
schema: {
summary: 'Reset the cart of the current user (based on jwt)',
response: {
200: Type.String()
}
},
handler: cartHandler.delAll
},
{
method: 'POST',
url: '/delete',
onRequest: [verifyToken, verifyUserRole(UserRole.CUSTOMER)],
schema: {
summary: 'Remove some models from the cart of the current user (based on jwt)',
body: DelCartInputDto,
response: {
200: Type.String(),
400: Type.String()
}
},
handler: cartHandler.del
}
]);