diff --git a/docs.json b/docs.json index a70122a..45f55c4 100644 --- a/docs.json +++ b/docs.json @@ -197,6 +197,100 @@ ] } ] + }, + { + "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/explode-false-query", + "docs/cn/api-reference/openapi-test/explode-true-query", + "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/academic-standards-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..8f3bd50 --- /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 官方的 CLI 工具。本指南将帮助你设置 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 documentation + +## Working relationship +- You can push back on ideas-this can lead to better documentation. Cite sources and explain your reasoning when you do so +- ALWAYS ask for clarification rather than making assumptions +- NEVER lie, guess, or make up information + +## Project context +- Format: MDX files with YAML frontmatter +- Config: docs.json for navigation, theme, settings +- Components: Mintlify components + +## Content strategy +- Document just enough for user success - not too much, not too little +- Prioritize accuracy and usability of information +- Make content evergreen when possible +- Search for existing information before adding new content. Avoid duplication unless it is done for a strategic reason +- Check existing patterns for consistency +- Start by making the smallest reasonable changes + +## Frontmatter requirements for pages +- title: Clear, descriptive page title +- description: Concise summary for SEO/navigation + +## Writing standards +- Second-person voice ("you") +- Prerequisites at start of procedural content +- Test all code examples before publishing +- Match style and formatting of existing pages +- Include both basic and advanced use cases +- Language tags on all code blocks +- Alt text on all images +- Relative paths for internal links + +## Git workflow +- NEVER use --no-verify when committing +- Ask how to handle uncommitted changes before starting +- Create a new branch when no clear branch exists for changes +- Commit frequently throughout development +- NEVER skip or disable pre-commit hooks + +## Do not +- Skip frontmatter on any MDX file +- Use absolute URLs for internal links +- Include untested code examples +- Make assumptions - always ask for clarification +```` diff --git a/docs/cn/ai-tools/cursor.mdx b/docs/cn/ai-tools/cursor.mdx new file mode 100644 index 0000000..17c5602 --- /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 technical writing rule + +You are an AI writing assistant specialized in creating exceptional technical documentation using Mintlify components and following industry-leading technical writing practices. + +## Core writing principles + +### Language and style requirements + +- Use clear, direct language appropriate for technical audiences +- Write in second person ("you") for instructions and procedures +- Use active voice over passive voice +- Employ present tense for current states, future tense for outcomes +- Avoid jargon unless necessary and define terms when first used +- Maintain consistent terminology throughout all documentation +- Keep sentences concise while providing necessary context +- Use parallel structure in lists, headings, and procedures + +### Content organization standards + +- Lead with the most important information (inverted pyramid structure) +- Use progressive disclosure: basic concepts before advanced ones +- Break complex procedures into numbered steps +- Include prerequisites and context before instructions +- Provide expected outcomes for each major step +- Use descriptive, keyword-rich headings for navigation and SEO +- Group related information logically with clear section breaks + +### User-centered approach + +- Focus on user goals and outcomes rather than system features +- Anticipate common questions and address them proactively +- Include troubleshooting for likely failure points +- Write for scannability with clear headings, lists, and white space +- Include verification steps to confirm success + +## Mintlify component reference + +### Callout components + +#### Note - Additional helpful information + + +Supplementary information that supports the main content without interrupting flow + + +#### Tip - Best practices and pro tips + + +Expert advice, shortcuts, or best practices that enhance user success + + +#### Warning - Important cautions + + +Critical information about potential issues, breaking changes, or destructive actions + + +#### Info - Neutral contextual information + + +Background information, context, or neutral announcements + + +#### Check - Success confirmations + + +Positive confirmations, successful completions, or achievement indicators + + +### Code components + +#### Single code block + +Example of a single code block: + +```javascript config.js +const apiConfig = { + baseURL: 'https://api.example.com', + timeout: 5000, + headers: { + 'Authorization': `Bearer ${process.env.API_TOKEN}` + } +}; +``` + +#### Code group with multiple languages + +Example of a code group: + + +```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' +``` + + +#### Request/response examples + +Example of request/response documentation: + + +```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" +} +``` + + +### Structural components + +#### Steps for procedures + +Example of step-by-step instructions: + + + + Run `npm install` to install required packages. + + + Verify installation by running `npm list`. + + + + + Create a `.env` file with your API credentials. + + ```bash + API_KEY=your_api_key_here + ``` + + + Never commit API keys to version control. + + + + +#### Tabs for alternative content + +Example of tabbed content: + + + + ```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 + ``` + + + +#### Accordions for collapsible content + +Example of accordion groups: + + + + - **Firewall blocking**: Ensure ports 80 and 443 are open + - **Proxy configuration**: Set HTTP_PROXY environment variable + - **DNS resolution**: Try using 8.8.8.8 as DNS server + + + + ```javascript + const config = { + performance: { cache: true, timeout: 30000 }, + security: { encryption: 'AES-256' } + }; + ``` + + + +### Cards and columns for emphasizing information + +Example of cards and card groups: + + +Complete walkthrough from installation to your first API call in under 10 minutes. + + + + + Learn how to authenticate requests using API keys or JWT tokens. + + + + Understand rate limits and best practices for high-volume usage. + + + +### API documentation components + +#### Parameter fields + +Example of parameter documentation: + + +Unique identifier for the user. Must be a valid UUID v4 format. + + + +User's email address. Must be valid and unique within the system. + + + +Maximum number of results to return. Range: 1-100. + + + +Bearer token for API authentication. Format: `Bearer YOUR_API_KEY` + + +#### Response fields + +Example of response field documentation: + + +Unique identifier assigned to the newly created user. + + + +ISO 8601 formatted timestamp of when the user was created. + + + +List of permission strings assigned to this user. + + +#### Expandable nested fields + +Example of nested field documentation: + + +Complete user object with all associated data. + + + + User profile information including personal details. + + + + User's first name as entered during registration. + + + + URL to user's profile picture. Returns null if no avatar is set. + + + + + + +### Media and advanced components + +#### Frames for images + +Wrap all images in frames: + + +Main dashboard showing analytics overview + + + +Analytics dashboard with charts + + +#### Videos + +Use the HTML video element for self-hosted video content: + + + +Embed YouTube videos using iframe elements: + + + +#### Tooltips + +Example of tooltip usage: + + +API + + +#### Updates + +Use updates for changelogs: + + +## New features +- Added bulk user import functionality +- Improved error messages with actionable suggestions + +## Bug fixes +- Fixed pagination issue with large datasets +- Resolved authentication timeout problems + + +## Required page structure + +Every documentation page must begin with YAML frontmatter: + +```yaml +--- +title: "Clear, specific, keyword-rich title" +description: "Concise description explaining page purpose and value" +--- +``` + +## Content quality standards + +### Code examples requirements + +- Always include complete, runnable examples that users can copy and execute +- Show proper error handling and edge case management +- Use realistic data instead of placeholder values +- Include expected outputs and results for verification +- Test all code examples thoroughly before publishing +- Specify language and include filename when relevant +- Add explanatory comments for complex logic +- Never include real API keys or secrets in code examples + +### API documentation requirements + +- Document all parameters including optional ones with clear descriptions +- Show both success and error response examples with realistic data +- Include rate limiting information with specific limits +- Provide authentication examples showing proper format +- Explain all HTTP status codes and error handling +- Cover complete request/response cycles + +### Accessibility requirements + +- Include descriptive alt text for all images and diagrams +- Use specific, actionable link text instead of "click here" +- Ensure proper heading hierarchy starting with H2 +- Provide keyboard navigation considerations +- Use sufficient color contrast in examples and visuals +- Structure content for easy scanning with headers and lists + +## Component selection logic + +- Use **Steps** for procedures and sequential instructions +- Use **Tabs** for platform-specific content or alternative approaches +- Use **CodeGroup** when showing the same concept in multiple programming languages +- Use **Accordions** for progressive disclosure of information +- Use **RequestExample/ResponseExample** specifically for API endpoint documentation +- Use **ParamField** for API parameters, **ResponseField** for API responses +- Use **Expandable** for nested object properties or hierarchical information +```` diff --git a/docs/cn/ai-tools/windsurf.mdx b/docs/cn/ai-tools/windsurf.mdx new file mode 100644 index 0000000..4b4f424 --- /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 technical writing rule + +## Project context + +- This is a documentation project on the Mintlify platform +- We use MDX files with YAML frontmatter +- Navigation is configured in `docs.json` +- We follow technical writing best practices + +## Writing standards + +- Use second person ("you") for instructions +- Write in active voice and present tense +- Start procedures with prerequisites +- Include expected outcomes for major steps +- Use descriptive, keyword-rich headings +- Keep sentences concise but informative + +## Required page structure + +Every page must start with frontmatter: + +```yaml +--- +title: "Clear, specific title" +description: "Concise description for SEO and navigation" +--- +``` + +## Mintlify components + +### Callouts + +- `` for helpful supplementary information +- `` for important cautions and breaking changes +- `` for best practices and expert advice +- `` for neutral contextual information +- `` for success confirmations + +### Code examples + +- When appropriate, include complete, runnable examples +- Use `` for multiple language examples +- Specify language tags on all code blocks +- Include realistic data, not placeholders +- Use `` and `` for API docs + +### Procedures + +- Use `` component for sequential instructions +- Include verification steps with `` components when relevant +- Break complex procedures into smaller steps + +### Content organization + +- Use `` for platform-specific content +- Use `` for progressive disclosure +- Use `` and `` for highlighting content +- Wrap images in `` components with descriptive alt text + +## API documentation requirements + +- Document all parameters with `` +- Show response structure with `` +- Include both success and error examples +- Use `` for nested object properties +- Always include authentication examples + +## Quality standards + +- Test all code examples before publishing +- Use relative paths for internal links +- Include alt text for all images +- Ensure proper heading hierarchy (start with h2) +- Check existing patterns for consistency +```` 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..f69590f --- /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/academic-standards-search.mdx b/docs/cn/api-reference/endpoint/academic-standards-search.mdx new file mode 100644 index 0000000..345cce9 --- /dev/null +++ b/docs/cn/api-reference/endpoint/academic-standards-search.mdx @@ -0,0 +1,4 @@ +--- +title: '搜索学术标准' +openapi: 'GET /academic-standards/search' +--- 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..c7e9078 --- /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..f19d86a --- /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..fa4123c --- /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..6cbbb42 --- /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/explode-false-query.mdx b/docs/cn/api-reference/openapi-test/explode-false-query.mdx new file mode 100644 index 0000000..f4eb224 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/explode-false-query.mdx @@ -0,0 +1,15 @@ +--- +title: 'Explode False 查询参数' +description: '测试以逗号分隔的 OpenAPI 数组查询参数' +openapi: 'local-spec.json GET /tweets' +--- + +本页面测试使用 `style: form` 和 `explode: false` 的数组查询参数。 + +Playground 请求应将多个 `tweet.fields` 值序列化为: + +```text +tweet.fields=author_id,attachments,id,text +``` + +而不应将相同的选择序列化为多个重复的 `tweet.fields` 查询参数。 diff --git a/docs/cn/api-reference/openapi-test/explode-true-query.mdx b/docs/cn/api-reference/openapi-test/explode-true-query.mdx new file mode 100644 index 0000000..fc61b52 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/explode-true-query.mdx @@ -0,0 +1,15 @@ +--- +title: 'Explode True 查询参数' +description: '测试重复出现的 OpenAPI 数组查询参数' +openapi: 'local-spec.json GET /tweets-exploded' +--- + +本页面测试使用 `style: form` 和 `explode: true` 的数组查询参数。 + +Playground 请求应将多个 `tweet.fields` 值序列化为重复的查询参数: + +```text +tweet.fields=author_id&tweet.fields=attachments&tweet.fields=id&tweet.fields=text +``` + +可使用本页面与 `explode: false` 版本进行对比,后者应将相同的选择序列化为单个以逗号分隔的 `tweet.fields` 查询参数。 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..bcebb58 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/index.mdx @@ -0,0 +1,13 @@ +--- +title: 'OpenAPI 引用测试' +description: '针对不同 OpenAPI 规范引用方式的测试集' +--- + +本节用于测试 OpenAPI 规范引用: + +- **相对路径** – `openapi/openapi-example.json`(相对于项目根目录的路径) +- **绝对路径** – `/openapi/openapi-example.json`(从仓库根目录开始的绝对路径) +- **同目录** – `docs/api-reference/openapi-test/local-spec.json`(规范与 MDX 位于同一目录) +- **Explode false 查询** – `tweet.fields` 数组查询参数序列化为以逗号分隔的值 +- **Explode true 查询** – `tweet.fields` 数组查询参数序列化为重复的参数 +- **远程** – `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..3e11c48 --- /dev/null +++ b/docs/cn/api-reference/openapi-test/local-spec.json @@ -0,0 +1,103 @@ +{ + "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" } } } + } + } + } + } + } + } + }, + "/tweets": { + "get": { + "summary": "Search tweets", + "description": "Tests comma-delimited query serialization for multi-value fields parameters.", + "parameters": [ + { + "name": "tweet.fields", + "in": "query", + "description": "Select tweet fields. With form style and explode disabled, multiple selected values should serialize as `tweet.fields=author_id,attachments,id,text`.", + "required": false, + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": ["author_id", "attachments", "id", "text"] + } + }, + "example": ["author_id", "attachments", "id", "text"] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { "type": "object", "properties": { "id": { "type": "string" } } } + } + } + } + } + } + } + }, + "/tweets-exploded": { + "get": { + "summary": "Search tweets with exploded fields", + "description": "Tests repeated query parameter serialization for multi-value fields parameters.", + "parameters": [ + { + "name": "tweet.fields", + "in": "query", + "description": "Select tweet fields. With form style and explode enabled, multiple selected values should serialize as repeated `tweet.fields` query parameters.", + "required": false, + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": ["author_id", "attachments", "id", "text"] + } + }, + "example": ["author_id", "attachments", "id", "text"] + } + ], + "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..f655580 --- /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..8c6dbaf --- /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..969c4d8 --- /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..71bfc53 --- /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..233ff6a --- /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..0a5290f --- /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 并进行嵌入。 + +### 使用嵌入 + +要获得更高的图片自定义能力,你也可以使用[嵌入](/writing-content/embed)来添加图片: + +```html + +``` + +## 嵌入和 HTML 元素 + + + +
+ + + +Mintlify 支持 [Markdown 中的 HTML 标签](https://www.markdownguide.org/basic-syntax/#html)。如果你更喜欢使用 HTML 标签而非 Markdown 语法,这会很有帮助,并让你能够灵活无限地创建文档。 + + + +### iFrames + +在文档中加载另一个 HTML 页面。最常用于嵌入视频。 + +```html + +``` diff --git a/docs/cn/essentials/markdown.mdx b/docs/cn/essentials/markdown.mdx new file mode 100644 index 0000000..87b5a57 --- /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_**` 可以得到 **_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..f675141 --- /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..0d468cd --- /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..ba02964 --- /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 stars 数量。 + + + 如果是 `link`:按钮链接到的地址。 + + 如果是 `github`:用于加载 GitHub 信息的仓库链接。 + + + 按钮内的文字。仅当 `type` 为 `link` 时才需要。 + + + + + + + 版本名称数组。仅当你希望在导航栏中通过下拉菜单展示不同版本的文档时才使用此项。 + + + + 锚点数组,包含 `icon`、`color` 和 `url`。 + + + 用于展示该锚点的 [Font Awesome](https://fontawesome.com/search?q=heart) 图标。 + + 示例:`comments` + + + 锚点标签的名称。 + + 示例:`Community` + + + 标识哪些页面属于该锚点的 URL 前缀。通常是你存放这些页面的文件夹名。 + + + 锚点图标背景的十六进制颜色。也可以通过传入一个包含 `from` 和 `to`(均为十六进制颜色)的对象来设置为渐变色。 + + + 当你希望在选中正确的文档版本之前隐藏某个锚点时使用。 + + + 如果你希望该锚点在没有直接链接到其中的文档之前一直保持隐藏,请传入 `true`。 + + + 可选值之一:"brands"、"duotone"、"light"、"sharp-solid"、"solid" 或 "thin" + + + + + + + 覆盖最顶部锚点的默认配置。 + + + 最顶部锚点的名称 + + + Font Awesome 图标。 + + + 可选值之一:"brands"、"duotone"、"light"、"sharp-solid"、"solid" 或 "thin" + + + + + + 导航标签页数组。 + + + 标签页标签的名称。 + + + 标识哪些页面属于该标签页的 URL 前缀。通常是你存放这些页面的文件夹名。 + + + + + + API 设置的配置。在 [API Components](/api-playground/demo) 中了解更多关于 API 页面的信息。 + + + 所有 API 端点的基础 url。如果 `baseUrl` 是一个数组,将启用多个基础 url 选项,供用户切换。 + + + + + + 所有 API 端点所使用的认证策略。 + + + 在 API playground 中使用的认证参数的名称。 + + 如果 method 为 `basic`,格式应为 `[usernameName]:[passwordName]` + + + 作为认证输入字段默认前缀的默认值。 + + 例如,`inputPrefix` 设为 `AuthKey` 时,认证字段的默认输入结果会继承为 `AuthKey`。 + + + + + + API playground 的配置 + + + + playground 的展示方式:显示、隐藏,或仅显示端点而不提供用户交互(`simple`) + + 在 [playground 指南](/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"] + ``` + + + + + + 一个社交媒体账号对象,其中 key:property 对分别代表社交媒体平台和账号 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..540fede --- /dev/null +++ b/docs/cn/implementation-exercises/async-export-jobs.mdx @@ -0,0 +1,117 @@ +--- +title: "实现异步导出任务" +description: "为工作区数据构建基于任务的 CSV 导出流程。" +icon: "file-arrow-down" +--- + +当你希望让编码 agent 为虚构的 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" + } +} +``` + +行为: + +- 校验 filters 和 resource 类型 +- 创建一条新的导出任务记录 +- 将任务入队以便后台处理 +- 立即返回 `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..60ab94a --- /dev/null +++ b/docs/cn/implementation-exercises/signed-webhooks.mdx @@ -0,0 +1,97 @@ +--- +title: "实现签名 webhooks" +description: "为账单事件添加入站 webhook 校验。" +icon: "shield-check" +--- + +当你希望让编码 agent 为虚构的 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..a18d6aa --- /dev/null +++ b/docs/cn/implementation-exercises/team-feature-flags.mdx @@ -0,0 +1,97 @@ +--- +title: "实现团队特性开关" +description: "添加按团队范围划分、支持环境定向的特性开关。" +icon: "toggle-on" +--- + +当你希望让编码 agent 为虚构的 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" + } +} +``` + +## 实现注意事项 + +- 对于相同的用户和开关,保持评估辅助函数的确定性 +- 将当前生效的开关集合短期缓存,以减少数据库读取 +- 评估端点应同时返回布尔结果和匹配到的开关记录 +- 围绕灰度边界和缺失的 team ID 添加单元测试 diff --git a/docs/cn/index.mdx b/docs/cn/index.mdx new file mode 100644 index 0000000..14d6363 --- /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" +--- + +## 开始设置 + +在几分钟内让你的文档站点上线运行。 + + + 按照我们的三步快速入门指南操作。 + + +## 编写内容 + +了解可在页面中使用的语法和组件参考。 + + + + 标题、文本格式、链接、提示框、折叠面板以及其他 MDX 组件。 + + + 语法高亮、代码组以及行内代码格式化。 + + + 在你的页面中嵌入图片、视频以及其他媒体。 + + + 内容只编写一次,即可在多个页面中复用。 + + + +## 打造你的专属站点 + +设计一个外观出色并能赋能用户的文档站点。 + + + + 在本地编辑文档并实时预览效果。 + + + 自定义站点的设计和配色,使其与你的品牌相匹配。 + + + 组织你的文档,帮助用户找到他们所需的内容并成功使用你的产品。 + + + 根据 OpenAPI 规范自动生成 API 文档。 + + + +## 需要灵感? + + + 浏览我们精选的优秀文档站点展示。 + diff --git a/docs/cn/quickstart.mdx b/docs/cn/quickstart.mdx new file mode 100644 index 0000000..3cedacc --- /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 仓库。你可以在 [dashboard](https://dashboard.mintlify.com) 中找到该仓库的链接。 + + 要在本地克隆该仓库以便对文档进行更改和预览,请参考 GitHub 文档中的 [Cloning a repository](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 步:部署你的更改 + + + + 从 [dashboard](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..96b36fc --- /dev/null +++ b/docs/cn/snippets/snippet-intro.mdx @@ -0,0 +1,4 @@ +软件开发的核心原则之一是 DRY(Don't Repeat +Yourself,不要重复自己)。这一原则同样适用于文档编写。 +如果你发现自己在多个位置重复相同的内容, +应该考虑创建自定义代码片段,以保持内容同步。