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

[SAH-60]: Implement Order Processing Validation #131

Merged
merged 10 commits into from
Jan 21, 2024
1 change: 1 addition & 0 deletions apps/api/src/middleware/zodValidate.ts
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ export const validate =

next();
} catch (error) {
console.error(error);
// @ts-ignore
return res.status(400).send(error.errors);
}
38 changes: 18 additions & 20 deletions apps/api/src/orders/router.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NextFunction, Response, Router, Request } from "express";
import { pushIntoOrders } from "../enqueue";
import { object, z } from "zod";
import { z } from "zod";
import { logger } from "../lib/winston";
import { logRequest } from "../middleware/requestLogger";
import { validate } from "../middleware/zodValidate";
@@ -9,32 +9,30 @@ import { processOrder } from "./operations/processOrder";

const ordersRouter = Router();

const orderSchema = z.object({
orderId: z.string(),
const orderObject = z.object({
customerId: z.string(),
order_items: z.object({
data: z
.object({
productId: z.string(),
price: z.number(),
quantity: z.number(),
})
.array(),
}),
});

ordersRouter.use(logRequest);

type OrdersActionType = {
created_at: Date;
customerId: string;
destination: string;
id: string;
orderId: string;
origin: string;
processedBy: string;
};

ordersRouter.post(
"/",
validate(orderSchema),
async (req: Request, res: Response<OrdersActionType>, next: NextFunction) => {
validate(orderObject),
async (req: Request, res: Response, next: NextFunction) => {
try {
// @ts-ignore
const order = await initOrder(req.locals);
await pushIntoOrders(req.body);
res.send({
...order,
const { object } = req.body.input;
await pushIntoOrders(object);
return res.status(200).json({
isValid: true,
});
} catch (error) {
next(error);
7 changes: 4 additions & 3 deletions apps/client/src/Products/ProductsCatalogue.tsx
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ import {
HiArrowPath,
HiSignalSlash,
} from "react-icons/hi2";
import { Products } from "@sahil/lib/graphql/__generated__/graphql";

export const ProductsCatalogue = () => {
const [offset, setOffset] = useState(0);
@@ -38,7 +39,7 @@ export const ProductsCatalogue = () => {
);

useEffect(() => {
setProducts(products);
setProducts(products as Products[]);
}, [products, setProducts]);

if (error) {
@@ -90,14 +91,14 @@ export const ProductsCatalogue = () => {
<ListHeader
onNextPage={() => setOffset((prev) => prev + 12)}
onPreviousPage={() => setOffset((prev) => prev - 12)}
isNextDisabled={offset + 12 >= productsCount}
isNextDisabled={offset + 12 >= productsCount!}
isPrevDisabled={offset === 0}
size={productsCount}
limit={12}
sizeLabel="Products"
/>
<List
data={products}
data={products as Products[]}
error={error}
loading={loading}
cols={4}
31 changes: 29 additions & 2 deletions apps/client/src/hooks/orders.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { useMutation, useQuery } from "@apollo/client";
import { useMutation, useQuery, useSubscription } from "@apollo/client";
import {
FETCH_ORDERS,
FETCH_ORDER_BY_PK,
INSERT_NEW_ORDER,
FETCH_ORDER_DELIVERIES,
FETCH_ORDERS_STATS,
INIT_ORDER_ACTION,
GET_ORDER_VALIDATION,
} from "@sahil/lib/graphql";
import {
InsertBusinessOrderMutation,
InsertBusinessOrderMutationVariables,
OrdersActionInput,
} from "@sahil/lib/graphql/__generated__/graphql";

export const useFetchOrders = () => {
const { error, data, loading } = useQuery(FETCH_ORDERS);
@@ -27,7 +34,10 @@ export const useFetchOrderByPK = (id: string) => {
};

export const usePlaceBusinessOrder = () => {
const [placeOrder, { data, loading, error }] = useMutation(INSERT_NEW_ORDER);
const [placeOrder, { data, loading, error }] = useMutation<
InsertBusinessOrderMutation,
InsertBusinessOrderMutationVariables
>(INSERT_NEW_ORDER);

return { loading, placeOrder, error };
};
@@ -46,3 +56,20 @@ export const useGetOrdersStats = () => {

return { error, ordersCount: data?.orders_aggregate?.aggregate, loading };
};

export const useInitBusinessOrder = () => {
const [initOrder, { data, loading, error }] = useMutation(INIT_ORDER_ACTION);

return { data, loading, error, initOrder };
};

export const useOrderValidSubscription = (actionId: string) => {
const { data, loading, error } = useSubscription(GET_ORDER_VALIDATION, {
variables: {
id: actionId,
},
skip: !actionId,
});

return { data: data?.insertBusinessOrder.output, loading, error };
};
5 changes: 3 additions & 2 deletions apps/client/src/hooks/products.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMutation, useQuery } from "@apollo/client";
import { FETCH_PRODUCTS, FETCH_PRODUCTS_BY_NAME } from "@sahil/lib/graphql";
import { GetProductsQuery } from "@sahil/lib/graphql/__generated__/graphql";
import { useRouter } from "next/router";

export const useFetchProducts = ({
@@ -14,7 +15,7 @@ export const useFetchProducts = ({

const graphqlQuery = name ? FETCH_PRODUCTS_BY_NAME : FETCH_PRODUCTS;

const { error, data, loading } = useQuery(graphqlQuery, {
const { error, data, loading } = useQuery<GetProductsQuery>(graphqlQuery, {
variables: {
offset,
limit,
@@ -25,6 +26,6 @@ export const useFetchProducts = ({
error,
data: data?.products,
loading,
productsCount: data?.products_aggregate?.aggregate.count,
productsCount: data?.products_aggregate?.aggregate?.count,
};
};
18 changes: 7 additions & 11 deletions apps/client/src/hooks/useOrderItemsStore.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { create } from "zustand";

type OrderItem = {
productId: string;
quantity: number;
};
import { Order_Item, Products } from "@sahil/lib/graphql/__generated__/graphql";

type OrderItemsStore = {
orderItems: OrderItem[];
products: any[];
addOrderItem: (item: OrderItem) => void;
removeOrderItem: (item: OrderItem) => void;
updateOrderItem: (item: OrderItem) => void;
setProducts: (products: any[]) => void;
orderItems: Order_Item[];
products: Products[];
addOrderItem: (item: Order_Item) => void;
removeOrderItem: (item: Order_Item) => void;
updateOrderItem: (item: Order_Item) => void;
setProducts: (products: Products[]) => void;
};

const INITIAL_STATE = {
Loading