docs: prepare yedir-ai for commercial delivery
This commit is contained in:
parent
286acefe4a
commit
c79724eefa
198
.env.example
198
.env.example
@ -1,73 +1,173 @@
|
||||
# Generate a random secret: https://generate-secret.vercel.app/32 or `openssl rand -base64 32`
|
||||
AUTH_SECRET=****
|
||||
# yedir-ai environment template
|
||||
# Copy this file to .env.local and fill real values locally or in your hosting platform.
|
||||
# Never commit real secrets.
|
||||
|
||||
# Auth URL (optional in Vercel, required for self-hosted)
|
||||
# Set to your application's public URL, e.g. https://your-domain.com
|
||||
# Also accepted as NEXTAUTH_URL (deprecated, prefer AUTH_URL)
|
||||
AUTH_URL=
|
||||
# -----------------------------------------------------------------------------
|
||||
# Core / Auth
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# 仅在受信反向代理(如 Vercel、Nginx with validated Host header)后部署时设为 true
|
||||
# 开启后禁用 next-auth 的 Host 头校验,非受信环境不要开启
|
||||
# Generate with: openssl rand -base64 32
|
||||
AUTH_SECRET=replace-with-random-secret
|
||||
|
||||
# Public application URL. Required for production and self-hosted Auth.js.
|
||||
AUTH_URL=https://your-domain.com
|
||||
NEXT_PUBLIC_APP_URL=https://your-domain.com
|
||||
|
||||
# Only enable behind a trusted reverse proxy with validated Host headers.
|
||||
AUTH_TRUST_HOST=false
|
||||
|
||||
# Google OAuth (optional)
|
||||
# https://console.cloud.google.com/apis/credentials
|
||||
# Optional OAuth providers.
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
|
||||
# Admin user credentials (used by create-admin.ts one-time setup script)
|
||||
# Set both to provision the initial admin account; if omitted, auto-generated
|
||||
# Optional initial admin provisioning.
|
||||
ADMIN_EMAIL=
|
||||
ADMIN_PASSWORD=
|
||||
|
||||
# The following keys below are automatically created and
|
||||
# added to your environment when you deploy on Vercel
|
||||
# Optional email verification.
|
||||
RESEND_API_KEY=
|
||||
RESEND_FROM_EMAIL=
|
||||
EMAIL_VERIFICATION_SECRET=
|
||||
|
||||
# Instructions to create an AI Gateway API key here: https://vercel.com/ai-gateway
|
||||
# API key required for non-Vercel deployments
|
||||
# For Vercel deployments, OIDC tokens are used automatically
|
||||
# https://vercel.com/ai-gateway
|
||||
AI_GATEWAY_API_KEY=****
|
||||
# Optional scheduled job protection.
|
||||
CRON_SECRET=
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Database
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Instructions to create a Vercel Blob Store here: https://vercel.com/docs/vercel-blob
|
||||
BLOB_READ_WRITE_TOKEN=****
|
||||
POSTGRES_URL=postgres://user:password@localhost:5432/yedir_ai
|
||||
|
||||
# Instructions to create a PostgreSQL database here: https://vercel.com/docs/postgres
|
||||
POSTGRES_URL=****
|
||||
# Production-safe defaults used by lib/db/index.ts.
|
||||
POSTGRES_MAX_CONNECTIONS=10
|
||||
POSTGRES_IDLE_TIMEOUT_SECONDS=20
|
||||
POSTGRES_CONNECT_TIMEOUT_SECONDS=5
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Object Storage
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Instructions to create a Redis store here:
|
||||
# https://vercel.com/docs/redis
|
||||
REDIS_URL=****
|
||||
# Vercel Blob fallback.
|
||||
BLOB_READ_WRITE_TOKEN=
|
||||
|
||||
# DashScope / 通义千问配置
|
||||
# 请求地址(阿里云 DashScope OpenAI 兼容接口)
|
||||
# S3-compatible storage fallback. Database-configured storage takes precedence.
|
||||
S3_ENDPOINT=
|
||||
S3_REGION=auto
|
||||
S3_BUCKET=
|
||||
S3_ACCESS_KEY_ID=
|
||||
S3_SECRET_ACCESS_KEY=
|
||||
S3_PUBLIC_URL=
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# AI Providers
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
AI_GATEWAY_API_KEY=
|
||||
NEXT_PUBLIC_DEFAULT_CHAT_MODEL=
|
||||
|
||||
# DashScope / Qwen OpenAI-compatible endpoint.
|
||||
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
DASHSCOPE_API_KEY=
|
||||
|
||||
# API Key(请在本地 .env.local 和 服务器环境中填写真实值,不要把真实 Key 提交到代码仓库)
|
||||
DASHSCOPE_API_KEY=your-dashscope-api-key
|
||||
|
||||
# 第三方 GPT5 提供方配置(OpenAI 兼容接口)
|
||||
# API 基础地址(例如:https://api.huandutech.com)
|
||||
GTP5_API_URL=https://api.huandutech.com
|
||||
|
||||
# API Key(请在本地 .env.local 和 服务器环境中填写真实值,不要把真实 Key 提交到代码仓库)
|
||||
GTP5_API_KEY=your-gtp5-api-key
|
||||
|
||||
# 模型名称(例如:gpt-5-nano)
|
||||
# Third-party GPT-compatible provider.
|
||||
GTP5_API_URL=
|
||||
GTP5_API_KEY=
|
||||
GTP5_MODEL=gpt-5-nano
|
||||
|
||||
# Tripo3D(可选)
|
||||
# 优先使用系统设置-本地AI里的 `tripo-3d` 提供商;若未配置则回退到环境变量
|
||||
TRIPO_API_KEY=your-tripo-api-key
|
||||
# FAL image/video/realtime providers.
|
||||
FAL_KEY=
|
||||
FAL_API_KEY=
|
||||
FAL_BASE_URL=https://fal.run
|
||||
FAL_MODEL=
|
||||
FAL_REALTIME_MODEL=
|
||||
|
||||
# 3D / CAD providers.
|
||||
TRIPO_API_KEY=
|
||||
TRIPO_BASE_URL=https://api.tripo3d.ai/v2/openapi
|
||||
|
||||
# KittyCAD / Zoo Text-to-CAD(可选)
|
||||
# 优先使用系统设置-本地AI里的 `kittycad-cad` 提供商;若未配置则回退到环境变量
|
||||
KITTYCAD_API_TOKEN=your-kittycad-api-token
|
||||
WORLDLABS_API_KEY=
|
||||
WORLDLABS_BASE_URL=
|
||||
WORLDLABS_IMPORT_TOKEN=
|
||||
WORLDLABS_KEY_POOL_IMPORT_TOKEN=
|
||||
KITTYCAD_API_TOKEN=
|
||||
KITTYCAD_API_KEY=
|
||||
KITTYCAD_BASE_URL=https://api.zoo.dev
|
||||
ZOO_API_TOKEN=
|
||||
ZOO_BASE_URL=https://api.zoo.dev
|
||||
|
||||
# FAL.ai(可选)
|
||||
# 用于图片生成和编辑;若未配置则回退到系统设置中的 AI 提供商
|
||||
FAL_KEY=your-fal-ai-key
|
||||
# RUXA / video callback.
|
||||
RUXA_CALLBACK_URL=
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Product Planning Integrations
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
PRODUCT_PLANNING_DETAIL_PLUS_BASE_URL=
|
||||
PRODUCT_PLANNING_DETAIL_PLUS_INTERNAL_BASE_URL=
|
||||
PRODUCT_PLANNING_DETAIL_PLUS_API_KEY=
|
||||
PRODUCT_PLANNING_QA_TOKEN=
|
||||
TAOBAO_API_KEY=
|
||||
TAOBAO_API_SECRET=
|
||||
TAOBAO_SALE_API_TOKEN=
|
||||
|
||||
PRODUCT_PLANNING_DB_HOST=
|
||||
PRODUCT_PLANNING_DB_PORT=3306
|
||||
PRODUCT_PLANNING_DB_NAME=
|
||||
PRODUCT_PLANNING_DB_USER=
|
||||
PRODUCT_PLANNING_DB_PASSWORD=
|
||||
PRODUCT_PLANNING_DB_CHARSET=utf8mb4
|
||||
PRODUCT_PLANNING_DB_SSL=false
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Home Performance / Queues
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
CANVAS_IMAGE_TASK_CONCURRENCY=3
|
||||
CANVAS_IMAGE_TASK_BATCH_DISPATCH_INTERVAL_MS=1000
|
||||
EXTERNAL_IMAGE_API_MAX_CONCURRENT=3
|
||||
EXTERNAL_IMAGE_API_MAX_QUEUE=20
|
||||
EXTERNAL_IMAGE_API_QUEUE_TIMEOUT_MS=120000
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Agent / PSD Runtime
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
AGENT_FORCE_LLM_PLANNER=false
|
||||
AGENT_FORCE_QWEN3VL_FALLBACK=false
|
||||
AGENT_IMAGE_GEN_LLM_OPTIMIZER_ENABLED=true
|
||||
AGENT_LLM_PROMPT_OPTIMIZER_ENABLED=true
|
||||
AGENT_REPLACEMENT_PARALLEL_WORKER_COUNT=2
|
||||
AGENT_PSD_LOCAL_CACHE_DIR=
|
||||
AGENT_PSD_REMOTE_ASSET_CACHE_DISABLED=false
|
||||
AGENT_PSD_REMOTE_ASSET_CACHE_MAX_BYTES=
|
||||
AGENT_PSD_REMOTE_ASSET_CACHE_MAX_ENTRY_BYTES=
|
||||
AGENT_PSD_REMOTE_ASSET_CACHE_TTL_MS=
|
||||
AGENT_PSD_RENDER_PNG_COMPRESSION_LEVEL=6
|
||||
AGENT_PSD_RENDER_TASK_CONCURRENCY=2
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Logging / Observability
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# debug | info | warn | error | silent
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Stack traces remain disabled in production unless explicitly enabled.
|
||||
LOG_INCLUDE_STACK=false
|
||||
|
||||
# Client logs are silent in production unless this is true.
|
||||
NEXT_PUBLIC_ENABLE_CLIENT_LOGS=false
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Optional Jobs
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
VIDEO_ARCHIVE_DELAY_HOURS=24
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Test / Local Dev
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
PORT=3001
|
||||
PLAYWRIGHT=false
|
||||
CI_PLAYWRIGHT=false
|
||||
PLAYWRIGHT_TEST_BASE_URL=http://127.0.0.1:3001
|
||||
|
||||
28
.github/workflows/playwright.yml
vendored
28
.github/workflows/playwright.yml
vendored
@ -9,6 +9,9 @@ jobs:
|
||||
test:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
github.event_name == 'push' ||
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
env:
|
||||
AUTH_SECRET: ${{ secrets.AUTH_SECRET }}
|
||||
POSTGRES_URL: ${{ secrets.POSTGRES_URL }}
|
||||
@ -22,32 +25,15 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
node-version: 20
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
version: 9.12.3
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
|
||||
163
README.md
163
README.md
@ -1,71 +1,118 @@
|
||||
<a href="https://chat.vercel.ai/">
|
||||
<img alt="Next.js 14 and App Router-ready AI chatbot." src="app/(chat)/opengraph-image.png">
|
||||
<h1 align="center">Chat SDK</h1>
|
||||
</a>
|
||||
# yedir-ai
|
||||
|
||||
<p align="center">
|
||||
Chat SDK is a free, open-source template built with Next.js and the AI SDK that helps you quickly build powerful chatbot applications.
|
||||
</p>
|
||||
yedir-ai 是一个面向商业化交付的 AI 设计工作台。它把 Lovart 风格的新首页、无限画布、Agent 工作流、图像生成与编辑、3D/CAD、本地 AI 配置中心和后台治理能力整合到同一个 Next.js 应用中。
|
||||
|
||||
<p align="center">
|
||||
<a href="https://chat-sdk.dev"><strong>Read Docs</strong></a> ·
|
||||
<a href="#features"><strong>Features</strong></a> ·
|
||||
<a href="#model-providers"><strong>Model Providers</strong></a> ·
|
||||
<a href="#deploy-your-own"><strong>Deploy Your Own</strong></a> ·
|
||||
<a href="#running-locally"><strong>Running locally</strong></a>
|
||||
</p>
|
||||
<br/>
|
||||
这个仓库已经不再定位为通用 Chat 模板。旧 Chat 页面入口已移除,`/api/chat` 目前保留为 Canvas/Agent 等内部生成链路使用。
|
||||
|
||||
## Features
|
||||
## 当前能力
|
||||
|
||||
- [Next.js](https://nextjs.org) App Router
|
||||
- Advanced routing for seamless navigation and performance
|
||||
- React Server Components (RSCs) and Server Actions for server-side rendering and increased performance
|
||||
- [AI SDK](https://ai-sdk.dev/docs/introduction)
|
||||
- Unified API for generating text, structured objects, and tool calls with LLMs
|
||||
- Hooks for building dynamic chat and generative user interfaces
|
||||
- Supports xAI (default), OpenAI, Fireworks, and other model providers
|
||||
- [shadcn/ui](https://ui.shadcn.com)
|
||||
- Styling with [Tailwind CSS](https://tailwindcss.com)
|
||||
- Component primitives from [Radix UI](https://radix-ui.com) for accessibility and flexibility
|
||||
- Data Persistence
|
||||
- [Neon Serverless Postgres](https://vercel.com/marketplace/neon) for saving chat history and user data
|
||||
- [Vercel Blob](https://vercel.com/storage/blob) for efficient file storage
|
||||
- [Auth.js](https://authjs.dev)
|
||||
- Simple and secure authentication
|
||||
- **Lovart 风格首页**:静态轻量壳优先渲染,站点配置、精选图、项目、教程和会员信息通过客户端渐进加载。
|
||||
- **Canvas/Agent 工作台**:支持多模态生成、图片编辑、素材编排、Agent 模式和项目化创作流程。
|
||||
- **图像与视频生成链路**:支持 Gemini、Volcano、Qwen、FAL、RUXA、Krea、Runway、Midjourney 等可配置供应商。
|
||||
- **3D / CAD 能力**:集成 Tripo3D、World Labs、KittyCAD/Zoo,并支持后台模型别名和 Key 池配置。
|
||||
- **后台设置中心**:本地 AI 设置已拆分为领域组件,支持折叠持久化、状态摘要、快捷目录和统一 section shell。
|
||||
- **生产治理**:包含类型检查、lint、日志脱敏、首页公开接口缓存/降级、仓库污染物检查和 CI 质量门禁。
|
||||
|
||||
## Model Providers
|
||||
## 技术栈
|
||||
|
||||
This template uses the [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) to access multiple AI models through a unified interface. The default configuration includes [xAI](https://x.ai) models (`grok-2-vision-1212`, `grok-3-mini`) routed through the gateway.
|
||||
- Next.js 16 App Router
|
||||
- React 19 RC
|
||||
- TypeScript
|
||||
- Tailwind CSS + Radix UI
|
||||
- Drizzle ORM + Postgres
|
||||
- Auth.js
|
||||
- Vercel Blob / S3-compatible object storage
|
||||
- Playwright
|
||||
- Ultracite / Biome
|
||||
|
||||
### AI Gateway Authentication
|
||||
## 快速开始
|
||||
|
||||
**For Vercel deployments**: Authentication is handled automatically via OIDC tokens.
|
||||
|
||||
**For non-Vercel deployments**: You need to provide an AI Gateway API key by setting the `AI_GATEWAY_API_KEY` environment variable in your `.env.local` file.
|
||||
|
||||
With the [AI SDK](https://ai-sdk.dev/docs/introduction), you can also switch to direct LLM providers like [OpenAI](https://openai.com), [Anthropic](https://anthropic.com), [Cohere](https://cohere.com/), and [many more](https://ai-sdk.dev/providers/ai-sdk-providers) with just a few lines of code.
|
||||
|
||||
## Deploy Your Own
|
||||
|
||||
You can deploy your own version of the Next.js AI Chatbot to Vercel with one click:
|
||||
|
||||
[](https://vercel.com/templates/next.js/nextjs-ai-chatbot)
|
||||
|
||||
## Running locally
|
||||
|
||||
You will need to use the environment variables [defined in `.env.example`](.env.example) to run Next.js AI Chatbot. It's recommended you use [Vercel Environment Variables](https://vercel.com/docs/projects/environment-variables) for this, but a `.env` file is all that is necessary.
|
||||
|
||||
> Note: You should not commit your `.env` file or it will expose secrets that will allow others to control access to your various AI and authentication provider accounts.
|
||||
|
||||
1. Install Vercel CLI: `npm i -g vercel`
|
||||
2. Link local instance with Vercel and GitHub accounts (creates `.vercel` directory): `vercel link`
|
||||
3. Download your environment variables: `vercel env pull`
|
||||
准备 Node.js 20、pnpm 9.12.3 和 Postgres。
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm db:migrate # Setup database or apply latest database changes
|
||||
pnpm dev
|
||||
cp .env.example .env.local
|
||||
pnpm db:migrate
|
||||
AUTH_TRUST_HOST=true PORT=3001 pnpm dev
|
||||
```
|
||||
|
||||
Your app template should now be running on [localhost:3000](http://localhost:3000).
|
||||
默认访问地址:
|
||||
|
||||
```text
|
||||
http://localhost:3001/
|
||||
```
|
||||
|
||||
后台设置页:
|
||||
|
||||
```text
|
||||
http://localhost:3001/settings
|
||||
```
|
||||
|
||||
未登录访问后台会重定向到 `/login?callbackUrl=%2Fsettings`。
|
||||
|
||||
## 环境变量
|
||||
|
||||
先从 `.env.example` 复制到 `.env.local`,再按部署环境填写真实值。不要提交 `.env.local` 或任何真实密钥。
|
||||
|
||||
最小本地运行通常需要:
|
||||
|
||||
- `AUTH_SECRET`
|
||||
- `AUTH_URL` 或本地开发使用 `AUTH_TRUST_HOST=true`
|
||||
- `POSTGRES_URL`
|
||||
- `BLOB_READ_WRITE_TOKEN` 或一组 S3 配置
|
||||
- 至少一个可用 AI Provider Key,或在后台设置中配置供应商
|
||||
|
||||
更多分组说明见 [docs/deployment.md](docs/deployment.md)。
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
pnpm lint
|
||||
pnpm check:logs
|
||||
pnpm exec tsc --noEmit --pretty false
|
||||
pnpm test
|
||||
pnpm db:migrate
|
||||
pnpm db:generate
|
||||
```
|
||||
|
||||
推荐提交前至少运行:
|
||||
|
||||
```bash
|
||||
pnpm lint
|
||||
pnpm check:logs
|
||||
pnpm exec tsc --noEmit --pretty false
|
||||
git diff --check
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```text
|
||||
app/ Next.js routes, route handlers, admin pages
|
||||
components/ UI, Canvas, home, editor and product modules
|
||||
components/home/lovart/ Lovart home focused render sections
|
||||
lib/ DB, AI providers, storage, observability, domain logic
|
||||
docs/ Deployment, operations, architecture and feature notes
|
||||
tests/ Playwright e2e and route-level tests
|
||||
.github/workflows/ Quality gates and Playwright CI
|
||||
```
|
||||
|
||||
## 部署与运维
|
||||
|
||||
- 生产部署建议使用受控反向代理,并只在 Host 头可信时设置 `AUTH_TRUST_HOST=true`。
|
||||
- 首页公开接口应保持快速返回,慢数据库或外部服务异常时返回缓存或 fallback。
|
||||
- 生产日志默认通过 `LOG_LEVEL=info` 控制,敏感字段会被 `lib/observability` 脱敏。
|
||||
- Playwright workflow 独立于基础质量门禁,避免把密钥依赖和 e2e 成本混入每次 lint/typecheck。
|
||||
|
||||
详细说明:
|
||||
|
||||
- [部署指南](docs/deployment.md)
|
||||
- [运维与质量门禁](docs/operations.md)
|
||||
- [系统架构说明](docs/architecture.md)
|
||||
|
||||
## 开发边界
|
||||
|
||||
- `/classic` 和 `/chat/[id]` 旧 Chat UI 已重定向到 `/`。
|
||||
- `/api/chat` 暂时是内部生成 API,不作为公开旧 Chat 页面入口。
|
||||
- Canvas、Agent、图像处理和后台设置仍有大型历史模块,后续应按领域继续拆分。
|
||||
- License 以仓库根目录 [LICENSE](LICENSE) 为准;本阶段未修改许可证和版权主体。
|
||||
|
||||
78
docs/architecture.md
Normal file
78
docs/architecture.md
Normal file
@ -0,0 +1,78 @@
|
||||
# yedir-ai 架构说明
|
||||
|
||||
yedir-ai 是一个以 AI 设计工作台为核心的 Next.js 应用,主要由首页体验、Canvas/Agent 创作链路、后台设置中心、内部生成 API、公开轻量 API 和基础设施治理组成。
|
||||
|
||||
## 高层边界
|
||||
|
||||
```text
|
||||
Browser
|
||||
|
|
||||
|-- / Lovart-style home shell
|
||||
|-- /canvas/* Canvas and Agent workspace
|
||||
|-- /settings Admin settings center
|
||||
|-- /api/site-settings Public lightweight settings API
|
||||
|-- /api/featured Public featured gallery API
|
||||
|-- /api/chat Internal generation API
|
||||
|
|
||||
Next.js App Router
|
||||
|
|
||||
|-- Auth.js session, admin access, OAuth
|
||||
|-- Drizzle/Postgres projects, settings, users, tasks
|
||||
|-- Storage service DB S3 config, env S3, Vercel Blob fallback
|
||||
|-- AI providers image, video, 3D, CAD, agent workflows
|
||||
|-- Observability structured logs and redaction
|
||||
```
|
||||
|
||||
## 首页
|
||||
|
||||
首页 `/` 优先渲染静态轻量壳,不在服务端阻塞等待 session、站点配置或个性化数据。站点配置、精选图、项目、会员和教程等数据通过客户端渐进加载。
|
||||
|
||||
公开首页接口应具备缓存、降级和观测头,避免数据库或外部服务波动拖慢首屏。
|
||||
|
||||
## Canvas / Agent
|
||||
|
||||
Canvas 是主要创作工作区,承载图像生成、编辑、素材编排、Agent 自动规划、多模态输入和项目化保存。
|
||||
|
||||
Agent 能力依赖内部生成链路、模型供应商配置和素材/PSD 等领域模块。相关巨型模块仍是后续治理重点,拆分时应保持 API shape 和保存逻辑不变。
|
||||
|
||||
## 后台设置中心
|
||||
|
||||
`/settings` 是管理员配置入口。本地 AI 设置已按领域拆分为 planning、model3d、image-pipeline、runtime 等组件,并保留统一 section shell、状态摘要、快捷目录和折叠持久化。
|
||||
|
||||
后台保存逻辑、数据库 setting key 和 SWR key 应保持稳定,避免配置迁移风险。
|
||||
|
||||
## 内部生成 API
|
||||
|
||||
`/api/chat` 目前不再对应旧 Chat UI,而是 Canvas/Agent 的内部生成 API。旧页面 `/classic` 和 `/chat/[id]` 已重定向到 `/`。
|
||||
|
||||
未来若要彻底替换 `/api/chat`,应先把 Canvas/Agent 调用方迁移到专用生成接口,再删除旧协议。
|
||||
|
||||
## 公开轻量 API
|
||||
|
||||
首页相关公开接口包括:
|
||||
|
||||
- `/api/site-settings?scope=home`
|
||||
- `/api/featured`
|
||||
- `/api/nav-links`
|
||||
- `/api/home-animation`
|
||||
- `/api/auth-settings`
|
||||
|
||||
这些接口应快速返回,必要时使用 stale cache 或 fallback。响应头应保留 `X-Cache`、`X-Fallback`、`Server-Timing`,方便判断慢点来自缓存、DB 还是降级。
|
||||
|
||||
## 数据与存储
|
||||
|
||||
Postgres 是主数据源。连接池默认使用有限连接数、短连接超时和 `prepare: false`,避免数据库不可用时拖垮公开接口。
|
||||
|
||||
对象存储优先使用数据库中的 S3 配置;环境变量 S3 和 Vercel Blob 是 fallback。日志中不应输出完整 endpoint、bucket key、签名 URL 或原图 URL。
|
||||
|
||||
## 质量与安全治理
|
||||
|
||||
主质量门禁包括:
|
||||
|
||||
- `pnpm lint`
|
||||
- `pnpm check:logs`
|
||||
- `pnpm exec tsc --noEmit --pretty false`
|
||||
- `git diff --check`
|
||||
- tracked 污染物检查
|
||||
|
||||
日志通过 `lib/observability` 结构化输出并脱敏。当前只治理了第一批高风险链路,Canvas 和 `/api/chat` 日志二期仍待推进。
|
||||
93
docs/deployment.md
Normal file
93
docs/deployment.md
Normal file
@ -0,0 +1,93 @@
|
||||
# yedir-ai 部署指南
|
||||
|
||||
本文档用于生产或准生产环境部署。所有真实密钥只应配置在运行环境中,不要提交到 Git。
|
||||
|
||||
## 运行环境
|
||||
|
||||
- Node.js 20
|
||||
- pnpm 9.12.3
|
||||
- Postgres
|
||||
- 可选 Redis
|
||||
- Vercel Blob 或 S3-compatible 对象存储
|
||||
- 至少一个可用 AI Provider,或在后台设置中配置供应商
|
||||
|
||||
## 基础步骤
|
||||
|
||||
```bash
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm db:migrate
|
||||
pnpm build
|
||||
pnpm start
|
||||
```
|
||||
|
||||
本地开发:
|
||||
|
||||
```bash
|
||||
AUTH_TRUST_HOST=true PORT=3001 pnpm dev
|
||||
```
|
||||
|
||||
## 环境变量分组
|
||||
|
||||
### Core / Auth
|
||||
|
||||
必须配置 `AUTH_SECRET` 和生产域名 `AUTH_URL`。只有在受信反向代理后部署,并确认 Host 头不会被用户伪造时,才允许设置 `AUTH_TRUST_HOST=true`。
|
||||
|
||||
Google、钉钉、邮箱验证等登录能力可以通过后台设置和环境变量组合启用。管理员初始化使用 `ADMIN_EMAIL` / `ADMIN_PASSWORD`,完成后建议移除或轮换。
|
||||
|
||||
### Database
|
||||
|
||||
主数据库使用 `POSTGRES_URL`。连接池默认值来自 `lib/db/index.ts`:
|
||||
|
||||
- `POSTGRES_MAX_CONNECTIONS=10`
|
||||
- `POSTGRES_IDLE_TIMEOUT_SECONDS=20`
|
||||
- `POSTGRES_CONNECT_TIMEOUT_SECONDS=5`
|
||||
|
||||
生产环境可按数据库规格调整,但不建议无上限放大连接数。
|
||||
|
||||
### Object Storage
|
||||
|
||||
优先使用后台数据库中的存储配置;环境变量 S3 和 `BLOB_READ_WRITE_TOKEN` 作为 fallback。
|
||||
|
||||
S3 公网访问建议配置 `S3_PUBLIC_URL`,避免把内部 endpoint 暴露给前端或用户。
|
||||
|
||||
### AI Providers
|
||||
|
||||
大多数供应商都可以在后台设置中配置。环境变量适合作为 bootstrap 或 fallback,例如 `DASHSCOPE_API_KEY`、`FAL_KEY`、`TRIPO_API_KEY`、`KITTYCAD_API_TOKEN`。
|
||||
|
||||
不要在日志、README、issue 或截图中暴露真实 API Key、签名 URL、OAuth code、session、cookie。
|
||||
|
||||
### Logging
|
||||
|
||||
生产建议:
|
||||
|
||||
```env
|
||||
LOG_LEVEL=info
|
||||
LOG_INCLUDE_STACK=false
|
||||
NEXT_PUBLIC_ENABLE_CLIENT_LOGS=false
|
||||
```
|
||||
|
||||
日志会经过 `lib/observability` 脱敏。需要排查问题时,优先临时提高服务端 `LOG_LEVEL`,不要开启浏览器生产日志。
|
||||
|
||||
## 反向代理与安全
|
||||
|
||||
- 代理层应保留正确的 `X-Forwarded-*` 头。
|
||||
- 只在可信代理后启用 `AUTH_TRUST_HOST=true`。
|
||||
- 上传和生成接口可能处理大文件,代理需要配置足够的 body size 和超时时间。
|
||||
- 对管理端、支付、生成任务回调和定时任务接口使用独立密钥或登录权限保护。
|
||||
|
||||
## 部署后烟测
|
||||
|
||||
```bash
|
||||
curl -I https://your-domain.com/
|
||||
curl -I https://your-domain.com/classic
|
||||
curl -I https://your-domain.com/chat/test-id
|
||||
curl -I https://your-domain.com/settings
|
||||
curl -I "https://your-domain.com/api/site-settings?scope=home"
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- `/` 返回 200。
|
||||
- `/classic` 和 `/chat/test-id` 重定向到 `/`。
|
||||
- `/settings` 未登录重定向到登录页。
|
||||
- 首页公开接口带有 `X-Cache` / `X-Fallback` / `Server-Timing` 等观测头。
|
||||
78
docs/operations.md
Normal file
78
docs/operations.md
Normal file
@ -0,0 +1,78 @@
|
||||
# yedir-ai 运维与质量门禁
|
||||
|
||||
本文档记录日常开发、合并前检查、性能烟测和常见故障处理方式。
|
||||
|
||||
## 合并前检查
|
||||
|
||||
```bash
|
||||
pnpm lint
|
||||
pnpm check:logs
|
||||
pnpm exec tsc --noEmit --pretty false
|
||||
git diff --check
|
||||
```
|
||||
|
||||
污染物检查:
|
||||
|
||||
```bash
|
||||
git ls-files | rg '(^|/)\\.DS_Store$|\\.swp$|\\.env\\.local$|^\\.claude/|^migration-backup|^tsconfig\\.tsbuildinfo$' || true
|
||||
```
|
||||
|
||||
预期无输出。
|
||||
|
||||
## CI
|
||||
|
||||
`.github/workflows/lint.yml` 是基础质量门禁,负责 lint、日志治理、类型检查、diff hygiene 和 tracked 污染物检查。
|
||||
|
||||
Playwright workflow 独立运行,避免 e2e 依赖、浏览器安装和 secrets 影响基础门禁反馈速度。
|
||||
|
||||
## 日志治理
|
||||
|
||||
新增或修改已治理文件时不要使用裸 `console.*`。使用:
|
||||
|
||||
```ts
|
||||
import { createLogger } from "@/lib/observability/logger";
|
||||
|
||||
const logger = createLogger("scope-name");
|
||||
logger.info("event name", { count: 1 });
|
||||
logger.error("event failed", error);
|
||||
```
|
||||
|
||||
客户端使用 `createClientLogger`。生产环境默认静默,除非显式设置 `NEXT_PUBLIC_ENABLE_CLIENT_LOGS=true`。
|
||||
|
||||
`pnpm check:logs` 会检查已治理文件是否重新引入裸 console,并验证 token、API Key、URL、base64、password 等敏感值不会明文输出。
|
||||
|
||||
## 首页性能烟测
|
||||
|
||||
```bash
|
||||
AUTH_TRUST_HOST=true PORT=3001 pnpm dev
|
||||
curl -I --max-time 30 http://127.0.0.1:3001/
|
||||
curl -I --max-time 30 "http://127.0.0.1:3001/api/site-settings?scope=home"
|
||||
curl -I --max-time 30 "http://127.0.0.1:3001/api/featured?page=1&pageSize=24"
|
||||
```
|
||||
|
||||
首页 HTML 应快速返回。公开轻量接口在数据库慢或不可用时应快速返回缓存或 fallback,不应长时间挂住首屏。
|
||||
|
||||
## 路由回归烟测
|
||||
|
||||
```bash
|
||||
curl -I http://127.0.0.1:3001/
|
||||
curl -I http://127.0.0.1:3001/classic
|
||||
curl -I http://127.0.0.1:3001/chat/test-id
|
||||
curl -I http://127.0.0.1:3001/settings
|
||||
curl -I -X POST http://127.0.0.1:3001/api/files/upload
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- `/` 返回 200。
|
||||
- `/classic` 和 `/chat/test-id` 返回 307 到 `/`。
|
||||
- `/settings` 未登录返回 307 到 `/login?callbackUrl=%2Fsettings`。
|
||||
- 上传接口未登录返回 401。
|
||||
|
||||
## 常见故障
|
||||
|
||||
- `.next/dev/lock` 阻止启动:已有 dev server 持锁,先确认进程归属,不要误杀其他工作区服务。
|
||||
- 首页接口慢:先看 `Server-Timing`、`X-Cache`、`X-Fallback`,再查数据库连接池和公开接口 fallback。
|
||||
- 登录 Host 错误:生产配置 `AUTH_URL`;仅在可信代理后设置 `AUTH_TRUST_HOST=true`。
|
||||
- 上传失败:确认后台存储配置、环境变量 S3 fallback 或 `BLOB_READ_WRITE_TOKEN` 至少一组可用。
|
||||
- 日志泄露风险:不要把完整 prompt、OAuth token、签名 URL、cookie、request body 放进日志 message。
|
||||
Loading…
x
Reference in New Issue
Block a user