# nhoogenkamp/sommelieriq-v2 architecture

> Architecture diagram of the GitHub repository nhoogenkamp/sommelieriq-v2, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nhoogenkamp/sommelieriq-v2
- Repository: https://github.com/nhoogenkamp/sommelieriq-v2

## Overview

SommelierIQ is a restaurant wine-recommendation platform: diners select a restaurant and dishes, then discover suitable wines from that restaurant’s available list. Restaurant staff maintain wine, food and sauce data, including CSV imports and AI-assisted profiling; role-based administration also covers users and restaurant accounts. The Flask API connects these workflows to persistence and optional billing/email services. The README documents rule-based pairing across food and wine characteristics. Some backend and frontend source was not sampled, so uncertain internal calls are omitted.

Main entry points: [`Server/app.py`](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/app.py) (Flask API), [`frontend/src/routes/AppRoutes.jsx`](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/routes/AppRoutes.jsx) (Application routes), [`Server/db.py`](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/db.py) (Application database), [`frontend/src/api/wineApi.js`](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/wineApi.js) (Wine API client)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_customer["Customer experience"]
  node_routes["Application routes<br/>[AppRoutes.jsx]"]
  node_restaurants["Restaurant discovery<br/>[Restaurants.jsx]"]
  node_wineview["Wine list<br/>[WineList.jsx]"]
  node_pairing["Dish selection<br/>[FoodPairing.jsx]"]
  node_pairingui["Pairing interface<br/>[PairingTabs.jsx]"]
  node_foodapi["Pairing API client<br/>[foodPairingApi.js]"]
  node_wineapi["Wine API client<br/>[wineApi.js]"]
end

subgraph group_management["Restaurant administration"]
  node_auth["Session and roles<br/>[AuthContext.jsx]"]
  node_protected["Role-protected pages<br/>[ProtectedRoute.jsx]"]
  node_menuupload["Menu imports<br/>[MenuUpload.jsx]"]
  node_wineadmin["Wine management<br/>[WineUpload.jsx]"]
  node_adminapi["Admin API client<br/>[adminApi.js]"]
end

subgraph group_backend["API and domain"]
  node_flask["Flask API<br/>[app.py]"]
  node_recommend["Pairing recommendations<br/>[recommendation.py]"]
  node_winehandlers["Wine operations<br/>[wines.py]"]
  node_menuhandlers["Menu operations<br/>[menu.py]"]
  node_dishupload["AI dish profiling<br/>[uploadDishesAI.py]"]
  node_authhandlers["Admin authentication<br/>[admin.py]"]
end

subgraph group_services["Persistence and integrations"]
  node_database[("Application database<br/>[db.py]")]
  node_stripe["Stripe billing<br/>[stripeWebhook.py]"]
  node_gmail["Gmail authorization<br/>[gmail_auth.py]"]
end

node_diner(("Diner"))
node_staff(("Restaurant staff"))
node_ai{{"AI profiling service"}}

node_diner -->|"opens"| node_routes
node_routes -->|"routes to"| node_restaurants
node_routes -->|"routes to"| node_wineview
node_routes -->|"routes to"| node_pairing
node_pairing -->|"renders"| node_pairingui
node_pairing -->|"requests data"| node_foodapi
node_foodapi -->|"calls API"| node_flask
node_wineview -->|"requests wines"| node_wineapi
node_wineapi -->|"calls API"| node_flask
node_flask -->|"dispatches"| node_recommend
node_flask -->|"dispatches"| node_winehandlers
node_flask -->|"dispatches"| node_menuhandlers
node_recommend -->|"reads data"| node_database
node_winehandlers -->|"reads and writes"| node_database
node_menuhandlers -->|"reads and writes"| node_database
node_staff -->|"opens"| node_routes
node_routes -->|"checks access"| node_protected
node_protected -->|"uses session"| node_auth
node_menuupload -->|"uploads data"| node_adminapi
node_menuupload -->|"uploads menu"| node_wineapi
node_menuupload -->|"submits imports"| node_flask
node_wineadmin -->|"manages wines"| node_wineapi
node_adminapi -->|"calls API"| node_flask
node_flask -->|"dispatches"| node_authhandlers
node_authhandlers -->|"reads and writes"| node_database
node_flask -->|"dispatches"| node_dishupload
node_dishupload -.->|"generates profiles"| node_ai
node_dishupload -->|"stores data"| node_database
node_flask -.->|"dispatches webhook"| node_stripe
node_stripe -.->|"updates billing"| node_database
node_flask -.->|"dispatches OAuth"| node_gmail

click node_routes "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/routes/AppRoutes.jsx"
click node_restaurants "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/Restaurants.jsx"
click node_wineview "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/WineList.jsx"
click node_pairing "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/FoodPairing.jsx"
click node_pairingui "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/components/foodPairing/PairingTabs.jsx"
click node_foodapi "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/foodPairingApi.js"
click node_wineapi "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/wineApi.js"
click node_auth "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/context/AuthContext.jsx"
click node_protected "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/context/ProtectedRoute.jsx"
click node_menuupload "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/admin/MenuUpload.jsx"
click node_wineadmin "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/admin/WineUpload.jsx"
click node_adminapi "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/adminApi.js"
click node_flask "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/app.py"
click node_recommend "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/recommendation.py"
click node_winehandlers "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/wines.py"
click node_menuhandlers "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/menu.py"
click node_dishupload "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/uploadDishesAI.py"
click node_authhandlers "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/admin.py"
click node_database "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/db.py"
click node_stripe "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/Stripe/stripeWebhook.py"
click node_gmail "https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/gmail/gmail_auth.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_routes,node_restaurants,node_wineview,node_pairing,node_pairingui,node_foodapi,node_wineapi toneBlue
class node_auth,node_protected,node_menuupload,node_wineadmin,node_adminapi toneAmber
class node_flask,node_recommend,node_winehandlers,node_menuhandlers,node_dishupload,node_authhandlers toneMint
class node_database,node_stripe,node_gmail toneRose
class node_diner,node_staff,node_ai toneIndigo
```

## Components

### Customer experience

- [Application routes](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/routes/AppRoutes.jsx): `frontend/src/routes/AppRoutes.jsx`
- [Restaurant discovery](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/Restaurants.jsx): `frontend/src/pages/Restaurants.jsx`
- [Wine list](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/WineList.jsx): `frontend/src/pages/WineList.jsx`
- [Dish selection](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/FoodPairing.jsx): `frontend/src/pages/FoodPairing.jsx`
- [Pairing interface](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/components/foodPairing/PairingTabs.jsx): `frontend/src/components/foodPairing/PairingTabs.jsx`
- [Pairing API client](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/foodPairingApi.js): `frontend/src/api/foodPairingApi.js`
- [Wine API client](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/wineApi.js): `frontend/src/api/wineApi.js`

### Restaurant administration

- [Session and roles](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/context/AuthContext.jsx): `frontend/src/context/AuthContext.jsx`
- [Role-protected pages](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/context/ProtectedRoute.jsx): `frontend/src/context/ProtectedRoute.jsx`
- [Menu imports](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/admin/MenuUpload.jsx): `frontend/src/pages/admin/MenuUpload.jsx`
- [Wine management](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/pages/admin/WineUpload.jsx): `frontend/src/pages/admin/WineUpload.jsx`
- [Admin API client](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/frontend/src/api/adminApi.js): `frontend/src/api/adminApi.js`

### API and domain

- [Flask API](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/app.py): `Server/app.py`
- [Pairing recommendations](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/recommendation.py): `Server/routes/recommendation.py`
- [Wine operations](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/wines.py): `Server/routes/wines.py`
- [Menu operations](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/menu.py): `Server/routes/menu.py`
- [AI dish profiling](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/uploadDishesAI.py): `Server/routes/uploadDishesAI.py`
- [Admin authentication](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/admin.py): `Server/routes/admin.py`

### Persistence and integrations

- [Application database](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/db.py): `Server/db.py`
- [Stripe billing](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/Stripe/stripeWebhook.py): `Server/routes/Stripe/stripeWebhook.py`
- [Gmail authorization](https://github.com/nhoogenkamp/sommelieriq-v2/blob/main/Server/routes/gmail/gmail_auth.py): `Server/routes/gmail/gmail_auth.py`

### Other components

- **Diner**
- **Restaurant staff**
- **AI profiling service**

## Connections

- Diner → Application routes: opens
- Application routes → Restaurant discovery: routes to
- Application routes → Wine list: routes to
- Application routes → Dish selection: routes to
- Dish selection → Pairing interface: renders
- Dish selection → Pairing API client: requests data
- Pairing API client → Flask API: calls API
- Wine list → Wine API client: requests wines
- Wine API client → Flask API: calls API
- Flask API → Pairing recommendations: dispatches
- Flask API → Wine operations: dispatches
- Flask API → Menu operations: dispatches
- Pairing recommendations → Application database: reads data
- Wine operations → Application database: reads and writes
- Menu operations → Application database: reads and writes
- Restaurant staff → Application routes: opens
- Application routes → Role-protected pages: checks access
- Role-protected pages → Session and roles: uses session
- Menu imports → Admin API client: uploads data
- Menu imports → Wine API client: uploads menu
- Menu imports → Flask API: submits imports
- Wine management → Wine API client: manages wines
- Admin API client → Flask API: calls API
- Flask API → Admin authentication: dispatches
- Admin authentication → Application database: reads and writes
- Flask API → AI dish profiling: dispatches
- AI dish profiling → AI profiling service: generates profiles
- AI dish profiling → Application database: stores data
- Flask API → Stripe billing: dispatches webhook
- Stripe billing → Application database: updates billing
- Flask API → Gmail authorization: dispatches OAuth
