113 lines
6.8 KiB
Markdown
113 lines
6.8 KiB
Markdown
# Coding Conventions
|
||
|
||
**Analysis Date:** 2026-04-07
|
||
|
||
## Naming Patterns
|
||
|
||
**Files:**
|
||
- Python 使用 `snake_case.py`,按领域分层放置,例如 `backend/packages/harness/deerflow/config/app_config.py`、`backend/packages/harness/deerflow/agents/lead_agent/agent.py`。
|
||
- Backend 测试文件统一 `test_*.py`,位于 `backend/tests/`,例如 `backend/tests/test_client.py`、`backend/tests/test_stream_bridge.py`。
|
||
- Frontend 页面与组件文件使用 `kebab-case.tsx` 或目录约定命名,例如 `frontend/src/app/workspace/page.tsx`、`frontend/src/components/workspace/workspace-container.tsx`。
|
||
- Frontend E2E 测试使用 `*.spec.ts`,位于 `frontend/tests/e2e/`;轻量模块测试使用 `*.test.ts` 或 `*.test.mjs`,例如 `frontend/src/core/api/stream-mode.test.ts`。
|
||
|
||
**Functions:**
|
||
- Python 函数与内部 helper 统一 `snake_case`,例如 `_make_e2e_config`(`backend/tests/test_client_e2e.py`)、`get_available_tools`(`backend/packages/harness/deerflow/tools/tools.py`)。
|
||
- TypeScript/JavaScript 函数统一 `camelCase`,例如 `copyToClipboard`(`frontend/src/lib/utils.ts`)、`skipIfMissingThread`(`frontend/tests/e2e/support/chat-helpers.ts`)。
|
||
|
||
**Variables:**
|
||
- Python 常量使用全大写下划线,如 `BUILTIN_TOOLS`(`backend/packages/harness/deerflow/tools/tools.py`)。
|
||
- TS 常量通常 `camelCase`,跨测试配置使用全大写语义常量,如 `THREAD_FOR_WELCOME`(`frontend/tests/e2e/support/chat-helpers.ts`)。
|
||
|
||
**Types:**
|
||
- Python 使用类型注解(`list[str]`、`dict[str, Any]`)与 `pydantic` 模型,见 `backend/packages/harness/deerflow/config/app_config.py`。
|
||
- Frontend 使用 TypeScript 严格模式,并偏向显式返回类型(例如 `Promise<void>` in `frontend/src/lib/utils.ts`)。
|
||
|
||
## Code Style
|
||
|
||
**Formatting:**
|
||
- Backend 使用 `ruff format`;规则来源 `backend/ruff.toml`(`quote-style = "double"`,`indent-style = "space"`,`line-length = 240`)。
|
||
- Frontend 使用 `prettier` + `prettier-plugin-tailwindcss`,配置在 `frontend/prettier.config.js`;CI 中执行 `pnpm format`(check 模式)。
|
||
|
||
**Linting:**
|
||
- Backend 通过 `ruff check .`,启用 `E/F/I/UP`(`backend/ruff.toml`)。
|
||
- Frontend 通过 `eslint` flat config(`frontend/eslint.config.js`),叠加 `next/core-web-vitals` 与 `typescript-eslint` type-checked 规则。
|
||
- Frontend 强制导入顺序(`import/order`)与分组换行,内部别名 `@/**` 归类为 internal。
|
||
|
||
## Import Organization
|
||
|
||
**Order:**
|
||
1. 标准库/内建模块(如 `import os`、`import path from "path"`)。
|
||
2. 第三方依赖(如 `from pydantic import BaseModel`、`import { expect, test } from "@playwright/test"`)。
|
||
3. 项目内部模块(如 `from deerflow...`、`from "@/env"`)。
|
||
|
||
**Path Aliases:**
|
||
- Frontend 启用 `@/* -> ./src/*`(`frontend/tsconfig.json`);新增代码应优先使用该别名替代跨层级相对路径。
|
||
- Backend 无类似别名约定;使用包内绝对导入 `deerflow.*`(见 `backend/packages/harness/deerflow/client.py`)。
|
||
|
||
## Error Handling
|
||
|
||
**Patterns:**
|
||
- Backend 在参数/配置非法时直接抛出 `ValueError` / `FileNotFoundError`,示例见 `backend/packages/harness/deerflow/config/app_config.py` 和 `backend/packages/harness/deerflow/client.py`。
|
||
- Backend 在可降级场景使用 `try/except` + `logger.warning/error`,不中断主流程(例如 MCP/ACP 工具加载,`backend/packages/harness/deerflow/tools/tools.py`)。
|
||
- Frontend 偏向显式 guard + return(例如 `frontend/src/app/workspace/page.tsx` 的条件重定向)。
|
||
|
||
## Logging
|
||
|
||
**Framework:** `logging`(Python) + `console`(Frontend 局部)
|
||
|
||
**Patterns:**
|
||
- Backend 统一模块级 `logger = logging.getLogger(__name__)`,记录关键分支、fallback、装载结果(`backend/packages/harness/deerflow/tools/tools.py`)。
|
||
- Frontend 存在业务调试日志(`console.log` / `console.warn`)用于 iframe 与失败分支,见 `frontend/src/lib/utils.ts`、`frontend/src/core/uploads/prompt-input-files.test.mjs`(通过 mock 断言 warning)。
|
||
|
||
## Comments
|
||
|
||
**When to Comment:**
|
||
- Backend 在复杂中间件顺序、循环依赖绕过、测试分层原则等高认知负担位置写块注释,示例:
|
||
- `backend/packages/harness/deerflow/agents/lead_agent/agent.py`(middleware 顺序约束)
|
||
- `backend/tests/conftest.py`(循环导入链与 mock 注入原因)
|
||
- `backend/tests/test_client_e2e.py`(测试金字塔与运行边界)
|
||
|
||
**JSDoc/TSDoc:**
|
||
- Frontend 在共享工具函数处使用 JSDoc 解释行为与边界(`frontend/src/lib/utils.ts`)。
|
||
- Backend 在公共类/函数上常见 docstring,测试文件顶部也有职责说明。
|
||
|
||
## Function Design
|
||
|
||
**Size:** 无硬性行数限制;允许长函数,但通过“局部 helper + 注释分段”提高可读性(见 `backend/packages/harness/deerflow/client.py`)。
|
||
|
||
**Parameters:**
|
||
- 偏向显式关键字参数与默认值,Python 常见 `*` 强制关键字调用(`DeerFlowClient.__init__`)。
|
||
- 测试 helper 参数常封装为对象/字典,减少调用点重复(`frontend/tests/e2e/support/chat-helpers.ts`)。
|
||
|
||
**Return Values:**
|
||
- Python 公开接口通常返回结构化对象或强类型(如 `StreamEvent` dataclass in `backend/packages/harness/deerflow/client.py`)。
|
||
- Frontend helper 对异常场景返回 `null/undefined` 并由调用方判定(`frontend/src/core/uploads/prompt-input-files.test.mjs` 覆盖该行为)。
|
||
|
||
## Module Design
|
||
|
||
**Exports:**
|
||
- Python 模块多为显式函数/类导出,避免通配导入;测试按模块行为组织断言。
|
||
- Frontend 使用 `export function` / `export const` 的命名导出为主(`frontend/src/lib/utils.ts`)。
|
||
|
||
**Barrel Files:**
|
||
- 后端包存在少量 `__init__.py` 聚合导出(如 `backend/packages/harness/deerflow/models/__init__.py`)。
|
||
- Frontend 未形成统一 barrel 规范;新增公共模块应优先“就近导出 + 明确 import 路径”,避免深层 barrel 隐式耦合。
|
||
|
||
## CI / 质量门禁约定
|
||
|
||
- CI 工作流定义于 `.github/workflows/lint-check.yml`、`.github/workflows/backend-unit-tests.yml`。
|
||
- 合入前最低门禁:
|
||
- Backend: `make lint`(ruff check + format --check)
|
||
- Frontend: `pnpm format`、`pnpm lint`、`pnpm typecheck`、`pnpm build`
|
||
- Backend 单测:`make test`(pytest)
|
||
- Frontend E2E 未纳入默认 CI 工作流;仅定义本地命令 `pnpm test:e2e`(`frontend/package.json`)。
|
||
|
||
## 简短结论
|
||
|
||
- 本仓库已形成“双栈分治”质量约定:Backend 以 `ruff + pytest` 为核心,Frontend 以 `eslint + prettier + typecheck + build` 为核心,并在 CI 中执行。
|
||
- 后续新增代码应严格沿用现有命名、导入分组与异常处理风格;新增测试优先补齐 Frontend 单元测试执行入口与 E2E 的 CI 接入,避免“有测试文件但无持续校验”。
|
||
|
||
---
|
||
|
||
*Convention analysis: 2026-04-07*
|