Files
color_full/docs/api-reference.md
qichi.liang c58ca26969 企业级重构:四层模块化架构 + RBAC授权 + 安全加固 + 颜色引擎/配方推演增强
架构
- 后端从 flat routes/ 重构为 modules/<domain>/ 模块化结构(8个模块)
- 四层架构:Route -> Service -> Repository -> Prisma
- 新增 shared/ 基础设施(AppError 异常体系、ALS 上下文、prom-client 指标)
- 前端 Toast/Skeleton/Alert 组件基建 + formulaService 模板

安全
- JWT 签名算法修复(HS256 用 createHmac 而非 createHash)
- 密码哈希 async scrypt + timingSafeEqual
- API Key 从 localStorage 迁移至服务端 runtime/config.json
- Helmet 安全头 + rate-limit 全局限流 100 req/min
- 全局 auth preHandler + RBAC + Ownership 中间件

颜色引擎
- 色匹配切换为 cube 粗筛 + CIEDE2000 精排
- PantoneColor 表 + 种子数据 + 搜索端点
- AI 配色 Prompt 注入成分库 colorant 列表

配方推演
- 本地优化引擎(同 category 替换 + 成本排序)
- baseFormulaId 支持 + Pareto 散点图

文档
- ADR-0003 四层架构、ADR-0004 RBAC 授权模型
- 更新 ADR-0001/0002
- api-reference.md(29端点)、project-overview.md

部署
- Dockerfile * 2 + nginx.conf + docker-compose.prod.yml
- 健康探针 + 优雅关闭 + pg_dump 备份脚本
- ESLint + Prettier + tsconfig strict
2026-05-21 17:29:52 +08:00

26 KiB
Raw Blame History

配方研发智能平台 — API 参考文档

版本 v0.1.0 | 更新时间 2026-05-21
后端框架 Fastify 5 + TypeScript | 数据库 PostgreSQL (pgvector) | AI 多 Provider 适配


目录


1. 通用约定

1.1 域名与端口

环境 前端 后端
开发 http://localhost:5173 http://localhost:3001

前端 dev server 自动代理 /api 到后端。

1.2 认证方式

所有带 🔒 标记的接口需在请求头携带 JWT Token。认证中间件在 src/app.ts 中以全局 preHandler 方式执行。

Authorization: Bearer <token>

公开接口(无需 Token

方法 路径 说明
GET /api/health 健康检查
POST /api/auth/register 注册
POST /api/auth/login 登录

1.3 统一响应信封

{
  "data": {},
  "pagination": { "page": 1, "limit": 20, "total": 100, "totalPages": 5 }
}

列表接口包含 pagination,单条查询仅含 dataDELETE 返回 204 No Content

1.4 统一错误信封

{ "error": "错误描述", "statusCode": 400 }
状态码 含义 触发条件
400 参数校验失败 Zod schema 校验不通过
401 未认证 Token 缺失/格式错误/过期/用户不存在
404 资源不存在 记录未找到
409 冲突 如删除被配方引用的成分
500 服务器错误 生产环境仅返回 Internal Server Error

1.5 输入校验

所有请求体/查询参数通过 Zod schema 校验(定义于 src/lib/validation.ts),校验失败时返回 400 并附带具体字段错误信息,例如:

{ "error": "name: 配方名称不能为空; phases: 至少需要一个相" }

2. 认证系统 (auth)

路由前缀 /api/auth
源文件 src/routes/auth.ts

JWT 采用 HMAC-SHA256 (HS256) 签名,密钥读取自环境变量 JWT_SECRET,有效期 24 小时。密码哈希采用 scrypt异步salt 长度 16 字节,输出 64 字节,格式 <salt_hex>:<hash_hex>)。

2.1 POST /api/auth/register — 注册

请求体

字段 类型 必填 约束 说明
username string 唯一用户名
password string ≥4 位 明文密码,服务端哈希存储

响应 201

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "username": "wang",
    "role": "engineer",
    "token": "eyJhbGciOiJIUzI1NiIs..."
  }
}

错误

状态码 错误信息 说明
400 用户名和密码为必填项 缺少字段
400 密码至少4位 密码过短
409 用户名已存在 username 重复

2.2 POST /api/auth/login — 登录

请求体 同注册password ≥1 位即可。

响应 200 — body 结构同注册返回。

错误

状态码 错误信息
400 用户名不能为空 / 密码不能为空
401 用户名或密码错误

2.3 GET /api/auth/me — 当前用户信息

Authorization: Bearer <token>

响应 200

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "username": "wang",
    "role": "engineer"
  }
}

错误 401 — Token 无效或用户已删除。


3. 成分目录 (ingredients) 🔒

路由前缀 /api/ingredients
源文件 src/routes/ingredients.tssrc/services/ingredientService.ts

3.1 功能分类枚举

emulsifier     — 乳化剂
humectant      — 保湿剂
thickener      — 增稠剂
preservative   — 防腐剂
antioxidant    — 抗氧化剂
fragrance      — 香精
colorant       — 着色剂
ph_adjuster    — pH 调节剂
sunscreen      — 防晒剂
surfactant     — 表面活性剂
emollient      — 润肤剂
other          — 其他

3.2 GET /?page=&limit=&search=&category= — 成分列表

参数 类型 默认值 说明
page int 1 页码
limit int 20 每页数量(最大 100
search string 模糊匹配 INCI 名称和中文名case-insensitive
category enum 功能分类筛选

请求示例

GET /api/ingredients?search=甘油&category=humectant&page=1&limit=10

响应 200

{
  "data": [
    {
      "id": "uuid",
      "inciName": "Glycerin",
      "chineseName": "甘油",
      "functionCategory": "humectant",
      "supplier": "BASF",
      "unit": "kg",
      "unitPrice": 12.5,
      "description": "天然保湿因子",
      "createdAt": "2026-05-20T10:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 42,
    "totalPages": 5
  }
}

3.3 GET /:id — 成分详情

响应 200 { "data": { /* 同上单条 */ } }
错误 404{ "error": "成分不存在" }

3.4 POST / — 创建成分

请求体

字段 类型 必填 约束 说明
inciName string INCI 国际命名
chineseName string 中文常用名
functionCategory enum 见 3.1 功能分类
supplier string 供应商
unit string 默认 "kg" 计量单位
unitPrice number ≥0 单价(元/单位)
description string 备注描述
{
  "inciName": "Niacinamide",
  "chineseName": "烟酰胺",
  "functionCategory": "humectant",
  "supplier": "DSM",
  "unit": "kg",
  "unitPrice": 180.0,
  "description": "维生素 B3美白活性物"
}

响应 201 { "data": { /* 创建后的成分对象 */ } }

3.5 PUT /:id — 更新成分

请求体 — 以上字段均可选partial update

{ "supplier": "新供应商", "unitPrice": 150.0 }

响应 200 { "data": { /* 更新后的成分 */ } }
错误 404 — 成分不存在

3.6 DELETE /:id — 删除成分

响应 204 No Content
错误 404 — 成分不存在
错误 409{ "error": "该成分已被配方引用,无法删除", "usageCount": 3 }

删除前检查 FormulaIngredient 表引用计数,被引用则拒绝删除。


4. 配方记录 (formulas) 🔒

路由前缀 /api/formulas
源文件 src/routes/formulas.tssrc/services/formulaService.ts

4.1 配方核心概念

  • 配方 (Formula) — 含名称、描述、所属项目、当前版本号
  • (Phase) — 工艺阶段分组(如水相、油相、后添加相),有排序
  • 成分关联 (FormulaIngredient) — 在某个版本的某个相中,含比例和工艺备注
  • 版本 (FormulaVersion) — 每次修改成分后自动生成新版本

4.2 GET /?page=&limit=&search=&sortBy=&sortOrder= — 配方列表

参数 类型 默认值 说明
page int 1 页码
limit int 20 每页数量≤100
search string 名称/描述模糊搜索
sortBy enum updatedAt createdAt / updatedAt / name
sortOrder enum desc asc / desc

响应 200

{
  "data": [
    {
      "id": "uuid",
      "name": "保湿精华液",
      "description": "清爽型保湿配方",
      "currentVersion": 2,
      "createdBy": "uuid",
      "createdAt": "2026-05-20T10:00:00.000Z",
      "updatedAt": "2026-05-21T08:30:00.000Z",
      "project": {
        "id": "uuid",
        "name": "夏季新品"
      }
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 50, "totalPages": 3 }
}

4.3 GET /:id — 配方详情

响应 200

{
  "data": {
    "id": "uuid",
    "name": "保湿精华液",
    "description": "清爽型保湿配方",
    "currentVersion": 2,
    "createdBy": "uuid",
    "createdAt": "2026-05-20T10:00:00.000Z",
    "updatedAt": "2026-05-21T08:30:00.000Z",
    "project": { "id": "uuid", "name": "夏季新品" },
    "versions": [
      {
        "id": "uuid",
        "versionNumber": 2,
        "description": "版本 v2",
        "snapshotData": { "phases": [...] },
        "createdBy": "uuid",
        "createdAt": "2026-05-21T08:30:00.000Z",
        "phases": [
          {
            "id": "uuid",
            "name": "水相",
            "sortOrder": 0,
            "ingredients": [
              {
                "id": "uuid",
                "ingredientId": "uuid",
                "percentage": 75.5,
                "processNotes": "预先加热至 75°C",
                "ingredient": {
                  "id": "uuid",
                  "inciName": "Aqua",
                  "chineseName": "水"
                }
              }
            ]
          },
          {
            "id": "uuid",
            "name": "后添加相",
            "sortOrder": 1,
            "ingredients": [
              {
                "id": "uuid",
                "ingredientId": "uuid",
                "percentage": 24.5,
                "processNotes": "降温至 40°C 后加入",
                "ingredient": {
                  "id": "uuid",
                  "inciName": "Niacinamide",
                  "chineseName": "烟酰胺"
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

仅返回最新版本(take: 1, orderBy versionNumber desc),历史版本见 版本历史接口

4.4 POST / — 创建配方

请求体

{
  "name": "保湿精华液",
  "description": "夏季保湿配方 v1",
  "projectId": "uuid或null",
  "phases": [
    {
      "name": "水相",
      "sortOrder": 0,
      "ingredients": [
        {
          "ingredientId": "uuid",
          "percentage": 80.0,
          "processNotes": "75°C 加热搅拌"
        }
      ]
    },
    {
      "name": "后添加相",
      "sortOrder": 1,
      "ingredients": [
        {
          "ingredientId": "uuid",
          "percentage": 20.0,
          "processNotes": "40°C 加入"
        }
      ]
    }
  ]
}

校验规则

  • name 必填,phases 必填且至少 1 个相
  • 每个相至少 1 个成分
  • 每个成分的 percentage 范围 (0, 100]
  • 所有成分百分比总和必须在 99.5% 100.5% 之间

响应 201 { "data": { /* 完整 Formula 对象(含新创建的版本和关联) */ } }

内部执行事务:创建 Formula → 创建 FormulaVersion(v1) → 创建 Phase[] → 创建 FormulaIngredient[] → 回查并返回完整对象。

4.5 PUT /:id — 更新配方元信息

请求体

{ "name": "新名称", "description": "新描述" }

仅更新 name/description不涉及版本变更。

响应 200 { "data": { /* 更新后的 Formula */ } }
错误 404 — 配方不存在

4.6 PUT /:id/composition — 更新配方成分(创建新版本)

请求体 — 同创建配方的 phases 结构:

{
  "phases": [
    {
      "name": "水相",
      "sortOrder": 0,
      "ingredients": [
        { "ingredientId": "uuid", "percentage": 70.0 }
      ]
    }
  ]
}

百分比验证规则同创建接口。执行事务:创建新版本号 → 创建 Phase[] → 创建 FormulaIngredient[] → 更新 Formula.currentVersion。

响应 200 { "data": { /* 含最新版本信息的完整 Formula */ } }
错误 400 — 百分比校验失败
错误 404 — 配方不存在

4.7 版本历史 & 版本对比

前端路由中包含 /formulas/:id/history/formulas/:id/compare 页面,对应的后端 API 尚未实现为独立端点。当前可通过配方详情接口的 versions 字段获取最新版本信息。

4.8 DELETE /:id — 删除配方

响应 204 No Content

级联删除逻辑(事务内顺序执行):

  1. 查询该配方所有 FormulaVersion
  2. 删除各版本下的 Phase 记录
  3. 删除各版本下的 FormulaIngredient 记录
  4. 删除所有 FormulaVersion
  5. 删除 Formula

错误 404 — 配方不存在


5. 颜色引擎 (color) 🔒

路由前缀 /api/color
源文件 src/routes/color.ts

使用 CIELAB 颜色空间作为内部标准色差计算采用欧几里得距离作为初步筛选CIEDE2000 作为精确对比(前端 colorjs.io

5.1 POST /recommend — AI 配色推荐

请求体

{
  "targetLab": {
    "L": 65.0,
    "a": 15.0,
    "b": -8.0
  }
}

处理流程

  1. 查询所有已有 ColorFormula 记录
  2. 按欧几里得距离Lab 空间中)排序取 Top 5
  3. 调用 AI recommendColorants 生成色浆组合推荐

响应 200

{
  "recommendations": [
    {
      "colorants": [
        { "name": "氧化铁红", "ratio": 0.35 },
        { "name": "二氧化钛", "ratio": 0.5 },
        { "name": "氧化铁黄", "ratio": 0.15 }
      ],
      "predictedDeltaE": 1.2,
      "confidence": 0.85
    }
  ],
  "matchedFormulas": [
    { "id": "uuid", "name": "珊瑚粉底液 #3", "deltaE": 0.8 }
  ]
}

5.2 GET /formulas/match?L=&a=&b=&limit= — 颜色配方匹配

参数 类型 必填 默认值 说明
L number CIELAB L* (0100)
a number CIELAB a*
b number CIELAB b*
limit int 5 返回数量≤20

响应 200

{
  "data": [
    {
      "id": "uuid",
      "name": "玫瑰豆沙色",
      "targetLab": { "L": 55, "a": 25, "b": 5 },
      "deltaE": 0.5,
      "colorantComposition": [...],
      "distance": 1.23
    }
  ]
}

5.3 POST /formulas — 保存颜色配方

请求体

字段 类型 必填 说明
name string 默认 "未命名颜色配方"
targetLab object { L: 0-100, a: number, b: number }
actualLab object 实际测得 Lab
deltaE number ΔE≥0
colorantComposition any 色浆组合(自由格式 JSON
formulaId uuid 关联的配方 ID

响应 201 { "data": { /* ColorFormula 对象 */ } }


6. AI 配方推演 (ai) 🔒

路由前缀 /api/ai
源文件 src/routes/ai.tssrc/services/ai/index.ts src/services/ai/templates/

所有 AI 能力通过 LLM API 实现OpenAI / DeepSeek支持 Mock 模式(返回预设 JSON。提示词模板定义在 src/services/ai/templates/index.ts

6.1 POST /predict-formula — 预测配方指标SSE 流)

请求体

{
  "ingredients": [
    { "name": "甘油", "percentage": 5, "category": "humectant" },
    { "name": "卡波姆", "percentage": 0.5, "category": "thickener" }
  ]
}

成分列表至少 1 个。

响应 200 Content-Type: text/event-stream

data: {"type":"result","content":"{\"sensoryIndex\":{\"spreadability\":78,...},...}"}

content 是 JSON 字符串,解析后格式:

{
  "sensoryIndex": {
    "spreadability": 78,
    "absorption": 82,
    "stickiness": 25,
    "overall": 75
  },
  "stabilityScore": 85,
  "costEstimate": 45.5,
  "confidence": 0.85,
  "reasoning": "甘油提供基础保湿,卡波姆增加稠度..."
}
字段 范围 说明
sensoryIndex.spreadability 0100 铺展性
sensoryIndex.absorption 0100 吸收速度
sensoryIndex.stickiness 0100 黏腻度
sensoryIndex.overall 0100 综合肤感
stabilityScore 0100 稳定性评分
costEstimate 数值 估算单位成本(元/kg
confidence 01 预测置信度

错误流 data: {"type":"error","content":"..."}

6.2 POST /explore-formula — 配方推演SSE 流)

请求体 — 至少设置一个约束条件(costLimittargetMetricsexcludeIngredients

{
  "baseFormulaName": "原保湿精华",
  "baseIngredients": [
    { "name": "甘油", "percentage": 5 }
  ],
  "costLimit": 50,
  "keepIngredients": ["甘油", "烟酰胺"],
  "excludeIngredients": ["酒精", "香精"],
  "targetMetrics": {
    "stability": 85,
    "sensory": 80
  }
}
字段 类型 说明
baseFormulaName string? 基础配方名称
baseIngredients array? 基础成分及比例
costLimit number? 成本上限(元/kg
keepIngredients string[]? 必须保留的成分名
excludeIngredients string[]? 必须排除的成分名
targetMetrics object? 目标指标(自由 key/value

响应 200 Content-Type: text/event-stream

data: {"type":"option","option":{...}}
data: {"type":"option","option":{...}}
data: {"type":"done"}

每个 option 对象:

{
  "name": "降本方案 A",
  "changes": [
    {
      "action": "reduce",
      "ingredient": "烟酰胺",
      "oldPercentage": 5,
      "newPercentage": 3
    },
    {
      "action": "add",
      "ingredient": "丁二醇",
      "oldPercentage": null,
      "newPercentage": 2
    }
  ],
  "predictedMetrics": {
    "costEstimate": 42.0,
    "stabilityScore": 82
  },
  "reasoning": "用丁二醇替代部分烟酰胺可降低成本同时维持保湿效果"
}

6.3 POST /extract-formula — AI 提取配方文本

请求体

{
  "text": "水相:去离子水(75%)、甘油(5%)、丁二醇(3%)加热至75度。\n油相角鲨烷(10%)、乳化蜡(5%)加热至80度。\n后添加防腐剂(1%)、香精(1%)降温至40度加入。"
}

响应 200

{
  "data": [
    {
      "inciName": "Aqua",
      "chineseName": "去离子水",
      "percentage": 75,
      "phase": "水相",
      "processNotes": "加热至75度"
    },
    {
      "inciName": "Glycerin",
      "chineseName": "甘油",
      "percentage": 5,
      "phase": "水相",
      "processNotes": ""
    }
  ]
}

错误 500{ "error": "AI 提取失败,请重试" }

6.4 GET /search?q= — AI 自然语言搜索

参数 类型 说明
q string必填 自然语言搜索词
GET /api/ai/search?q=适合敏感肌的保湿配方不含酒精

处理流程

  1. AI 解析自然语言 → 提取关键词和筛选条件
  2. 用关键词执行 PostgreSQL ILIKE 搜索
  3. AI 不可用时降级为直接关键词搜索

响应 200

{
  "data": [
    {
      "id": "uuid",
      "name": "敏感肌保湿乳",
      "description": "无酒精、无香精",
      "currentVersion": 1,
      "project": { "name": "敏感肌系列" }
    }
  ],
  "keywords": ["敏感肌", "保湿", "无酒精"]
}

7. 项目管理 (projects) 🔒

路由前缀 /api/projects
源文件 src/routes/projects.tssrc/services/projectService.ts

7.1 GET / — 项目列表

响应 200

{
  "data": [
    {
      "id": "uuid",
      "name": "夏季新品",
      "description": "2026 夏季产品线",
      "createdBy": "uuid",
      "createdAt": "2026-05-20T10:00:00.000Z",
      "_count": { "formulas": 5 }
    }
  ]
}

7.2 POST / — 创建项目

请求体

{ "name": "夏季新品", "description": "2026 夏季产品线" }

响应 201 { "data": { /* Project 对象 */ } }

7.3 PUT /:id — 更新项目

请求体

{ "name": "2026 秋季新品" }

响应 200 { "data": { /* 更新后的 Project */ } }

7.4 DELETE /:id — 删除项目

响应 204 No Content


8. 配置管理 (config) 🔒

路由前缀 /api/config
源文件 src/routes/config.tssrc/lib/configStore.ts

API Key 存储于服务器端 runtime/config.json 文件,不通过客户端 localStorage 传输。服务启动时自动加载,运行时可通过接口更新。

8.1 GET / — 获取配置状态

响应 200

{
  "aiMock": "true",
  "hasOpenAI": true,
  "hasDeepseek": false
}

不返回 API Key 实际值,仅返回是否已配置。

8.2 PUT / — 更新配置

请求体

{
  "openaiKey": "sk-...",
  "deepseekKey": "sk-...",
  "openaiBaseUrl": "https://api.openai.com/v1",
  "deepseekBaseUrl": "https://api.deepseek.com/v1",
  "aiMock": "false"
}

所有字段均可选。更新后自动 re-init AI Provider 并清空缓存。

响应 200 { "ok": true }

8.3 POST /test — 测试 AI Provider 连接

请求体

{ "provider": "openai" }

provider 取值:"openai" | "deepseek"

响应 200

{ "ok": true, "model": "gpt-4o" }

错误

{ "ok": false, "error": "Provider \"openai\" 未配置" }

9. 数据模型

9.1 实体关系图

User ──1:N──→ Formula ──1:N──→ FormulaVersion ──1:N──→ Phase
  │               │                                          │
  │               │                                    1:N   │
  │               │                                   FormulaIngredient ──N:1──→ Ingredient
  │               │
  │          1:N  │
  ├──────→ ColorFormula
  │
  └──────→ Project ──1:N──→ Formula

9.2 Prisma Schema 摘要

User (users)

  • id UUID PK
  • username 唯一
  • passwordHash — scrypt(salt:16, output:64) hex
  • roleengineer / admin
  • createdAt

Project (projects)

  • id UUID PK
  • name String
  • description String?
  • createdBy → User
  • createdAt

Formula (formulas)

  • id UUID PK
  • name String
  • description String?
  • projectId → Project?
  • currentVersion Int (default 1)
  • createdBy → User
  • createdAt / updatedAt
  • embedding vector(1536)? — pgvector 向量,用于语义搜索

FormulaVersion (formula_versions)

  • id UUID PK
  • formulaId → Formula
  • versionNumber Int — (formulaId, versionNumber) UNIQUE
  • description String?
  • snapshotData JSON — 版本快照
  • createdBy → User
  • createdAt

Phase (phases)

  • id UUID PK
  • formulaId → FormulaVersion
  • name String
  • sortOrder Int

FormulaIngredient (formula_ingredients)

  • id UUID PK
  • formulaVersionId → FormulaVersion
  • phaseId → Phase
  • ingredientId → Ingredient
  • percentage Float
  • processNotes String?

Ingredient (ingredients)

  • id UUID PK
  • inciName String
  • chineseName String
  • functionCategory enum — 见 3.1
  • supplier String?
  • unit String (default "kg")
  • unitPrice Float?
  • description String?
  • createdAt

ColorFormula (color_formulas)

  • id UUID PK
  • name String
  • targetLab JSON — { L, a, b }
  • actualLab JSON? — { L, a, b }
  • deltaE Float?
  • colorantComposition JSON?
  • formulaId → Formula?
  • createdBy → User
  • createdAt

AIAuditLog (ai_audit_logs)

  • id UUID PK
  • capability String — 调用的 AI 能力名
  • modelName String — 使用的模型
  • promptHash String — 提示词哈希
  • tokensUsed Int?
  • durationMs Int?
  • createdAt

10. AI 模板说明

所有 AI 调用使用预定义提示词模板(src/services/ai/templates/index.tsJSON 模式约束输出格式。

10.1 模板-能力映射

模板函数 能力 system prompt 角色
predictMetricsPrompt 预测配方指标 资深化妆品配方工程师
parseNLQueryPrompt 自然语言搜索 查询解析器
generateFormulaPrompt 配方推演 资深化妆品配方工程师
recommendColorantsPrompt 配色推荐 化妆品色彩专家
extractFormulaPrompt 配方文本提取 数据结构化提取

10.2 AI Service 架构

Route (ai.ts)
  │
  ▼
AIService (services/ai/index.ts)
  ├── LRUCache (200 条, 带 TTL)
  ├── RateLimiter (10 req/s)
  ├── 重试 (最多 3 次)
  ├── fallback → mock 模式
  └── audit log → ai_audit_logs 表
  │
  ▼
AIProvider 接口
  ├── createOpenAIProvider  (api.openai.com/v1)
  └── createDeepSeekProvider (api.deepseek.com/v1)

Mock 模式:当 AI_MOCK=true 或 AI API 不可用时,返回预设数据(定义在 MOCK_RESPONSES 中)。

10.3 可用 Provider

Provider 默认模型 Base URL
openai gpt-4o https://api.openai.com/v1
deepseek deepseek-chat https://api.deepseek.com/v1

通过 PUT /api/config 切换,需提供对应 API Key。可通过 POST /api/config/test 验证连接。

10.4 缓存策略

LRUCache 容量 200 条Key 为 sha256(prompt),默认 TTL 根据能力不同设置。reload() 时清空全部缓存。


附录

A. 环境变量

变量 默认值 说明
PORT 3001 后端端口
DATABASE_URL postgresql://colorfull:colorfull@localhost:5432/colorfull 数据库连接
JWT_SECRET dev-secret-change-me JWT 签名密钥(生产环境必须覆盖)
AI_DEFAULT_MODEL deepseek-chat 默认 AI 模型
AI_MOCK true 是否启用 Mock 模式
OPENAI_API_KEY OpenAI API Key
DEEPSEEK_API_KEY DeepSeek API Key
OPENAI_BASE_URL OpenAI 自定义 Base URL
DEEPSEEK_BASE_URL DeepSeek 自定义 Base URL

B. Docker 服务

# 启动 PostgreSQL (pgvector) + MinIO
docker compose up -d

# 数据库连接信息
Host: localhost:5432
Database: colorfull
User: colorfull
Password: colorfull

C. 项目脚本

# 后端
cd backend
pnpm dev          # 开发模式 (tsx watch)
pnpm test         # 运行测试
pnpm db:migrate   # Prisma 迁移
pnpm db:seed      # 种子数据

# 前端
cd frontend
pnpm dev          # Vite 开发服务器
pnpm build        # 生产构建
pnpm test         # 运行测试
pnpm lint         # ESLint