# syeedur-01/safeplate architecture

> Architecture diagram of the GitHub repository syeedur-01/safeplate, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/syeedur-01/safeplate
- Repository: https://github.com/syeedur-01/safeplate

## Overview

This is a food-safety and nutrition scanning application: users set a profile, submit a dish or packaged-food image with context, and receive an analysis. The graph separates the web workflow, API boundary, AI recognition, domain evaluation, and knowledge/rule data. It also retains documented-by-module capabilities such as allergens, nutrition, suitability, swaps, shopping, and scan history; those implementation paths are present in the tree but their runtime wiring was not sampled, so uncertain connections are omitted.

Main entry points: [`apps/web/src/App.tsx`](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/App.tsx) (App routing), [`apps/api/src/worker.ts`](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/worker.ts) (Worker entry), [`apps/api/src/scan-route.ts`](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/scan-route.ts) (Scan endpoint), [`packages/ai/src/provider.ts`](https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/provider.ts) (Vision provider)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web application"]
  node_app["App routing<br/>[App.tsx]"]
  node_scan_ui["Scan form<br/>[Scan.tsx]"]
  node_image["Image downscaling<br/>[downscale.ts]"]
  node_api_client["Scan client<br/>[client.ts]"]
  node_profile["Profile onboarding<br/>[Onboarding.tsx]"]
  node_profile_store[("Profile storage<br/>[profile-store.ts]")]
  node_history["Scan history<br/>[History.tsx]"]
end

subgraph group_api["API service"]
  node_api_app["HTTP routes<br/>[app.ts]"]
  node_scan_route["Scan endpoint<br/>[scan-route.ts]"]
  node_api_config["Service configuration<br/>[config.ts]"]
  node_worker["Worker entry<br/>[worker.ts]"]
  node_sanitizer["Input sanitization<br/>[sanitize.ts]"]
end

subgraph group_ai["AI analysis"]
  node_ai_provider["Vision provider<br/>[provider.ts]"]
  node_gemini["Gemini integration<br/>[gemini-provider.ts]"]
  node_scan_runner["Scan orchestration<br/>[run-scan.ts]"]
end

subgraph group_domain["Food evaluation"]
  node_engine["Food analysis<br/>[analyze.ts]"]
  node_allergens["Allergen evaluation<br/>[allergens.ts]"]
  node_suitability["Profile suitability<br/>[suitability.ts]"]
  node_label["Label analysis<br/>[label.ts]"]
  node_nutrition["Nutrition analysis<br/>[nutrition.ts]"]
  node_safety["Food safety<br/>[safety.ts]"]
  node_swaps["Food swaps<br/>[swaps.ts]"]
  node_shopping["Shopping guidance<br/>[shopping.ts]"]
end

subgraph group_knowledge["Knowledge and contracts"]
  node_knowledge_data[("Food knowledge data<br/>[index.ts]")]
  node_knowledge_messages["Safety messages<br/>[messages.ts]"]
  node_contracts["Shared data contracts<br/>[knowledge.ts]"]
end

node_user(("App user"))

node_user -->|"uses"| node_app
node_app -->|"routes to"| node_scan_ui
node_app -->|"routes to"| node_profile
node_app -->|"routes to"| node_history
node_app -->|"checks saved profile"| node_profile_store
node_profile -->|"saves profile"| node_profile_store
node_scan_ui -->|"downscales image"| node_image
node_scan_ui -->|"submits scan"| node_api_client
node_api_client -->|"posts scan"| node_scan_route
node_worker -->|"serves requests"| node_api_app
node_worker -->|"loads configuration"| node_api_config
node_worker -->|"loads dishes"| node_knowledge_data
node_worker -->|"selects provider"| node_ai_provider
node_api_app -->|"registers route"| node_scan_route
node_scan_route -->|"sanitizes input"| node_sanitizer
node_scan_route -->|"uses provider"| node_ai_provider
node_api_config -->|"configures provider"| node_ai_provider
node_ai_provider -->|"implemented by"| node_gemini
node_engine -->|"evaluates suitability"| node_suitability
node_suitability -->|"checks allergens"| node_allergens
node_label -->|"evaluates suitability"| node_suitability
node_swaps -->|"checks allergens"| node_allergens
node_swaps -->|"uses nutrition"| node_nutrition
node_swaps -->|"checks suitability"| node_suitability
node_knowledge_messages -->|"uses contracts"| node_contracts

click node_app "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/App.tsx"
click node_scan_ui "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/pages/Scan.tsx"
click node_image "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/lib/downscale.ts"
click node_api_client "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/api/client.ts"
click node_profile "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/pages/Onboarding.tsx"
click node_profile_store "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/state/profile-store.ts"
click node_history "https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/pages/History.tsx"
click node_api_app "https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/app.ts"
click node_scan_route "https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/scan-route.ts"
click node_api_config "https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/config.ts"
click node_worker "https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/worker.ts"
click node_sanitizer "https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/sanitize.ts"
click node_ai_provider "https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/provider.ts"
click node_gemini "https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/gemini-provider.ts"
click node_scan_runner "https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/run-scan.ts"
click node_engine "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/analyze.ts"
click node_allergens "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/allergens.ts"
click node_suitability "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/suitability.ts"
click node_label "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/label.ts"
click node_nutrition "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/nutrition.ts"
click node_safety "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/safety.ts"
click node_swaps "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/swaps.ts"
click node_shopping "https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/shopping.ts"
click node_knowledge_data "https://github.com/syeedur-01/safeplate/blob/main/packages/knowledge/src/index.ts"
click node_knowledge_messages "https://github.com/syeedur-01/safeplate/blob/main/packages/knowledge/src/messages.ts"
click node_contracts "https://github.com/syeedur-01/safeplate/blob/main/packages/contracts/src/knowledge.ts"

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_app,node_scan_ui,node_image,node_api_client,node_profile,node_profile_store,node_history,node_user toneBlue
class node_api_app,node_scan_route,node_api_config,node_worker,node_sanitizer toneAmber
class node_ai_provider,node_gemini,node_scan_runner toneMint
class node_engine,node_allergens,node_suitability,node_label,node_nutrition,node_safety,node_swaps,node_shopping toneRose
class node_knowledge_data,node_knowledge_messages,node_contracts toneIndigo
```

## Components

### Web application

- [App routing](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/App.tsx): `apps/web/src/App.tsx`
- [Scan form](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/pages/Scan.tsx): `apps/web/src/pages/Scan.tsx`
- [Image downscaling](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/lib/downscale.ts): `apps/web/src/lib/downscale.ts`
- [Scan client](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/api/client.ts): `apps/web/src/api/client.ts`
- [Profile onboarding](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/pages/Onboarding.tsx): `apps/web/src/pages/Onboarding.tsx`
- [Profile storage](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/state/profile-store.ts): `apps/web/src/state/profile-store.ts`
- [Scan history](https://github.com/syeedur-01/safeplate/blob/main/apps/web/src/pages/History.tsx): `apps/web/src/pages/History.tsx`

### API service

- [HTTP routes](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/app.ts): `apps/api/src/app.ts`
- [Scan endpoint](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/scan-route.ts): `apps/api/src/scan-route.ts`
- [Service configuration](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/config.ts): `apps/api/src/config.ts`
- [Worker entry](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/worker.ts): `apps/api/src/worker.ts`
- [Input sanitization](https://github.com/syeedur-01/safeplate/blob/main/apps/api/src/sanitize.ts): `apps/api/src/sanitize.ts`

### AI analysis

- [Vision provider](https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/provider.ts): `packages/ai/src/provider.ts`
- [Gemini integration](https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/gemini-provider.ts): `packages/ai/src/gemini-provider.ts`
- [Scan orchestration](https://github.com/syeedur-01/safeplate/blob/main/packages/ai/src/run-scan.ts): `packages/ai/src/run-scan.ts`

### Food evaluation

- [Food analysis](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/analyze.ts): `packages/engine/src/analyze.ts`
- [Allergen evaluation](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/allergens.ts): `packages/engine/src/allergens.ts`
- [Profile suitability](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/suitability.ts): `packages/engine/src/suitability.ts`
- [Label analysis](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/label.ts): `packages/engine/src/label.ts`
- [Nutrition analysis](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/nutrition.ts): `packages/engine/src/nutrition.ts`
- [Food safety](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/safety.ts): `packages/engine/src/safety.ts`
- [Food swaps](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/swaps.ts): `packages/engine/src/swaps.ts`
- [Shopping guidance](https://github.com/syeedur-01/safeplate/blob/main/packages/engine/src/shopping.ts): `packages/engine/src/shopping.ts`

### Knowledge and contracts

- [Food knowledge data](https://github.com/syeedur-01/safeplate/blob/main/packages/knowledge/src/index.ts): `packages/knowledge/src/index.ts`
- [Safety messages](https://github.com/syeedur-01/safeplate/blob/main/packages/knowledge/src/messages.ts): `packages/knowledge/src/messages.ts`
- [Shared data contracts](https://github.com/syeedur-01/safeplate/blob/main/packages/contracts/src/knowledge.ts): `packages/contracts/src/knowledge.ts`

### Other components

- **App user**

## Connections

- App user → App routing: uses
- App routing → Scan form: routes to (evidence: `apps/web/src/App.tsx`)
- App routing → Profile onboarding: routes to (evidence: `apps/web/src/App.tsx`)
- App routing → Scan history: routes to (evidence: `apps/web/src/App.tsx`)
- App routing → Profile storage: checks saved profile (evidence: `apps/web/src/App.tsx`)
- Profile onboarding → Profile storage: saves profile (evidence: `apps/web/src/pages/Onboarding.tsx`)
- Scan form → Image downscaling: downscales image (evidence: `apps/web/src/pages/Scan.tsx`)
- Scan form → Scan client: submits scan (evidence: `apps/web/src/pages/Scan.tsx`)
- Scan client → Scan endpoint: posts scan (evidence: `apps/web/src/api/client.ts`)
- Worker entry → HTTP routes: serves requests (evidence: `apps/api/src/worker.ts`)
- Worker entry → Service configuration: loads configuration (evidence: `apps/api/src/worker.ts`)
- Worker entry → Food knowledge data: loads dishes (evidence: `apps/api/src/worker.ts`)
- Worker entry → Vision provider: selects provider (evidence: `apps/api/src/worker.ts`)
- HTTP routes → Scan endpoint: registers route (evidence: `apps/api/src/app.ts`)
- Scan endpoint → Input sanitization: sanitizes input (evidence: `apps/api/src/scan-route.ts`)
- Scan endpoint → Vision provider: uses provider (evidence: `apps/api/src/scan-route.ts`)
- Service configuration → Vision provider: configures provider (evidence: `apps/api/src/config.ts`)
- Vision provider → Gemini integration: implemented by (evidence: `packages/ai/src/gemini-provider.ts`)
- Food analysis → Profile suitability: evaluates suitability
- Profile suitability → Allergen evaluation: checks allergens (evidence: `packages/engine/src/suitability.ts`)
- Label analysis → Profile suitability: evaluates suitability (evidence: `packages/engine/src/label.ts`)
- Food swaps → Allergen evaluation: checks allergens (evidence: `packages/engine/src/swaps.ts`)
- Food swaps → Nutrition analysis: uses nutrition (evidence: `packages/engine/src/swaps.ts`)
- Food swaps → Profile suitability: checks suitability (evidence: `packages/engine/src/swaps.ts`)
- Safety messages → Shared data contracts: uses contracts (evidence: `packages/knowledge/src/messages.ts`)
