@namewta/speculo 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/package.json +1 -1
- package/template/canonical/canonical-specdev-wayfinder.md +146 -41
- package/template/skills/typescript-engineering-standards/README.md +36 -0
- package/template/skills/typescript-engineering-standards/SKILL.md +158 -0
- package/template/skills/typescript-engineering-standards/examples/comment-patterns.md +47 -0
- package/template/skills/typescript-engineering-standards/examples/naming-patterns.md +42 -0
- package/template/skills/typescript-engineering-standards/examples/project-layouts.md +75 -0
- package/template/skills/typescript-engineering-standards/examples/review-output-example.md +25 -0
- package/template/skills/typescript-engineering-standards/examples/type-modeling-patterns.md +66 -0
- package/template/skills/typescript-engineering-standards/manifest.txt +33 -0
- package/template/skills/typescript-engineering-standards/references/00-standard-levels-and-precedence.md +51 -0
- package/template/skills/typescript-engineering-standards/references/01-project-architecture-and-directory-layout.md +105 -0
- package/template/skills/typescript-engineering-standards/references/02-file-directory-and-symbol-naming.md +117 -0
- package/template/skills/typescript-engineering-standards/references/03-modules-imports-exports-and-dependencies.md +111 -0
- package/template/skills/typescript-engineering-standards/references/04-typescript-type-system.md +150 -0
- package/template/skills/typescript-engineering-standards/references/05-functions-async-errors-and-resources.md +142 -0
- package/template/skills/typescript-engineering-standards/references/06-comments-jsdoc-and-documentation.md +104 -0
- package/template/skills/typescript-engineering-standards/references/07-testing-strategy.md +84 -0
- package/template/skills/typescript-engineering-standards/references/08-react-and-frontend.md +91 -0
- package/template/skills/typescript-engineering-standards/references/09-node-cli-and-cross-platform.md +92 -0
- package/template/skills/typescript-engineering-standards/references/10-formatting-lint-and-complexity.md +107 -0
- package/template/skills/typescript-engineering-standards/references/11-configuration-dependencies-and-ci.md +86 -0
- package/template/skills/typescript-engineering-standards/references/12-security-performance-and-i18n.md +65 -0
- package/template/skills/typescript-engineering-standards/references/13-git-review-and-delivery.md +79 -0
- package/template/skills/typescript-engineering-standards/references/14-adoption-exceptions-and-migration.md +84 -0
- package/template/skills/typescript-engineering-standards/references/15-orca-derived-observations.md +54 -0
- package/template/skills/typescript-engineering-standards/references/README.md +45 -0
- package/template/skills/typescript-engineering-standards/templates/.editorconfig +12 -0
- package/template/skills/typescript-engineering-standards/templates/AGENTS.typescript.md +21 -0
- package/template/skills/typescript-engineering-standards/templates/code-review-checklist.md +37 -0
- package/template/skills/typescript-engineering-standards/templates/package-scripts.json +11 -0
- package/template/skills/typescript-engineering-standards/templates/prettier.json +6 -0
- package/template/skills/typescript-engineering-standards/templates/pull-request-template.md +37 -0
- package/template/skills/typescript-engineering-standards/templates/tsconfig.base.json +17 -0
- package/template/skills/typescript-engineering-standards/templates/tsconfig.project-references.json +8 -0
- package/template/workflows/specdev/A-archive-and-consolidate/A-archive-and-consolidate.md +89 -25
- package/template/workflows/specdev/A-archive-and-consolidate/consolidation-interview.md +56 -0
- package/template/workflows/specdev/INDEX.md +1 -1
- package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +85 -27
- package/template/workflows/specdev/W-wayfinder/investigation-ticket-template.md +15 -4
- package/template/workflows/specdev/W-wayfinder/wayfinder-map-template.md +48 -12
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# 项目目录示例
|
|
2
|
+
|
|
3
|
+
## 小型 Node 服务
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
src/
|
|
7
|
+
├── app/
|
|
8
|
+
│ ├── create-server.ts
|
|
9
|
+
│ └── load-environment.ts
|
|
10
|
+
├── features/
|
|
11
|
+
│ └── user-auth/
|
|
12
|
+
│ ├── authenticate-user.ts
|
|
13
|
+
│ ├── authenticate-user.test.ts
|
|
14
|
+
│ └── user-token.ts
|
|
15
|
+
├── infrastructure/
|
|
16
|
+
│ ├── database/
|
|
17
|
+
│ └── http/
|
|
18
|
+
└── shared/
|
|
19
|
+
└── result.ts
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## React 应用
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
src/
|
|
26
|
+
├── app/
|
|
27
|
+
│ ├── App.tsx
|
|
28
|
+
│ └── routes.tsx
|
|
29
|
+
├── features/
|
|
30
|
+
│ ├── workspace-search/
|
|
31
|
+
│ │ ├── WorkspaceSearchPanel.tsx
|
|
32
|
+
│ │ ├── workspace-search-query.ts
|
|
33
|
+
│ │ └── use-workspace-search.ts
|
|
34
|
+
│ └── user-settings/
|
|
35
|
+
├── shared/
|
|
36
|
+
│ ├── components/
|
|
37
|
+
│ └── hooks/
|
|
38
|
+
└── infrastructure/
|
|
39
|
+
└── api/
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`shared/components` 只放真正无业务归属且有多个真实调用方的组件。
|
|
43
|
+
|
|
44
|
+
## Electron
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
src/
|
|
48
|
+
├── main/
|
|
49
|
+
│ ├── app-lifecycle.ts
|
|
50
|
+
│ └── windows/
|
|
51
|
+
├── preload/
|
|
52
|
+
│ └── workspace-api.ts
|
|
53
|
+
├── renderer/
|
|
54
|
+
│ ├── app/
|
|
55
|
+
│ └── features/
|
|
56
|
+
├── shared/
|
|
57
|
+
│ └── workspace-contract.ts
|
|
58
|
+
└── types/
|
|
59
|
+
└── electron-api.d.ts
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Monorepo
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
apps/
|
|
66
|
+
├── web/
|
|
67
|
+
└── api/
|
|
68
|
+
packages/
|
|
69
|
+
├── domain/
|
|
70
|
+
├── contracts/
|
|
71
|
+
├── ui/
|
|
72
|
+
└── test-support/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
包边界应与独立发布、运行环境或稳定依赖方向对应,不要仅为缩短相对路径拆包。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 代码审查输出示例
|
|
2
|
+
|
|
3
|
+
## 阻塞问题
|
|
4
|
+
|
|
5
|
+
### `src/features/workspace/load-workspace.ts:42`
|
|
6
|
+
|
|
7
|
+
`JSON.parse()` 的结果被直接断言为 `WorkspaceConfig`。当配置缺少 `rootPath` 时,错误会延迟到文件系统调用,并可能访问错误位置。
|
|
8
|
+
|
|
9
|
+
建议在配置边界使用 Schema 验证,将解析函数返回类型固定为已验证的 `WorkspaceConfig`,并补充缺失字段和路径穿越测试。
|
|
10
|
+
|
|
11
|
+
## 重要问题
|
|
12
|
+
|
|
13
|
+
### `src/main/process-registry.ts:88`
|
|
14
|
+
|
|
15
|
+
关闭窗口时只移除了事件监听器,没有终止仍在运行的子进程。重复打开窗口会留下孤儿进程。
|
|
16
|
+
|
|
17
|
+
建议让注册函数返回统一 `dispose()`,在窗口关闭和应用退出两个路径都调用,并增加清理回归测试。
|
|
18
|
+
|
|
19
|
+
## 建议
|
|
20
|
+
|
|
21
|
+
### `src/features/search/utils.ts`
|
|
22
|
+
|
|
23
|
+
该文件同时包含查询解析、排序和本地存储。当前功能仍正确,但后续修改会持续扩大职责。
|
|
24
|
+
|
|
25
|
+
建议在下一次触及该模块时拆为 `search-query-parser.ts`、`search-result-sort.ts` 和 `search-history-storage.ts`。本问题不必阻塞当前仅修复文案的变更。
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 类型建模示例
|
|
2
|
+
|
|
3
|
+
## 状态机
|
|
4
|
+
|
|
5
|
+
不推荐:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
type RequestState = {
|
|
9
|
+
isLoading: boolean
|
|
10
|
+
hasError: boolean
|
|
11
|
+
data?: Data
|
|
12
|
+
error?: Error
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
推荐:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
type RequestState =
|
|
20
|
+
| { kind: 'idle' }
|
|
21
|
+
| { kind: 'loading' }
|
|
22
|
+
| { kind: 'success'; data: Data }
|
|
23
|
+
| { kind: 'failure'; error: Error }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 外部边界
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export function parseWorkspaceMessage(input: unknown): WorkspaceMessage {
|
|
30
|
+
return workspaceMessageSchema.parse(input)
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
内部代码只接收已经验证的 `WorkspaceMessage`。
|
|
35
|
+
|
|
36
|
+
## `satisfies`
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const routes = {
|
|
40
|
+
home: '/',
|
|
41
|
+
settings: '/settings'
|
|
42
|
+
} satisfies Record<string, `/${string}`>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
保留具体字面量,同时验证整体契约。
|
|
46
|
+
|
|
47
|
+
## 结果类型
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
type Result<TValue, TError> =
|
|
51
|
+
| { ok: true; value: TValue }
|
|
52
|
+
| { ok: false; error: TError }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
适合调用方需要显式分支、失败属于正常业务结果的场景。不可恢复的程序错误仍可抛异常。
|
|
56
|
+
|
|
57
|
+
## 单位类型
|
|
58
|
+
|
|
59
|
+
高风险领域可使用品牌类型避免单位混用:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
type Milliseconds = number & { readonly __brand: 'Milliseconds' }
|
|
63
|
+
type Bytes = number & { readonly __brand: 'Bytes' }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
仅在实际能降低错误且不会制造大量转换噪声时采用。
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
SKILL.md
|
|
3
|
+
examples/comment-patterns.md
|
|
4
|
+
examples/naming-patterns.md
|
|
5
|
+
examples/project-layouts.md
|
|
6
|
+
examples/review-output-example.md
|
|
7
|
+
examples/type-modeling-patterns.md
|
|
8
|
+
references/00-standard-levels-and-precedence.md
|
|
9
|
+
references/01-project-architecture-and-directory-layout.md
|
|
10
|
+
references/02-file-directory-and-symbol-naming.md
|
|
11
|
+
references/03-modules-imports-exports-and-dependencies.md
|
|
12
|
+
references/04-typescript-type-system.md
|
|
13
|
+
references/05-functions-async-errors-and-resources.md
|
|
14
|
+
references/06-comments-jsdoc-and-documentation.md
|
|
15
|
+
references/07-testing-strategy.md
|
|
16
|
+
references/08-react-and-frontend.md
|
|
17
|
+
references/09-node-cli-and-cross-platform.md
|
|
18
|
+
references/10-formatting-lint-and-complexity.md
|
|
19
|
+
references/11-configuration-dependencies-and-ci.md
|
|
20
|
+
references/12-security-performance-and-i18n.md
|
|
21
|
+
references/13-git-review-and-delivery.md
|
|
22
|
+
references/14-adoption-exceptions-and-migration.md
|
|
23
|
+
references/15-orca-derived-observations.md
|
|
24
|
+
references/README.md
|
|
25
|
+
templates/.editorconfig
|
|
26
|
+
templates/AGENTS.typescript.md
|
|
27
|
+
templates/code-review-checklist.md
|
|
28
|
+
templates/package-scripts.json
|
|
29
|
+
templates/prettier.json
|
|
30
|
+
templates/pull-request-template.md
|
|
31
|
+
templates/tsconfig.base.json
|
|
32
|
+
templates/tsconfig.project-references.json
|
|
33
|
+
manifest.txt
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# 规则级别与优先顺序
|
|
2
|
+
|
|
3
|
+
## 规范词义
|
|
4
|
+
|
|
5
|
+
- **必须**:影响正确性、安全、类型边界、资源生命周期或团队一致性的硬性要求。
|
|
6
|
+
- **应当**:绝大多数情况下适用;偏离时应有可说明的理由。
|
|
7
|
+
- **建议**:默认推荐,但可根据规模、框架和团队经验调整。
|
|
8
|
+
- **禁止**:高概率制造缺陷、隐藏风险或显著降低维护性的做法。
|
|
9
|
+
|
|
10
|
+
## 冲突优先级
|
|
11
|
+
|
|
12
|
+
从高到低:
|
|
13
|
+
|
|
14
|
+
1. 用户明确要求和产品约束。
|
|
15
|
+
2. 运行平台、框架、协议或公开 API 的硬约束。
|
|
16
|
+
3. 已生效的仓库配置与自动化检查。
|
|
17
|
+
4. 当前模块一致、可解释的局部惯例。
|
|
18
|
+
5. 本 Skill 的默认规范。
|
|
19
|
+
|
|
20
|
+
## 事实优先
|
|
21
|
+
|
|
22
|
+
审查现有项目时,不要仅凭文件名或技术栈推断规则。应读取配置和相邻实现,确认:
|
|
23
|
+
|
|
24
|
+
- 模块系统是 ESM、CommonJS 还是打包器模式。
|
|
25
|
+
- 测试框架和测试命名。
|
|
26
|
+
- 格式化与 Lint 工具。
|
|
27
|
+
- 路径别名和包边界。
|
|
28
|
+
- React、Node、Electron 等运行环境。
|
|
29
|
+
- 哪些文件由代码生成器维护。
|
|
30
|
+
|
|
31
|
+
## 一致性不是绝对理由
|
|
32
|
+
|
|
33
|
+
“项目一直这么写”不能自动证明做法正确。以下问题即使历史代码广泛存在,也应阻止继续扩散:
|
|
34
|
+
|
|
35
|
+
- 不可信输入未经验证。
|
|
36
|
+
- 敏感信息泄露。
|
|
37
|
+
- 无法清理的监听器、Timer、连接或进程。
|
|
38
|
+
- `any` 向公共 API 传播。
|
|
39
|
+
- 循环依赖或跨运行环境非法导入。
|
|
40
|
+
- 测试被删除、跳过或规则被关闭以掩盖失败。
|
|
41
|
+
|
|
42
|
+
处理方式应以增量治理为主:新代码不继续引入,触及旧代码时适度修复,避免无关全仓库改写。
|
|
43
|
+
|
|
44
|
+
## 建议与缺陷的区分
|
|
45
|
+
|
|
46
|
+
代码审查中:
|
|
47
|
+
|
|
48
|
+
- 能导致错误、安全问题或维护阻塞的,标记为缺陷。
|
|
49
|
+
- 存在合理替代方案、但当前实现仍正确的,标记为建议。
|
|
50
|
+
- 纯偏好且仓库已有统一风格的,不应提出。
|
|
51
|
+
- 无法证明风险的猜测,应明确说明不确定性。
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# 项目架构与目录布局
|
|
2
|
+
|
|
3
|
+
## 先表达边界
|
|
4
|
+
|
|
5
|
+
目录优先表达以下稳定边界之一:
|
|
6
|
+
|
|
7
|
+
- 运行环境:`main/`、`renderer/`、`server/`、`worker/`、`cli/`。
|
|
8
|
+
- 产品领域:`user-auth/`、`orders/`、`payments/`。
|
|
9
|
+
- 架构职责:`domain/`、`application/`、`infrastructure/`。
|
|
10
|
+
- 独立发布单元:`apps/`、`packages/`。
|
|
11
|
+
|
|
12
|
+
不要在同一层混合互不相干的分类逻辑,例如同时出现全局 `components/`、`payments/`、`services/`、`cli/`。
|
|
13
|
+
|
|
14
|
+
## 领域优先,技术类型局部化
|
|
15
|
+
|
|
16
|
+
项目很小时可按技术类型组织;业务增长后应将技术目录移动到领域内部。
|
|
17
|
+
|
|
18
|
+
推荐:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
src/
|
|
22
|
+
├── app/
|
|
23
|
+
├── features/
|
|
24
|
+
│ ├── user-auth/
|
|
25
|
+
│ │ ├── login-service.ts
|
|
26
|
+
│ │ ├── login-service.test.ts
|
|
27
|
+
│ │ └── components/
|
|
28
|
+
│ └── payments/
|
|
29
|
+
├── shared/
|
|
30
|
+
└── infrastructure/
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
不推荐长期维持:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
src/
|
|
37
|
+
├── components/
|
|
38
|
+
├── hooks/
|
|
39
|
+
├── services/
|
|
40
|
+
├── types/
|
|
41
|
+
└── utils/
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 局部平铺
|
|
45
|
+
|
|
46
|
+
一个职责明确的领域目录应默认平铺文件,不为每个文件建立同名目录。
|
|
47
|
+
|
|
48
|
+
建议增加子目录的条件:
|
|
49
|
+
|
|
50
|
+
- 形成稳定、可命名的子领域。
|
|
51
|
+
- 同级实现文件长期超过约 8~12 个,定位成本明显上升。
|
|
52
|
+
- 文件组拥有独立入口、资源、测试夹具或生命周期。
|
|
53
|
+
- 文件组需要整体移动、替换或发布。
|
|
54
|
+
- 依赖方向或运行环境需要物理隔离。
|
|
55
|
+
|
|
56
|
+
不要创建仅包含一个普通实现文件的目录,也不要为了对称而制造空层级。
|
|
57
|
+
|
|
58
|
+
## `shared/` 准入
|
|
59
|
+
|
|
60
|
+
代码进入共享层前应满足:
|
|
61
|
+
|
|
62
|
+
1. 至少有两个真实调用方。
|
|
63
|
+
2. 不依赖具体业务领域。
|
|
64
|
+
3. 具有具体、可命名的能力。
|
|
65
|
+
4. API 相对稳定。
|
|
66
|
+
5. 不会造成反向依赖。
|
|
67
|
+
6. 共享确实减少重复,而非提前抽象。
|
|
68
|
+
|
|
69
|
+
`shared/` 不是“不知道放哪里”的收容区。
|
|
70
|
+
|
|
71
|
+
## 多运行环境
|
|
72
|
+
|
|
73
|
+
Electron、全栈、Worker 或混合运行环境项目应物理隔离:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
src/
|
|
77
|
+
├── main/
|
|
78
|
+
├── preload/
|
|
79
|
+
├── renderer/
|
|
80
|
+
├── shared/
|
|
81
|
+
└── types/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
要求:
|
|
85
|
+
|
|
86
|
+
- 各环境使用独立 `tsconfig` 或项目引用。
|
|
87
|
+
- 浏览器代码不导入 Node 专属模块。
|
|
88
|
+
- 服务端代码不无意依赖 DOM。
|
|
89
|
+
- 跨环境数据通过显式、可序列化契约。
|
|
90
|
+
- 桥接层 API 最小化,并验证来自外部边界的数据。
|
|
91
|
+
|
|
92
|
+
## 推荐深度
|
|
93
|
+
|
|
94
|
+
目录深度不是硬性指标,但从领域根目录到普通实现文件通常不应超过三层。深层目录往往表示过度分类、缺少领域命名或每文件一目录。
|
|
95
|
+
|
|
96
|
+
## 拆分信号
|
|
97
|
+
|
|
98
|
+
出现以下情况时考虑拆模块或拆包:
|
|
99
|
+
|
|
100
|
+
- 一个目录同时包含多个运行环境代码。
|
|
101
|
+
- 改动一个领域经常触发另一个无关领域。
|
|
102
|
+
- 同一目录的文件命名需要大量前缀才能区分。
|
|
103
|
+
- 公共入口不断扩大。
|
|
104
|
+
- 依赖图出现循环。
|
|
105
|
+
- 不同部分需要不同构建、发布或权限策略。
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# 文件、目录与标识符命名
|
|
2
|
+
|
|
3
|
+
## 默认命名
|
|
4
|
+
|
|
5
|
+
| 对象 | 默认规则 | 示例 |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| 目录 | `kebab-case` | `user-auth/` |
|
|
8
|
+
| 普通 TypeScript 文件 | `kebab-case.ts` | `session-expiration-policy.ts` |
|
|
9
|
+
| React 业务组件 | `PascalCase.tsx` | `SessionExpiredDialog.tsx` |
|
|
10
|
+
| Hook | `use-*.ts` / `use-*.tsx` | `use-session-timeout.ts` |
|
|
11
|
+
| 单元测试 | 源文件名 + `.test` | `login-service.test.ts` |
|
|
12
|
+
| 集成测试 | `.integration.test` | `payment-flow.integration.test.ts` |
|
|
13
|
+
| E2E | `.e2e.spec` | `checkout.e2e.spec.ts` |
|
|
14
|
+
| 声明文件 | 环境或能力名 | `electron-api.d.ts` |
|
|
15
|
+
| 工程脚本 | 动宾结构 | `generate-icons.ts` |
|
|
16
|
+
|
|
17
|
+
若仓库已统一使用 `kebab-case.tsx` 组件文件,应保持一致。不要在同一领域混用两种组件文件命名。
|
|
18
|
+
|
|
19
|
+
## 文件名表达领域和职责
|
|
20
|
+
|
|
21
|
+
推荐结构:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
<domain>-<responsibility>.ts
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
例如:
|
|
28
|
+
|
|
29
|
+
- `user-session-store.ts`
|
|
30
|
+
- `payment-retry-policy.ts`
|
|
31
|
+
- `terminal-output-parser.ts`
|
|
32
|
+
- `github-auth-client.ts`
|
|
33
|
+
- `workspace-path-validator.ts`
|
|
34
|
+
|
|
35
|
+
## 职责后缀
|
|
36
|
+
|
|
37
|
+
- `-service`:完成一个应用能力;不得成为万能类。
|
|
38
|
+
- `-repository`:领域对象的持久化抽象。
|
|
39
|
+
- `-client`:调用外部 HTTP、RPC 或 SDK。
|
|
40
|
+
- `-adapter`:在两个接口或模型间适配。
|
|
41
|
+
- `-gateway`:外部系统或资源边界。
|
|
42
|
+
- `-store`:状态存储与更新。
|
|
43
|
+
- `-selector`:从状态中派生数据。
|
|
44
|
+
- `-policy`:可替换的业务决策。
|
|
45
|
+
- `-validator`:校验并返回结果或错误。
|
|
46
|
+
- `-parser`:把外部格式转换为结构化数据。
|
|
47
|
+
- `-serializer`:把结构化数据转换为外部格式。
|
|
48
|
+
- `-mapper`:在两个明确模型之间映射。
|
|
49
|
+
- `-factory`:构造复杂对象或依赖图。
|
|
50
|
+
- `-registry`:注册和查找一组实现。
|
|
51
|
+
- `-scheduler`:计划或调度任务。
|
|
52
|
+
- `-coordinator`:协调多个独立流程。
|
|
53
|
+
- `-contract`:跨模块、跨进程或公开 API 契约。
|
|
54
|
+
|
|
55
|
+
后缀不能替代领域信息。单独的 `service.ts`、`handler.ts`、`manager.ts` 仍然模糊。
|
|
56
|
+
|
|
57
|
+
## 默认禁止的模糊名称
|
|
58
|
+
|
|
59
|
+
- `utils.ts`
|
|
60
|
+
- `helpers.ts`
|
|
61
|
+
- `common.ts`
|
|
62
|
+
- `misc.ts`
|
|
63
|
+
- `general.ts`
|
|
64
|
+
- `data.ts`
|
|
65
|
+
- `manager.ts`
|
|
66
|
+
- `processor.ts`
|
|
67
|
+
- `handler.ts`
|
|
68
|
+
- 全局 `types.ts`
|
|
69
|
+
- 全局 `constants.ts`
|
|
70
|
+
|
|
71
|
+
若父目录已提供完整语义,局部 `types.ts` 或 `constants.ts` 可以存在,但更推荐 `payment-types.ts`、`terminal-constants.ts` 等可搜索名称。
|
|
72
|
+
|
|
73
|
+
## 标识符
|
|
74
|
+
|
|
75
|
+
| 对象 | 规则 |
|
|
76
|
+
|---|---|
|
|
77
|
+
| 变量、函数、方法 | `camelCase` |
|
|
78
|
+
| 类型、类、组件 | `PascalCase` |
|
|
79
|
+
| 常量 | 真正全局稳定值用 `SCREAMING_SNAKE_CASE` |
|
|
80
|
+
| 私有字段 | 使用 `#field` 或普通 `private`,不加 `_` 前缀 |
|
|
81
|
+
| Hook | `useXxx` |
|
|
82
|
+
| 事件属性 | `onXxx` |
|
|
83
|
+
| 内部事件处理函数 | `handleXxx` |
|
|
84
|
+
| 泛型 | 简单时 `T`,复杂时 `TResult`、`TContext` |
|
|
85
|
+
|
|
86
|
+
## 布尔命名
|
|
87
|
+
|
|
88
|
+
优先使用:
|
|
89
|
+
|
|
90
|
+
- `isConnected`
|
|
91
|
+
- `hasPendingChanges`
|
|
92
|
+
- `canRetry`
|
|
93
|
+
- `shouldPersist`
|
|
94
|
+
- `didTimeout`
|
|
95
|
+
- `willReconnect`
|
|
96
|
+
|
|
97
|
+
避免 `flag`、`enabled`、`notDisabled`、`isNotInvalid` 等含义弱或双重否定名称。
|
|
98
|
+
|
|
99
|
+
## 单位进入名称
|
|
100
|
+
|
|
101
|
+
数值变量必须尽量包含单位或语义:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const timeoutMs = 30_000
|
|
105
|
+
const payloadSizeBytes = 1_024
|
|
106
|
+
const retryCount = 3
|
|
107
|
+
const pageOffset = 20
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 避免无信息变量
|
|
111
|
+
|
|
112
|
+
除极短循环或数学表达式外,避免 `obj`、`data`、`info`、`value`、`result`、`temp`。使用角色名称:
|
|
113
|
+
|
|
114
|
+
- `parsedPayload`
|
|
115
|
+
- `validationResult`
|
|
116
|
+
- `pendingSession`
|
|
117
|
+
- `persistedWorkspace`
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# 模块、导入、导出与依赖
|
|
2
|
+
|
|
3
|
+
## 命名导出优先
|
|
4
|
+
|
|
5
|
+
默认使用命名导出:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
export function parseTerminalOutput(input: string): ParsedOutput {
|
|
9
|
+
// ...
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
默认导出仅用于:
|
|
14
|
+
|
|
15
|
+
- 框架规定的页面、路由或配置入口。
|
|
16
|
+
- 工具链必须的默认导出。
|
|
17
|
+
- 仓库已形成明确且一致的入口惯例。
|
|
18
|
+
|
|
19
|
+
命名导出便于搜索、自动导入、重构和统一引用名称。
|
|
20
|
+
|
|
21
|
+
## 一个文件一个主要公开概念
|
|
22
|
+
|
|
23
|
+
一个文件可包含少量私有辅助函数,但通常只公开一个主要能力或一组高度相关能力。辅助函数达到独立职责后,应拆成具有具体名称的文件。
|
|
24
|
+
|
|
25
|
+
不要为了测试内部细节而导出私有辅助函数;优先通过公共行为测试,或将真正独立的纯逻辑抽出。
|
|
26
|
+
|
|
27
|
+
## Barrel 文件
|
|
28
|
+
|
|
29
|
+
允许 `index.ts`:
|
|
30
|
+
|
|
31
|
+
- 作为包或领域的明确公共入口。
|
|
32
|
+
- 隐藏内部实现并稳定外部 API。
|
|
33
|
+
- 作为依赖装配或框架入口。
|
|
34
|
+
|
|
35
|
+
禁止:
|
|
36
|
+
|
|
37
|
+
- 每个目录机械创建 `index.ts`。
|
|
38
|
+
- 建立全项目万能 Barrel。
|
|
39
|
+
- 通过 Barrel 暴露内部实现。
|
|
40
|
+
- 通过 Barrel 形成循环依赖。
|
|
41
|
+
|
|
42
|
+
## 导入顺序
|
|
43
|
+
|
|
44
|
+
默认顺序:
|
|
45
|
+
|
|
46
|
+
1. Node.js 内置模块。
|
|
47
|
+
2. 第三方依赖。
|
|
48
|
+
3. 项目别名。
|
|
49
|
+
4. 相对路径实现。
|
|
50
|
+
5. 类型导入按照工具规则分组或合并。
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { readFile } from 'node:fs/promises'
|
|
54
|
+
|
|
55
|
+
import { z } from 'zod'
|
|
56
|
+
|
|
57
|
+
import { createLogger } from '@/shared/logger'
|
|
58
|
+
|
|
59
|
+
import { parseConfig } from './config-parser'
|
|
60
|
+
|
|
61
|
+
import type { AppConfig } from './app-config'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
要求:
|
|
65
|
+
|
|
66
|
+
- Node 内置模块使用 `node:` 前缀。
|
|
67
|
+
- 仅作为类型使用时采用 `import type`。
|
|
68
|
+
- 不保留未使用或重复导入。
|
|
69
|
+
- 副作用导入必须有明确原因。
|
|
70
|
+
- 路径别名对应稳定边界,不用于任意跨层跳转。
|
|
71
|
+
|
|
72
|
+
## 依赖方向
|
|
73
|
+
|
|
74
|
+
推荐:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
UI / Entry
|
|
78
|
+
↓
|
|
79
|
+
Application orchestration
|
|
80
|
+
↓
|
|
81
|
+
Domain
|
|
82
|
+
↓
|
|
83
|
+
Ports / contracts
|
|
84
|
+
↑
|
|
85
|
+
Infrastructure adapters
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- 领域逻辑不直接依赖数据库、HTTP、文件系统或 UI 框架。
|
|
89
|
+
- 共享模块不依赖具体领域。
|
|
90
|
+
- 底层模块不反向导入界面层。
|
|
91
|
+
- 跨环境调用通过显式契约和适配器。
|
|
92
|
+
|
|
93
|
+
## 循环依赖
|
|
94
|
+
|
|
95
|
+
循环依赖是架构问题,不应通过调整导入顺序或增加 Barrel 隐藏。解决方式:
|
|
96
|
+
|
|
97
|
+
- 提取真正共享的契约。
|
|
98
|
+
- 使用依赖注入反转方向。
|
|
99
|
+
- 合并实际属于同一职责的模块。
|
|
100
|
+
- 将端口放在需求方而非实现方。
|
|
101
|
+
- 缩小公共入口。
|
|
102
|
+
|
|
103
|
+
## 公共 API
|
|
104
|
+
|
|
105
|
+
公开库或跨包模块应:
|
|
106
|
+
|
|
107
|
+
- 明确列出允许导出的入口。
|
|
108
|
+
- 避免消费者导入内部路径。
|
|
109
|
+
- 不暴露框架、数据库或第三方 SDK 的内部类型,除非这是刻意的 API 设计。
|
|
110
|
+
- 保持输入、输出和错误契约稳定。
|
|
111
|
+
- 变更时考虑语义化版本和迁移说明。
|