@wneng/create-keel 0.2.0 → 0.3.0
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/dist/index.js +497 -38
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/src/feature/templates/arch/adr.md.eta +31 -0
- package/src/feature/templates/backend/design.md.eta +35 -0
- package/src/feature/templates/frontend/design.md.eta +34 -0
- package/src/feature/templates/pm/prd.md.eta +37 -0
- package/src/feature/templates/sample/user-signup/arch/adr.md.eta +48 -0
- package/src/feature/templates/sample/user-signup/backend/design.md.eta +77 -0
- package/src/feature/templates/sample/user-signup/frontend/design.md.eta +54 -0
- package/src/feature/templates/sample/user-signup/pm/prd.md.eta +46 -0
- package/src/feature/templates/sample/user-signup/test/test-plan.md.eta +40 -0
- package/src/feature/templates/test/test-plan.md.eta +23 -0
- package/src/standards/templates/coding-style-dart.md.eta +49 -0
- package/src/standards/templates/coding-style-go.md.eta +52 -0
- package/src/standards/templates/coding-style-java.md.eta +50 -0
- package/src/standards/templates/coding-style-python.md.eta +51 -0
- package/src/standards/templates/coding-style-rust.md.eta +52 -0
- package/src/standards/templates/coding-style-typescript.md.eta +50 -0
- package/src/standards/templates/dependency-cruiser.config.cjs.eta +57 -0
- package/src/standards/templates/design-tokens.ts.eta +37 -0
- package/src/standards/templates/module-boundaries.md.eta +82 -0
- package/src/standards/templates/tech-stack-agent.md.eta +35 -0
- package/src/standards/templates/tech-stack-miniapp.md.eta +34 -0
- package/src/standards/templates/tech-stack-mobile.md.eta +36 -0
- package/src/standards/templates/tech-stack-server.md.eta +50 -0
- package/src/standards/templates/tech-stack-web.md.eta +36 -0
- package/src/standards/templates/ui-design-system.md.eta +70 -0
- package/src/templates/docs-skeleton/files/usage-quickstart.md +11 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Rust 编码规范
|
|
2
|
+
|
|
3
|
+
> 真值是 `rustfmt` + `clippy` 配置;本文件解释 *为什么* 与 *如何调整*。机器校验在 CI 中 `clippy` job 阻断违规。
|
|
4
|
+
|
|
5
|
+
config: agent/rustfmt.toml
|
|
6
|
+
|
|
7
|
+
## 命名规范
|
|
8
|
+
|
|
9
|
+
- crate / 模块:`snake_case`
|
|
10
|
+
- 类型 / trait / 枚举:`PascalCase`;变体也是 `PascalCase`
|
|
11
|
+
- 函数 / 变量 / 字段:`snake_case`;常量 / 静态:`UPPER_SNAKE_CASE`
|
|
12
|
+
- 生命周期:单字母 `'a` 起步,复杂时表义 `'session`
|
|
13
|
+
|
|
14
|
+
## 格式化
|
|
15
|
+
|
|
16
|
+
- `cargo fmt` 单一权威;CI 中 `cargo fmt --check` 阻断
|
|
17
|
+
- 行宽 100(rustfmt 默认);4 空格缩进
|
|
18
|
+
- import 顺序:标准库 → 第三方 → 本 crate;rustfmt 处理
|
|
19
|
+
|
|
20
|
+
## 错误处理
|
|
21
|
+
|
|
22
|
+
- 业务函数返回 `Result<T, E>`;禁止 `unwrap()` / `expect()` 在 release 路径
|
|
23
|
+
- 错误类型:库代码用 `thiserror`;应用代码用 `anyhow::Result`
|
|
24
|
+
- `?` 是 happy path;想日志或转换错误时用 `.context("...")` (`anyhow`) 或 `.map_err(...)`
|
|
25
|
+
- panic 仅在不可恢复(断言违反、初始化失败)时用
|
|
26
|
+
|
|
27
|
+
## 所有权与并发
|
|
28
|
+
|
|
29
|
+
- 优先 borrow,其次 `Clone`,再次 `Arc`;`Rc` 仅在单线程
|
|
30
|
+
- `unsafe` 必须有 `// SAFETY: ...` 注释解释不变量
|
|
31
|
+
- 跨线程数据走 `Send + Sync`;共享可变状态走 `Arc<Mutex<T>>` 并尽量缩小锁粒度
|
|
32
|
+
- async:`tokio` 单一运行时;不要混 async-std
|
|
33
|
+
|
|
34
|
+
## 依赖与模块
|
|
35
|
+
|
|
36
|
+
- `Cargo.toml` 钉版本(`= "x.y.z"`),与 `tech-stack-agent.md` 对齐
|
|
37
|
+
- workspace:跨 `apps/*` 在 multi-app 模式下走顶层 `crates/<shared>`,禁止直接 path import 兄弟 app
|
|
38
|
+
- 第三方 crate 引入前确认 license 与维护活跃度
|
|
39
|
+
|
|
40
|
+
## 注释与文档
|
|
41
|
+
|
|
42
|
+
- 导出 item 必须有 `///` doc comment;crate 根写 `//!` 模块级 doc
|
|
43
|
+
- `// Why:` 段说明非显然的决策
|
|
44
|
+
- `cargo doc --no-deps` 在 CI 中验证 doc 不报错
|
|
45
|
+
|
|
46
|
+
## lint 配置真值
|
|
47
|
+
|
|
48
|
+
| 工具 | 配置文件 | CI job |
|
|
49
|
+
|------|---------|--------|
|
|
50
|
+
| rustfmt | `agent/rustfmt.toml` | `format-check` |
|
|
51
|
+
| clippy | `agent/Cargo.toml` 中 `[lints.clippy]` 段 | `clippy` |
|
|
52
|
+
| cargo deny | `agent/deny.toml` | `security` |
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# TypeScript 编码规范
|
|
2
|
+
|
|
3
|
+
> 真值是 ESLint / Prettier 配置;本文件解释 *为什么* 与 *如何调整*。机器校验在 CI 中 `eslint` job 阻断违规。
|
|
4
|
+
|
|
5
|
+
config: web/.eslintrc.cjs
|
|
6
|
+
|
|
7
|
+
## 命名规范
|
|
8
|
+
|
|
9
|
+
- 文件:`kebab-case.ts`,组件文件除外 → `PascalCase.tsx`
|
|
10
|
+
- 类型 / 接口 / 类:`PascalCase`,禁止 `I` 前缀
|
|
11
|
+
- 变量 / 函数:`camelCase`,常量级(模块顶部全大写枚举):`UPPER_SNAKE_CASE`
|
|
12
|
+
- React 组件:`PascalCase`;hooks:`use<Name>`
|
|
13
|
+
|
|
14
|
+
## 格式化
|
|
15
|
+
|
|
16
|
+
- Prettier 单一权威;本仓库不在评审里讨论分号 / 引号 / 行宽
|
|
17
|
+
- 行宽 100;2 空格缩进;尾随逗号 `all`
|
|
18
|
+
- import 顺序:node 内置 → 第三方 → 别名 (`@/...`) → 相对路径,每段空行隔开
|
|
19
|
+
|
|
20
|
+
## 错误处理
|
|
21
|
+
|
|
22
|
+
- 业务函数返回 `Result<T, E>` 或抛出 `ScaffolderError` 子类;禁止裸 `throw new Error(...)`
|
|
23
|
+
- `try / catch` 必须 narrow `unknown`:`catch (e)` 后用 `instanceof` 或 type guard
|
|
24
|
+
- async 函数禁止吞错;`Promise.allSettled` 用于刻意聚合失败
|
|
25
|
+
|
|
26
|
+
## 类型用法
|
|
27
|
+
|
|
28
|
+
- 严格模式:`tsc --noEmit` 在 CI 阻断;本地禁止 `// @ts-ignore`,必要时用 `@ts-expect-error` 并解释
|
|
29
|
+
- 优先 `interface` 描述对象形状;`type` 用于联合 / 映射 / 函数签名
|
|
30
|
+
- 禁止 `any`;不可避免时用 `unknown` 加 type guard
|
|
31
|
+
|
|
32
|
+
## 依赖与导入
|
|
33
|
+
|
|
34
|
+
- 单 app:相对路径;多 app:路径别名 `@apps/<name>` 或 `@contracts/...`
|
|
35
|
+
- 跨 `apps/*` import 在 multi-app 模式下被 `dependency-cruiser` 阻断
|
|
36
|
+
- 第三方依赖必须在 `tech-stack-<env>.md` 钉版本表中存在
|
|
37
|
+
|
|
38
|
+
## 注释与文档
|
|
39
|
+
|
|
40
|
+
- TSDoc:导出符号必须有一行说明;复杂逻辑加 `Why:` 段说明意图
|
|
41
|
+
- 对外 API:`@param` `@returns` `@throws` 完整
|
|
42
|
+
- 禁止注释掉的代码;用 git 历史
|
|
43
|
+
|
|
44
|
+
## lint 配置真值
|
|
45
|
+
|
|
46
|
+
| 工具 | 配置文件 | CI job |
|
|
47
|
+
|------|---------|--------|
|
|
48
|
+
| ESLint | `web/.eslintrc.cjs`(前端)/ `server/.eslintrc.cjs`(后端) | `lint` |
|
|
49
|
+
| Prettier | `.prettierrc` | `format-check` |
|
|
50
|
+
| TypeScript | `tsconfig.json` | `typecheck` |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dependency-cruiser configuration — engineering-standards module boundaries.
|
|
3
|
+
*
|
|
4
|
+
* Generated by `@wneng/create-keel` (engineering-standards plan).
|
|
5
|
+
* Edit with care; the rules here are referenced by:
|
|
6
|
+
* - docs/03-工程规范与研发基础设施/module-boundaries.md (narrative truth)
|
|
7
|
+
* - tools/governance-lint/checks/stack-pinning.js (exit code mapping)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** @type {import('dependency-cruiser').IConfiguration} */
|
|
11
|
+
module.exports = {
|
|
12
|
+
forbidden: [
|
|
13
|
+
{
|
|
14
|
+
name: 'GOV.BOUND.CROSS_APP',
|
|
15
|
+
severity: 'error',
|
|
16
|
+
comment:
|
|
17
|
+
'apps/<X> must not directly import from apps/<Y>. Move shared code to contracts/ or packages/<shared>/.',
|
|
18
|
+
from: { path: '^(?:[^/]+)/apps/([^/]+)/' },
|
|
19
|
+
to: { path: '^(?:[^/]+)/apps/(?!\\1)([^/]+)/' },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'GOV.BOUND.CIRCULAR',
|
|
23
|
+
severity: 'error',
|
|
24
|
+
comment: 'Circular dependencies make the build graph unstable.',
|
|
25
|
+
from: {},
|
|
26
|
+
to: { circular: true },
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'no-orphans',
|
|
30
|
+
comment: 'Orphan modules (no incoming edges) usually indicate dead code.',
|
|
31
|
+
severity: 'warn',
|
|
32
|
+
from: {
|
|
33
|
+
orphan: true,
|
|
34
|
+
pathNot: [
|
|
35
|
+
'(^|/)\\.(?:eslint|prettier|babel|tsconfig)',
|
|
36
|
+
'\\.d\\.ts$',
|
|
37
|
+
'(^|/)src/index\\.[jt]sx?$',
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
to: {},
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
options: {
|
|
44
|
+
doNotFollow: { path: 'node_modules' },
|
|
45
|
+
tsConfig: { fileName: 'tsconfig.json' },
|
|
46
|
+
enhancedResolveOptions: {
|
|
47
|
+
exportsFields: ['exports'],
|
|
48
|
+
conditionNames: ['import', 'require', 'node'],
|
|
49
|
+
},
|
|
50
|
+
reporterOptions: {
|
|
51
|
+
err: {
|
|
52
|
+
// Standard error format consumed by governance-lint
|
|
53
|
+
showRules: true,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens — generated by `@wneng/create-keel` (engineering-standards).
|
|
3
|
+
*
|
|
4
|
+
* The exported constant *names* here MUST exactly match the token name
|
|
5
|
+
* column in `docs/05-前端客户端详细设计/ui-design-system.md`. The
|
|
6
|
+
* governance-lint `ui-token-drift` check enforces this; mismatches
|
|
7
|
+
* surface as `GOV.UI.TOKEN_DRIFT` in CI.
|
|
8
|
+
*
|
|
9
|
+
* Edit values, not names. Renaming a token requires a coordinated PR
|
|
10
|
+
* that touches both this file and the manifest's token table in the
|
|
11
|
+
* same commit.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Colors ---------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
export const colorPrimary = '#2563EB';
|
|
17
|
+
export const colorSurface = '#FFFFFF';
|
|
18
|
+
export const colorTextDefault = '#0F172A';
|
|
19
|
+
export const colorTextMuted = '#64748B';
|
|
20
|
+
export const colorBorder = '#E2E8F0';
|
|
21
|
+
export const colorDanger = '#DC2626';
|
|
22
|
+
|
|
23
|
+
// Spacing --------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
export const space1 = '4px';
|
|
26
|
+
export const space2 = '8px';
|
|
27
|
+
export const space3 = '12px';
|
|
28
|
+
export const space4 = '16px';
|
|
29
|
+
export const space6 = '24px';
|
|
30
|
+
export const space8 = '32px';
|
|
31
|
+
|
|
32
|
+
// Typography -----------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
export const fontHeading1 = { fontSize: '32px', lineHeight: 1.25, fontWeight: 600 } as const;
|
|
35
|
+
export const fontHeading2 = { fontSize: '24px', lineHeight: 1.3, fontWeight: 600 } as const;
|
|
36
|
+
export const fontBody = { fontSize: '14px', lineHeight: 1.5, fontWeight: 400 } as const;
|
|
37
|
+
export const fontCaption = { fontSize: '12px', lineHeight: 1.4, fontWeight: 400 } as const;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# 模块引用边界
|
|
2
|
+
|
|
3
|
+
> 本文件给出仓库内的引用方向规则。机器侧守门交给 `dependency-cruiser` / `archunit` / `gomodguard` 等工具;本文件解释**为什么**有这些边界,以及**如何**调整。
|
|
4
|
+
|
|
5
|
+
config: <% if (it.standards.multiApp) { %>dependency-cruiser.config.cjs<% } else { %>(单 app 模式无机器守门,仅本文件叙事)<% } %>
|
|
6
|
+
|
|
7
|
+
## 总原则
|
|
8
|
+
|
|
9
|
+
依赖**只**沿允许的方向流动。违反方向的 import / require / require_once 会导致以下后果之一:
|
|
10
|
+
|
|
11
|
+
1. 短期:编译能过,但循环依赖让构建图不稳定
|
|
12
|
+
2. 中期:模块边界腐烂,重构难度指数上升
|
|
13
|
+
3. 长期:单一模块测试不再独立,整仓 CI 时长翻倍
|
|
14
|
+
|
|
15
|
+
为防止这种漂移,本文件 + `dependency-cruiser`(multi-app 模式下)一起做硬约束。
|
|
16
|
+
|
|
17
|
+
## 命名规范
|
|
18
|
+
|
|
19
|
+
边界检查中用到的几个稳定标识:
|
|
20
|
+
|
|
21
|
+
- `apps/<name>/` —— 多 app 模式下的应用根
|
|
22
|
+
- `contracts/` —— 跨执行环境的机器可消费契约
|
|
23
|
+
- `packages/` —— 多 app 共享的代码(root 级,可选)
|
|
24
|
+
|
|
25
|
+
## 错误处理
|
|
26
|
+
|
|
27
|
+
import 违规会被 dependency-cruiser 报告为以下错误码:
|
|
28
|
+
|
|
29
|
+
- `GOV.BOUND.CROSS_APP` —— `apps/A` 直接引用了 `apps/B` 的代码
|
|
30
|
+
- `GOV.BOUND.CIRCULAR` —— 模块循环依赖
|
|
31
|
+
|
|
32
|
+
修复路径:把共享代码挪到 `contracts/`(机器可消费契约)或 `packages/<shared>/`(根级可选 workspace)。
|
|
33
|
+
|
|
34
|
+
## 格式化
|
|
35
|
+
|
|
36
|
+
- 模块导出文件按 layer 命名:`index.ts` 是公共入口,`internal/` 下是私有
|
|
37
|
+
- 跨包 import 必须经过 `index.ts`,**禁止**深路径 `from "@app/internal/foo"`
|
|
38
|
+
|
|
39
|
+
<% if (it.standards.multiApp) { %>## 多 app 模式(当前启用)
|
|
40
|
+
|
|
41
|
+
仓库已切换到多 app 模式,`<env>/apps/<name>/` 下每个目录是独立应用。
|
|
42
|
+
|
|
43
|
+
**禁止**:
|
|
44
|
+
- `apps/A/` 中的代码 import `apps/B/` 中的任何文件(任何深度)
|
|
45
|
+
- 跨 app 共享 utility 直接放在某个 app 内部
|
|
46
|
+
|
|
47
|
+
**允许**:
|
|
48
|
+
- 通过 `contracts/` 共享 schema / 错误码 / 状态机
|
|
49
|
+
- 通过根 `packages/<name>/` 共享代码(需要在 PR 中说明为什么不能放契约层)
|
|
50
|
+
|
|
51
|
+
机器守门:[`dependency-cruiser.config.cjs`](../../dependency-cruiser.config.cjs) 在 CI 中阻断违规 import。
|
|
52
|
+
|
|
53
|
+
## 调整流程
|
|
54
|
+
|
|
55
|
+
1. 改 `dependency-cruiser.config.cjs` 中的 forbidden 规则前,必须在 ADR 中说明
|
|
56
|
+
2. 同 PR 改本文件正文部分(这是双写,让 review 看到边界变化)
|
|
57
|
+
3. CI 跑 dependency-cruiser;不通过就改回去
|
|
58
|
+
4. 真要破例:在违规处添加 `// eslint-disable-next-line import/no-restricted-paths` 并 PR 描述给出理由
|
|
59
|
+
<% } else { %>## 单 app 模式(当前启用)
|
|
60
|
+
|
|
61
|
+
仓库目前是单 app 模式,`<env>/` 下直接放一份工程文件,没有 `apps/` 子目录。
|
|
62
|
+
|
|
63
|
+
**约束**:
|
|
64
|
+
- 跨执行环境(如后端 server/ ↔ 前端 web/)必须通过 `contracts/` 共享类型与契约
|
|
65
|
+
- 不要在 server/ 中 import web/ 的文件,或反之
|
|
66
|
+
|
|
67
|
+
**没有机器守门**:单 app 模式下不强制 dependency-cruiser;这是有意为之,因为单 app 模式工程量小,引入额外工具收益不抵成本。
|
|
68
|
+
|
|
69
|
+
## 升级到多 app 模式
|
|
70
|
+
|
|
71
|
+
如果将来仓库需要容纳第二个应用:
|
|
72
|
+
|
|
73
|
+
1. `mkdir <env>/apps/<原应用名>` 并 `git mv` 全部源码
|
|
74
|
+
2. 同 PR 启用 `--multi-app` 选项,重新生成本文件 + `dependency-cruiser.config.cjs`
|
|
75
|
+
3. 在 ADR 中记录"为什么从单 app 升级"
|
|
76
|
+
4. 完整 promote / add-app 流程见 [`docs/governance/git-workflow.md`](../governance/git-workflow.md)
|
|
77
|
+
<% } %>
|
|
78
|
+
|
|
79
|
+
## 关联
|
|
80
|
+
|
|
81
|
+
- 编码规范:见 `coding-style-<lang>.md` 系列
|
|
82
|
+
- 部署:跨 app 共享配置走 `deploy/`,不要让一个 app 依赖另一个 app 的 deploy 制品
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
runtime: <%= it.standards.env %>
|
|
3
|
+
language: <%= it.standards.language %>
|
|
4
|
+
packageManager: <%= it.standards.packageManager %>
|
|
5
|
+
manifestPath: <%= it.standards.manifestPath %>
|
|
6
|
+
lastReviewed: <%= it.standards.lastReviewed %>
|
|
7
|
+
dependencies:
|
|
8
|
+
<% for (const dep of it.standards.dependencies) { %> - name: "<%= dep.name %>"
|
|
9
|
+
version: "<%= dep.version %>"
|
|
10
|
+
policy: <%= dep.policy %>
|
|
11
|
+
<% } %>---
|
|
12
|
+
|
|
13
|
+
# 桌面 / Agent 技术栈钉版本表
|
|
14
|
+
|
|
15
|
+
> frontmatter 是机器真值;governance-lint 会把上面 `dependencies` 与 `<%= it.standards.manifestPath %>` 的实际版本逐条比对。
|
|
16
|
+
|
|
17
|
+
## 为什么钉版本
|
|
18
|
+
|
|
19
|
+
- **桌面端发布周期长**:用户桌面上的版本几个月不更新很正常;不可重现的依赖会让远程 debug 极其痛苦
|
|
20
|
+
- **平台二进制兼容**:Tauri / Electron 的原生模块在 Windows / macOS / Linux 表现不一致,主版本变化最容易触发签名失败
|
|
21
|
+
|
|
22
|
+
## policy 三档
|
|
23
|
+
|
|
24
|
+
policy 语义与 [tech-stack-server.md](tech-stack-server.md) 一致。桌面端常用 `minor` 起步,对 `tokio` / `serde` 一类基础设施级依赖也只用 `minor`(Rust 生态的 SemVer 通常守得住)。
|
|
25
|
+
|
|
26
|
+
## Rust crate 特有的考虑
|
|
27
|
+
|
|
28
|
+
- workspace 中所有 crate 的同名依赖必须钉同一版本(`Cargo.toml` 中 `[workspace.dependencies]` 段)
|
|
29
|
+
- 与 C / C++ 共享库通过 FFI 交互的 crate(如 `openssl-sys`):标 `major-only`,因为底层 ABI 变化会导致 panic
|
|
30
|
+
- `unsafe` 较多的 crate:标 `major-only`,每次升级都人工 review CHANGELOG
|
|
31
|
+
|
|
32
|
+
## 关联
|
|
33
|
+
|
|
34
|
+
- 编码规范:[coding-style-rust.md](coding-style-rust.md)
|
|
35
|
+
- 依赖安全:[../governance/security.md](../governance/security.md)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
runtime: <%= it.standards.env %>
|
|
3
|
+
language: <%= it.standards.language %>
|
|
4
|
+
packageManager: <%= it.standards.packageManager %>
|
|
5
|
+
manifestPath: <%= it.standards.manifestPath %>
|
|
6
|
+
lastReviewed: <%= it.standards.lastReviewed %>
|
|
7
|
+
dependencies:
|
|
8
|
+
<% for (const dep of it.standards.dependencies) { %> - name: "<%= dep.name %>"
|
|
9
|
+
version: "<%= dep.version %>"
|
|
10
|
+
policy: <%= dep.policy %>
|
|
11
|
+
<% } %>---
|
|
12
|
+
|
|
13
|
+
# 小程序技术栈钉版本表
|
|
14
|
+
|
|
15
|
+
> frontmatter 是机器真值;governance-lint 会把上面 `dependencies` 与 `<%= it.standards.manifestPath %>` 的实际版本逐条比对。
|
|
16
|
+
|
|
17
|
+
## 为什么钉版本
|
|
18
|
+
|
|
19
|
+
- **平台 SDK 审核期长**:宿主(微信 / 支付宝 / 抖音)的基础库版本不在本表;本表管的是 npm 侧依赖
|
|
20
|
+
- **小程序包大小限制**:依赖增删都影响 2 MB / 8 MB 包限制;钉版本帮助定位"哪次升级把包撑爆了"
|
|
21
|
+
|
|
22
|
+
## policy 三档
|
|
23
|
+
|
|
24
|
+
policy 语义与 [tech-stack-server.md](tech-stack-server.md) 一致。小程序场景常用 `minor` + 严选第三方包。
|
|
25
|
+
|
|
26
|
+
## 宿主基础库
|
|
27
|
+
|
|
28
|
+
- 微信:`miniapp/project.config.json` 中的 `libVersion` 是宿主版本,非 npm 依赖;不进本表
|
|
29
|
+
- 自定义组件库(如 vant-weapp):进本表,policy 标 `minor`
|
|
30
|
+
|
|
31
|
+
## 关联
|
|
32
|
+
|
|
33
|
+
- 编码规范:[coding-style-typescript.md](coding-style-typescript.md)
|
|
34
|
+
- 依赖安全:[../governance/security.md](../governance/security.md)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
runtime: <%= it.standards.env %>
|
|
3
|
+
language: <%= it.standards.language %>
|
|
4
|
+
packageManager: <%= it.standards.packageManager %>
|
|
5
|
+
manifestPath: <%= it.standards.manifestPath %>
|
|
6
|
+
lastReviewed: <%= it.standards.lastReviewed %>
|
|
7
|
+
dependencies:
|
|
8
|
+
<% for (const dep of it.standards.dependencies) { %> - name: "<%= dep.name %>"
|
|
9
|
+
version: "<%= dep.version %>"
|
|
10
|
+
policy: <%= dep.policy %>
|
|
11
|
+
<% } %>---
|
|
12
|
+
|
|
13
|
+
# 移动端技术栈钉版本表
|
|
14
|
+
|
|
15
|
+
> frontmatter 是机器真值;governance-lint 会把上面 `dependencies` 与 `<%= it.standards.manifestPath %>` 的实际版本逐条比对。
|
|
16
|
+
|
|
17
|
+
## 为什么钉版本
|
|
18
|
+
|
|
19
|
+
- **应用商店审核失败回溯**:移动端经常因第三方 SDK 更新触发审核拒绝;版本钉死能精确定位
|
|
20
|
+
- **多设备一致性**:CI 与开发机装出同一份依赖
|
|
21
|
+
- **离线场景**:移动端不像服务端能随时回滚镜像,钉版本是唯一保险
|
|
22
|
+
|
|
23
|
+
## policy 三档
|
|
24
|
+
|
|
25
|
+
policy 语义、调整流程,与 [tech-stack-server.md](tech-stack-server.md) 一致。
|
|
26
|
+
|
|
27
|
+
## 移动端特有的考虑
|
|
28
|
+
|
|
29
|
+
- iOS 系统 API / Android SDK 不归本表管,由 `mobile/ios/Podfile` 与 `mobile/android/build.gradle` 中的对应版本约束
|
|
30
|
+
- React Native / Flutter SDK 主版本升级常涉及原生模块重新链接;务必标 `major-only`
|
|
31
|
+
- 推送、地图、支付 SDK:标 `major-only`(合规要求强约束)
|
|
32
|
+
|
|
33
|
+
## 关联
|
|
34
|
+
|
|
35
|
+
- 编码规范:[coding-style-<%= it.standards.language %>.md](coding-style-<%= it.standards.language %>.md)
|
|
36
|
+
- 依赖安全:[../governance/security.md](../governance/security.md)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
runtime: <%= it.standards.env %>
|
|
3
|
+
language: <%= it.standards.language %>
|
|
4
|
+
packageManager: <%= it.standards.packageManager %>
|
|
5
|
+
manifestPath: <%= it.standards.manifestPath %>
|
|
6
|
+
lastReviewed: <%= it.standards.lastReviewed %>
|
|
7
|
+
dependencies:
|
|
8
|
+
<% for (const dep of it.standards.dependencies) { %> - name: "<%= dep.name %>"
|
|
9
|
+
version: "<%= dep.version %>"
|
|
10
|
+
policy: <%= dep.policy %>
|
|
11
|
+
<% } %>---
|
|
12
|
+
|
|
13
|
+
# 后端技术栈钉版本表
|
|
14
|
+
|
|
15
|
+
> 这个文件的 **frontmatter 是机器真值**:CI 中的 `governance-lint` 会把上面 `dependencies` 数组与 `<%= it.standards.manifestPath %>` 的实际版本逐条对比。
|
|
16
|
+
>
|
|
17
|
+
> 本文件正文是**为什么**这样选 + **如何调整**。机器无法回答这两个问题。
|
|
18
|
+
|
|
19
|
+
## 为什么钉版本
|
|
20
|
+
|
|
21
|
+
- **审计可追溯**:哪天升级、为什么升级、谁拍板,都留在这个文件的 git 历史里
|
|
22
|
+
- **可重现构建**:六个月后回到这个 commit,依赖能装出同一棵树
|
|
23
|
+
- **AI 不擅自升级**:scaffolder 的 governance-lint 把"未走 PR 的 minor / major 漂移"当作 CI 失败
|
|
24
|
+
|
|
25
|
+
## policy 三档
|
|
26
|
+
|
|
27
|
+
| policy | 含义 | 何时使用 |
|
|
28
|
+
|--------|------|----------|
|
|
29
|
+
| `free` | 任意漂移都不报 | 工具链辅助包(如类型 stub),版本变化不影响业务 |
|
|
30
|
+
| `minor` | minor / patch 漂移 → warning;major → error | 默认。绝大多数 runtime 框架与库 |
|
|
31
|
+
| `major-only` | 任何漂移(含 patch)→ error | 安全敏感库(加密、token 验证、SSO) |
|
|
32
|
+
|
|
33
|
+
## 调整流程
|
|
34
|
+
|
|
35
|
+
1. 改 `<%= it.standards.manifestPath %>` 中的版本(或让包管理器自动 bump)
|
|
36
|
+
2. 同 PR 改本文件 frontmatter 的对应行;这是**双写**有意为之,让 PR review 必须看到版本变化
|
|
37
|
+
3. CI 中 `governance-lint` 验证两边一致;不一致就阻断
|
|
38
|
+
4. PR 描述中说明:升级动机(功能 / 安全 / 性能)+ 兼容性影响
|
|
39
|
+
|
|
40
|
+
## 何时**不**钉
|
|
41
|
+
|
|
42
|
+
- 仅开发期使用的 lint / format / 测试工具:可以放在 `devDependencies` 但**不**进本表
|
|
43
|
+
- 容器基础镜像版本:在 `deploy/Dockerfile` 里钉,本表不重复
|
|
44
|
+
- 系统包(apt / yum):交给运行时镜像维护者
|
|
45
|
+
|
|
46
|
+
## 关联
|
|
47
|
+
|
|
48
|
+
- 编码规范:[coding-style-<%= it.standards.language %>.md](coding-style-<%= it.standards.language %>.md)
|
|
49
|
+
- 依赖安全:[../governance/security.md](../governance/security.md)
|
|
50
|
+
- 升级流程模板:参考最近的 PR 历史 `git log --grep="bump"`
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
runtime: <%= it.standards.env %>
|
|
3
|
+
language: <%= it.standards.language %>
|
|
4
|
+
packageManager: <%= it.standards.packageManager %>
|
|
5
|
+
manifestPath: <%= it.standards.manifestPath %>
|
|
6
|
+
lastReviewed: <%= it.standards.lastReviewed %>
|
|
7
|
+
dependencies:
|
|
8
|
+
<% for (const dep of it.standards.dependencies) { %> - name: "<%= dep.name %>"
|
|
9
|
+
version: "<%= dep.version %>"
|
|
10
|
+
policy: <%= dep.policy %>
|
|
11
|
+
<% } %>---
|
|
12
|
+
|
|
13
|
+
# 前端 / Web 技术栈钉版本表
|
|
14
|
+
|
|
15
|
+
> frontmatter 是机器真值;governance-lint 会把上面 `dependencies` 与 `<%= it.standards.manifestPath %>` 的实际版本逐条比对。
|
|
16
|
+
|
|
17
|
+
## 为什么钉版本
|
|
18
|
+
|
|
19
|
+
- **审计可追溯**:升级历史进 git,PR review 看得到
|
|
20
|
+
- **可重现构建**:CI cache 一致;六个月后能装出同一棵 lockfile
|
|
21
|
+
|
|
22
|
+
## policy 三档
|
|
23
|
+
|
|
24
|
+
policy 字段的语义、调整流程、不钉的例外,与 [tech-stack-server.md](tech-stack-server.md) 一致。本文件不重复。
|
|
25
|
+
|
|
26
|
+
## Web 特有的考虑
|
|
27
|
+
|
|
28
|
+
- React / Vue 的 minor 升级常带 hooks API 改动;新增 `policy: minor` 表示"先发 warning,看到再合"
|
|
29
|
+
- `typescript` 单独列为 minor:tsc 主版本变化几乎一定要改代码
|
|
30
|
+
- bundler(Vite / Webpack)和 polyfill 工具链版本若进 production bundle,必须钉;纯 dev 工具不进本表
|
|
31
|
+
|
|
32
|
+
## 关联
|
|
33
|
+
|
|
34
|
+
- 编码规范:[coding-style-typescript.md](coding-style-typescript.md)
|
|
35
|
+
- UI 设计系统:[../05-前端客户端详细设计/ui-design-system.md](../05-前端客户端详细设计/ui-design-system.md)(启用 design 角色或 full 档时存在)
|
|
36
|
+
- 依赖安全:[../governance/security.md](../governance/security.md)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# UI 设计系统
|
|
2
|
+
|
|
3
|
+
> 这是 UI / 视觉真值的入口。设计稿仍在 Figma;本文件 + `web/src/design-tokens.ts` 是工程侧能消费的版本。
|
|
4
|
+
>
|
|
5
|
+
> governance-lint 的 `GOV.UI.TOKEN_DRIFT` 检查会比对本文件 token 表与 `design-tokens.ts` 的 export 名集合,发现差异即阻断。
|
|
6
|
+
|
|
7
|
+
## Token 表
|
|
8
|
+
|
|
9
|
+
下面三类 token 是 design-tokens.ts 的真值;改一项,必须同 PR 改 ts 文件中对应 export。
|
|
10
|
+
|
|
11
|
+
### 颜色
|
|
12
|
+
|
|
13
|
+
| name | 值 | 用途 |
|
|
14
|
+
|------|-----|------|
|
|
15
|
+
| `colorPrimary` | `#2563EB` | 主操作按钮、链接 |
|
|
16
|
+
| `colorSurface` | `#FFFFFF` | 卡片 / 模态背景 |
|
|
17
|
+
| `colorTextDefault` | `#0F172A` | 默认文本 |
|
|
18
|
+
| `colorTextMuted` | `#64748B` | 次要 / 辅助文本 |
|
|
19
|
+
| `colorBorder` | `#E2E8F0` | 分隔线 / 输入框边框 |
|
|
20
|
+
| `colorDanger` | `#DC2626` | 错误状态、危险操作 |
|
|
21
|
+
|
|
22
|
+
### 间距(spacing scale)
|
|
23
|
+
|
|
24
|
+
按 4px 基线倍数;**禁止**使用任意像素值。
|
|
25
|
+
|
|
26
|
+
| name | 值 | 用途 |
|
|
27
|
+
|------|-----|------|
|
|
28
|
+
| `space1` | `4px` | 紧凑(图标到文字) |
|
|
29
|
+
| `space2` | `8px` | 表单字段内 |
|
|
30
|
+
| `space3` | `12px` | 默认内边距 |
|
|
31
|
+
| `space4` | `16px` | 卡片内边距 |
|
|
32
|
+
| `space6` | `24px` | 卡片间距 |
|
|
33
|
+
| `space8` | `32px` | 区块间距 |
|
|
34
|
+
|
|
35
|
+
### 字号(typography)
|
|
36
|
+
|
|
37
|
+
| name | 值 | 用途 |
|
|
38
|
+
|------|-----|------|
|
|
39
|
+
| `fontHeading1` | `32px / 1.25 / 600` | 页面 H1 |
|
|
40
|
+
| `fontHeading2` | `24px / 1.3 / 600` | 区块标题 |
|
|
41
|
+
| `fontBody` | `14px / 1.5 / 400` | 正文 |
|
|
42
|
+
| `fontCaption` | `12px / 1.4 / 400` | 辅助说明 |
|
|
43
|
+
|
|
44
|
+
## 组件命名
|
|
45
|
+
|
|
46
|
+
组件库统一前缀,避免与第三方库冲突:
|
|
47
|
+
|
|
48
|
+
- `KButton` —— 主按钮 / 次按钮 / 危险按钮三态由 prop 切换
|
|
49
|
+
- `KModal` —— 模态对话框;标题 / 内容 / footer 三槽位
|
|
50
|
+
- `KFormItem` —— 表单单项;label + 控件 + 错误提示
|
|
51
|
+
|
|
52
|
+
新增组件命名遵循同前缀;超过组件库范围(业务组件)走 PascalCase 不加前缀。
|
|
53
|
+
|
|
54
|
+
## 调整流程
|
|
55
|
+
|
|
56
|
+
1. 设计在 Figma 改 token;导出 SVG / PNG 到 `docs/design/figma-exports/`
|
|
57
|
+
2. 同 PR 改本文件 token 表 + `web/src/design-tokens.ts` 中对应 export
|
|
58
|
+
3. CI 跑 `governance-lint`:本表 token 名集合必须等于 design-tokens.ts 的 export 集合
|
|
59
|
+
4. 若故意要让两边不同(极少见),删除本文件,改用其他 token 真值(需要新 ADR)
|
|
60
|
+
|
|
61
|
+
## 何时**不**用本系统
|
|
62
|
+
|
|
63
|
+
- 第三方组件库自带的 token:直接用;不要 wrap 一层把它们重命名成 K 前缀
|
|
64
|
+
- 一次性的展示页(活动 banner、营销页):可以脱离本系统,但不要把脱离的 token 散播到通用组件中
|
|
65
|
+
|
|
66
|
+
## 关联
|
|
67
|
+
|
|
68
|
+
- 配色无障碍要求:所有 `colorText*` 与对应 `colorSurface*` 的对比度必须 ≥ 4.5:1(WCAG AA)
|
|
69
|
+
- 设计稿源:`docs/design/figma-exports/`
|
|
70
|
+
- 二进制 Figma 源文件:走 LFS(见 [`docs/governance/assets.md`](../governance/assets.md))
|
|
@@ -35,9 +35,20 @@ npx @wneng/create-keel create my-full \
|
|
|
35
35
|
--agent rust-desktop --deploy kubernetes --contract rest+events \
|
|
36
36
|
--ai kiro --license apache-2.0 --gitLfs --integrations \
|
|
37
37
|
--ci github --roles qa,field,data,legal-security,marketing,design \
|
|
38
|
+
--engineering-standards full \
|
|
38
39
|
--yes
|
|
39
40
|
```
|
|
40
41
|
|
|
42
|
+
### 0.1.1 工程规范是另一个正交维度
|
|
43
|
+
|
|
44
|
+
档位决定 *目录与角色* 的启用范围;`--engineering-standards <tier>` 决定 *栈版本钉死、编码风格、模块边界、UI 设计系统* 的生成范围:
|
|
45
|
+
|
|
46
|
+
| `--engineering-standards` | 启用 | 默认 |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `lite` | 仅每语言 `coding-style-<lang>.md` + 对应 lint 配置 | —— |
|
|
49
|
+
| `standard` | + `tech-stack-<env>.md` + `module-boundaries.md` + (multi-app + JS/TS)`dependency-cruiser.config.cjs` | ✓ `--yes` 默认 |
|
|
50
|
+
| `full` | + `ui-design-system.md` + `web/src/design-tokens.ts`(启用 frontend 时) | —— |
|
|
51
|
+
|
|
41
52
|
**已有项目升档**:
|
|
42
53
|
|
|
43
54
|
| 升档动作 | 操作 |
|