diff --git a/backend/src/index.ts b/backend/src/index.ts index bfe2554..def069b 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -38,6 +38,8 @@ const typeDefs = `#graphql product(ean: String!): Product categories: [Category!]! + shoppingList(id: ID!): ShoppingList + } @@ -101,6 +103,7 @@ const resolvers = { return result.rows[0] ?? null; }, + products: async ( _parent: unknown, args: { @@ -137,8 +140,146 @@ const resolvers = { return result.rows; }, + + + shoppingList: async ( + _parent: unknown, + args: { id: string }, + ) => { + const result = await pool.query( + ` + SELECT + id, + name, + status, + in_use AS "inUse" + FROM shopping_lists + WHERE id = $1 + `, + [args.id], + ); + + return result.rows[0] ?? null; + }, + }, + + Mutation: { + createShoppingList: async ( + _parent: unknown, + args: { name: string }, + ) => { + const result = await pool.query( + ` + INSERT INTO shopping_lists (owner_id, name) + VALUES ($1, $2) + RETURNING + id, + name, + status, + in_use AS "inUse" + `, + ['anonymous', args.name], + ); + + return result.rows[0]; + }, + + addItemToList: async ( + _parent: unknown, + args: { + listId: string; + ean: string; + quantity?: number; + }, + ) => { + const quantity = args.quantity ?? 1; + + if (quantity <= 0) { + throw new Error('Antall må være større enn 0'); + } + + // Sjekk at handlelisten finnes + const listResult = await pool.query( + ` + SELECT id + FROM shopping_lists + WHERE id = $1 + `, + [args.listId], + ); + + if (listResult.rows.length === 0) { + throw new Error('Handlelisten finnes ikke'); + } + + // Sjekk at produktet finnes + const productResult = await pool.query( + ` + SELECT ean + FROM products + WHERE ean = $1 + `, + [args.ean], + ); + + if (productResult.rows.length === 0) { + throw new Error('Produktet finnes ikke'); + } + + // Legg til varen. + // Hvis varen allerede finnes i listen, økes quantity. + await pool.query( + ` + INSERT INTO list_items (list_id, ean, quantity) + VALUES ($1, $2, $3) + ON CONFLICT (list_id, ean) + DO UPDATE SET + quantity = list_items.quantity + EXCLUDED.quantity + `, + [args.listId, args.ean, quantity], + ); + + // Returner handlelisten + const result = await pool.query( + ` + SELECT + id, + name, + status, + in_use AS "inUse" + FROM shopping_lists + WHERE id = $1 + `, + [args.listId], + ); + + return result.rows[0]; + }, }, + ShoppingList: { + items: async (list: { id: string }) => { + const result = await pool.query( + ` + SELECT + id, + ean, + quantity, + note, + checked + FROM list_items + WHERE list_id = $1 + ORDER BY id + `, + [list.id], + ); + + return result.rows; + }, + }, + +//evt en ekstra { + Product: { category: async (product: { categoryId?: number | null }) => { if (!product.categoryId) { @@ -180,7 +321,6 @@ const resolvers = { }, }; - const server = new ApolloServer({ typeDefs, resolvers, introspection: true, }); // Port 3001 er kravet i oppgaven, men kan overstyres i .env diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..749f7fc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "T27-Project-2", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}