Skip to content

Commit

Permalink
Merge pull request #39 from yalla-coop/179-products-graphql-2
Browse files Browse the repository at this point in the history
setup single get product endpoint
  • Loading branch information
ajluker authored Jul 15, 2024
2 parents 7736445 + c66ffe8 commit e4eb91f
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 65 deletions.
62 changes: 42 additions & 20 deletions web/database/variants/variants.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,62 @@
import { query } from '../connect.js';

async function getVariants() {
return (await query(`SELECT * FROM fdc_variants order by product_id`)).rows
return (await query(`SELECT * FROM fdc_variants order by product_id`)).rows;
}

async function getVariantsByProductId(productId) {
return (
await query(`SELECT * FROM fdc_variants where product_id = $1`, [productId])
).rows;
}

async function variantCount() {
return Number((await query(`SELECT count(*) FROM fdc_variants`)).rows[0].count);
return Number(
(await query(`SELECT count(*) FROM fdc_variants`)).rows[0].count
);
}

async function getPagedVariants(lastId, limit) {
return (await query(`SELECT * FROM fdc_variants where product_id > $1 order by product_id limit $2`, [lastId, limit])).rows
return (
await query(
`SELECT * FROM fdc_variants where product_id > $1 order by product_id limit $2`,
[lastId, limit]
)
).rows;
}

function indexedByProductId(variants) {
return variants.reduce((accumulator, row) => {
const productId = row.productId;
return {
...accumulator,
[productId]: accumulator[productId] ? [...accumulator[productId], row] : [row]
};
}, {});
return variants.reduce((accumulator, row) => {
const productId = row.productId;
return {
...accumulator,
[productId]: accumulator[productId]
? [...accumulator[productId], row]
: [row]
};
}, {});
}

async function getAndAddVariantsToProducts(products) {
return addVariantsToProducts(products, indexedByProductId(await getVariants()))
return addVariantsToProducts(
products,
indexedByProductId(await getVariants())
);
}

function addVariantsToProducts(products, variantsByProductId){
return products.map(product => ({ ...product, fdcVariants: variantsByProductId[product.id] || [] }))
function addVariantsToProducts(products, variantsByProductId) {
return products.map((product) => ({
...product,
fdcVariants: variantsByProductId[product.id] || []
}));
}

export {
getVariants,
getPagedVariants,
indexedByProductId,
variantCount,
getAndAddVariantsToProducts,
addVariantsToProducts
}
getVariants,
getVariantsByProductId,
getPagedVariants,
indexedByProductId,
variantCount,
getAndAddVariantsToProducts,
addVariantsToProducts
};
44 changes: 44 additions & 0 deletions web/fdc-modules/products/controllers/get-product.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import shopify from '../../../shopify.js';
import getSession from '../../../utils/getShopifySession.js';
import { createDFCProductsFromShopify } from '../dfc/dfc-products.js';
import {
findFDCProducts,
getFdcVariantsByProductIdFromDB
} from './shopify/products.js';

const getProduct = async (req, res) => {
try {
const { EnterpriseName, ProductId } = req.params;

const session = await getSession(`${EnterpriseName}.myshopify.com`);

if (!session) {
return res.status(401).json({ message: 'Unauthorised' });
}

const client = new shopify.api.clients.Graphql({ session });

const fdcVariantsFromDB = await getFdcVariantsByProductIdFromDB(ProductId);

if (Object.keys(fdcVariantsFromDB).length === 0) {
return res.status(200).json('No product found');
}

const fdcProduct = await findFDCProducts(
client,
Object.keys(fdcVariantsFromDB)
);

const dfcProducts = await createDFCProductsFromShopify(
fdcProduct,
fdcVariantsFromDB
);

return res.status(200).json(dfcProducts);
} catch (error) {
console.error('Unable to load products', error);
throw new Error(error);
}
};

export default getProduct;
2 changes: 1 addition & 1 deletion web/fdc-modules/products/controllers/get-products.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const getProducts = async (req, res) => {
const fdcVariantsFromDB = await getFdcVariantsFromDB();

if (Object.keys(fdcVariantsFromDB).length === 0) {
return res.status(200).json([]);
return res.status(200).json('No products found');
}

const fdcProducts = await findFDCProducts(
Expand Down
52 changes: 8 additions & 44 deletions web/fdc-modules/products/controllers/shopify/products.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getShopifyIdSubstring } from '../../../../database/utils/get-shopify-id-substring.js';
import {
getVariants,
getVariantsByProductId,
indexedByProductId
} from '../../../../database/variants/variants.js';

Expand All @@ -20,6 +21,13 @@ export async function getFdcVariantsFromDB() {
return mappedVariantsByProductId;
}

export async function getFdcVariantsByProductIdFromDB(productId) {
const variants = await getVariantsByProductId(productId);
const mappedVariantsByProductId = indexedByProductId(variants);

return mappedVariantsByProductId;
}

export async function findProductsByIds(client, ids) {
const query = `
query findProducts($ids: [ID!]!) {
Expand Down Expand Up @@ -71,47 +79,3 @@ export async function findProductsByIds(client, ids) {
}))
}));
}

export async function findProductById(client, id) {
const query = `
query findProduct($id: ID!) {
product: node(id: $id) {
... on Product {
id
tags
title
description
images(first: 10) {
edges {
node {
id
src
}
}
}
variants(first: 250) {
edges {
node {
id
title
}
}
}
}
}
}
`;
const response = await client.query({
data: {
query,
variables: { id: `gid://shopify/Product/${id}` }
}
});

if (response.errors) {
console.error('Failed to load Product', JSON.stringify(response.errors));
throw new Error('Failed to load Product');
}

return response.body.data.product;
}
2 changes: 2 additions & 0 deletions web/fdc-modules/products/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Router } from 'express';
import getProducts from './controllers/get-products.js';
import getProduct from './controllers/get-product.js';

const fdcProductRoutes = Router({ mergeParams: true });

fdcProductRoutes.get('/', getProducts);
fdcProductRoutes.get('/:ProductId', getProduct);

export default fdcProductRoutes;

0 comments on commit e4eb91f

Please sign in to comment.