docs: prepare yedir-ai for commercial delivery

This commit is contained in:
Your Name 2026-05-26 21:21:22 +08:00
parent 286acefe4a
commit c79724eefa
6 changed files with 510 additions and 128 deletions

View File

@ -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

View File

@ -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
View File

@ -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:
[![Deploy with Vercel](https://vercel.com/button)](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
View 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
View 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
View 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。