From e60bcd8e06ea943c2f3cab6f61ddcbe1df0fef91 Mon Sep 17 00:00:00 2001 From: Celine Hagen Date: Fri, 9 Oct 2026 09:51:25 +0200 Subject: [PATCH] oppgave/wine-details-query --- backend/src/index.ts | 81 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/backend/src/index.ts b/backend/src/index.ts index bfa85f1..8326f5d 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -18,6 +18,25 @@ const typeDefs = `#graphql ratingCount: Int! } + type WineDetails { + id: ID! + name: String! + type: String! + elaborate: String + abv: Float + body: String + acidity: String + winery: String! + wineryWebsite: String + region: String! + country: String! + vintages: [Int!]! + grapes: [String!]! + foodPairings: [String!]! + avgRating: Float + ratingCount: Int! + } + type WinePage { items: [Wine!]! totalCount: Int! @@ -36,6 +55,8 @@ const typeDefs = `#graphql offset: Int = 0 ): WinePage! + wine(id: ID!): WineDetails + foodCategories: [FoodCategory!]! winesByFoodCategory( @@ -92,6 +113,66 @@ const resolvers = { }; }, + wine: async ( + _: unknown, + args: { id: string } +) => { + const wineId = Number(args.id); + + if (!Number.isInteger(wineId)) { + return null; + } + + const result = await pool.query( + ` + SELECT + w.id, + w.name, + w.type, + w.elaborate, + w.abv::float AS abv, + w.body, + w.acidity, + wi.name AS winery, + wi.website AS "wineryWebsite", + r.name AS region, + c.name AS country, + w.vintages, + w.avg_rating::float AS "avgRating", + w.rating_count AS "ratingCount", + + COALESCE( + ( + SELECT array_agg(g.name ORDER BY g.name) + FROM wine_grapes wg + JOIN grapes g ON g.id = wg.grape_id + WHERE wg.wine_id = w.id + ), + ARRAY[]::text[] + ) AS grapes, + + COALESCE( + ( + SELECT array_agg(f.name ORDER BY f.name) + FROM wine_foods wf + JOIN foods f ON f.id = wf.food_id + WHERE wf.wine_id = w.id + ), + ARRAY[]::text[] + ) AS "foodPairings" + + FROM wines w + JOIN wineries wi ON w.winery_id = wi.id + JOIN regions r ON w.region_id = r.id + JOIN countries c ON w.country_code = c.code + WHERE w.id = $1 + `, + [wineId] + ); + + return result.rows[0] ?? null; + }, + foodCategories: async () => { const result = await pool.query( `