@teamix-evo/skills 0.12.1 → 0.13.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/README.md +1 -1
- package/manifest.json +11 -28
- package/package.json +2 -2
- package/src/teamix-evo-code-opentrek/SKILL.md +13 -13
- package/src/teamix-evo-code-opentrek/api-layering.md +53 -44
- package/src/teamix-evo-code-opentrek/checklist.md +24 -24
- package/src/teamix-evo-code-opentrek/file-structure.md +55 -36
- package/src/teamix-evo-code-opentrek/forms-and-validation.md +17 -16
- package/src/teamix-evo-code-opentrek/reuse-first.md +6 -9
- package/src/teamix-evo-code-opentrek/testing.md +14 -14
- package/src/teamix-evo-code-uni-manager/SKILL.md +15 -15
- package/src/teamix-evo-code-uni-manager/api-layering.md +74 -58
- package/src/teamix-evo-code-uni-manager/checklist.md +28 -28
- package/src/teamix-evo-code-uni-manager/error-and-loading.md +2 -2
- package/src/teamix-evo-code-uni-manager/file-structure.md +77 -62
- package/src/teamix-evo-code-uni-manager/forms-and-validation.md +17 -15
- package/src/teamix-evo-code-uni-manager/reuse-first.md +7 -10
- package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +1 -1
- package/src/teamix-evo-code-uni-manager/testing.md +37 -37
- package/src/teamix-evo-design-opentrek/SKILL.md +17 -20
- package/src/teamix-evo-design-opentrek/boundaries.md +1 -1
- package/src/teamix-evo-design-opentrek/checklist.md +5 -5
- package/src/teamix-evo-design-opentrek/components.md +19 -19
- package/src/teamix-evo-design-opentrek/examples/standard-card-list.html +1 -1
- package/src/teamix-evo-design-opentrek/examples/standard-table-list.html +1 -1
- package/src/teamix-evo-design-opentrek/foundations.md +6 -6
- package/src/teamix-evo-design-opentrek/pages/dashboard-page/SKILL.md +18 -19
- package/src/teamix-evo-design-opentrek/pages/dashboard-page/patterns/dashboard-opentrek.md +6 -6
- package/src/teamix-evo-design-opentrek/pages/detail-page/SKILL.md +24 -25
- package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/api-doc-detail.md +3 -7
- package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/comparison-detail.md +3 -7
- package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/monitor-detail.md +3 -7
- package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/resource-detail.md +10 -10
- package/src/teamix-evo-design-opentrek/pages/form-page/SKILL.md +26 -27
- package/src/teamix-evo-design-opentrek/pages/list-page/SKILL.md +35 -36
- package/src/teamix-evo-design-opentrek/pages/list-page/_shared/item-card-spec.md +41 -32
- package/src/teamix-evo-design-opentrek/pages/list-page/patterns/card-list-opentrek.md +10 -10
- package/src/teamix-evo-design-opentrek/pages/list-page/patterns/card-list.md +23 -23
- package/src/teamix-evo-design-opentrek/pages/list-page/patterns/standard-list-opentrek.md +8 -8
- package/src/teamix-evo-design-opentrek/pages/list-page/patterns/standard-list.md +8 -8
- package/src/teamix-evo-design-opentrek/patterns/color-mapping.md +2 -2
- package/src/teamix-evo-design-opentrek/patterns/dashboard.md +1 -1
- package/src/teamix-evo-design-opentrek/patterns/detail-page.md +9 -9
- package/src/teamix-evo-design-opentrek/patterns/form-page.md +6 -6
- package/src/teamix-evo-design-opentrek/patterns/list-page.md +9 -9
- package/src/teamix-evo-design-opentrek/patterns/page-types.md +3 -3
- package/src/teamix-evo-design-opentrek/principles.md +541 -0
- package/src/teamix-evo-design-opentrek/rules/common-components.json +206 -76
- package/src/teamix-evo-design-opentrek/rules/component-specs.json +2 -2
- package/src/teamix-evo-design-opentrek/rules/page-frame.json +197 -193
- package/src/teamix-evo-design-opentrek/{generation-flow.md → workflow.md} +141 -22
- package/src/teamix-evo-design-uni-manager/SKILL.md +5 -5
- package/src/teamix-evo-design-uni-manager/boundaries.md +2 -2
- package/src/teamix-evo-design-uni-manager/brand.md +1 -1
- package/src/teamix-evo-design-uni-manager/checklist.md +2 -2
- package/src/teamix-evo-design-uni-manager/components.md +11 -11
- package/src/teamix-evo-design-uni-manager/foundations.md +7 -7
- package/src/teamix-evo-design-uni-manager/generation-flow.md +3 -3
- package/src/teamix-evo-manage/SKILL.md +111 -709
- package/src/teamix-evo-manage/init.md +98 -0
- package/src/teamix-evo-manage/migrate.md +100 -0
- package/src/teamix-evo-manage/rearchitect-capture-guide.md +174 -0
- package/src/teamix-evo-manage/rearchitect.md +373 -0
- package/src/teamix-evo-manage/update-component-staging.md +188 -0
- package/src/teamix-evo-manage/update-token-rename.md +126 -0
- package/src/teamix-evo-manage/update-token-treatment.md +116 -0
- package/src/teamix-evo-manage/update.md +213 -0
- package/src/teamix-evo-design-opentrek/brand.md +0 -154
- package/src/teamix-evo-design-opentrek/pages/list-page/_shared/search-combo-spec.md +0 -194
- package/src/teamix-evo-design-opentrek/philosophy.md +0 -98
- package/src/teamix-evo-design-opentrek/rules/README.md +0 -39
- package/src/teamix-evo-design-opentrek/rules/_assets/OP_AGENT RUNTIME.svg +0 -1
- package/src/teamix-evo-design-opentrek/rules/_assets/OP_AI GATEWAY.svg +0 -1
- package/src/teamix-evo-design-opentrek/rules/_assets/OP_AI STUDIO.svg +0 -1
- package/src/teamix-evo-design-opentrek/rules/_assets/OP_DEV-2.svg +0 -1
- package/src/teamix-evo-design-opentrek/rules/_assets/OP_LOGO.svg +0 -1
- package/src/teamix-evo-design-opentrek/rules/_assets/OP_OPS.svg +0 -1
- package/src/teamix-evo-design-opentrek/rules/layout-rules.json +0 -218
- package/src/teamix-evo-design-opentrek/rules/page-header-spec.md +0 -123
- package/src/teamix-evo-design-opentrek/rules/sidebar-spec.md +0 -217
- package/src/teamix-evo-upgrade/SKILL.md +0 -431
- /package/src/teamix-evo-design-opentrek/{rules/boundaries.rules.json → boundaries.json} +0 -0
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ pnpm --filter @teamix-evo/skills scaffold:skill
|
|
|
39
39
|
|
|
40
40
|
## 消费态命令(CLI)
|
|
41
41
|
|
|
42
|
-
由 `teamix-evo skills` 子命令族管理(
|
|
42
|
+
由 `teamix-evo skills` 子命令族管理(npm 包直接渲染到 IDE 镜像,见 [ADR 0013](../../docs/adr/0013-skills-source-mirror.md)):
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
teamix-evo skills init # 自举:按 variant + scope 全装符合条件的 skill(ADR 0034)
|
package/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://teamix-evo.dev/schema/skills-package/v1.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
4
|
"package": "skills",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.13.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"teamix-evo": ">=0.1.0"
|
|
8
8
|
},
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
{
|
|
11
11
|
"id": "teamix-evo-manage",
|
|
12
12
|
"name": "teamix-evo-manage",
|
|
13
|
-
"description": "Single entry point for the teamix-evo lifecycle:
|
|
14
|
-
"version": "0.
|
|
13
|
+
"description": "Single entry point for the teamix-evo lifecycle: init, update, migrate, switch, restore, uninstall.\nTRIGGER when: user runs or asks about `teamix-evo init` / `teamix-evo tokens ...` / `teamix-evo skills ...` / `teamix-evo ui ...` / `teamix-evo biz-ui ...` / `teamix-evo blocks ...` / `teamix-evo lint ...` / `teamix-evo migrate` / `teamix-evo restore ...` / `teamix-evo switch ...`; mentions 初始化/接入/更新/升级/迁移/卸载/staging/codemod/token 治理/baseline; touches `.teamix-evo/config.json` or `manifest.json`.\nSKIP: content tasks — components, pages, services (→ code-*); visual design review (→ design-*); pure styling / token tweaks (→ ESLint).\nCoordinates with: teamix-evo-design-* / teamix-evo-code-* — manage precedes content skills, never co-triggers.",
|
|
14
|
+
"version": "0.13.0",
|
|
15
15
|
"source": "src/teamix-evo-manage",
|
|
16
16
|
"ides": [
|
|
17
17
|
"qoder",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
{
|
|
28
28
|
"id": "teamix-evo-design-opentrek",
|
|
29
29
|
"name": "teamix-evo-design-opentrek",
|
|
30
|
-
"description": "Apply OpenTrek design system rules
|
|
31
|
-
"version": "0.
|
|
30
|
+
"description": "Apply OpenTrek design system rules when AI generates or reviews a full UI screen / page.\nTRIGGER when: user asks to 新建/优化/重构 页面, create/review/refactor a page/screen/dashboard; intent involves layout structure or multi-component composition; file write under `src/pages/**`.\nSKIP: single-component edits (加按钮, 改 label); pure tokens/theme overrides; pure code refactor with no visual change; lifecycle commands (→ teamix-evo-manage).\nCoordinates with: teamix-evo-code-opentrek (run alongside when the screen also creates new files).",
|
|
31
|
+
"version": "0.13.0",
|
|
32
32
|
"source": "src/teamix-evo-design-opentrek",
|
|
33
33
|
"variant": "opentrek",
|
|
34
34
|
"ides": [
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
{
|
|
45
45
|
"id": "teamix-evo-code-opentrek",
|
|
46
46
|
"name": "teamix-evo-code-opentrek",
|
|
47
|
-
"description": "Enforce teamix-evo coding conventions in OpenTrek
|
|
48
|
-
"version": "0.
|
|
47
|
+
"description": "Enforce teamix-evo coding conventions in OpenTrek apps — reuse-first, `src/` layering, import boundaries.\nTRIGGER when: user asks to 新增/重构/写 组件/页面/接口/hook; phrases like \"create a CRUD page\" / \"add an API call\" / \"调接口\" / \"加组件\"; file write under `src/pages/**`, `src/components/**`, `src/features/**`.\nSKIP: pure visual/layout design with no code change (→ design-opentrek); lifecycle commands (→ manage); token/style-only changes (→ ESLint).\nCoordinates with: teamix-evo-design-opentrek (design handles visual side, this skill handles file placement and reuse).",
|
|
48
|
+
"version": "0.13.0",
|
|
49
49
|
"source": "src/teamix-evo-code-opentrek",
|
|
50
50
|
"variant": "opentrek",
|
|
51
51
|
"ides": [
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
{
|
|
62
62
|
"id": "teamix-evo-design-uni-manager",
|
|
63
63
|
"name": "teamix-evo-design-uni-manager",
|
|
64
|
-
"description": "Apply Uni-Manager design system rules
|
|
65
|
-
"version": "0.
|
|
64
|
+
"description": "Apply Uni-Manager design system rules when AI generates or reviews a UI screen / page (专有云/混合云/云管).\nTRIGGER when: user asks to 新建/优化/重构 页面/控制台/仪表盘, create/review/refactor a page/dashboard/console; intent involves layout or multi-component composition; file write under `src/pages/**`.\nSKIP: single-component edits; pure tokens/theme overrides; pure code refactor with no visual change; lifecycle commands (→ teamix-evo-manage).\nCoordinates with: teamix-evo-code-uni-manager (run alongside when the screen also creates new files).",
|
|
65
|
+
"version": "0.13.0",
|
|
66
66
|
"source": "src/teamix-evo-design-uni-manager",
|
|
67
67
|
"variant": "uni-manager",
|
|
68
68
|
"ides": [
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
{
|
|
79
79
|
"id": "teamix-evo-code-uni-manager",
|
|
80
80
|
"name": "teamix-evo-code-uni-manager",
|
|
81
|
-
"description": "Enforce teamix-evo coding conventions in uni-manager
|
|
82
|
-
"version": "0.
|
|
81
|
+
"description": "Enforce teamix-evo coding conventions in uni-manager apps — reuse-first, tenant/region context propagation, `src/` layering.\nTRIGGER when: user asks to 新增/重构/写 组件/页面/接口/hook in a 云管/专有云/多租户 console; phrases like \"create a CRUD page\" / \"add an API call\" / \"调接口\"; file write under `src/pages/**`, `src/components/**`, `src/features/**`.\nSKIP: pure visual/layout design with no code change (→ design-uni-manager); lifecycle commands (→ manage); token/style-only changes (→ ESLint).\nCoordinates with: teamix-evo-design-uni-manager (design handles visual side, this skill handles file placement and reuse).",
|
|
82
|
+
"version": "0.13.0",
|
|
83
83
|
"source": "src/teamix-evo-code-uni-manager",
|
|
84
84
|
"variant": "uni-manager",
|
|
85
85
|
"ides": [
|
|
@@ -91,23 +91,6 @@
|
|
|
91
91
|
"core"
|
|
92
92
|
],
|
|
93
93
|
"template": false
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"id": "teamix-evo-upgrade",
|
|
97
|
-
"name": "teamix-evo-upgrade",
|
|
98
|
-
"description": "Help the user adopt token renames in `.teamix-evo/.upgrade-hints/tokens-<ts>.json` AND component source upgrades in `.teamix-evo/.upgrade-staging/{ui,biz-ui}-<ts>/` after `teamix-evo update` / `teamix-evo tokens update` / `teamix-evo switch` / `teamix-evo ui upgrade` / `teamix-evo biz-ui upgrade`. Read each hint or staging manifest, scan the project for usages or compare current vs incoming source, propose codemod / file-replace diffs, apply only after explicit user approval, then archive processed inputs.\nTRIGGER when: user references `.teamix-evo/.upgrade-hints/`、`.teamix-evo/.upgrade-staging/`、`tokens-*.json` hint files、`ui-*` or `biz-ui-*` staging directories、phrases like \"处理 token 改名\"、\"应用 codemod\"、\"扫一下 legacy token\"、\"升级 token 引用\"、\"更新 token 名\"、\"组件升级\"、\"ui-staging\"、\"biz-ui staging\"、\"apply ui staging\"、\"apply biz-ui staging\"、\"应用组件升级\"、\"apply token rename codemod\"、\"adopt token rename hints\"、\"scan for legacy tokens\"、\"token rename upgrade\"、\"component source upgrade\"、\"review ui staging diff\"、\"token 治理\"、\"tokens diagnose\"、\"tokens treat\"、\"治理计划\"、\".treatment-plan.md\"、\"baseline 锁定\"、\"token 反哺\"、\"清理 token 违规\"、\"token cleanup\"、\"lint baseline\"、\"降违规\"、\"全部治理\"; AI sees output of `teamix-evo update` / `teamix-evo tokens update` / `teamix-evo switch --apply` / `teamix-evo ui upgrade` / `teamix-evo biz-ui upgrade` mentioning `💡 token rename hint:` or `staging at .teamix-evo/.upgrade-staging/...` and the user wants to follow up; AI sees output of `teamix-evo init` showing token-discipline ESLint warnings and the user wants to clean up; user opens any `.teamix-evo/.upgrade-hints/tokens-*.json` or any file under `.teamix-evo/.upgrade-staging/{ui,biz-ui}-*/` or `.teamix-evo/.treatment-plan.md`.\nSKIP: any other lifecycle work — `init` / `update` orchestration / variant switch itself / install / uninstall / generating staging (defer to teamix-evo-manage); pure visual or design changes (defer to teamix-evo-design-<variant>); any code authoring unrelated to the rename / staging window (defer to teamix-evo-code-<variant>); refuse to auto-apply — never write source code without explicit per-file user confirmation.\nCoordinates with: teamix-evo-manage (manage drives the upgrade flow that emits hints + staging; this skill consumes the resulting files).",
|
|
99
|
-
"version": "0.2.0",
|
|
100
|
-
"source": "src/teamix-evo-upgrade",
|
|
101
|
-
"ides": [
|
|
102
|
-
"qoder",
|
|
103
|
-
"claude"
|
|
104
|
-
],
|
|
105
|
-
"updateStrategy": "managed",
|
|
106
|
-
"managedRegions": [
|
|
107
|
-
"core"
|
|
108
|
-
],
|
|
109
|
-
"template": false,
|
|
110
|
-
"scope": "global"
|
|
111
94
|
}
|
|
112
95
|
]
|
|
113
96
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamix-evo/skills",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Skills (AI IDE capabilities) for Teamix Evo",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@clack/prompts": "^0.8.0",
|
|
14
14
|
"tsx": "^4.0.0",
|
|
15
|
-
"@teamix-evo/registry": "0.
|
|
15
|
+
"@teamix-evo/registry": "0.14.0"
|
|
16
16
|
},
|
|
17
17
|
"publishConfig": {
|
|
18
18
|
"access": "public",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: teamix-evo-code-opentrek
|
|
3
3
|
description: |
|
|
4
|
-
Enforce teamix-evo coding conventions in OpenTrek
|
|
5
|
-
TRIGGER when: user asks to
|
|
6
|
-
SKIP: pure visual
|
|
7
|
-
Coordinates with: teamix-evo-design-opentrek (
|
|
4
|
+
Enforce teamix-evo coding conventions in OpenTrek apps — reuse-first, `src/` layering, import boundaries.
|
|
5
|
+
TRIGGER when: user asks to 新增/重构/写 组件/页面/接口/hook; phrases like "create a CRUD page" / "add an API call" / "调接口" / "加组件"; file write under `src/pages/**`, `src/components/**`, `src/features/**`.
|
|
6
|
+
SKIP: pure visual/layout design with no code change (→ design-opentrek); lifecycle commands (→ manage); token/style-only changes (→ ESLint).
|
|
7
|
+
Coordinates with: teamix-evo-design-opentrek (design handles visual side, this skill handles file placement and reuse).
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# teamix-evo-code-opentrek
|
|
@@ -23,7 +23,7 @@ Activate this skill whenever AI is about to **write or refactor code** inside a
|
|
|
23
23
|
- "把这段重构一下"
|
|
24
24
|
- "create a CRUD page for orders"
|
|
25
25
|
- "add an API call to fetch users"
|
|
26
|
-
- Any time AI is about to create a new file under `src/pages/`、`src/components/`、`src/
|
|
26
|
+
- Any time AI is about to create a new file under `src/pages/`、`src/components/`、`src/features/`
|
|
27
27
|
|
|
28
28
|
If the task is purely about _visual design_ of a screen (layout / colors / spacing), use [`teamix-evo-design`](../teamix-evo-design/SKILL.md) instead — or run both in tandem.
|
|
29
29
|
|
|
@@ -31,10 +31,10 @@ If the task is purely about _visual design_ of a screen (layout / colors / spaci
|
|
|
31
31
|
|
|
32
32
|
Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-4 are baseline (**必须执行,不得跳过**); steps 5-7 are topic gates (run when the task touches that topic); step 8 is the final self-review (**必须执行,不得跳过**).
|
|
33
33
|
|
|
34
|
-
1. **🚧 Reuse-first check** — **MUST READ** [`reuse-first.md`](reuse-first.md). Before creating any new component, query the `@teamix-evo/ui` registry (via
|
|
35
|
-
2. **🚧 Layering check** — **MUST READ** [`api-layering.md`](api-layering.md). Any code that talks to a backend goes under `src/
|
|
36
|
-
3. **🚧 Directory check** — **MUST READ** [`file-structure.md`](file-structure.md). Place the new file under the right top-level folder (pages / components /
|
|
37
|
-
4. **🚧 Forms gate** — if the task involves a form, **MUST READ** [`forms-and-validation.md`](forms-and-validation.md). `react-hook-form` + `zod`; schema lives at `src/
|
|
34
|
+
1. **🚧 Reuse-first check** — **MUST READ** [`reuse-first.md`](reuse-first.md). Before creating any new component, query the `@teamix-evo/ui` registry (via `.teamix-evo/meta/ui/manifest.json` + `<id>.md`) and grep the local project. Only write new code when no reuse path exists.
|
|
35
|
+
2. **🚧 Layering check** — **MUST READ** [`api-layering.md`](api-layering.md). Any code that talks to a backend goes under `src/features/<domain>/api.ts`. Components never call `fetch` / `axios` directly. Data hooks live in `src/features/<domain>/hooks.ts` and consume api functions.
|
|
36
|
+
3. **🚧 Directory check** — **MUST READ** [`file-structure.md`](file-structure.md). Place the new file under the right top-level folder (pages / components / features / utils / lib / stores / contexts). Each folder has a single responsibility and an import boundary.
|
|
37
|
+
4. **🚧 Forms gate** — if the task involves a form, **MUST READ** [`forms-and-validation.md`](forms-and-validation.md). `react-hook-form` + `zod`; schema lives at `src/features/<domain>/schema.ts`. Never wire forms with raw `useState`.
|
|
38
38
|
5. **Error/loading gate** — if the task adds a page or data hook, **MUST READ** [`error-and-loading.md`](error-and-loading.md). Ensure global ErrorBoundary, page-level fallback, and three-state handling (`isPending` / `isError` / data) are in place; mutations report success/error via `toast`.
|
|
39
39
|
6. **Routing gate** — if the task adds a route or page-entry, **MUST READ** [`routing-and-codesplit.md`](routing-and-codesplit.md). Pages use `React.lazy`; auth/role guards live in `src/routes/guards.tsx`; 404 / 403 / 500 fallbacks exist.
|
|
40
40
|
7. **Testing gate** — **MUST READ** [`testing.md`](testing.md). Pure functions and zod schemas are **mandatory** to test; hooks and reusable components are recommended. Test files sit next to the source as `*.test.ts(x)`; `vitest` + `@testing-library/react` + `msw`.
|
|
@@ -50,14 +50,14 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
|
|
|
50
50
|
|
|
51
51
|
## Outputs
|
|
52
52
|
|
|
53
|
-
- Code placed under the conventional path (`src/pages/<id>/`、`src/
|
|
53
|
+
- Code placed under the conventional path (`src/pages/<id>/`、`src/features/<domain>/api.ts`、…)
|
|
54
54
|
- Reuse decisions explicitly logged ("reused `Button` from `@teamix-evo/ui`" / "no match found, wrote a new `OrderCard` under `src/components/`")
|
|
55
55
|
- Pass / fail status against [`checklist.md`](checklist.md)
|
|
56
56
|
|
|
57
57
|
## How to invoke (typical flow)
|
|
58
58
|
|
|
59
59
|
1. Parse user intent → identify which artifact is being created (page / component / service / hook / util / form / route)
|
|
60
|
-
2. Read [`reuse-first.md`](reuse-first.md) and run the reuse query (
|
|
60
|
+
2. Read [`reuse-first.md`](reuse-first.md) and run the reuse query (读 `.teamix-evo/meta/` 本地文件, then local grep)
|
|
61
61
|
3. Read [`file-structure.md`](file-structure.md) to pick the destination directory
|
|
62
62
|
4. If the change touches network / backend, read [`api-layering.md`](api-layering.md)
|
|
63
63
|
5. If the change involves a form, read [`forms-and-validation.md`](forms-and-validation.md)
|
|
@@ -73,7 +73,7 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
|
|
|
73
73
|
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
|
74
74
|
| [`reuse-first.md`](reuse-first.md) | Decision flow for reusing existing components / utilities before writing new ones |
|
|
75
75
|
| [`file-structure.md`](file-structure.md) | Top-level `src/` folder layout、ownership、import boundaries、naming、global-state tier (useState → Context → store) |
|
|
76
|
-
| [`api-layering.md`](api-layering.md) | Where API code lives (`src/
|
|
76
|
+
| [`api-layering.md`](api-layering.md) | Where API code lives (`src/features/<domain>/`)、how data flows from api → hook → component |
|
|
77
77
|
| [`forms-and-validation.md`](forms-and-validation.md) | `react-hook-form` + `zod` patterns、schema location、submit/error wiring |
|
|
78
78
|
| [`error-and-loading.md`](error-and-loading.md) | Global / page ErrorBoundary、react-query three-state、Suspense、toast、reportError |
|
|
79
79
|
| [`routing-and-codesplit.md`](routing-and-codesplit.md) | `React.lazy` per page、guards、404/403/500 fallback、search-params state、Suspense placement |
|
|
@@ -88,7 +88,7 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
|
|
|
88
88
|
## Why these conventions
|
|
89
89
|
|
|
90
90
|
- **Single source for UI** — `@teamix-evo/ui` is a source-injected component library (89 entries). Re-implementing `Button`、`Dialog`、`DataTable` etc. inside the consumer app fragments the design system and breaks token discipline.
|
|
91
|
-
- **Stable seams for change** — keeping API calls in `src/
|
|
91
|
+
- **Stable seams for change** — keeping API calls in `src/features/<domain>/api.ts` means a backend rename only edits one file; keeping components free of fetch logic means they stay easy to test and reuse.
|
|
92
92
|
- **Predictable file location** — when AI (or a new teammate) opens an unfamiliar consumer app, the directory shape is the same across all teamix-evo-bootstrapped projects.
|
|
93
93
|
|
|
94
94
|
<!-- teamix-evo:managed:end -->
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 2 的强制读取项。任何涉及后端通信的代码必须先读本文件。
|
|
4
4
|
|
|
5
|
-
> **核心原则**:组件不直接 fetch
|
|
5
|
+
> **核心原则**:组件不直接 fetch。每个业务领域的代码聚合在 `src/features/<domain>/`,通过 hooks 暴露给组件。
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## 三层结构
|
|
9
|
+
## Feature-based 三层结构
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
┌────────────────────────────────────┐
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
│ 仅通过 hook
|
|
19
19
|
▼
|
|
20
20
|
┌────────────────────────────────────┐
|
|
21
|
-
│ src/hooks
|
|
21
|
+
│ src/features/<domain>/hooks.ts │ Hook 层:状态管理 + 缓存(react-query 等)
|
|
22
22
|
│ - 包装请求生命周期(loading/error) │
|
|
23
23
|
│ - 处理缓存 / 重试 / 失效 │
|
|
24
24
|
│ - 不写具体的 URL / payload 拼装 │
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
│ 调用纯函数
|
|
27
27
|
▼
|
|
28
28
|
┌────────────────────────────────────┐
|
|
29
|
-
│ src/
|
|
29
|
+
│ src/features/<domain>/api.ts │ API 层:请求纯函数
|
|
30
30
|
│ - 输入参数 → 输出 Promise<T> │
|
|
31
31
|
│ - 拼 URL / 序列化 / 反序列化 │
|
|
32
32
|
│ - 不依赖 React │
|
|
@@ -40,30 +40,43 @@
|
|
|
40
40
|
└────────────────────────────────────┘
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
### 目录结构
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
src/features/
|
|
47
|
+
├── order/ # 订单领域
|
|
48
|
+
│ ├── api.ts # 请求纯函数(listOrders, createOrder, ...)
|
|
49
|
+
│ ├── hooks.ts # react-query 封装(useOrderList, useCreateOrder, ...)
|
|
50
|
+
│ ├── types.ts # 领域类型(Order, OrderStatus, OrderListParams, ...)
|
|
51
|
+
│ ├── mocks.ts # 本地 mock 数据(开发阶段)
|
|
52
|
+
│ └── schema.ts # zod schema(CreateOrderInputSchema, ...)
|
|
53
|
+
├── user/ # 用户领域
|
|
54
|
+
│ ├── api.ts
|
|
55
|
+
│ ├── hooks.ts
|
|
56
|
+
│ ├── types.ts
|
|
57
|
+
│ └── mocks.ts
|
|
58
|
+
└── tenant/ # 租户领域
|
|
59
|
+
└── ...
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
新增一个业务领域 = 新增一个 `features/<domain>/` 文件夹,不会让任何一个目录膨胀。
|
|
63
|
+
|
|
43
64
|
---
|
|
44
65
|
|
|
45
|
-
## §1 · `
|
|
66
|
+
## §1 · `features/<domain>/api.ts` 约定
|
|
46
67
|
|
|
47
68
|
### 文件组织
|
|
48
69
|
|
|
49
|
-
按**领域**(domain)
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
src/services/
|
|
53
|
-
├── order.ts # 订单领域:list / get / create / update / cancel
|
|
54
|
-
├── user.ts # 用户领域
|
|
55
|
-
├── tenant.ts # 租户领域
|
|
56
|
-
└── index.ts # 统一 re-export(可选)
|
|
57
|
-
```
|
|
70
|
+
按**领域**(domain)拆为独立文件夹,每个领域的请求函数放 `api.ts`。
|
|
58
71
|
|
|
59
72
|
❌ 不要按动词拆:`getOrders.ts` / `createOrder.ts` / `updateOrder.ts` —— 会爆文件数。
|
|
60
73
|
|
|
61
74
|
### 函数签名约定
|
|
62
75
|
|
|
63
76
|
```ts
|
|
64
|
-
// src/
|
|
77
|
+
// src/features/order/api.ts
|
|
65
78
|
import { http } from '@/lib/http';
|
|
66
|
-
import type { Order, OrderListParams, CreateOrderInput } from '
|
|
79
|
+
import type { Order, OrderListParams, CreateOrderInput } from './types';
|
|
67
80
|
|
|
68
81
|
export async function listOrders(params: OrderListParams): Promise<Order[]> {
|
|
69
82
|
const { data } = await http.get('/api/orders', { params });
|
|
@@ -84,33 +97,35 @@ export async function createOrder(input: CreateOrderInput): Promise<Order> {
|
|
|
84
97
|
要点:
|
|
85
98
|
|
|
86
99
|
- **纯函数**(不依赖 React 上下文,可以在 SSR / Node 测试中单独跑)
|
|
87
|
-
-
|
|
88
|
-
- **错误不在
|
|
100
|
+
- **类型来自同目录 `./types`**,同一领域内用相对路径引用
|
|
101
|
+
- **错误不在 api 层处理** —— 抛出去给 hook / 全局 interceptor 处理(归一化在 `src/lib/http.ts`)
|
|
89
102
|
- **不写 console.log / 业务弹窗** —— 是数据通道,不是 UI 通道
|
|
90
103
|
|
|
91
104
|
### 反模式
|
|
92
105
|
|
|
93
106
|
- ❌ `fetch('https://api.example.com/...')` 写死 host(应该用 `http` wrapper)
|
|
94
|
-
- ❌
|
|
95
|
-
- ❌ 在
|
|
96
|
-
- ❌ 一个
|
|
107
|
+
- ❌ api 函数返回 `{ loading, data, error }`(那是 hook 该做的)
|
|
108
|
+
- ❌ 在 api 里 `import { toast } from 'sonner'` 弹通知(归到 hook 或全局 interceptor)
|
|
109
|
+
- ❌ 一个 api 函数同时拼 URL、做业务计算、改全局 store
|
|
97
110
|
|
|
98
111
|
---
|
|
99
112
|
|
|
100
|
-
## §2 · `
|
|
113
|
+
## §2 · `features/<domain>/hooks.ts` 约定
|
|
101
114
|
|
|
102
115
|
### 命名
|
|
103
116
|
|
|
104
117
|
- Query 类:`useOrderList`、`useOrder(id)`、`useUserProfile`
|
|
105
118
|
- Mutation 类:`useCreateOrder`、`useCancelOrder`、`useUpdateUser`
|
|
106
119
|
|
|
120
|
+
同一领域的 query + mutation hooks 聚合在一个 `hooks.ts` 里。
|
|
121
|
+
|
|
107
122
|
### 实现(以 `@tanstack/react-query` 为例)
|
|
108
123
|
|
|
109
124
|
```ts
|
|
110
|
-
// src/hooks
|
|
111
|
-
import { useQuery } from '@tanstack/react-query';
|
|
112
|
-
import { listOrders } from '
|
|
113
|
-
import type { OrderListParams } from '
|
|
125
|
+
// src/features/order/hooks.ts
|
|
126
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
127
|
+
import { listOrders, createOrder } from './api';
|
|
128
|
+
import type { OrderListParams } from './types';
|
|
114
129
|
|
|
115
130
|
export function useOrderList(params: OrderListParams) {
|
|
116
131
|
return useQuery({
|
|
@@ -119,12 +134,6 @@ export function useOrderList(params: OrderListParams) {
|
|
|
119
134
|
staleTime: 30_000,
|
|
120
135
|
});
|
|
121
136
|
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
// src/hooks/useCreateOrder.ts
|
|
126
|
-
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
127
|
-
import { createOrder } from '@/services/order';
|
|
128
137
|
|
|
129
138
|
export function useCreateOrder() {
|
|
130
139
|
const qc = useQueryClient();
|
|
@@ -137,8 +146,8 @@ export function useCreateOrder() {
|
|
|
137
146
|
|
|
138
147
|
### 反模式
|
|
139
148
|
|
|
140
|
-
- ❌ Hook 里再次拼 URL(违反"
|
|
141
|
-
- ❌ 一个 hook
|
|
149
|
+
- ❌ Hook 里再次拼 URL(违反"api 拼 URL"边界)
|
|
150
|
+
- ❌ 一个 hook 调多个领域的 api 把数据缝合 —— 缝合应该在 api 层(返回组合好的 DTO)
|
|
142
151
|
- ❌ Hook 里写业务跳转 / 路由切换 —— 由组件接 `mutation.onSuccess` callback 处理
|
|
143
152
|
|
|
144
153
|
---
|
|
@@ -188,15 +197,15 @@ http.interceptors.response.use(
|
|
|
188
197
|
## §4 · 类型分层
|
|
189
198
|
|
|
190
199
|
```
|
|
191
|
-
src/types
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
└── api.ts # 通用 ApiResponse<T>、Pagination<T>
|
|
200
|
+
src/features/order/types.ts # Order、OrderStatus、OrderListParams、CreateOrderInput
|
|
201
|
+
src/features/user/types.ts # User、UserRole、...
|
|
202
|
+
src/types/api.ts # 通用 ApiResponse<T>、Pagination<T>(跨领域共享)
|
|
195
203
|
```
|
|
196
204
|
|
|
197
|
-
- **Domain 类型**(如 `Order`)放 `src/
|
|
198
|
-
-
|
|
199
|
-
-
|
|
205
|
+
- **Domain 类型**(如 `Order`)放 `src/features/<domain>/types.ts`,同领域内用相对路径 `./types` 引用
|
|
206
|
+
- 组件消费时用 `@/features/order/types` 引入
|
|
207
|
+
- **跨领域通用类型**(如 `ApiResponse<T>`、`Pagination<T>`)放 `src/types/api.ts`
|
|
208
|
+
- **API 入参 / 出参类型**:与 domain 类型分开命名(`OrderListParams` vs `Order`),但放同一个 `types.ts`
|
|
200
209
|
|
|
201
210
|
---
|
|
202
211
|
|
|
@@ -219,9 +228,9 @@ src/types/
|
|
|
219
228
|
```
|
|
220
229
|
## 数据层改动
|
|
221
230
|
|
|
222
|
-
- src/
|
|
223
|
-
- src/
|
|
224
|
-
- src/hooks
|
|
231
|
+
- src/features/order/types.ts: 新增 `OrderListParams`、`OrderStatus`
|
|
232
|
+
- src/features/order/api.ts: 新增 `listOrders`、`cancelOrder`(纯函数,使用 `@/lib/http`)
|
|
233
|
+
- src/features/order/hooks.ts: 新增 `useOrderList`(useQuery, key=['orders', params])
|
|
225
234
|
- src/pages/orders/index.tsx: 仅消费 `useOrderList`,不直接 fetch
|
|
226
235
|
```
|
|
227
236
|
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
## 1. 复用判定 ✓
|
|
10
10
|
|
|
11
|
-
- [ ] 新建 UI 组件前,查过 `@teamix-evo/ui` 注册表(
|
|
11
|
+
- [ ] 新建 UI 组件前,查过 `@teamix-evo/ui` 注册表(`.teamix-evo/meta/ui/manifest.json` + `<id>.md`)
|
|
12
12
|
- [ ] 新建 UI 组件前,grep 过本项目 `src/components/`
|
|
13
|
-
- [ ] 新建工具函数前,grep 过 `src/utils/` `src/lib/` `src/
|
|
13
|
+
- [ ] 新建工具函数前,grep 过 `src/utils/` `src/lib/` `src/features/`
|
|
14
14
|
- [ ] 没有重复实现 ui 包已经提供的能力(Button、Input、Dialog、DataTable 等)
|
|
15
15
|
- [ ] 没有 fork ui 包源码改样式(改样式应当走 design token)
|
|
16
16
|
- [ ] 响应里**显式列出**复用决策日志(✅ 复用了哪些 / 🆕 新写了哪些及原因)
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
|
|
20
20
|
- [ ] 组件**没有**直接调 `fetch` / `axios`
|
|
21
21
|
- [ ] 组件**没有**直接读 `import.meta.env` / `process.env`(env 走 `src/lib/env.ts`)
|
|
22
|
-
- [ ] 所有后端调用都落在 `src/
|
|
23
|
-
- [ ]
|
|
24
|
-
- [ ]
|
|
25
|
-
- [ ] 数据 hook 在 `src/hooks
|
|
22
|
+
- [ ] 所有后端调用都落在 `src/features/<domain>/api.ts`,且是纯函数
|
|
23
|
+
- [ ] API 函数**不依赖 React**(没有 `useXxx`、没有 `useState`)
|
|
24
|
+
- [ ] API 函数**不弹通知 / 不跳路由**
|
|
25
|
+
- [ ] 数据 hook 在 `src/features/<domain>/hooks.ts`,使用统一的数据库(react-query / swr,不混用)
|
|
26
26
|
- [ ] 全局只有一份 http 实例,在 `src/lib/http.ts`
|
|
27
27
|
|
|
28
28
|
## 3. 目录归位 ✓
|
|
29
29
|
|
|
30
|
-
- [ ]
|
|
31
|
-
- [ ]
|
|
30
|
+
- [ ] 业务领域代码(api/hooks/types/mocks)放在 `src/features/<domain>/`
|
|
31
|
+
- [ ] 新文件位于约定的顶层目录(`pages/`、`components/`、`features/`、`stores/`、`utils/`、`lib/`)
|
|
32
|
+
- [ ] **没有**新增同义层(如 `views/`、`services/`、`helpers/` 与现有目录并存)
|
|
32
33
|
- [ ] 仅在单个页面使用的组件 / hook 放在 `src/pages/<id>/_components/` 或 `_hooks/`(下划线前缀)
|
|
33
|
-
- [ ]
|
|
34
|
-
- [ ] React Hook 在 `hooks/`,不在 `utils/`(`utils/` 不依赖 React)
|
|
34
|
+
- [ ] 跨页面复用的组件升到 `src/components/`;跨领域共享的 hook 放 `src/hooks/`(极少数)
|
|
35
35
|
- [ ] 类型声明文件没有运行时代码(纯类型)
|
|
36
36
|
|
|
37
37
|
## 4. 命名 ✓
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
- [ ] 跨目录 import 走 `@/*` 别名,**未使用** `../../../` 相对路径上跳超过 2 层
|
|
48
48
|
- [ ] **未发生反向依赖**:
|
|
49
49
|
- `components/` 没有 import `pages/`
|
|
50
|
-
- `
|
|
51
|
-
- `hooks
|
|
52
|
-
- `utils/` `lib/`
|
|
50
|
+
- `features/<domain>/api.ts` 没有 import `hooks` `components/` `pages/`
|
|
51
|
+
- `features/<domain>/hooks.ts` 没有 import `pages/`
|
|
52
|
+
- `utils/` `lib/` 没有 import 业务层
|
|
53
53
|
- [ ] 页面私有目录(`_components/` `_hooks/`)**没有**被其他页面 import
|
|
54
54
|
|
|
55
55
|
## 6. 类型 ✓
|
|
56
56
|
|
|
57
|
-
- [ ] Domain 类型放 `src/
|
|
58
|
-
- [ ]
|
|
57
|
+
- [ ] Domain 类型放 `src/features/<domain>/types.ts`,不在 api / component 文件就地定义
|
|
58
|
+
- [ ] API 函数有显式的入参 / 返回 `Promise<T>` 类型
|
|
59
59
|
- [ ] 没有 `any`(必要的转义类型用 `unknown` 配合 narrowing,或加注释说明原因)
|
|
60
60
|
- [ ] Hook 的返回类型由 `react-query` / `swr` 自动推断,无需手写
|
|
61
61
|
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
(若改动涉及表单 — 详见 [`forms-and-validation.md`](forms-and-validation.md))
|
|
78
78
|
|
|
79
79
|
- [ ] 表单状态用 `react-hook-form`,**未用** `useState` 拼字段
|
|
80
|
-
- [ ] 校验用 `zod` schema,schema 落 `src/
|
|
80
|
+
- [ ] 校验用 `zod` schema,schema 落 `src/features/<domain>/schema.ts`
|
|
81
81
|
- [ ] 类型从 schema 推导(`z.infer<...>`),**未手写**重复 interface
|
|
82
82
|
- [ ] 错误信息写在 schema 里,UI 只读取,**未在组件里硬编码**校验文案
|
|
83
83
|
- [ ] 提交走 mutation hook,**未在** `<form onSubmit>` 里直接 fetch
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
|
|
114
114
|
(详见 [`testing.md`](testing.md))
|
|
115
115
|
|
|
116
|
-
- [ ] 新增纯函数(`src/utils/`、`src/
|
|
116
|
+
- [ ] 新增纯函数(`src/utils/`、`src/features/*/api.ts`)有同名 `*.test.ts`(**必测**)
|
|
117
117
|
- [ ] 新增 zod schema 有 `parse` 成功 / 失败用例(**必测**)
|
|
118
118
|
- [ ] 关键业务路径(下单 / 支付 / 鉴权)有组件 / hook 测试(**必测**)
|
|
119
119
|
- [ ] 测试文件就近放在 `<source>.test.ts(x)`,**未**集中到顶层 `tests/`
|
|
@@ -137,10 +137,10 @@
|
|
|
137
137
|
|
|
138
138
|
1. **组件直接 fetch / axios** —— 数据层未分层
|
|
139
139
|
2. **新建 Button / Input / Dialog 等基础组件** —— 重造 ui 包能力
|
|
140
|
-
3. **
|
|
141
|
-
4. **`src/views/` 与 `src/pages/` 并存(或 `src/
|
|
140
|
+
3. **features/*/api.ts 函数依赖 React** —— 边界穿透
|
|
141
|
+
4. **`src/views/` 与 `src/pages/` 并存(或 `src/services/` 与 `src/features/`)** —— 同义层污染
|
|
142
142
|
5. **响应里没有复用决策日志** —— 流程未跑通
|
|
143
|
-
6. **反向依赖**(
|
|
143
|
+
6. **反向依赖**(api 引 hook、component 引 page) —— 依赖图破坏
|
|
144
144
|
7. **多份 http 实例** —— 鉴权 / 错误处理无法统一
|
|
145
145
|
8. **没有全局 ErrorBoundary** —— 异常直接白屏给用户
|
|
146
146
|
9. **表单用 `useState` 拼字段、用 onChange 手写校验** —— 弃 react-hook-form + zod
|
|
@@ -158,12 +158,12 @@
|
|
|
158
158
|
## 编码合规自检
|
|
159
159
|
|
|
160
160
|
- 复用判定: ✅ 复用 ui 包 Button / DataTable;🆕 新写 OrderStatusBadge(原因:业务状态映射)
|
|
161
|
-
- 数据层: ✅
|
|
162
|
-
- 目录: ✅ 页面在 pages/orders/;✅ 跨页面组件在 components/
|
|
161
|
+
- 数据层: ✅ features/order/api.ts 纯函数;✅ features/order/hooks.ts 包 react-query;✅ 组件未 fetch
|
|
162
|
+
- 目录: ✅ 页面在 pages/orders/;✅ 领域代码在 features/order/;✅ 跨页面组件在 components/
|
|
163
163
|
- 命名: ✅ kebab 目录 / Pascal 组件 / camel hook
|
|
164
164
|
- 边界: ✅ 全部走 @/\*;✅ 无反向依赖
|
|
165
|
-
- 类型: ✅
|
|
166
|
-
- 表单(若涉及): ✅ useForm + zodResolver;✅ schema 在
|
|
165
|
+
- 类型: ✅ features/order/types.ts 集中声明
|
|
166
|
+
- 表单(若涉及): ✅ useForm + zodResolver;✅ schema 在 features/order/schema.ts
|
|
167
167
|
- 错误/加载(若涉及): ✅ 三态全处理;✅ ErrorBoundary 已在 App 根;✅ mutation toast
|
|
168
168
|
- 路由(若涉及): ✅ React.lazy + Suspense;✅ 守卫已复用;✅ 404 兜底已存在
|
|
169
169
|
- 测试: ✅ 新增 formatXxx → formatXxx.test.ts(5 case);✅ schema parse 失败用例已加
|