@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.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/manifest.json +11 -28
  3. package/package.json +2 -2
  4. package/src/teamix-evo-code-opentrek/SKILL.md +13 -13
  5. package/src/teamix-evo-code-opentrek/api-layering.md +53 -44
  6. package/src/teamix-evo-code-opentrek/checklist.md +24 -24
  7. package/src/teamix-evo-code-opentrek/file-structure.md +55 -36
  8. package/src/teamix-evo-code-opentrek/forms-and-validation.md +17 -16
  9. package/src/teamix-evo-code-opentrek/reuse-first.md +6 -9
  10. package/src/teamix-evo-code-opentrek/testing.md +14 -14
  11. package/src/teamix-evo-code-uni-manager/SKILL.md +15 -15
  12. package/src/teamix-evo-code-uni-manager/api-layering.md +74 -58
  13. package/src/teamix-evo-code-uni-manager/checklist.md +28 -28
  14. package/src/teamix-evo-code-uni-manager/error-and-loading.md +2 -2
  15. package/src/teamix-evo-code-uni-manager/file-structure.md +77 -62
  16. package/src/teamix-evo-code-uni-manager/forms-and-validation.md +17 -15
  17. package/src/teamix-evo-code-uni-manager/reuse-first.md +7 -10
  18. package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +1 -1
  19. package/src/teamix-evo-code-uni-manager/testing.md +37 -37
  20. package/src/teamix-evo-design-opentrek/SKILL.md +17 -20
  21. package/src/teamix-evo-design-opentrek/boundaries.md +1 -1
  22. package/src/teamix-evo-design-opentrek/checklist.md +5 -5
  23. package/src/teamix-evo-design-opentrek/components.md +19 -19
  24. package/src/teamix-evo-design-opentrek/examples/standard-card-list.html +1 -1
  25. package/src/teamix-evo-design-opentrek/examples/standard-table-list.html +1 -1
  26. package/src/teamix-evo-design-opentrek/foundations.md +6 -6
  27. package/src/teamix-evo-design-opentrek/pages/dashboard-page/SKILL.md +18 -19
  28. package/src/teamix-evo-design-opentrek/pages/dashboard-page/patterns/dashboard-opentrek.md +6 -6
  29. package/src/teamix-evo-design-opentrek/pages/detail-page/SKILL.md +24 -25
  30. package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/api-doc-detail.md +3 -7
  31. package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/comparison-detail.md +3 -7
  32. package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/monitor-detail.md +3 -7
  33. package/src/teamix-evo-design-opentrek/pages/detail-page/patterns/resource-detail.md +10 -10
  34. package/src/teamix-evo-design-opentrek/pages/form-page/SKILL.md +26 -27
  35. package/src/teamix-evo-design-opentrek/pages/list-page/SKILL.md +35 -36
  36. package/src/teamix-evo-design-opentrek/pages/list-page/_shared/item-card-spec.md +41 -32
  37. package/src/teamix-evo-design-opentrek/pages/list-page/patterns/card-list-opentrek.md +10 -10
  38. package/src/teamix-evo-design-opentrek/pages/list-page/patterns/card-list.md +23 -23
  39. package/src/teamix-evo-design-opentrek/pages/list-page/patterns/standard-list-opentrek.md +8 -8
  40. package/src/teamix-evo-design-opentrek/pages/list-page/patterns/standard-list.md +8 -8
  41. package/src/teamix-evo-design-opentrek/patterns/color-mapping.md +2 -2
  42. package/src/teamix-evo-design-opentrek/patterns/dashboard.md +1 -1
  43. package/src/teamix-evo-design-opentrek/patterns/detail-page.md +9 -9
  44. package/src/teamix-evo-design-opentrek/patterns/form-page.md +6 -6
  45. package/src/teamix-evo-design-opentrek/patterns/list-page.md +9 -9
  46. package/src/teamix-evo-design-opentrek/patterns/page-types.md +3 -3
  47. package/src/teamix-evo-design-opentrek/principles.md +541 -0
  48. package/src/teamix-evo-design-opentrek/rules/common-components.json +206 -76
  49. package/src/teamix-evo-design-opentrek/rules/component-specs.json +2 -2
  50. package/src/teamix-evo-design-opentrek/rules/page-frame.json +197 -193
  51. package/src/teamix-evo-design-opentrek/{generation-flow.md → workflow.md} +141 -22
  52. package/src/teamix-evo-design-uni-manager/SKILL.md +5 -5
  53. package/src/teamix-evo-design-uni-manager/boundaries.md +2 -2
  54. package/src/teamix-evo-design-uni-manager/brand.md +1 -1
  55. package/src/teamix-evo-design-uni-manager/checklist.md +2 -2
  56. package/src/teamix-evo-design-uni-manager/components.md +11 -11
  57. package/src/teamix-evo-design-uni-manager/foundations.md +7 -7
  58. package/src/teamix-evo-design-uni-manager/generation-flow.md +3 -3
  59. package/src/teamix-evo-manage/SKILL.md +111 -709
  60. package/src/teamix-evo-manage/init.md +98 -0
  61. package/src/teamix-evo-manage/migrate.md +100 -0
  62. package/src/teamix-evo-manage/rearchitect-capture-guide.md +174 -0
  63. package/src/teamix-evo-manage/rearchitect.md +373 -0
  64. package/src/teamix-evo-manage/update-component-staging.md +188 -0
  65. package/src/teamix-evo-manage/update-token-rename.md +126 -0
  66. package/src/teamix-evo-manage/update-token-treatment.md +116 -0
  67. package/src/teamix-evo-manage/update.md +213 -0
  68. package/src/teamix-evo-design-opentrek/brand.md +0 -154
  69. package/src/teamix-evo-design-opentrek/pages/list-page/_shared/search-combo-spec.md +0 -194
  70. package/src/teamix-evo-design-opentrek/philosophy.md +0 -98
  71. package/src/teamix-evo-design-opentrek/rules/README.md +0 -39
  72. package/src/teamix-evo-design-opentrek/rules/_assets/OP_AGENT RUNTIME.svg +0 -1
  73. package/src/teamix-evo-design-opentrek/rules/_assets/OP_AI GATEWAY.svg +0 -1
  74. package/src/teamix-evo-design-opentrek/rules/_assets/OP_AI STUDIO.svg +0 -1
  75. package/src/teamix-evo-design-opentrek/rules/_assets/OP_DEV-2.svg +0 -1
  76. package/src/teamix-evo-design-opentrek/rules/_assets/OP_LOGO.svg +0 -1
  77. package/src/teamix-evo-design-opentrek/rules/_assets/OP_OPS.svg +0 -1
  78. package/src/teamix-evo-design-opentrek/rules/layout-rules.json +0 -218
  79. package/src/teamix-evo-design-opentrek/rules/page-header-spec.md +0 -123
  80. package/src/teamix-evo-design-opentrek/rules/sidebar-spec.md +0 -217
  81. package/src/teamix-evo-upgrade/SKILL.md +0 -431
  82. /package/src/teamix-evo-design-opentrek/{rules/boundaries.rules.json → boundaries.json} +0 -0
@@ -10,13 +10,13 @@
10
10
 
11
11
  ```
12
12
  src/
13
+ ├── features/ # 业务领域(每个子目录聚合 api/hooks/types/mocks/schema)
13
14
  ├── pages/ # 路由页面(每个目录对应一条路由)
14
15
  ├── components/ # 跨页面复用的业务组件
15
- ├── services/ # 后端通信(纯函数,见 api-layering.md)
16
- ├── hooks/ # 自定义 Hook(包含数据 hook、UI hook)
16
+ ├── hooks/ # 跨领域共享的通用 Hook(极少数,如 useDebounce)
17
17
  ├── contexts/ # React Context(跨子树共享、低频更新的全局态)
18
18
  ├── stores/ # 高频全局态(zustand / jotai / redux,首次需要时引入,只用一种)
19
- ├── types/ # Domain / API 类型声明(.ts 仅类型,无运行时)
19
+ ├── types/ # 跨领域通用类型(ApiResponse<T>、Pagination<T>)
20
20
  ├── utils/ # 纯函数工具(无 React、无副作用)
21
21
  ├── lib/ # 三方 SDK 包装、http 实例、环境配置、monitor
22
22
  ├── routes/ # 路由配置 + 守卫(若用 react-router 集中式声明)
@@ -29,7 +29,7 @@ src/
29
29
  └── App.tsx # 根组件
30
30
  ```
31
31
 
32
- > 没列出的目录按需补,但**不要**新增同义层(如同时有 `utils/` 和 `helpers/`、`api/` 和 `services/`、`views/` 和 `pages/`)。`*.test.ts(x)` 文件**就近**放在被测文件同目录,**不要**集中堆到顶层 `tests/`(见 [`testing.md`](testing.md))。
32
+ > 没列出的目录按需补,但**不要**新增同义层(如同时有 `utils/` 和 `helpers/`、`services/` 和 `features/`、`views/` 和 `pages/`)。`*.test.ts(x)` 文件**就近**放在被测文件同目录,**不要**集中堆到顶层 `tests/`(见 [`testing.md`](testing.md))。
33
33
 
34
34
  ---
35
35
 
@@ -56,7 +56,7 @@ src/pages/
56
56
 
57
57
  - 页面组件**默认 default export**,与文件名一致
58
58
  - `_components/` `_hooks/` 用下划线前缀标记**私有**,**禁止跨页面 import**
59
- - 跨页面用得到的组件/hook → 升到 `src/components/` `src/hooks/`
59
+ - 跨页面用得到的组件 → 升到 `src/components/`;领域 hook → 放 `src/features/<domain>/hooks.ts`
60
60
 
61
61
  ### `src/components/`
62
62
 
@@ -78,27 +78,46 @@ src/components/
78
78
  - **不要**重复 `@teamix-evo/ui` 已经提供的能力(见 [reuse-first.md](reuse-first.md))
79
79
  - **不要**写"小工具组件"如 `Wrapper`、`Container` —— 用 div + tailwind 即可
80
80
 
81
- ### `src/services/`
81
+ ### `src/features/`
82
82
 
83
- **职责**:后端通信纯函数。详见 [`api-layering.md`](api-layering.md)。
83
+ **职责**:业务领域代码。每个子目录聚合一个领域的全部代码。详见 [`api-layering.md`](api-layering.md)。
84
+
85
+ ```
86
+ src/features/
87
+ ├── order/
88
+ │ ├── api.ts # 请求纯函数(listOrders, createOrder, ...)
89
+ │ ├── hooks.ts # react-query 封装(useOrderList, useCreateOrder, ...)
90
+ │ ├── types.ts # 领域类型(Order, OrderStatus, ...)
91
+ │ ├── mocks.ts # 本地 mock 数据(开发阶段)
92
+ │ └── schema.ts # zod schema(CreateOrderInputSchema, ...)
93
+ ├── user/
94
+ │ └── ...
95
+ └── tenant/
96
+ └── ...
97
+ ```
98
+
99
+ 约束:
100
+
101
+ - 一个领域 = 一个子目录,**不按技术类型拆**
102
+ - api.ts 是纯函数层,**不依赖 React**
103
+ - hooks.ts 调同目录 api.ts,**禁止**直接 fetch
104
+ - types.ts 仅类型,无运行时代码
105
+ - 同领域内用相对路径 `./types`、`./api`
84
106
 
85
107
  ### `src/hooks/`
86
108
 
87
- **职责**:跨页面复用的自定义 Hook
109
+ **职责**:跨领域共享的通用 Hook(极少数)。
88
110
 
89
111
  ```
90
112
  src/hooks/
91
- ├── useOrderList.ts # 数据 hook(包 react-query)
92
- ├── useCreateOrder.ts
93
- ├── useDebounce.ts # UI hook
113
+ ├── useDebounce.ts # 通用 UI hook
94
114
  └── useMediaQuery.ts
95
115
  ```
96
116
 
97
117
  约束:
98
118
 
99
- - 命名必须 `use` 开头
100
- - hook = 单文件
101
- - 数据 hook 调 `src/services/`,**禁止**直接 fetch
119
+ - 领域数据 hook **不放这里**,放 `src/features/<domain>/hooks.ts`
120
+ - 只放与业务领域无关的通用 hook
102
121
 
103
122
  ### 全局态选型决策
104
123
 
@@ -133,13 +152,13 @@ Context 文件位置:
133
152
 
134
153
  ### `src/types/`
135
154
 
136
- **职责**:类型声明。
155
+ **职责**:跨领域通用类型声明。
137
156
 
138
157
  约束:
139
158
 
140
159
  - 只放 `.ts` 类型文件,**不导出运行时代码**
141
- - domain 拆:`order.ts`、`user.ts`
142
- - 通用类型放 `api.ts`、`common.ts`
160
+ - Domain 类型放 `src/features/<domain>/types.ts`,**不放这里**
161
+ - 仅放跨领域通用类型:`api.ts`(ApiResponse<T>、Pagination<T>)、`common.ts`
143
162
 
144
163
  ### `src/utils/`
145
164
 
@@ -147,7 +166,7 @@ Context 文件位置:
147
166
 
148
167
  约束:
149
168
 
150
- - **不依赖 React**(用了 React 应该是 hook,放 `src/hooks/`)
169
+ - **不依赖 React**(用了 React 应该是 hook,放 `src/features/<domain>/hooks.ts` 或 `src/hooks/`)
151
170
  - **不依赖 DOM**(用了 DOM 应该是 lib 层包装)
152
171
  - **不发请求**(发请求是 service)
153
172
  - 一个文件一个主题:`format.ts`、`validate.ts`、`array.ts`
@@ -205,7 +224,7 @@ src/routes/
205
224
  ```ts
206
225
  // ✅
207
226
  import { Button } from '@teamix-evo/ui';
208
- import { listOrders } from '@/services/order';
227
+ import { listOrders } from '@/features/order/api';
209
228
  import { OrderStatusBadge } from '@/components/OrderStatusBadge';
210
229
 
211
230
  // ❌
@@ -217,21 +236,21 @@ import { listOrders } from '../../../services/order';
217
236
  ## Import 边界(单向依赖)
218
237
 
219
238
  ```
220
- pages ──▶ components, hooks, services, types, utils, lib, stores
221
- components ──▶ hooks, services, types, utils, lib (NOT pages)
222
- hooks ──▶ services, types, utils, lib, stores (NOT components, NOT pages)
223
- services ──▶ types, lib (NOT hooks, NOT components, NOT pages)
224
- stores ──▶ types, utils, lib (NOT services, NOT hooks)
225
- types ──▶ (no runtime imports)
226
- utils ──▶ types only
227
- lib ──▶ types only
239
+ pages ──▶ components, features, hooks, types, utils, lib, stores
240
+ components ──▶ features, hooks, types, utils, lib (NOT pages)
241
+ features/* ──▶ lib, types (内部 api→types, hooks→api+types; NOT components, NOT pages)
242
+ hooks ──▶ types, utils, lib (NOT features, NOT components, NOT pages)
243
+ stores ──▶ types, utils, lib (NOT features, NOT hooks)
244
+ types ──▶ (no runtime imports)
245
+ utils ──▶ types only
246
+ lib ──▶ types only
228
247
  ```
229
248
 
230
249
  要点:
231
250
 
232
- - **services 不依赖 React** —— 它是纯函数层
251
+ - **features/*/api.ts 不依赖 React** —— 它是纯函数层
233
252
  - **types / utils / lib 是叶子层** —— 不依赖业务层,谁都能引
234
- - **反向依赖直接否决**(component 不能 import page,service 不能 import hook)
253
+ - **反向依赖直接否决**(component 不能 import page,api 不能 import hook)
235
254
 
236
255
  ---
237
256
 
@@ -240,10 +259,10 @@ lib ──▶ types only
240
259
  | 反模式 | 为什么禁 | 应该怎么做 |
241
260
  | ------------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- |
242
261
  | `src/views/`、`src/screens/` 与 `src/pages/` 并存 | 同义层,认知爆炸 | 二选一,统一叫 `pages/` |
243
- | `src/api/` 与 `src/services/` 并存 | 同义层 | 统一叫 `services/` |
262
+ | `src/services/` 与 `src/features/` 并存 | 同义层 | 统一用 `features/` |
244
263
  | `src/utils/` 与 `src/helpers/` 并存 | 同义层 | 统一叫 `utils/` |
245
264
  | 在 `src/components/` 里写 page-only 组件 | 抽象层级别错位 | 放 `src/pages/<id>/_components/` |
246
- | 在 `src/utils/` 里写 React Hook | 边界错位 | `src/hooks/` |
265
+ | 在 `src/utils/` 里写 React Hook | 边界错位 | 领域 hook → `features/<domain>/hooks.ts`;通用 hook → `src/hooks/` |
247
266
  | 一个文件 export 5 个不相关的工具 | 命名失焦 | 拆成多文件,一个主题一个文件 |
248
267
  | `index.ts` 大量 `export *` 当 barrel | 影响 tree-shaking、循环依赖 | 显式 named export 需要的几个 |
249
268
  | 为消除一处 props drilling 直接引 zustand | 升级过度,徒增心智 | 用 React `Context` |
@@ -264,15 +283,15 @@ lib ──▶ types only
264
283
  | 新增订单列表页 | `src/pages/orders/index.tsx` |
265
284
  | 新增订单状态徽章(跨页面用) | `src/components/OrderStatusBadge.tsx` |
266
285
  | 新增订单状态徽章(只在订单页用) | `src/pages/orders/_components/OrderStatusBadge.tsx` |
267
- | 新增"取消订单"接口调用 | `src/services/order.ts` 加 `cancelOrder` |
268
- | 新增"取消订单"的 mutation hook | `src/hooks/useCancelOrder.ts` |
286
+ | 新增"取消订单"接口调用 | `src/features/order/api.ts` 加 `cancelOrder` |
287
+ | 新增"取消订单"的 mutation hook | `src/features/order/hooks.ts` 加 `useCancelOrder` |
269
288
  | 新增日期格式化函数 | `src/utils/format.ts`(先 grep 是否已存在) |
270
289
  | 新增鉴权拦截器 | `src/lib/http.ts` 加 interceptor |
271
- | 新增订单 domain 类型 | `src/types/order.ts` |
290
+ | 新增订单 domain 类型 | `src/features/order/types.ts` |
272
291
  | 跨少量组件分享当前用户 / 主题 | `src/contexts/UserContext.tsx`(用 React Context) |
273
292
  | 跨域高频全局态(首次需要) | `src/stores/useXxxStore.ts`(按需引 zustand,固定后只用一种) |
274
- | 列表 / 详情等服务端数据 | `src/hooks/useXxx.ts` 包 `react-query`,**不进** store / Context |
275
- | 新增"下单表单"(react-hook-form + zod) | `src/pages/orders/new/_components/CreateOrderForm.tsx` + `src/services/order.schema.ts` |
293
+ | 列表 / 详情等服务端数据 | `src/features/<domain>/hooks.ts` 包 `react-query`,**不进** store / Context |
294
+ | 新增"下单表单"(react-hook-form + zod) | `src/pages/orders/new/_components/CreateOrderForm.tsx` + `src/features/order/schema.ts` |
276
295
  | 跨页面复用表单(地址 / 客户搜索) | `src/components/forms/<Name>Form.tsx` + 对应 schema |
277
296
  | 新增路由 / 页面入口 | `src/routes/index.tsx` 注册 + `src/pages/<id>/index.tsx`(default export,被 `React.lazy` 引入) |
278
297
  | 新增鉴权 / 角色守卫 | `src/routes/guards.tsx` |
@@ -22,22 +22,24 @@
22
22
  ## Schema 落点
23
23
 
24
24
  ```
25
- src/services/
26
- ├── order.ts # 请求函数:listOrders、createOrder
27
- └── order.schema.ts # zod schema:CreateOrderInput、UpdateOrderInput
25
+ src/features/order/
26
+ ├── api.ts # 请求函数:listOrders、createOrder
27
+ ├── schema.ts # zod schema:CreateOrderInput、UpdateOrderInput
28
+ ├── hooks.ts # react-query 封装
29
+ └── types.ts # 领域类型
28
30
  ```
29
31
 
30
32
  约定:
31
33
 
32
- - **每个 domain 一个 `<domain>.schema.ts`**,与 service 同目录
34
+ - **每个 domain 一个 `schema.ts`**,与 api / hooks / types 同目录
33
35
  - 从 schema 派生类型:`export type CreateOrderInput = z.infer<typeof CreateOrderInputSchema>`
34
- - service 的入参 / 返回类型**优先用** schema 推导,而不是手写 interface
36
+ - api 的入参 / 返回类型**优先用** schema 推导,而不是手写 interface
35
37
  - **不要**把 schema 写在页面 / 组件文件里 —— schema 是 domain 资产,跨页面复用
36
38
 
37
39
  ### 示例
38
40
 
39
41
  ```ts
40
- // src/services/order.schema.ts
42
+ // src/features/order/schema.ts
41
43
  import { z } from 'zod';
42
44
 
43
45
  export const CreateOrderInputSchema = z.object({
@@ -57,13 +59,12 @@ export type CreateOrderInput = z.infer<typeof CreateOrderInputSchema>;
57
59
  ```
58
60
 
59
61
  ```ts
60
- // src/services/order.ts
62
+ // src/features/order/api.ts
61
63
  import { http } from '@/lib/http';
62
- import type { CreateOrderInput } from './order.schema';
63
- import type { Order } from '@/types/order';
64
+ import type { CreateOrderInput } from './schema';
65
+ import type { Order } from './types';
64
66
 
65
67
  export async function createOrder(input: CreateOrderInput): Promise<Order> {
66
- // 服务端层也可在这里再 parse 一次防御
67
68
  const { data } = await http.post('/api/orders', input);
68
69
  return data;
69
70
  }
@@ -100,11 +101,11 @@ src/components/forms/
100
101
  // src/pages/orders/new/_components/CreateOrderForm.tsx
101
102
  import { useForm } from 'react-hook-form';
102
103
  import { zodResolver } from '@hookform/resolvers/zod';
103
- import { useCreateOrder } from '@/hooks/useCreateOrder';
104
+ import { useCreateOrder } from '@/features/order/hooks';
104
105
  import {
105
106
  CreateOrderInputSchema,
106
107
  type CreateOrderInput,
107
- } from '@/services/order.schema';
108
+ } from '@/features/order/schema';
108
109
  import { Button, Input, Form, FormField, FormItem } from '@/components/ui';
109
110
 
110
111
  export function CreateOrderForm() {
@@ -155,7 +156,7 @@ export function CreateOrderForm() {
155
156
  - ❌ 在 `onChange` 里手写 `if (value.length > 20) setError(...)`
156
157
  - ❌ 校验报错信息硬编码在组件里("请输入正确的手机号") —— 写在 schema 里,UI 只读
157
158
  - ❌ 表单状态用 `useState`,然后再加 `useEffect` 同步校验 —— 直接用 `useForm`
158
- - ❌ schema 在组件文件里就地定义 —— 抽到 `<domain>.schema.ts`
159
+ - ❌ schema 在组件文件里就地定义 —— 抽到 `features/<domain>/schema.ts`
159
160
  - ❌ 提交逻辑写在 `<form onSubmit>` 里直接 fetch —— 走 mutation hook
160
161
 
161
162
  ---
@@ -215,8 +216,8 @@ pnpm add react-hook-form zod @hookform/resolvers
215
216
  ```
216
217
  ## 表单改动
217
218
 
218
- - src/services/order.schema.ts: 新增 CreateOrderInputSchema(zod)、派生类型
219
- - src/services/order.ts: createOrder 入参用派生类型
219
+ - src/features/order/schema.ts: 新增 CreateOrderInputSchema(zod)、派生类型
220
+ - src/features/order/api.ts: createOrder 入参用派生类型
220
221
  - src/pages/orders/new/_components/CreateOrderForm.tsx: useForm + zodResolver
221
- - src/hooks/useCreateOrder.ts: useMutation 包 createOrder,onError 区分字段级 / 通用
222
+ - src/features/order/hooks.ts: useCreateOrder — useMutation 包 createOrder,onError 区分字段级 / 通用
222
223
  ```
@@ -34,8 +34,8 @@
34
34
 
35
35
  ### 查询顺序(从快到慢)
36
36
 
37
- 1. **MCP `list_components`** —— 一次列全部,扫描是否有同名 / 近义。
38
- 2. **MCP `find_components` query=<关键词>** —— 子串匹配 id / name / description
37
+ 1. **读 `.teamix-evo/meta/ui/manifest.json`** —— 一次列全部,扫描是否有同名 / 近义。
38
+ 2. **`grep <关键词> .teamix-evo/meta/ui/manifest.json`** —— 子串匹配 id / name / description;需要详细 Props/示例时读 `.teamix-evo/meta/ui/<id>.md`。
39
39
  3. **本项目 grep** —— `grep -r "from '@/components/ui'" src/` 看哪些已经装机。
40
40
  4. **本项目 `.teamix-evo/ui/manifest.lock.json`** —— 已装机的 ui entry 清单。
41
41
 
@@ -64,11 +64,8 @@
64
64
 
65
65
  ### 页面骨架来源(列表 / 详情 / 表单 / 仪表盘)
66
66
 
67
- > ⚠️ **AI 默认不调用 `@teamix-evo/templates` 包**(见 ADR 0031 skill-templates-decoupling)。页面骨架按下列优先级生成:
68
-
69
67
  1. **首选** —— 读 `teamix-evo-design-opentrek` skill 的 [`patterns/{list|detail|form|dashboard}-page.md`](../teamix-evo-design-opentrek/patterns/),按 Zone Map 与决策树用 ui 原子件 + biz-ui 业务件**直接拼装**到 `src/pages/<id>/`
70
- 2. **patterns/ 未覆盖时** —— 按业界流行的中后台页面架构(antd Pro / shadcn Examples 等)与用户描述自由实现,**不要回退到 templates 包**
71
- 3. **`@teamix-evo/templates` 包与 CLI 命令仍保留**,但仅在用户**显式**要求(如"用 templates 包的 frozen 骨架")时才走 `teamix-evo templates add`
68
+ 2. **patterns/ 未覆盖时** —— 按业界流行的中后台页面架构(antd Pro / shadcn Examples 等)与用户描述自由实现
72
69
 
73
70
  ### 决策表
74
71
 
@@ -77,7 +74,7 @@
77
74
  | 列表页 / 详情页 / 表单页 / 仪表盘骨架 | 读 design skill `patterns/*.md` → ui + biz-ui 拼装 |
78
75
  | "带筛选的用户表格"、"带审批流的卡片" | 优先 `biz-ui` |
79
76
  | 一次性的、强领域绑定的组合 | 写在 `src/components/<domain>/` 里,**不要污染 biz-ui** |
80
- | patterns/ 未覆盖的特殊页面 | 按业界流行架构 + 用户描述自由实现,**不调用 templates 包** |
77
+ | patterns/ 未覆盖的特殊页面 | 按业界流行架构 + 用户描述自由实现 |
81
78
 
82
79
  ---
83
80
 
@@ -87,7 +84,7 @@
87
84
 
88
85
  1. **本项目 grep**:
89
86
  ```bash
90
- grep -rn "function <近义名>" src/utils/ src/lib/ src/hooks/
87
+ grep -rn "function <近义名>" src/utils/ src/lib/ src/features/
91
88
  ```
92
89
  2. **`@teamix-evo/*` 是否提供**(少数情况,如格式化、token 工具)
93
90
  3. **依赖里的成熟库** —— 例如:
@@ -112,7 +109,7 @@
112
109
  1. **命名要能让下次复用查得到** —— 起 `OrderStatusBadge` 而不是 `MyBadge`;`useOrderList` 而不是 `useList`。
113
110
  2. **抽象层级别低于一次性页面** —— 跨页面会用的才放 `src/components/`,只在一个页面用的写在 `src/pages/<id>/_components/`。
114
111
  3. **暴露面尽量窄** —— 默认只 `export` 这次需要的 API,别一次性 `export *`。
115
- 4. **写完登记** —— 在 PR 描述里明确“新增 `<path>`,因为 ui / biz-ui / patterns / 本项目均未提供 X 能力”(注:不再以 `templates` 包作为兑底依据,见 ADR 0031 skill-templates-decoupling)。
112
+ 4. **写完登记** —— 在 PR 描述里明确”新增 `<path>`,因为 ui / biz-ui / patterns / 本项目均未提供 X 能力”。
116
113
 
117
114
  ---
118
115
 
@@ -29,12 +29,12 @@ src/
29
29
  ├── utils/
30
30
  │ ├── format.ts
31
31
  │ └── format.test.ts # ← 紧邻
32
- ├── services/
33
- ├── order.ts
34
- └── order.test.ts
35
- ├── hooks/
36
- ├── useOrderList.ts
37
- └── useOrderList.test.ts
32
+ ├── features/
33
+ └── order/
34
+ ├── api.ts
35
+ ├── api.test.ts # ← 紧邻
36
+ ├── hooks.ts
37
+ └── hooks.test.tsx
38
38
  └── components/
39
39
  ├── OrderStatusBadge.tsx
40
40
  └── OrderStatusBadge.test.tsx
@@ -61,7 +61,7 @@ src/test/
61
61
 
62
62
  | 优先级 | 类型 | 例子 | 必测? |
63
63
  | ------ | ------------------------------------- | ----------------------------------- | -------------- |
64
- | P0 | 纯函数(`src/utils/`、`src/services/`) | `formatMoney`、`isValidOrder` | ✅ **必测** |
64
+ | P0 | 纯函数(`src/utils/`、`features/*/api.ts`) | `formatMoney`、`isValidOrder` | ✅ **必测** |
65
65
  | P0 | zod schema | `CreateOrderInputSchema.parse(...)` | ✅ **必测** |
66
66
  | P0 | 关键业务路径(下单 / 支付 / 鉴权) | E2E-style 组件测 | ✅ **必测** |
67
67
  | P1 | Hook(数据 hook + 自定义 UI hook) | `useOrderList`、`useDebounce` | 推荐 |
@@ -133,9 +133,9 @@ afterAll(() => server.close());
133
133
  ```
134
134
 
135
135
  ```ts
136
- // src/services/order.test.ts
136
+ // src/features/order/api.test.ts
137
137
  import { describe, it, expect } from 'vitest';
138
- import { listOrders } from './order';
138
+ import { listOrders } from './api';
139
139
 
140
140
  describe('listOrders', () => {
141
141
  it('返回订单列表', async () => {
@@ -149,10 +149,10 @@ describe('listOrders', () => {
149
149
  ### Hook
150
150
 
151
151
  ```tsx
152
- // src/hooks/useOrderList.test.tsx
152
+ // src/features/order/hooks.test.tsx
153
153
  import { renderHook, waitFor } from '@testing-library/react';
154
154
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
155
- import { useOrderList } from './useOrderList';
155
+ import { useOrderList } from './hooks';
156
156
 
157
157
  function wrapper({ children }: { children: React.ReactNode }) {
158
158
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
@@ -247,7 +247,7 @@ renderWithProviders(<OrderListPage />, { route: '/orders?status=pending' });
247
247
  | 测 `setState` 是否被调用 | 测了实现,重构即崩 | 测渲染结果 / 用户行为 |
248
248
  | `getByTestId` 当默认查询 | data-testid 跟可访问性绑不上 | `getByRole` / `getByLabelText` 优先 |
249
249
  | 一个 it 里 expect 10 次无关断言 | 失败定位难 | 拆多个 it |
250
- | mock 整个 hook(`vi.mock('@/hooks/...')`) | 失去集成价值 | msw mock 后端,hook 真跑 |
250
+ | mock 整个 hook(`vi.mock('@/features/...')`) | 失去集成价值 | msw mock 后端,hook 真跑 |
251
251
  | 自己 mock fetch / axios | 与生产代码路径不一致 | 用 msw |
252
252
  | 测试里写 `setTimeout(..., 1000)` 等异步 | 慢且不稳定 | `await waitFor` / `findBy*` |
253
253
  | 全局 mock console.error 静默 | 错过真实告警 | 让测试输出 console.error,但 setup 里 fail on it |
@@ -308,8 +308,8 @@ pnpm exec msw init public/ --save # 浏览器 worker
308
308
  ## 测试覆盖
309
309
 
310
310
  - 新增 src/utils/calcDiscount.ts → 同目录 calcDiscount.test.ts(5 个 case)
311
- - 新增 src/services/order.ts:createOrder → order.test.ts(成功 / 422 字段错 / 500)
312
- - 新增 src/hooks/useCreateOrder.ts → useCreateOrder.test.tsx(success / error)
311
+ - 新增 src/features/order/api.ts:createOrder → api.test.ts(成功 / 422 字段错 / 500)
312
+ - 新增 src/features/order/hooks.ts:useCreateOrderhooks.test.tsx(success / error)
313
313
  - 复用 src/components/OrderStatusBadge.tsx → 已有 test 覆盖,无需补
314
314
  - 跳过测: src/pages/orders/new/index.tsx(纯组合,关键逻辑已在 hook / form 层测)
315
315
  ```
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: teamix-evo-code-uni-manager
3
3
  description: |
4
- Enforce teamix-evo coding conventions in uni-manager (hybrid-cloud / multi-tenant console) consumer apps — reuse-first against `@teamix-evo/ui` registry + `biz-ui/uni-manager` (um-topbar / CloudBadge), API code under `src/services/` with tenant / region context propagation, `src/` layering and import boundaries.
5
- TRIGGER when: user asks to "新增 / 重构 / 写一个" 组件 / 页面 / 接口 / 钩子 / 工具 / hook in a hybrid-cloud / 专有云 / 多租户 / 多区域 console; phrases like "create a CRUD page""add an API call"、"extract a hook""refactor this fetch"、"调一下接口"、"加个组件"、"加个按钮"; file write under `src/pages/**`、`src/components/**`、`src/services/**`、`src/hooks/**`; AI is about to write any new `.tsx` / `.ts` file in a teamix-evo-installed uni-manager-variant project.
6
- SKIP: pure visual / layout design questions about an already-existing screen with no code change (defer to teamix-evo-design-uni-manager); teamix-evo lifecycle (init / update / uninstall) — those go to teamix-evo-manage; changes only to design tokens / styles / theme — those go to ESLint and `tokens.overrides.css`.
7
- Coordinates with: teamix-evo-design-uni-manager (run alongside when the change also creates a UI screen — design handles the visual side, this skill handles file placement and reuse).
4
+ Enforce teamix-evo coding conventions in uni-manager apps — reuse-first, tenant/region context propagation, `src/` layering.
5
+ TRIGGER 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/**`.
6
+ SKIP: pure visual/layout design with no code change ( design-uni-manager); lifecycle commands ( manage); token/style-only changes (→ ESLint).
7
+ Coordinates with: teamix-evo-design-uni-manager (design handles visual side, this skill handles file placement and reuse).
8
8
  ---
9
9
 
10
10
  # teamix-evo-code-uni-manager
@@ -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 多云实例"
25
25
  - "add an API call to list instances across regions"
26
- - Any time AI is about to create a new file under `src/pages/`、`src/components/`、`src/services/`、`src/hooks/` in a hybrid-cloud console
26
+ - Any time AI is about to create a new file under `src/pages/`、`src/components/`、`src/features/` in a hybrid-cloud console
27
27
 
28
28
  If the task is purely about _visual design_ of a screen, use [`teamix-evo-design-uni-manager`](../teamix-evo-design-uni-manager/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, use [`teamix-evo-design
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 MCP `list_components` / `find_components`), the **biz-ui/uni-manager** layer (um-topbar / CloudBadge / ContextSwitcher placeholders), and grep the local project. Only write new code when no reuse path exists. **组件兗底铁律**:找不到时优先 ui 原子件组合,**禁止**自撸基础件。
35
- 2. **🚧 Layering check** — **MUST READ** [`api-layering.md`](api-layering.md). Any code that talks to a backend goes under `src/services/<domain>.ts`; multi-tenant / multi-region / multi-cloud context (tenantId / regionId / cloudProvider) is **propagated through `lib/http.ts` interceptors**, not as ad-hoc params per call. Components never call `fetch` / `axios` directly. Data hooks live in `src/hooks/` and consume services.
36
- 3. **🚧 Directory check** — **MUST READ** [`file-structure.md`](file-structure.md). Place the new file under the right top-level folder; uni-manager-specific shells (TenantContext / RegionContext / CloudBadge) have conventional locations.
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/services/<domain>.schema.ts`. Dangerous operations (delete / release / destroy) **must** route through `useDangerConfirm` (input resource name).
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`), the **biz-ui/uni-manager** layer (um-topbar / CloudBadge / ContextSwitcher placeholders), and grep the local project. Only write new code when no reuse path exists. **组件兗底铁律**:找不到时优先 ui 原子件组合,**禁止**自撸基础件。
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`; multi-tenant / multi-region / multi-cloud context (tenantId / regionId / cloudProvider) is **propagated through `lib/http.ts` interceptors**, not as ad-hoc params per call. 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); uni-manager-specific shells (TenantContext / RegionContext / CloudBadge) have conventional locations.
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`. Dangerous operations (delete / release / destroy) **must** route through `useDangerConfirm` (input resource name).
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`. Cross-cloud resource-not-found has a dedicated fallback.
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`; **list-page filters MUST sync `tenantId` / `regionId` / `cloudProvider` into URL search params**; um-topbar context switch rewrites the current URL.
40
40
  7. **Testing gate** — **MUST READ** [`testing.md`](testing.md). Pure functions and zod schemas are **mandatory** to test; tenant-context-aware http handlers must be covered by msw.
@@ -51,17 +51,17 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
51
51
 
52
52
  ## Outputs
53
53
 
54
- - Code placed under the conventional path
55
- - Reuse decisions explicitly logged ("reused `Button` from `@teamix-evo/ui`" / "reused `um-topbar` from `biz-ui/uni-manager`" / "no match found, wrote a new `OrderCard`")
54
+ - Code placed under the conventional path (`src/pages/<id>/`、`src/features/<domain>/api.ts`、…)
55
+ - Reuse decisions explicitly logged ("reused `Button` from `@teamix-evo/ui`" / "reused `um-topbar` from `biz-ui/uni-manager`" / "no match found, wrote a new `InstanceCard` under `src/components/`")
56
56
  - Tenant / region / cloud context propagation logged
57
57
  - Pass / fail status against [`checklist.md`](checklist.md)
58
58
 
59
59
  ## How to invoke (typical flow)
60
60
 
61
61
  1. Parse user intent → identify which artifact is being created (page / component / service / hook / util / form / route)
62
- 2. Read [`reuse-first.md`](reuse-first.md) and run the reuse query (MCP first, then biz-ui/uni-manager, then local grep)
62
+ 2. Read [`reuse-first.md`](reuse-first.md) and run the reuse query ( `.teamix-evo/meta/` 本地文件, then biz-ui/uni-manager, then local grep)
63
63
  3. Read [`file-structure.md`](file-structure.md) to pick the destination directory
64
- 4. If the change touches network / backend, read [`api-layering.md`](api-layering.md) — confirm tenant / region / cloud headers are injected via interceptor
64
+ 4. If the change touches network / backend, read [`api-layering.md`](api-layering.md) — confirm tenant / region / cloud headers are injected via interceptor; place api in `src/features/<domain>/api.ts`
65
65
  5. If the change involves a form, read [`forms-and-validation.md`](forms-and-validation.md) — for dangerous operations, plug `useDangerConfirm`
66
66
  6. If the change adds a page / data hook, read [`error-and-loading.md`](error-and-loading.md) for fallback / Skeleton / toast wiring
67
67
  7. If the change adds a route or page entry, read [`routing-and-codesplit.md`](routing-and-codesplit.md) — confirm tenant / region URL sync
@@ -75,7 +75,7 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
75
75
  | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
76
76
  | [`reuse-first.md`](reuse-first.md) | 复用决策流(ui 原子件 + biz-ui/uni-manager + 本项目);组件兜底铁律 |
77
77
  | [`file-structure.md`](file-structure.md) | 顶层 `src/` 目录骨架、归属、import 边界、命名、全局态分级(含 TenantContext / RegionContext) |
78
- | [`api-layering.md`](api-layering.md) | API 三层结构 + 多租户 / 多区域 / 跨云上下文注入 |
78
+ | [`api-layering.md`](api-layering.md) | Feature-based 三层结构(`features/<domain>/`)+ 多租户 / 多区域 / 跨云上下文注入 |
79
79
  | [`forms-and-validation.md`](forms-and-validation.md) | `react-hook-form` + `zod`;危险操作走 `useDangerConfirm`(输入资源名称确认) |
80
80
  | [`error-and-loading.md`](error-and-loading.md) | 全局 / 页面 ErrorBoundary、三态、Suspense、toast、跨云资源专属 fallback |
81
81
  | [`routing-and-codesplit.md`](routing-and-codesplit.md) | `React.lazy`、guards、404/403/500、tenant/region/cloud 进 URL search params、um-topbar 切换 URL 改写 |
@@ -91,7 +91,7 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
91
91
  ## Why these conventions(uni-manager 视角)
92
92
 
93
93
  - **Single source for UI** — `@teamix-evo/ui` 89 原子件 + `biz-ui/uni-manager`(当前 1 实物 um-topbar,其余如 CloudBadge / ContextSwitcher 是概念占位)。Re-implementing 顶部 topbar / 基础件会破坏一致性三件套(UM1/UM2/UM3)。
94
- - **Stable seams for change** — tenant / region / cloud 上下文集中在 `lib/http.ts` interceptor 与 `contexts/TenantContext.tsx`,新增云厂商或区域不需要改 89 处 service 调用。
94
+ - **Stable seams for change** — tenant / region / cloud 上下文集中在 `lib/http.ts` interceptor 与 `contexts/TenantContext.tsx`,新增云厂商或区域不需要改 89 处 api 调用。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.
95
95
  - **Predictable file location** — 所有 uni-manager 项目目录形状一致;新接手的人 5 分钟内能找到「租户切换在哪管」「跨云列表怎么写」「危险操作怎么二次确认」。
96
96
 
97
97
  <!-- teamix-evo:managed:end -->