# huafanfan/cookbook architecture

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

- Interactive diagram: https://gitdiagram.com/huafanfan/cookbook
- Repository: https://github.com/huafanfan/cookbook

## Overview

这是一个局域网菜谱应用：用户搜索或筛选菜谱、查看详情并照步骤烹饪；也可编辑菜谱、查看修改历史，以及共享点赞、收藏和厨具状态。前端通过 API 访问 Fastify 服务；菜谱与修改历史以文件保存，图片经扫描后提供。另有 HowToCook 导入与同步能力。图中调用关系依据已采样源码及 README 明确说明；未采样的页面和路由内部连线从略。

Main entry points: [`src/client/lib/api.ts`](https://github.com/huafanfan/cookbook/blob/main/src/client/lib/api.ts) (浏览器 API 客户端), [`src/server/index.ts`](https://github.com/huafanfan/cookbook/blob/main/src/server/index.ts) (Fastify 应用组装), [`src/client/App.tsx`](https://github.com/huafanfan/cookbook/blob/main/src/client/App.tsx) (前端应用), [`src/server/routes/recipes.ts`](https://github.com/huafanfan/cookbook/blob/main/src/server/routes/recipes.ts) (菜谱 API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["浏览与烹饪"]
  node_app["前端应用<br/>[App.tsx]"]
  node_home["搜索与筛选<br/>[HomePage.tsx]"]
  node_recipe["菜谱详情与烹饪<br/>[RecipePage.tsx]"]
  node_edit["编辑菜谱<br/>[EditRecipePage.tsx]"]
  node_history["修改历史"]
  node_api["浏览器 API 客户端<br/>[api.ts]"]
  node_local["浏览器偏好与草稿<br/>[storage.ts]"]
end

subgraph group_server["菜谱服务"]
  node_server["Fastify 应用组装<br/>[index.ts]"]
  node_recipe_routes["菜谱 API<br/>[recipes.ts]"]
  node_state_routes["用户状态 API<br/>[user-state.ts]"]
  node_image_routes["图片服务<br/>[images.ts]"]
  node_search["搜索与摘要<br/>[search.ts]"]
  node_repository["菜谱仓库"]
end

subgraph group_state["文件数据"]
  node_user_store[("共享用户状态")]
  node_recipe_files[("菜谱与图片文件")]
  node_history_files[("修改历史文件")]
end

subgraph group_import["来源导入"]
  node_import_script["菜谱导入"]
  node_sync_script["来源同步<br/>[sync-howtocook.ts]"]
  node_parser["Markdown 解析<br/>[howtocook-parse.ts]"]
  node_merge["同步合并<br/>[sync-merge.ts]"]
end

node_cook(("家庭用户"))
node_howtocook["HowToCook 内容源"]

node_cook -->|"使用"| node_app
node_app -->|"呈现"| node_home
node_app -->|"呈现"| node_recipe
node_app -->|"呈现"| node_edit
node_app -->|"呈现"| node_history
node_home -->|"请求列表"| node_api
node_recipe -->|"请求详情"| node_api
node_edit -->|"读取并保存"| node_api
node_history -->|"请求历史"| node_api
node_edit -->|"读写草稿"| node_local
node_recipe -->|"读写偏好"| node_local
node_api -->|"HTTP 请求"| node_recipe_routes
node_api -->|"HTTP 请求"| node_state_routes
node_server -->|"加载仓库"| node_repository
node_server -->|"加载状态"| node_user_store
node_server -->|"注册路由"| node_recipe_routes
node_server -->|"注册路由"| node_state_routes
node_server -->|"注册路由"| node_image_routes
node_recipe_routes -->|"读取与保存"| node_repository
node_recipe_routes -->|"搜索菜谱"| node_search
node_recipe_routes -->|"读取状态"| node_user_store
node_state_routes -->|"读写状态"| node_user_store
node_image_routes -->|"读取图片白名单"| node_repository
node_repository -->|"读取菜谱与图片"| node_recipe_files
node_repository -->|"读写历史"| node_history_files
node_user_store --> node_recipe_files
node_howtocook -.->|"提供内容"| node_import_script
node_import_script -->|"解析菜谱"| node_parser
node_sync_script -->|"解析菜谱"| node_parser
node_sync_script -->|"合并变更"| node_merge
node_import_script -->|"写入导入菜谱"| node_recipe_files
node_sync_script -->|"同步菜谱"| node_recipe_files

click node_app "https://github.com/huafanfan/cookbook/blob/main/src/client/App.tsx"
click node_home "https://github.com/huafanfan/cookbook/blob/main/src/client/pages/HomePage.tsx"
click node_recipe "https://github.com/huafanfan/cookbook/blob/main/src/client/pages/RecipePage.tsx"
click node_edit "https://github.com/huafanfan/cookbook/blob/main/src/client/pages/EditRecipePage.tsx"
click node_history "https://github.com/huafanfan/cookbook/blob/main/src/client/pages/RecipeHistoryPage.tsx"
click node_api "https://github.com/huafanfan/cookbook/blob/main/src/client/lib/api.ts"
click node_local "https://github.com/huafanfan/cookbook/blob/main/src/client/lib/storage.ts"
click node_server "https://github.com/huafanfan/cookbook/blob/main/src/server/index.ts"
click node_recipe_routes "https://github.com/huafanfan/cookbook/blob/main/src/server/routes/recipes.ts"
click node_state_routes "https://github.com/huafanfan/cookbook/blob/main/src/server/routes/user-state.ts"
click node_image_routes "https://github.com/huafanfan/cookbook/blob/main/src/server/routes/images.ts"
click node_search "https://github.com/huafanfan/cookbook/blob/main/src/server/services/search.ts"
click node_repository "https://github.com/huafanfan/cookbook/blob/main/src/server/services/recipe-repository.ts"
click node_user_store "https://github.com/huafanfan/cookbook/blob/main/src/server/services/user-state-store.ts"
click node_recipe_files "https://github.com/huafanfan/cookbook/blob/main/src/server/services/recipe-repository.ts"
click node_history_files "https://github.com/huafanfan/cookbook/blob/main/src/server/services/recipe-repository.ts"
click node_import_script "https://github.com/huafanfan/cookbook/blob/main/scripts/import-howtocook.ts"
click node_sync_script "https://github.com/huafanfan/cookbook/blob/main/scripts/sync-howtocook.ts"
click node_parser "https://github.com/huafanfan/cookbook/blob/main/src/server/lib/howtocook-parse.ts"
click node_merge "https://github.com/huafanfan/cookbook/blob/main/scripts/lib/sync-merge.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_home,node_recipe,node_edit,node_history,node_api,node_local toneBlue
class node_server,node_recipe_routes,node_state_routes,node_image_routes,node_search,node_repository toneAmber
class node_user_store,node_recipe_files,node_history_files toneMint
class node_import_script,node_sync_script,node_parser,node_merge toneRose
class node_cook,node_howtocook toneIndigo
```

## Components

### 浏览与烹饪

- [前端应用](https://github.com/huafanfan/cookbook/blob/main/src/client/App.tsx): `src/client/App.tsx`
- [搜索与筛选](https://github.com/huafanfan/cookbook/blob/main/src/client/pages/HomePage.tsx): `src/client/pages/HomePage.tsx`
- [菜谱详情与烹饪](https://github.com/huafanfan/cookbook/blob/main/src/client/pages/RecipePage.tsx): `src/client/pages/RecipePage.tsx`
- [编辑菜谱](https://github.com/huafanfan/cookbook/blob/main/src/client/pages/EditRecipePage.tsx): `src/client/pages/EditRecipePage.tsx`
- [修改历史](https://github.com/huafanfan/cookbook/blob/main/src/client/pages/RecipeHistoryPage.tsx): `src/client/pages/RecipeHistoryPage.tsx`
- [浏览器 API 客户端](https://github.com/huafanfan/cookbook/blob/main/src/client/lib/api.ts): `src/client/lib/api.ts`
- [浏览器偏好与草稿](https://github.com/huafanfan/cookbook/blob/main/src/client/lib/storage.ts): `src/client/lib/storage.ts`

### 菜谱服务

- [Fastify 应用组装](https://github.com/huafanfan/cookbook/blob/main/src/server/index.ts): `src/server/index.ts`
- [菜谱 API](https://github.com/huafanfan/cookbook/blob/main/src/server/routes/recipes.ts): `src/server/routes/recipes.ts`
- [用户状态 API](https://github.com/huafanfan/cookbook/blob/main/src/server/routes/user-state.ts): `src/server/routes/user-state.ts`
- [图片服务](https://github.com/huafanfan/cookbook/blob/main/src/server/routes/images.ts): `src/server/routes/images.ts`
- [搜索与摘要](https://github.com/huafanfan/cookbook/blob/main/src/server/services/search.ts): `src/server/services/search.ts`
- [菜谱仓库](https://github.com/huafanfan/cookbook/blob/main/src/server/services/recipe-repository.ts): `src/server/services/recipe-repository.ts`

### 文件数据

- [共享用户状态](https://github.com/huafanfan/cookbook/blob/main/src/server/services/user-state-store.ts): `src/server/services/user-state-store.ts`
- [菜谱与图片文件](https://github.com/huafanfan/cookbook/blob/main/src/server/services/recipe-repository.ts): `src/server/services/recipe-repository.ts`
- [修改历史文件](https://github.com/huafanfan/cookbook/blob/main/src/server/services/recipe-repository.ts): `src/server/services/recipe-repository.ts`

### 来源导入

- [菜谱导入](https://github.com/huafanfan/cookbook/blob/main/scripts/import-howtocook.ts): `scripts/import-howtocook.ts`
- [来源同步](https://github.com/huafanfan/cookbook/blob/main/scripts/sync-howtocook.ts): `scripts/sync-howtocook.ts`
- [Markdown 解析](https://github.com/huafanfan/cookbook/blob/main/src/server/lib/howtocook-parse.ts): `src/server/lib/howtocook-parse.ts`
- [同步合并](https://github.com/huafanfan/cookbook/blob/main/scripts/lib/sync-merge.ts): `scripts/lib/sync-merge.ts`

### Other components

- **家庭用户**
- **HowToCook 内容源**

## Connections

- 家庭用户 → 前端应用: 使用
- 前端应用 → 搜索与筛选: 呈现
- 前端应用 → 菜谱详情与烹饪: 呈现
- 前端应用 → 编辑菜谱: 呈现
- 前端应用 → 修改历史: 呈现
- 搜索与筛选 → 浏览器 API 客户端: 请求列表
- 菜谱详情与烹饪 → 浏览器 API 客户端: 请求详情
- 编辑菜谱 → 浏览器 API 客户端: 读取并保存
- 修改历史 → 浏览器 API 客户端: 请求历史
- 编辑菜谱 → 浏览器偏好与草稿: 读写草稿
- 菜谱详情与烹饪 → 浏览器偏好与草稿: 读写偏好
- 浏览器 API 客户端 → 菜谱 API: HTTP 请求
- 浏览器 API 客户端 → 用户状态 API: HTTP 请求
- Fastify 应用组装 → 菜谱仓库: 加载仓库
- Fastify 应用组装 → 共享用户状态: 加载状态
- Fastify 应用组装 → 菜谱 API: 注册路由
- Fastify 应用组装 → 用户状态 API: 注册路由
- Fastify 应用组装 → 图片服务: 注册路由
- 菜谱 API → 菜谱仓库: 读取与保存
- 菜谱 API → 搜索与摘要: 搜索菜谱
- 菜谱 API → 共享用户状态: 读取状态
- 用户状态 API → 共享用户状态: 读写状态
- 图片服务 → 菜谱仓库: 读取图片白名单
- 菜谱仓库 → 菜谱与图片文件: 读取菜谱与图片
- 菜谱仓库 → 修改历史文件: 读写历史
- 共享用户状态 → 菜谱与图片文件
- HowToCook 内容源 → 菜谱导入: 提供内容
- 菜谱导入 → Markdown 解析: 解析菜谱
- 来源同步 → Markdown 解析: 解析菜谱
- 来源同步 → 同步合并: 合并变更
- 菜谱导入 → 菜谱与图片文件: 写入导入菜谱
- 来源同步 → 菜谱与图片文件: 同步菜谱
