diff --git a/docs.json b/docs.json index 207f6d7..3432f1c 100644 --- a/docs.json +++ b/docs.json @@ -191,6 +191,97 @@ ] } ] + }, + { + "language": "cn", + "tabs": [ + { + "tab": "指南", + "groups": [ + { + "group": "入门指南", + "pages": [ + "docs/cn/index", + "docs/cn/quickstart", + "docs/cn/development" + ] + }, + { + "group": "自定义", + "pages": [ + "docs/cn/essentials/settings", + "docs/cn/essentials/navigation" + ] + }, + { + "group": "撰写内容", + "pages": [ + "docs/cn/essentials/markdown", + "docs/cn/essentials/code", + "docs/cn/essentials/images", + "docs/cn/essentials/reusable-snippets" + ] + }, + { + "group": "AI 工具", + "pages": [ + "docs/cn/ai-tools/cursor", + "docs/cn/ai-tools/claude-code", + "docs/cn/ai-tools/windsurf" + ] + }, + { + "group": "实现练习", + "pages": [ + "docs/cn/implementation-exercises/signed-webhooks", + "docs/cn/implementation-exercises/async-export-jobs", + "docs/cn/implementation-exercises/team-feature-flags" + ] + } + ] + }, + { + "tab": "API 参考", + "groups": [ + { + "group": "API 文档", + "pages": [ + "docs/cn/api-reference/introduction" + ] + }, + { + "group": "OpenAPI 参考测试", + "pages": [ + "docs/cn/api-reference/openapi-test/index", + "docs/cn/api-reference/openapi-test/relative", + "docs/cn/api-reference/openapi-test/absolute", + "docs/cn/api-reference/openapi-test/same-dir", + "docs/cn/api-reference/openapi-test/remote" + ] + }, + { + "group": "端点示例", + "pages": [ + "docs/cn/api-reference/endpoint/get", + "docs/cn/api-reference/endpoint/create", + "docs/cn/api-reference/endpoint/delete", + "docs/cn/api-reference/endpoint/webhook", + "docs/cn/api-reference/endpoint/search", + "docs/cn/api-reference/endpoint/change-location", + "docs/cn/api-reference/endpoint/hierarchy", + "docs/cn/api-reference/endpoint/get-asset-proof", + "docs/cn/api-reference/endpoint/get-pots" + ] + }, + { + "group": "AsyncAPI 文档", + "asyncapi": { + "source": "docs/api-reference/asyncapi.json" + } + } + ] + } + ] } ], "global": { diff --git a/docs/cn/ai-tools/claude-code.mdx b/docs/cn/ai-tools/claude-code.mdx new file mode 100644 index 0000000..693ca82 --- /dev/null +++ b/docs/cn/ai-tools/claude-code.mdx @@ -0,0 +1,76 @@ +--- +title: "Claude Code 设置" +description: "为你的文档工作流配置 Claude Code" +icon: "asterisk" +--- + +Claude Code 是 Anthropic 官方的命令行工具。本指南将帮助你设置 Claude Code,以协助你编写和维护文档。 + +## 前置条件 + +- 已激活的 Claude 订阅(Pro、Max 或 API 访问权限) + +## 设置 + +1. 全局安装 Claude Code: + + ```bash + npm install -g @anthropic-ai/claude-code +``` + +2. 进入你的文档目录。 +3. (可选)将下方的 `CLAUDE.md` 文件添加到你的项目中。 +4. 运行 `claude` 启动。 + +## 创建 `CLAUDE.md` + +在你的文档仓库根目录创建一个 `CLAUDE.md` 文件,以便让 Claude Code 学习你具体的文档规范: + +````markdown +# Mintlify 文档 + +## 协作关系 +- 你可以对想法提出不同意见——这有助于产出更好的文档。当你这样做时,请引用来源并解释你的理由 +- 始终请求澄清,而不是做出假设 +- 永远不要撒谎、猜测或编造信息 + +## 项目背景 +- 格式:带 YAML frontmatter 的 MDX 文件 +- 配置:docs.json 用于导航、主题和设置 +- 组件:Mintlify 组件 + +## 内容策略 +- 适度记录以确保用户成功——不多不少 +- 优先保证信息的准确性和可用性 +- 尽可能让内容保持长期有效 +- 添加新内容前先搜索现有信息。除非出于战略原因,否则避免重复 +- 检查现有模式以保持一致性 +- 从最小合理的改动开始 + +## 页面 frontmatter 要求 +- title:清晰且描述性的页面标题 +- description:用于 SEO 和导航的简明摘要 + +## 写作规范 +- 使用第二人称(“你”) +- 在程序性内容开头列出前置条件 +- 发布前测试所有代码示例 +- 与现有页面的风格和格式保持一致 +- 同时包含基础和进阶用例 +- 所有代码块都加上语言标签 +- 所有图片都加上替代文本 +- 内部链接使用相对路径 + +## Git 工作流 +- 提交时永远不要使用 --no-verify +- 在开始之前询问如何处理未提交的更改 +- 当没有明确的分支可用于改动时,创建新分支 +- 在开发过程中频繁提交 +- 永远不要跳过或禁用 pre-commit 钩子 + +## 切勿 +- 在任何 MDX 文件中省略 frontmatter +- 内部链接使用绝对 URL +- 包含未测试的代码示例 +- 做出假设——务必请求澄清 +```` diff --git a/docs/cn/ai-tools/cursor.mdx b/docs/cn/ai-tools/cursor.mdx new file mode 100644 index 0000000..bed9fa9 --- /dev/null +++ b/docs/cn/ai-tools/cursor.mdx @@ -0,0 +1,420 @@ +--- +title: "Cursor 设置" +description: "为你的文档工作流配置 Cursor" +icon: "arrow-pointer" +--- + +使用 Cursor 协助编写和维护你的文档。本指南将展示如何配置 Cursor,以便在技术写作任务和使用 Mintlify 组件时获得更好的效果。 + +## 前置条件 + +- 已安装 Cursor 编辑器 +- 拥有文档仓库的访问权限 + +## 项目规则 + +创建所有团队成员都可以使用的项目规则。在你的文档仓库根目录: + +```bash +mkdir -p .cursor +``` + +创建 `.cursor/rules.md`: + +````markdown +# Mintlify 技术写作规则 + +你是一位 AI 写作助手,专长是使用 Mintlify 组件并遵循行业领先的技术写作实践,创作卓越的技术文档。 + +## 核心写作原则 + +### 语言与风格要求 + +- 使用清晰直接、适合技术受众的语言 +- 在说明和操作步骤中使用第二人称(“你”) +- 使用主动语态而非被动语态 +- 现在时表示当前状态,将来时表示结果 +- 除非必要否则避免行话;首次出现时需要定义术语 +- 在所有文档中保持术语一致 +- 句子简洁,同时提供必要的上下文 +- 在列表、标题和操作步骤中使用并行结构 + +### 内容组织标准 + +- 最重要的信息放在前面(倒金字塔结构) +- 采用渐进式披露:先讲基础概念,再讲高级概念 +- 将复杂流程拆分为编号步骤 +- 在说明之前列出前置条件和上下文 +- 为每个主要步骤提供预期结果 +- 使用描述性、富含关键词的标题以利于导航和 SEO +- 通过清晰的分节合理组织相关信息 + +### 以用户为中心 + +- 关注用户目标和结果,而非系统功能 +- 预见常见问题并主动予以解答 +- 为可能的失败点提供故障排查 +- 通过清晰的标题、列表和留白让内容易于扫读 +- 提供验证步骤以确认成功 + +## Mintlify 组件参考 + +### 提示组件 + +#### Note - 额外的有用信息 + + +为主要内容提供补充信息,但不打断阅读流程 + + +#### Tip - 最佳实践和专业建议 + + +提升用户成功率的专家建议、捷径或最佳实践 + + +#### Warning - 重要警示 + + +关于潜在问题、破坏性变更或破坏性操作的关键信息 + + +#### Info - 中性的背景信息 + + +背景信息、上下文或中性的公告 + + +#### Check - 成功确认 + + +正面确认、成功完成或达成里程碑的标识 + + +### 代码组件 + +#### 单个代码块 + +单个代码块示例: + +```javascript config.js +const apiConfig = { + baseURL: 'https://api.example.com', + timeout: 5000, + headers: { + 'Authorization': `Bearer ${process.env.API_TOKEN}` + } +}; +``` + +#### 多语言代码组 + +代码组示例: + + +```javascript Node.js +const response = await fetch('/api/endpoint', { + headers: { Authorization: `Bearer ${apiKey}` } +}); +``` + +```python Python +import requests +response = requests.get('/api/endpoint', + headers={'Authorization': f'Bearer {api_key}'}) +``` + +```curl cURL +curl -X GET '/api/endpoint' \ + -H 'Authorization: Bearer YOUR_API_KEY' +``` + + +#### 请求/响应示例 + +请求/响应文档示例: + + +```bash cURL +curl -X POST 'https://api.example.com/users' \ + -H 'Content-Type: application/json' \ + -d '{"name": "John Doe", "email": "john@example.com"}' +``` + + + +```json Success +{ + "id": "user_123", + "name": "John Doe", + "email": "john@example.com", + "created_at": "2024-01-15T10:30:00Z" +} +``` + + +### 结构组件 + +#### 流程步骤 + +分步说明示例: + + + + 运行 `npm install` 安装所需的包。 + + + 运行 `npm list` 验证安装。 + + + + + 创建一个包含 API 凭证的 `.env` 文件。 + + ```bash + API_KEY=your_api_key_here + ``` + + + 切勿将 API 密钥提交到版本控制。 + + + + +#### 用于切换内容的 Tabs + +标签页内容示例: + + + + ```bash + brew install node + npm install -g package-name + ``` + + + + ```powershell + choco install nodejs + npm install -g package-name + ``` + + + + ```bash + sudo apt install nodejs npm + npm install -g package-name + ``` + + + +#### 折叠内容的 Accordion + +手风琴分组示例: + + + + - **防火墙拦截**:确保 80 和 443 端口已开放 + - **代理配置**:设置 HTTP_PROXY 环境变量 + - **DNS 解析**:尝试使用 8.8.8.8 作为 DNS 服务器 + + + + ```javascript + const config = { + performance: { cache: true, timeout: 30000 }, + security: { encryption: 'AES-256' } + }; + ``` + + + +### 用于突出信息的 Cards 和 Columns + +卡片与卡片组示例: + + +从安装到完成第一个 API 调用,只需不到 10 分钟。 + + + + + 了解如何使用 API 密钥或 JWT 令牌对请求进行身份认证。 + + + + 了解速率限制以及大流量场景下的最佳实践。 + + + +### API 文档组件 + +#### 参数字段 + +参数文档示例: + + +用户的唯一标识符。必须是合法的 UUID v4 格式。 + + + +用户的邮箱地址。必须有效且在系统中唯一。 + + + +返回结果的最大数量。范围:1-100。 + + + +用于 API 认证的 Bearer 令牌。格式:`Bearer YOUR_API_KEY` + + +#### 响应字段 + +响应字段文档示例: + + +分配给新建用户的唯一标识符。 + + + +用户创建时间的 ISO 8601 格式时间戳。 + + + +分配给该用户的权限字符串列表。 + + +#### 可展开的嵌套字段 + +嵌套字段文档示例: + + +包含所有相关数据的完整用户对象。 + + + + 包含个人详细信息的用户资料。 + + + + 注册时填写的用户名字。 + + + + 用户头像的 URL。如果未设置头像则返回 null。 + + + + + + +### 媒体与高级组件 + +#### 用于图片的 Frame + +将所有图片包裹在 Frame 中: + + +显示分析概览的主仪表盘 + + + +包含图表的分析仪表盘 + + +#### 视频 + +使用 HTML video 元素嵌入自托管视频: + + + +使用 iframe 元素嵌入 YouTube 视频: + + + +#### Tooltip 工具提示 + +工具提示用法示例: + + +API + + +#### Updates 更新 + +使用 Updates 编写更新日志: + + +## 新功能 +- 新增批量用户导入功能 +- 改进了带可执行建议的错误信息 + +## 错误修复 +- 修复了大数据集的分页问题 +- 解决了身份认证超时问题 + + +## 必需的页面结构 + +每个文档页面都必须以 YAML frontmatter 开头: + +```yaml +--- +title: "清晰、具体、富含关键词的标题" +description: "说明页面用途和价值的简明描述" +--- +``` + +## 内容质量标准 + +### 代码示例要求 + +- 始终提供完整、可运行的示例,以便用户复制并执行 +- 展示恰当的错误处理和边界情况处理 +- 使用真实数据而非占位值 +- 包含预期的输出和结果以便验证 +- 发布前彻底测试所有代码示例 +- 指定语言,并在相关时附上文件名 +- 为复杂逻辑添加解释性注释 +- 切勿在代码示例中包含真实的 API 密钥或机密 + +### API 文档要求 + +- 记录所有参数(包括可选参数),并附清晰描述 +- 用真实数据展示成功和错误的响应示例 +- 列出速率限制信息及具体限额 +- 提供格式正确的身份认证示例 +- 解释所有 HTTP 状态码及错误处理 +- 覆盖完整的请求/响应流程 + +### 无障碍要求 + +- 为所有图片和示意图提供描述性替代文本 +- 使用具体、可执行的链接文本,而不是“点击这里” +- 确保正确的标题层级,从 H2 开始 +- 考虑键盘导航的可用性 +- 在示例和视觉元素中使用足够的色彩对比度 +- 使用标题和列表组织内容,便于扫读 + +## 组件选择逻辑 + +- 使用 **Steps** 表示流程和顺序说明 +- 使用 **Tabs** 表示平台特定内容或可选方案 +- 使用 **CodeGroup** 在多种编程语言中展示同一概念 +- 使用 **Accordions** 进行信息的渐进式披露 +- 使用 **RequestExample/ResponseExample** 专门用于 API 端点文档 +- 使用 **ParamField** 表示 API 参数,使用 **ResponseField** 表示 API 响应 +- 使用 **Expandable** 表示嵌套对象属性或分层信息 +```` diff --git a/docs/cn/ai-tools/windsurf.mdx b/docs/cn/ai-tools/windsurf.mdx new file mode 100644 index 0000000..d9bfdc2 --- /dev/null +++ b/docs/cn/ai-tools/windsurf.mdx @@ -0,0 +1,96 @@ +--- +title: "Windsurf 设置" +description: "为你的文档工作流配置 Windsurf" +icon: "water" +--- + +配置 Windsurf 的 Cascade AI 助手,协助你编写和维护文档。本指南展示如何为 Mintlify 文档工作流设置 Windsurf。 + +## 前置条件 + +- 已安装 Windsurf 编辑器 +- 拥有文档仓库的访问权限 + +## 工作区规则 + +创建工作区规则,为 Windsurf 提供有关文档项目和规范的上下文。 + +在项目根目录创建 `.windsurf/rules.md`: + +````markdown +# Mintlify 技术写作规则 + +## 项目背景 + +- 这是一个基于 Mintlify 平台的文档项目 +- 我们使用带 YAML frontmatter 的 MDX 文件 +- 导航在 `docs.json` 中配置 +- 我们遵循技术写作最佳实践 + +## 写作规范 + +- 在说明中使用第二人称(“你”) +- 使用主动语态和现在时 +- 操作流程开头列出前置条件 +- 为主要步骤提供预期结果 +- 使用描述性、富含关键词的标题 +- 句子简洁但信息丰富 + +## 必需的页面结构 + +每个页面都必须以 frontmatter 开头: + +```yaml +--- +title: "清晰、具体的标题" +description: "便于 SEO 和导航的简明描述" +--- +``` + +## Mintlify 组件 + +### 提示框 + +- `` 用于有用的补充信息 +- `` 用于重要警示和破坏性变更 +- `` 用于最佳实践和专家建议 +- `` 用于中性的背景信息 +- `` 用于成功确认 + +### 代码示例 + +- 在合适的场景下提供完整、可运行的示例 +- 使用 `` 展示多语言示例 +- 在所有代码块上指定语言标签 +- 使用真实数据而非占位符 +- 在 API 文档中使用 `` 和 `` + +### 操作流程 + +- 使用 `` 组件呈现顺序说明 +- 在相关时通过 `` 组件加入验证步骤 +- 将复杂流程拆分为更小的步骤 + +### 内容组织 + +- 使用 `` 展示平台特定内容 +- 使用 `` 实现渐进式披露 +- 使用 `` 和 `` 突出内容 +- 将图片包裹在 `` 中,并提供描述性替代文本 + +## API 文档要求 + +- 使用 `` 记录所有参数 +- 使用 `` 展示响应结构 +- 同时提供成功和错误示例 +- 使用 `` 表示嵌套对象属性 +- 始终提供身份认证示例 + +## 质量标准 + +- 发布前测试所有代码示例 +- 内部链接使用相对路径 +- 为所有图片提供替代文本 +- 确保正确的标题层级(从 h2 开始) +- 检查现有模式以保持一致性 +```` diff --git a/docs/cn/api-reference/async-api/lighting-measured.mdx b/docs/cn/api-reference/async-api/lighting-measured.mdx new file mode 100644 index 0000000..0a26888 --- /dev/null +++ b/docs/cn/api-reference/async-api/lighting-measured.mdx @@ -0,0 +1,4 @@ +--- +title: '光照测量' +asyncapi: 'api-reference/asyncapi.json lightingMeasured' +--- diff --git a/docs/cn/api-reference/endpoint/change-location.mdx b/docs/cn/api-reference/endpoint/change-location.mdx new file mode 100644 index 0000000..8e53301 --- /dev/null +++ b/docs/cn/api-reference/endpoint/change-location.mdx @@ -0,0 +1,4 @@ +--- +title: '更改位置' +openapi: 'PUT /plants/{id}/location' +--- \ No newline at end of file diff --git a/docs/cn/api-reference/endpoint/create-bulk.mdx b/docs/cn/api-reference/endpoint/create-bulk.mdx new file mode 100644 index 0000000..1d59ca2 --- /dev/null +++ b/docs/cn/api-reference/endpoint/create-bulk.mdx @@ -0,0 +1,6 @@ +--- +title: '批量创建植物' +openapi: 'POST /plants/bulk' +--- + +这是批量创建端点的一些自定义 markdown 内容。 \ No newline at end of file diff --git a/docs/cn/api-reference/endpoint/create.mdx b/docs/cn/api-reference/endpoint/create.mdx new file mode 100644 index 0000000..7d509eb --- /dev/null +++ b/docs/cn/api-reference/endpoint/create.mdx @@ -0,0 +1,8 @@ +--- +title: '创建植物' +openapi: 'openapi/openapi.json POST /plants' +de_link: "https://developers.example.de/docs/api-reference/endpoint/create" +fr_link: "https://developers.example.fr/docs/api-reference/endpoint/create" +--- + +这是创建端点的一些自定义 markdown 内容。 \ No newline at end of file diff --git a/docs/cn/api-reference/endpoint/delete.mdx b/docs/cn/api-reference/endpoint/delete.mdx new file mode 100644 index 0000000..eeb7947 --- /dev/null +++ b/docs/cn/api-reference/endpoint/delete.mdx @@ -0,0 +1,4 @@ +--- +title: '删除植物' +openapi: 'DELETE /plants/{id}' +--- diff --git a/docs/cn/api-reference/endpoint/get-asset-proof.mdx b/docs/cn/api-reference/endpoint/get-asset-proof.mdx new file mode 100644 index 0000000..4b05f79 --- /dev/null +++ b/docs/cn/api-reference/endpoint/get-asset-proof.mdx @@ -0,0 +1,5 @@ +--- +title: "获取资产证明" +openapi: "POST /getAssetProof" +description: "检索压缩 Solana NFT 或代币的加密 Merkle 证明。" +--- \ No newline at end of file diff --git a/docs/cn/api-reference/endpoint/get-pots.mdx b/docs/cn/api-reference/endpoint/get-pots.mdx new file mode 100644 index 0000000..0920e59 --- /dev/null +++ b/docs/cn/api-reference/endpoint/get-pots.mdx @@ -0,0 +1,4 @@ +--- +title: 获取花盆 +openapi: "GET /pots" +--- \ No newline at end of file diff --git a/docs/cn/api-reference/endpoint/get.mdx b/docs/cn/api-reference/endpoint/get.mdx new file mode 100644 index 0000000..16a5a6a --- /dev/null +++ b/docs/cn/api-reference/endpoint/get.mdx @@ -0,0 +1,7 @@ +--- +title: '获取植物' +openapi: 'GET /plants' +de_link: "https://developers.example.de/docs/api-reference/endpoint/get" +fr_link: "https://developers.example.fr/docs/api-reference/endpoint/get" +es_link: "https://developers.example.es/docs/api-reference/endpoint/get" +--- diff --git a/docs/cn/api-reference/endpoint/hierarchy.mdx b/docs/cn/api-reference/endpoint/hierarchy.mdx new file mode 100644 index 0000000..9916b35 --- /dev/null +++ b/docs/cn/api-reference/endpoint/hierarchy.mdx @@ -0,0 +1,5 @@ +--- +title: "获取植物层级结构" +openapi: "GET /plants/{id}/hierarchy" +description: "获取展示父子关系的植物层级结构" +--- \ No newline at end of file diff --git a/docs/cn/api-reference/endpoint/search.mdx b/docs/cn/api-reference/endpoint/search.mdx new file mode 100644 index 0000000..83939fb --- /dev/null +++ b/docs/cn/api-reference/endpoint/search.mdx @@ -0,0 +1,4 @@ +--- +title: '搜索植物' +openapi: 'POST /plants/search' +--- diff --git a/docs/cn/api-reference/endpoint/webhook.mdx b/docs/cn/api-reference/endpoint/webhook.mdx new file mode 100644 index 0000000..d0488dc --- /dev/null +++ b/docs/cn/api-reference/endpoint/webhook.mdx @@ -0,0 +1,6 @@ +--- +title: '新植物' +openapi: 'WEBHOOK /plant/webhook' +--- + +这是 webhook 端点的一些自定义 markdown 内容。 diff --git a/docs/cn/api-reference/introduction.mdx b/docs/cn/api-reference/introduction.mdx new file mode 100644 index 0000000..3ca3b9d --- /dev/null +++ b/docs/cn/api-reference/introduction.mdx @@ -0,0 +1,35 @@ +--- +title: '简介 (Reed Docs)' +description: '用于展示 API 端点的示例章节' +de_link: "https://developers.example.de/docs/api-reference/introduction" +fr_link: "https://developers.example.fr/docs/api-reference/introduction" +es_link: "https://developers.example.es/docs/api-reference/introduction" +--- + + + 如果你不打算构建 API 参考文档,可以删除 api-reference 文件夹来移除本章节。 + + +## 欢迎 + +构建 API 文档有两种方式:[OpenAPI](https://mintlify.com/docs/api-playground/openapi/setup) 和 [MDX 组件](https://mintlify.com/docs/api-playground/mdx/configuration)。在该入门套件中,我们使用以下 OpenAPI 规范。 + + + 查看 OpenAPI 规范文件 + + +## 身份认证 + +所有 API 端点都使用 Bearer 令牌进行身份认证,该认证方式从规范文件中读取。 + +```json +"security": [ + { + "bearerAuth": [] + } +] +``` diff --git a/docs/cn/api-reference/openapi-test/absolute.mdx b/docs/cn/api-reference/openapi-test/absolute.mdx new file mode 100644 index 0000000..9313443 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/absolute.mdx @@ -0,0 +1,7 @@ +--- +title: '绝对路径引用' +description: '使用从仓库根目录起的绝对路径引用规范' +openapi: '/openapi/openapi-example.json GET /users' +--- + +引用 `/openapi/openapi-example.json` —— 从仓库根目录起的绝对路径(以斜杠开头)。 diff --git a/docs/cn/api-reference/openapi-test/index.mdx b/docs/cn/api-reference/openapi-test/index.mdx new file mode 100644 index 0000000..96ce9c9 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/index.mdx @@ -0,0 +1,11 @@ +--- +title: 'OpenAPI 引用测试' +description: '用于测试不同 OpenAPI 规范引用方式的测试集' +--- + +本章节测试 OpenAPI 规范引用方式: + +- **相对路径** – `openapi/openapi-example.json`(相对于项目根目录的路径) +- **绝对路径** – `/openapi/openapi-example.json`(从仓库根目录开始的绝对路径) +- **同目录** – `docs/api-reference/openapi-test/local-spec.json`(规范与 MDX 位于同一目录) +- **远程** – `https://petstore3.swagger.io/api/v3/openapi.json`(托管的 URL) diff --git a/docs/cn/api-reference/openapi-test/local-spec.json b/docs/cn/api-reference/openapi-test/local-spec.json new file mode 100644 index 0000000..d47423a --- /dev/null +++ b/docs/cn/api-reference/openapi-test/local-spec.json @@ -0,0 +1,29 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Local Same-Dir API", + "description": "Spec colocated with MDX page", + "version": "1.0.0" + }, + "servers": [{ "url": "https://api.example.com" }], + "paths": { + "/items": { + "get": { + "summary": "List items", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { "type": "object", "properties": { "id": { "type": "string" } } } + } + } + } + } + } + } + } + } +} diff --git a/docs/cn/api-reference/openapi-test/relative.mdx b/docs/cn/api-reference/openapi-test/relative.mdx new file mode 100644 index 0000000..2e03d75 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/relative.mdx @@ -0,0 +1,7 @@ +--- +title: '相对路径引用' +description: '使用相对于项目根目录的路径引用规范' +openapi: 'openapi/openapi-example.json GET /users' +--- + +引用 `openapi/openapi-example.json` —— 相对于项目根目录的路径(不以斜杠开头)。 diff --git a/docs/cn/api-reference/openapi-test/remote.mdx b/docs/cn/api-reference/openapi-test/remote.mdx new file mode 100644 index 0000000..86cc3cd --- /dev/null +++ b/docs/cn/api-reference/openapi-test/remote.mdx @@ -0,0 +1,7 @@ +--- +title: '远程引用' +description: '通过远程 URL 引用 OpenAPI 规范' +openapi: 'https://petstore3.swagger.io/api/v3/openapi.json GET /pets' +--- + +通过 URL 引用 Swagger Petstore 规范:`https://petstore3.swagger.io/api/v3/openapi.json`。 diff --git a/docs/cn/api-reference/openapi-test/same-dir.mdx b/docs/cn/api-reference/openapi-test/same-dir.mdx new file mode 100644 index 0000000..4e17f58 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/same-dir.mdx @@ -0,0 +1,7 @@ +--- +title: '同目录引用' +description: '引用与本 MDX 位于同一目录的规范' +openapi: 'local-spec.json GET /items' +--- + +引用 `local-spec.json`,它与本页面位于同一目录。从项目根目录起的路径为:`docs/api-reference/openapi-test/local-spec.json`。 diff --git a/docs/cn/development.mdx b/docs/cn/development.mdx new file mode 100644 index 0000000..10b2f68 --- /dev/null +++ b/docs/cn/development.mdx @@ -0,0 +1,93 @@ +--- +title: "本地开发" +description: "在本地预览改动以更新你的文档" +--- + + + **前置条件**: + + - Node.js 19 或更高版本 + - 一个包含 `docs.json` 文件的文档仓库 + + +按以下步骤在你所选的操作系统上安装并运行 Mintlify。我们同时支持 Windows 和 macOS。 + + + + ```bash + npm i -g mint + ``` + + + 进入包含 `docs.json` 文件的文档目录,然后运行以下命令: + + ```bash + mint dev + ``` + + 你的文档本地预览将在 `http://localhost:3000` 上可用。 + + + +## 自定义端口 + +Mintlify 默认使用 3000 端口。你可以通过 `--port` 参数自定义 Mintlify 运行的端口。例如,要在 3333 端口运行 Mintlify,可使用如下命令: + +```bash +mint dev --port 3333 +``` + +如果你尝试使用的端口已被占用,Mintlify 会使用下一个可用端口: + +```md +Port 3000 is already in use. Trying 3001 instead. +``` + +## Mintlify 版本 + +请注意,每个 CLI 版本都对应一个特定版本的 Mintlify。如果你的本地预览与生产版本不一致,请更新 CLI: + +```bash +npm mint update +``` + +## 校验链接 + +CLI 可以协助校验文档中的链接。要识别失效链接,请使用以下命令: + +```bash +mint broken-links +``` + +## 部署 + +如果部署成功,你将看到如下内容: + + + 部署确认信息的截图,显示所有检查均已通过。 + + +## 代码格式化 + +我们建议在 IDE 中使用扩展来识别并格式化 MDX。如果你是 VSCode 用户,可考虑使用 [MDX VSCode 扩展](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) 进行语法高亮,以及 [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) 进行代码格式化。 + +## 故障排查 + + + + 这可能是由于 node 版本过低导致的。请尝试以下操作: + + 1. 移除当前已安装的 CLI:`npm remove -g mint` + 2. 升级到 Node v19 或更高版本。 + 3. 重新安装 CLI:`npm i -g mint` + + + 解决方案:进入你的设备根目录,删除 `~/.mintlify` 文件夹,然后再次运行 `mint dev`。 + + + +想了解最新 CLI 版本中有什么变更?请查看 [CLI 更新日志](https://www.npmjs.com/package/mintlify?activeTab=versions)。 diff --git a/docs/cn/essentials/code.mdx b/docs/cn/essentials/code.mdx new file mode 100644 index 0000000..ec90df2 --- /dev/null +++ b/docs/cn/essentials/code.mdx @@ -0,0 +1,35 @@ +--- +title: '代码块' +description: '展示行内代码和代码块' +icon: 'code' +--- + +## 行内代码 + +要将某个 `单词` 或 `短语` 标记为代码,请用反引号 (`) 将其包围。 + +``` +To denote a `word` or `phrase` as code, enclose it in backticks (`). +``` + +## 代码块 + +使用 [围栏式代码块](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks),用三个反引号将代码包裹起来,并在起始反引号后写上代码片段的编程语言,以获得语法高亮。你也可以在编程语言之后选填代码块的名称。 + +```java HelloWorld.java +class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} +``` + +````md +```java HelloWorld.java +class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} +``` +```` diff --git a/docs/cn/essentials/images.mdx b/docs/cn/essentials/images.mdx new file mode 100644 index 0000000..0c57734 --- /dev/null +++ b/docs/cn/essentials/images.mdx @@ -0,0 +1,71 @@ +--- +title: '图片与嵌入' +description: '添加图片、视频和其他 HTML 元素' +icon: 'image' +--- + + + +## 图标图片来源 + +行内使用本地图片作为图标来源:,并与现有的内置图标路径进行对比:。 + +行内使用远程图片作为图标来源:。 + +```md + + + +``` + +## 图片 + +### 使用 Markdown + +[Markdown 语法](https://www.markdownguide.org/basic-syntax/#images) 允许你使用以下代码添加图片: + +```md +![title](/path/image.jpg) +``` + +请注意,图片文件大小必须小于 5MB。否则,我们建议将其托管在 [Cloudinary](https://cloudinary.com/) 或 [S3](https://aws.amazon.com/s3/) 等服务上,然后使用该 URL 来嵌入。 + +### 使用嵌入 + +如果想在图片上获得更多自定义能力,你也可以使用[嵌入](/docs/cn/writing-content/embed)来添加图片: + +```html + +``` + +## 嵌入和 HTML 元素 + + + +
+ + + +Mintlify 支持 [Markdown 中的 HTML 标签](https://www.markdownguide.org/basic-syntax/#html)。如果你更倾向于使用 HTML 标签而非 Markdown 语法,这非常有用,可让你以无限的灵活性创建文档。 + + + +### iFrame + +在文档中加载另一个 HTML 页面。最常用于嵌入视频。 + +```html + +``` diff --git a/docs/cn/essentials/markdown.mdx b/docs/cn/essentials/markdown.mdx new file mode 100644 index 0000000..400bd71 --- /dev/null +++ b/docs/cn/essentials/markdown.mdx @@ -0,0 +1,116 @@ +--- +title: 'Markdown 语法' +description: '使用标准 markdown 编写文本、标题与样式' +icon: 'text-size' +--- + +## 标题 + +最适合用作章节标题。 + +```md +## Titles +``` + +### 子标题 + +最适合用作小节标题。 + +```md +### Subtitles +``` + + + +每个**标题**和**子标题**都会创建一个锚点,并会出现在右侧的目录中。 + + + +## 文本格式 + +我们支持大多数 Markdown 格式。只需在文本两侧添加 `**`、`_` 或 `~` 即可设置格式。 + +| 样式 | 写法 | 效果 | +| -------- | ----------------- | --------------- | +| 加粗 | `**bold**` | **bold** | +| 斜体 | `_italic_` | _italic_ | +| 删除线 | `~strikethrough~` | ~strikethrough~ | + +你可以将这些组合使用。例如,写 `**_bold and italic_**` 可以得到**_粗斜体_**文本。 + +要编写上标和下标文本需要使用 HTML,即在文本两侧添加 `` 或 ``。 + +| 文本大小 | 写法 | 效果 | +| -------- | ------------------------ | ---------------------- | +| 上标 | `superscript` | superscript | +| 下标 | `subscript` | subscript | + +## 链接到页面 + +你可以通过将文本包裹在 `[]()` 中来添加链接。例如,写 `[link to google](https://google.com)` 即可生成 [link to google](https://google.com)。 + +指向文档内页面的链接需要使用根相对路径。也就是说,需要包含完整的文件夹路径。例如,`[link to text](/writing-content/text)` 链接到我们组件部分中名为 "Text" 的页面。 + +像 `[link to text](../text)` 这样的相对链接打开速度会较慢,因为我们无法轻松地对其进行优化。 + +## 引用块 + +### 单行 + +要创建引用块,请在段落前添加一个 `>`。 + +> Dorothy followed her through many of the beautiful rooms in her castle. + +```md +> Dorothy followed her through many of the beautiful rooms in her castle. +``` + +### 多行 + +> Dorothy followed her through many of the beautiful rooms in her castle. +> +> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood. + +```md +> Dorothy followed her through many of the beautiful rooms in her castle. +> +> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood. +``` + +### LaTeX + +Mintlify 通过 Latex 组件支持 [LaTeX](https://www.latex-project.org)。 + +8 x (vk x H1 - H2) = (0,1) + +```md +8 x (vk x H1 - H2) = (0,1) +``` + +## 折叠面板 + +当某个部分有一个简短的顶层回答,并在其中包含可选细节时,请使用嵌套折叠面板。 + +[跳转到常见检查](#deployment-troubleshooting:common-checks) + + + 从部署日志开始,并确认项目使用的是预期的分支。 + + + - 确认最新提交已完成构建。 + - 检查所需的环境变量是否已设置。 + - 修复配置更改后,重新运行部署。 + + + +```md + + Start with the deployment logs and confirm the project is using the expected branch. + + + - Confirm the latest commit has finished building. + - Check that required environment variables are set. + - Re-run the deployment after fixing configuration changes. + + +``` diff --git a/docs/cn/essentials/navigation.mdx b/docs/cn/essentials/navigation.mdx new file mode 100644 index 0000000..c10ff9e --- /dev/null +++ b/docs/cn/essentials/navigation.mdx @@ -0,0 +1,87 @@ +--- +title: '导航' +description: 'docs.json 中的 navigation 字段定义了导航菜单中显示的页面' +icon: 'map' +--- + +导航菜单是每个网站上都会显示的链接列表。 + +每次添加新页面时,你都可能需要更新 `docs.json`。页面不会自动出现。 + +## 导航语法 + +我们的导航语法是递归的,这意味着你可以创建嵌套的导航组。在页面名称中无需包含 `.mdx`。 + + + +```json Regular Navigation +"navigation": { + "tabs": [ + { + "tab": "Docs", + "groups": [ + { + "group": "Getting Started", + "pages": ["quickstart"] + } + ] + } + ] +} +``` + +```json Nested Navigation +"navigation": { + "tabs": [ + { + "tab": "Docs", + "groups": [ + { + "group": "Getting Started", + "pages": [ + "quickstart", + { + "group": "Nested Reference Pages", + "pages": ["nested-reference-page"] + } + ] + } + ] + } + ] +} +``` + + + +## 文件夹 + +只需将你的 MDX 文件放入文件夹,并在 `docs.json` 中更新路径即可。 + +例如,要在 `https://yoursite.com/your-folder/your-page` 提供一个页面,你需要创建一个名为 `your-folder` 的文件夹,并在其中放置一个名为 `your-page.mdx` 的 MDX 文件。 + + + +除非将其嵌套在另一个文件夹中,否则不能将 `api` 用作文件夹名称。Mintlify 使用 Next.js,它将顶层的 `api` 文件夹保留用于内部服务器调用。像 `api-reference` 这样的文件夹名称是可以接受的。 + + + +```json Navigation With Folder +"navigation": { + "tabs": [ + { + "tab": "Docs", + "groups": [ + { + "group": "Group Name", + "pages": ["your-folder/your-page"] + } + ] + } + ] +} +``` + +## 隐藏页面 + +未包含在 `docs.json` 中的 MDX 文件不会显示在侧边栏中,但仍可通过搜索栏访问,也可以通过直接链接访问。 diff --git a/docs/cn/essentials/reusable-snippets.mdx b/docs/cn/essentials/reusable-snippets.mdx new file mode 100644 index 0000000..3e670da --- /dev/null +++ b/docs/cn/essentials/reusable-snippets.mdx @@ -0,0 +1,102 @@ +--- +title: "可复用代码片段" +description: "通过可复用的自定义片段保持内容同步" +icon: "recycle" +--- + +import SnippetIntro from '/snippets/snippet-intro.mdx'; + + + +## 创建自定义片段 + +**前置条件**:你必须在 `snippets` 目录中创建你的片段文件。 + + + `snippets` 目录中的任何页面都将被视为片段,不会被渲染为独立页面。如果你想从片段创建一个独立页面,请将该片段导入到另一个文件中,并将其作为组件调用。 + + +### 默认导出 + +1. 在你的片段文件中添加希望在多个位置复用的内容。你也可以选择添加变量,这些变量可以在导入片段时通过 props 填入。 + +```mdx snippets/my-snippet.mdx +Hello world! This is my content I want to reuse across pages. My keyword of the +day is {word}. +``` + + + 你想要复用的内容必须放在 `snippets` 目录内,否则导入将无法正常工作。 + + +2. 将片段导入到目标文件中。 + +```mdx destination-file.mdx +--- +title: My title +description: My Description +--- + +import MySnippet from '/snippets/path/to/my-snippet.mdx'; + +## Header + +Lorem impsum dolor sit amet. + + +``` + +### 可复用变量 + +1. 从你的片段文件中导出一个变量: + +```mdx snippets/path/to/custom-variables.mdx +export const myName = 'my name'; + +export const myObject = { fruit: 'strawberries' }; +``` + +2. 在目标文件中导入该片段并使用该变量: + +```mdx destination-file.mdx +--- +title: My title +description: My Description +--- + +import { myName, myObject } from '/snippets/path/to/custom-variables.mdx'; + +Hello, my name is {myName} and I like {myObject.fruit}. +``` + +### 可复用组件 + +1. 在你的片段文件中,通过以箭头函数形式导出组件,创建一个接收 props 的组件。 + +```mdx snippets/custom-component.mdx +export const MyComponent = ({ title }) => ( +
+

{title}

+

... snippet content ...

+
+); +``` + + + MDX 不会在箭头函数体内进行编译。请尽可能坚持使用 HTML 语法,或者在需要使用 MDX 时使用默认导出。 + + +2. 将该片段导入到目标文件并传入 props。 + +```mdx destination-file.mdx +--- +title: My title +description: My Description +--- + +import { MyComponent } from '/snippets/custom-component.mdx'; + +Lorem ipsum dolor sit amet. + + +``` diff --git a/docs/cn/essentials/settings.mdx b/docs/cn/essentials/settings.mdx new file mode 100644 index 0000000..ba822db --- /dev/null +++ b/docs/cn/essentials/settings.mdx @@ -0,0 +1,310 @@ +--- +title: '全局设置' +description: 'Mintlify 通过 docs.json 文件让你完全控制文档的外观和体验' +icon: 'gear' +--- + +每个 Mintlify 站点都需要一个包含核心配置项的 `docs.json` 文件。请在下方了解更多[属性](#properties)。 + +## 属性 + + +你项目的名称。用作全局标题。 + +示例:`mintlify` + + + + + 一个包含所有页面分组的数组 + + + 分组的名称。 + + 示例:`Settings` + + + + 将作为页面的 Markdown 文件的相对路径。 + + 示例:`["customization", "page"]` + + + + + + + + Logo 图片的路径,或者包含 "light" 和 "dark" 模式下 logo 图片路径的对象 + + + 浅色模式下 logo 的路径 + + + 深色模式下 logo 的路径 + + + 点击 logo 后跳转到的链接 + + + + + + favicon 图片的路径 + + + + 全局主题的十六进制颜色代码 + + + 主色。最常用于浅色模式下的高亮内容、章节标题和强调色 + + + 深色模式下的主色。最常用于深色模式下的高亮内容、章节标题和强调色 + + + 用于重要按钮的主色 + + + 浅色和深色模式下的背景颜色 + + + 浅色模式下背景的十六进制颜色代码 + + + 深色模式下背景的十六进制颜色代码 + + + + + + + + 你希望在顶部栏中包含的链接的 `name` 和 `url` 数组 + + + 按钮的名称。 + + 示例:`Contact us` + + + 点击按钮后跳转的 URL。示例:`https://mintlify.com/docs` + + + + + + + + + Link 会显示一个按钮。GitHub 会显示提供的 URL 所对应仓库的信息,包括 GitHub Star 数量。 + + + 如果是 `link`:按钮跳转到的链接。 + + 如果是 `github`:用于加载 GitHub 信息的仓库链接。 + + + 按钮内的文本。仅当 `type` 为 `link` 时必填。 + + + + + + + 版本名称数组。仅当你希望在导航栏中通过下拉菜单显示不同版本的文档时使用。 + + + + anchor 数组,包含 `icon`、`color` 和 `url`。 + + + 用于标识 anchor 的 [Font Awesome](https://fontawesome.com/search?q=heart) 图标。 + + 示例:`comments` + + + anchor 标签的名称。 + + 示例:`Community` + + + 表明哪些页面属于该 anchor 的 URL 起始路径。通常这是你放置页面的文件夹名称。 + + + anchor 图标背景的十六进制颜色。也可以传入一个包含 `from` 和 `to` 属性的对象(两者均为十六进制颜色)来形成渐变色。 + + + 当你希望在选择对应文档版本之前隐藏某个 anchor 时使用。 + + + 如果你希望在直接链接他人进入该 anchor 内文档之前将其隐藏,请传入 `true`。 + + + 可选值之一:"brands"、"duotone"、"light"、"sharp-solid"、"solid" 或 "thin" + + + + + + + 覆盖最顶部 anchor 的默认配置。 + + + 最顶部 anchor 的名称 + + + Font Awesome 图标。 + + + 可选值之一:"brands"、"duotone"、"light"、"sharp-solid"、"solid" 或 "thin" + + + + + + 导航标签数组。 + + + 标签名称。 + + + 表明哪些页面属于该标签的 URL 起始路径。通常这是你放置页面的文件夹名称。 + + + + + + API 设置的配置。可在 [API 组件](/docs/cn/api-playground/demo) 中了解更多关于 API 页面的内容。 + + + 所有 API 端点的基础 URL。如果 `baseUrl` 是一个数组,将启用多个可供用户切换的基础 URL 选项。 + + + + + + 用于所有 API 端点的身份验证策略。 + + + API playground 中使用的身份验证参数名称。 + + 如果 method 为 `basic`,格式应为 `[usernameName]:[passwordName]` + + + 作为身份验证输入字段前缀的默认值。 + + 例如,若 `inputPrefix` 为 `AuthKey`,则身份验证字段的默认输入结果将继承为 `AuthKey`。 + + + + + + API playground 的配置 + + + + playground 是显示、隐藏,还是仅展示端点而不提供用户交互(`simple`)。 + + 更多内容请参阅 [playground 指南](/docs/cn/api-playground/demo) + + + + + + 启用此标志可确保 OpenAPI 页面中的键顺序与 OpenAPI 文件中定义的键顺序保持一致。 + + 此行为很快将默认启用,届时该字段将被弃用。 + + + + + + + 指向你的 OpenAPI 文件的 URL 或相对路径的字符串,或字符串数组。 + + 示例: + + ```json Absolute + "openapi": "https://example.com/openapi.json" + ``` + ```json Relative + "openapi": "/openapi.json" + ``` + ```json Multiple + "openapi": ["https://example.com/openapi1.json", "/openapi2.json", "/openapi3.json"] + ``` + + + + + + 社交媒体账号对象,其中键值对分别表示社交媒体平台及其账号 URL。 + + 示例: + ```json + { + "x": "https://x.com/mintlify", + "website": "https://mintlify.com" + } + ``` + + + 以下值之一:`website`、`facebook`、`x`、`discord`、`slack`、`github`、`linkedin`、`instagram`、`hacker-news` + + 示例:`x` + + + 社交平台的 URL。 + + 示例:`https://x.com/mintlify` + + + + + + 启用反馈按钮的配置 + + + + 启用一个按钮,允许用户通过 pull request 提交编辑建议 + + + 启用一个按钮,允许用户对文档提出 issue + + + + + + 自定义深色模式切换。 + + + 如果你希望对新用户始终显示浅色或深色模式,请进行设置。未设置时,我们默认采用与用户操作系统相同的模式。 + + + 设置为 true 可隐藏深色/浅色模式切换。你可以将 `isHidden` 与 `default` 结合使用,以强制让文档仅使用浅色或深色模式。例如: + + + ```json Only Dark Mode + "modeToggle": { + "default": "dark", + "isHidden": true + } + ``` + + ```json Only Light Mode + "modeToggle": { + "default": "light", + "isHidden": true + } + ``` + + + + + + + + + 在每个页面背后显示的背景图片。可参考 [Infisical](https://infisical.com/docs) 和 [FRPC](https://frpc.io) 的示例。 + diff --git a/docs/cn/implementation-exercises/async-export-jobs.mdx b/docs/cn/implementation-exercises/async-export-jobs.mdx new file mode 100644 index 0000000..32c7f91 --- /dev/null +++ b/docs/cn/implementation-exercises/async-export-jobs.mdx @@ -0,0 +1,117 @@ +--- +title: "实现异步导出任务" +description: "为工作区数据构建基于任务的 CSV 导出流程。" +icon: "file-arrow-down" +--- + +当你希望让编码代理为虚构的 Acorn Analytics 产品添加后台导出任务时,可以使用本指南。 + +## 需要构建的内容 + +- `POST /api/exports` 用于创建新的导出任务 +- `GET /api/exports/:id` 用于轮询任务状态 +- `GET /api/exports/:id/download` 用于获取已完成的文件 +- 一个用于生成 CSV 导出的后台 worker + +## 创建导出任务 + +`POST /api/exports` + +请求体: + +```json +{ + "resource": "events", + "format": "csv", + "filters": { + "project_id": "proj_123", + "from": "2026-04-01T00:00:00Z", + "to": "2026-04-06T00:00:00Z" + } +} +``` + +行为: + +- 校验筛选条件和资源类型 +- 创建一条新的导出任务记录 +- 将任务入队以便后台处理 +- 立即返回 `202 Accepted` +- 如果调用方在 10 秒内未收到响应,它应能安全地重试该请求 + +响应: + +```json +{ + "id": "exp_4821", + "status": "queued", + "status_url": "/api/exports/exp_4821" +} +``` + +## 任务生命周期 + +任务会经历以下状态: + +- `queued` +- `running` +- `completed` +- `failed` + +状态响应: + +```json +{ + "id": "exp_4821", + "status": "running", + "progress": 42 +} +``` + +当导出完成时,返回: + +```json +{ + "id": "exp_4821", + "status": "completed", + "download_url": "/api/exports/exp_4821/download", + "expires_at": "2026-04-07T18:24:11Z" +} +``` + +## Worker 要求 + +- 在创建任务时对提交的筛选载荷进行快照 +- 将行数据流式写入 CSV 文件,而不是将完整导出缓存在内存中 +- 在写入数据块时更新 `progress` +- 如果生成意外中止,将任务标记为 `failed` 并附带错误信息 +- 已完成的产物保留 24 小时 + +## 下载端点 + +`GET /api/exports/:id/download` + +- 要求请求用户与任务属于同一工作区 +- 如果任务尚未完成,返回 `404` +- 如果产物已过期,返回 `410` +- 以 `text/csv` 流式返回文件 + +## 建议的表结构 + +```sql +create table export_jobs ( + id text primary key, + workspace_id text not null, + requested_by text not null, + resource text not null, + format text not null, + filters jsonb not null, + status text not null, + progress integer not null default 0, + artifact_path text, + error_message text, + expires_at timestamptz, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now() +); +``` diff --git a/docs/cn/implementation-exercises/signed-webhooks.mdx b/docs/cn/implementation-exercises/signed-webhooks.mdx new file mode 100644 index 0000000..50e0555 --- /dev/null +++ b/docs/cn/implementation-exercises/signed-webhooks.mdx @@ -0,0 +1,97 @@ +--- +title: "实现签名 webhook" +description: "为计费事件添加入站 webhook 验证。" +icon: "shield-check" +--- + +当你希望让编码代理为虚构的 Acorn Billing API 添加签名 webhook 支持时,可以使用本指南。 + +## 需要构建的内容 + +- 一个 `POST /api/webhooks/acorn-billing` 端点 +- 在执行任何业务逻辑之前进行签名校验 +- 支持 `invoice.paid`、`invoice.failed` 和 `subscription.canceled` +- 通过投递 ID 请求头进行投递去重 + +## 请求格式 + +Acorn Billing 发送的 JSON webhook 带有以下请求头: + +- `x-acorn-delivery-id`:本次投递尝试的唯一 ID +- `x-acorn-timestamp`:Unix 时间戳(以秒为单位) +- `x-acorn-signature`:HMAC SHA-256 十六进制摘要 + +请求体示例如下: + +```json +{ + "id": "evt_9f2c0c0d", + "type": "invoice.paid", + "created_at": "2026-04-01T18:24:11Z", + "data": { + "invoice_id": "inv_4821", + "customer_id": "cus_1942", + "amount": 12900, + "currency": "usd" + } +} +``` + +## 验证流程 + +1. 解析 JSON 请求体。 +2. 将签名载荷构造为 `${timestamp}.${JSON.stringify(body)}`。 +3. 使用 HMAC SHA-256 和 `ACORN_WEBHOOK_SECRET` 计算预期摘要。 +4. 使用常量时间比较将预期摘要与 `x-acorn-signature` 进行对比。 +5. 拒绝时间戳早于 5 分钟之前的请求。 + +```ts +import { createHmac, timingSafeEqual } from 'node:crypto'; + +export function verifyAcornSignature(body: unknown, timestamp: string, signature: string) { + const payload = `${timestamp}.${JSON.stringify(body)}`; + const expected = createHmac('sha256', process.env.ACORN_WEBHOOK_SECRET!) + .update(payload) + .digest('hex'); + + return timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); +} +``` + +## 处理器行为 + +- 一旦签名有效且事件已入队,立即返回 `200 OK`。 +- 存储 `x-acorn-delivery-id`,以便忽略重复投递。 +- 按 `type` 路由事件。 +- 不要让 webhook 响应阻塞在下游 API 调用上。 + +## 事件处理规则 + +### `invoice.paid` + +- 将发票标记为已支付 +- 添加一条付款时间线记录 +- 向客户发送收据邮件 + +### `invoice.failed` + +- 将发票标记为逾期 +- 调度重试通知工作流 + +### `subscription.canceled` + +- 记录取消时间 +- 在计费周期结束时撤销高级访问权限 + +## 本地测试 + +在测试时使用以下载荷配合本地签名器: + +```bash +curl -X POST http://localhost:3000/api/webhooks/acorn-billing \ + -H "content-type: application/json" \ + -H "x-acorn-delivery-id: del_123" \ + -H "x-acorn-timestamp: 1712426400" \ + -H "x-acorn-signature: " \ + -d '{"id":"evt_9f2c0c0d","type":"invoice.paid","data":{"invoice_id":"inv_4821"}}' +``` diff --git a/docs/cn/implementation-exercises/team-feature-flags.mdx b/docs/cn/implementation-exercises/team-feature-flags.mdx new file mode 100644 index 0000000..d637740 --- /dev/null +++ b/docs/cn/implementation-exercises/team-feature-flags.mdx @@ -0,0 +1,97 @@ +--- +title: "实现团队功能开关" +description: "添加按团队作用域并支持环境定向的功能开关。" +icon: "toggle-on" +--- + +当你希望让编码代理为虚构的 Acorn Workspace 产品添加按团队作用域的功能开关时,可以使用本指南。 + +## 需要构建的内容 + +- 一个具有工作区级默认值的功能开关模型 +- 可选的团队级覆盖 +- 针对 `development`、`staging` 和 `production` 的可选环境级覆盖 +- 一个类似 `isFeatureEnabled(flagKey, context)` 的辅助函数 +- 用于渐进式发布的百分比灰度 + +## 数据模型 + +使用如下结构: + +```ts +type FeatureFlag = { + key: string; + enabled: boolean; + rolloutPercentage?: number; + environment?: 'development' | 'staging' | 'production'; + teamId?: string; +}; +``` + +只要每条记录针对不同的作用域,你就可以为同一个 `key` 存储多条记录。 + +## 评估上下文 + +辅助函数应接受: + +```ts +type EvaluationContext = { + workspaceId: string; + teamId?: string; + environment: 'development' | 'staging' | 'production'; + userId: string; +}; +``` + +## 评估规则 + +1. 从工作区级开关开始。 +2. 检查是否存在针对同一 key 的环境级开关。 +3. 检查是否存在针对同一 key 的团队级开关。 +4. 如果匹配的开关设置了 `rolloutPercentage`,将 `userId` 哈希到 `0` 到 `99` 的桶中。 +5. 当用户落在灰度区间内时返回 `true`。 + +## 管理行为 + +- 产品管理员可以创建和编辑开关 +- 团队负责人可以编辑自己团队的团队级覆盖 +- 变更应无需重启服务器即可生效 +- 审计日志应记录是谁在何时修改了开关 + +## API 形态 + +### 创建开关 + +`POST /api/feature-flags` + +```json +{ + "key": "new-sidebar", + "enabled": true, + "environment": "production", + "teamId": "team_design" +} +``` + +### 评估开关 + +`POST /api/feature-flags/evaluate` + +```json +{ + "key": "new-sidebar", + "context": { + "workspaceId": "ws_123", + "teamId": "team_design", + "environment": "production", + "userId": "user_42" + } +} +``` + +## 实现说明 + +- 对于同一用户和同一开关,保持评估辅助函数的确定性 +- 短时间缓存活跃开关集,以减少数据库读取 +- 评估端点同时返回布尔结果和匹配到的开关记录 +- 针对灰度边界和缺失的团队 ID 添加单元测试 diff --git a/docs/cn/index.mdx b/docs/cn/index.mdx new file mode 100644 index 0000000..cb66847 --- /dev/null +++ b/docs/cn/index.mdx @@ -0,0 +1,100 @@ +--- +title: "简介" +description: "欢迎来到文档的新家" +de_link: "https://developers.example.de/docs" +fr_link: "https://developers.example.fr/docs" +es_link: "https://developers.example.es/docs" +--- + +## 开始设置 + +几分钟内即可让你的文档站点运行起来 + + + 按照三步快速入门指南操作 + + +## 打造你的风格 + +打造一个外观出色、助力用户的文档站点。 + + + + 在本地编辑你的文档并实时预览。 + + + 自定义站点的设计与配色,以匹配你的品牌。 + + + 组织你的文档,帮助用户快速找到所需内容并成功使用你的产品。 + + + 从 OpenAPI 规范自动生成 API 文档。 + + + +## 创建精美页面 + +打造世界级文档所需的一切。 + + + + 使用 MDX 来美化你的文档页面。 + + + 添加示例代码,演示如何使用你的产品。 + + + 展示图片和其他媒体内容。 + + + 一次编写,在整个文档中复用。 + + + +## 需要灵感? + + + 浏览我们精选的优秀文档站点案例。 + diff --git a/docs/cn/quickstart.mdx b/docs/cn/quickstart.mdx new file mode 100644 index 0000000..436cf62 --- /dev/null +++ b/docs/cn/quickstart.mdx @@ -0,0 +1,158 @@ +--- +title: "快速入门" +description: "几分钟内开始构建出色的文档" +timestamp: "true" +mode: "frame" +de_link: "https://developers.example.de/docs/quickstart" +fr_link: "https://developers.example.fr/docs/quickstart" +es_link: "https://developers.example.es/docs/quickstart" +--- + +## 三步快速上手 + +在本地运行你的文档站点以预览改动。最佳方式是按顺序完成每一步;在这里打好基础,后续会事半功倍。确保充分理解每一步后再进行下一步。 + +### 第 1 步:设置本地环境 + + + + 在引导流程中,如果你之前没有,会为你创建一个包含文档内容的 GitHub 仓库。你可以在[控制台](https://dashboard.mintlify.com)中找到该仓库的链接。 + + 要将仓库克隆到本地以便进行修改和预览,请参考 GitHub 文档中的[克隆仓库](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository)指南。 + + + 1. 安装 Mintlify CLI:`npm i -g mint` + 2. 进入你的文档目录并运行:`mint dev` + 3. 打开 `http://localhost:3000` 查看实时文档! + + + 编辑文件时,预览会自动更新。 + + + + +### 第 2 步:部署你的改动 + + + + 从[控制台](https://dashboard.mintlify.com/settings/organization/github-app)安装 Mintlify GitHub 应用。 + + 我们的 GitHub 应用会自动将你的改动部署到文档站点,你无需自行管理部署流程。 + + + 作为第一次改动,我们来更新文档站点的名称和配色。 + + 1. 在编辑器中打开 `docs.json`。 + 2. 将 `"name"` 字段改为你的项目名称。 + 3. 更新 `"colors"` 以匹配你的品牌。 + 4. 保存后,在 `http://localhost:3000` 中可即时看到变化。 + + + 试着更改主色调,立刻看到效果! + + + + +### 第 3 步:正式上线 + + + 1. 提交并推送你的改动。 + 2. 你的文档会在片刻之间更新并上线! + + +hello hello hello + +## 下一步 + +文档运行起来后,继续探索这些关键功能: + +| 功能 | 描述 | 链接 | +| ----------- | --------------- | ---------------------------------------------------------- | +| 编写内容 | 学习 MDX 语法 | [/essentials/markdown](/essentials/markdown) | +| 自定义样式 | 匹配你的品牌 | [/essentials/settings](/essentials/settings) | +| 代码示例 | 语法高亮 | [/essentials/code](/essentials/code) | +| API 文档 | OpenAPI 集成 | [/api-reference/introduction](/api-reference/introduction) | + + + **示例 XML 订阅源**: + 下载 feed.xml + + 来查看静态 XML 文件是如何提供服务的。 + + + + + 学习 MDX 语法并开始编写你的文档。 + + + 让你的文档完美契合品牌风格。 + + + 添加带语法高亮的代码块。 + + + 从 OpenAPI 规范自动生成 API 文档。 + + + 查看 Get Plants 端点文档。 + + + 查看用户 API 文档。 + + + +## 核心功能 + + + + - 创建并组织 MDX 文件 + - 使用 frontmatter 添加元数据 + - 添加图片和资源 + - 使用标题和分节进行结构化 + + + - 配置站点配色和品牌元素 + - 自定义导航结构 + - 添加自定义 CSS 和组件 + - 配置搜索功能 + + + - 热重载预览服务器 + - 通过 GitHub 自动部署 + - 版本控制集成 + - 用于常见任务的 CLI 命令 + + + - 带语法高亮的代码块 + - 交互式 API 文档 + - 搜索与导航 + - 移动端自适应设计 + + + +## 快速小贴士 + + + + - 全局安装 Mintlify CLI + - 将仓库克隆到本地 + - 运行 `mint dev` 进行预览 + - 修改后即时查看更新 + + + - 将内容有序组织到文件夹中 + - 使用具描述性的文件名 + - 撰写清晰、简明的文档 + - 先在本地测试你的改动 + + + - 检查 `docs.json` 配置 + - 验证文件路径和链接 + - 查看控制台错误信息 + - 参阅 Mintlify 文档 + + + + + **需要帮助?** 参阅我们的[完整文档](https://mintlify.com/docs)或加入我们的[社区](https://mintlify.com/community)。 + diff --git a/docs/cn/snippets/snippet-intro.mdx b/docs/cn/snippets/snippet-intro.mdx new file mode 100644 index 0000000..7ae5b7c --- /dev/null +++ b/docs/cn/snippets/snippet-intro.mdx @@ -0,0 +1 @@ +软件开发的核心原则之一是 DRY(Don't Repeat Yourself,不要重复自己)。这一原则同样适用于文档。如果你发现自己在多处重复相同的内容,可以考虑创建自定义片段,以保持内容同步。