Skip to content
Merged
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
175 changes: 170 additions & 5 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,187 @@
import 'dotenv/config';
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { pool } from './db.js';

// Midlertidig skjema for å sjekke at serveren kjører.
// Erstattes av det ekte skjemaet når databasen er på plass.
const typeDefs = `#graphql
type Category {
id: ID!
parentId: ID
name: String!
}
type Price {
storeCode: String!
price: Float!
unitPrice: Float
url: String
}
type Product {
ean: String!
name: String!
brand: String
imageUrl: String
categoryId: ID
category: Category
prices: [Price!]!
}
type Query {
hello: String!
products(
search: String
category: ID
limit: Int = 20
offset: Int = 0
): [Product!]!
product(ean: String!): Product
categories: [Category!]!
}
type ShoppingListItem {
id: ID!
ean: String!
quantity: Int!
note: String
checked: Boolean!
}
type ShoppingList {
id: ID!
name: String!
status: String!
inUse: Boolean!
items: [ShoppingListItem!]!
}
type Mutation {
createShoppingList(name: String!): ShoppingList!
addItemToList(
listId: ID!
ean: String!
quantity: Int = 1
): ShoppingList!
}
`;

const resolvers = {
Query: {
hello: () => 'Hei fra Handlelappen-backend!',
categories: async () => {
const result = await pool.query(`
SELECT
id,
parent_id AS "parentId",
name
FROM categories
ORDER BY name
`);

return result.rows;
},

product: async (_parent: unknown, args: { ean: string }) => {
const result = await pool.query(
`
SELECT
ean,
name,
brand,
image_url AS "imageUrl",
category_id AS "categoryId"
FROM products
WHERE ean = $1
`,
[args.ean],
);

return result.rows[0] ?? null;
},

products: async (
_parent: unknown,
args: {
search?: string;
category?: string;
limit?: number;
offset?: number;
},
) => {
const search = args.search ?? null;
const category = args.category ?? null;
const limit = args.limit ?? 20;
const offset = args.offset ?? 0;

const result = await pool.query(
`
SELECT
ean,
name,
brand,
image_url AS "imageUrl",
category_id AS "categoryId"
FROM products
WHERE
($1::text IS NULL OR name ILIKE '%' || $1 || '%')
AND
($2::integer IS NULL OR category_id = $2)
ORDER BY name
LIMIT $3
OFFSET $4
`,
[search, category, limit, offset],
);

return result.rows;
},
},

Product: {
category: async (product: { categoryId?: number | null }) => {
if (!product.categoryId) {
return null;
}

const result = await pool.query(
`
SELECT
id,
parent_id AS "parentId",
name
FROM categories
WHERE id = $1
`,
[product.categoryId],
);

return result.rows[0] ?? null;
},

prices: async (product: { ean: string }) => {
const result = await pool.query(
`
SELECT
store_code AS "storeCode",
price,
unit_price AS "unitPrice",
url
FROM prices
WHERE ean = $1
ORDER BY price
`,
[product.ean],
);

return result.rows;
},
},
};

const server = new ApolloServer({ typeDefs, resolvers });

const server = new ApolloServer({ typeDefs, resolvers, introspection: true, });

// Port 3001 er kravet i oppgaven, men kan overstyres i .env
const port = Number(process.env.PORT ?? 3001);
Expand Down