@h-ai/cli 0.1.0-alpha.54 → 0.1.0-alpha.55

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 (64) hide show
  1. package/README.md +4 -0
  2. package/package.json +7 -7
  3. package/templates/base/package.json.hbs +1 -1
  4. package/templates/skills/AGENTS.md +8 -22
  5. package/templates/skills/CLAUDE.md +3 -16
  6. package/templates/skills/bridges/admin/AGENTS.md +3 -16
  7. package/templates/skills/bridges/admin/CLAUDE.md +3 -11
  8. package/templates/skills/bridges/admin/copilot-instructions.md +2 -39
  9. package/templates/skills/bridges/api/AGENTS.md +5 -18
  10. package/templates/skills/bridges/api/CLAUDE.md +3 -11
  11. package/templates/skills/bridges/api/copilot-instructions.md +3 -38
  12. package/templates/skills/bridges/fullstack/AGENTS.md.hbs +24 -59
  13. package/templates/skills/bridges/fullstack/CLAUDE.md.hbs +1 -15
  14. package/templates/skills/bridges/fullstack/copilot-instructions.md.hbs +5 -45
  15. package/templates/skills/bridges/h5/AGENTS.md +4 -17
  16. package/templates/skills/bridges/h5/CLAUDE.md +3 -11
  17. package/templates/skills/bridges/h5/copilot-instructions.md +2 -37
  18. package/templates/skills/bridges/mobile-app/AGENTS.md +5 -18
  19. package/templates/skills/bridges/mobile-app/CLAUDE.md +3 -11
  20. package/templates/skills/bridges/mobile-app/copilot-instructions.md +2 -38
  21. package/templates/skills/bridges/website/AGENTS.md +4 -17
  22. package/templates/skills/bridges/website/CLAUDE.md +3 -11
  23. package/templates/skills/bridges/website/copilot-instructions.md +2 -37
  24. package/templates/skills/copilot-instructions.md +2 -36
  25. package/templates/skills/hai-ai/SKILL.md +35 -389
  26. package/templates/skills/hai-ai/guide.md +383 -0
  27. package/templates/skills/hai-ai/reference.md +1 -1
  28. package/templates/skills/hai-api-client/SKILL.md +6 -6
  29. package/templates/skills/hai-api-contract/SKILL.md +10 -25
  30. package/templates/skills/hai-app-create/SKILL.md +29 -388
  31. package/templates/skills/hai-app-create/reference.md +350 -0
  32. package/templates/skills/hai-app-review/SKILL.md +9 -23
  33. package/templates/skills/hai-app-tests/SKILL.md +29 -494
  34. package/templates/skills/hai-app-tests/reference.md +442 -0
  35. package/templates/skills/hai-audit/SKILL.md +6 -6
  36. package/templates/skills/hai-build/SKILL.md +19 -338
  37. package/templates/skills/hai-build/reference.md +326 -0
  38. package/templates/skills/hai-cache/SKILL.md +27 -32
  39. package/templates/skills/hai-capacitor/SKILL.md +19 -366
  40. package/templates/skills/hai-capacitor/reference.md +352 -0
  41. package/templates/skills/hai-ci/SKILL.md +6 -21
  42. package/templates/skills/hai-core/SKILL.md +25 -566
  43. package/templates/skills/hai-core/reference.md +533 -0
  44. package/templates/skills/hai-crypto/SKILL.md +6 -20
  45. package/templates/skills/hai-datapipe/SKILL.md +9 -23
  46. package/templates/skills/hai-deploy/SKILL.md +6 -24
  47. package/templates/skills/hai-framework-sync/SKILL.md +8 -20
  48. package/templates/skills/hai-iam/SKILL.md +27 -371
  49. package/templates/skills/hai-iam/reference.md +343 -0
  50. package/templates/skills/hai-kit/SKILL.md +6 -6
  51. package/templates/skills/hai-payment/SKILL.md +6 -26
  52. package/templates/skills/hai-pr-review/SKILL.md +6 -22
  53. package/templates/skills/hai-reach/SKILL.md +19 -317
  54. package/templates/skills/hai-reach/reference.md +303 -0
  55. package/templates/skills/hai-reldb/SKILL.md +19 -472
  56. package/templates/skills/hai-reldb/reference.md +452 -0
  57. package/templates/skills/hai-scheduler/SKILL.md +6 -6
  58. package/templates/skills/hai-serv/SKILL.md +27 -759
  59. package/templates/skills/hai-serv/reference.md +736 -0
  60. package/templates/skills/hai-storage/SKILL.md +7 -25
  61. package/templates/skills/hai-ui/SKILL.md +29 -625
  62. package/templates/skills/hai-ui/reference.md +598 -0
  63. package/templates/skills/hai-vecdb/SKILL.md +18 -303
  64. package/templates/skills/hai-vecdb/reference.md +291 -0
@@ -0,0 +1,350 @@
1
+ # hai-app-create — 详细用法
2
+
3
+ 从 [SKILL.md](SKILL.md) 选择主题后读取对应小节。代码片段展示 API 用法;省略的业务变量、schema、依赖与 return 上下文需由应用补齐。
4
+
5
+ > 面向 AI 助手的应用功能创建指南。**必须遵循 TDD**:先写测试(Red)→ 再实现(Green)→ 再重构(Refactor)。
6
+ > 若目标是纯 API service workspace,优先围绕 `apps/*-contract`、`apps/*-service` 与测试组织改动,而不是套用页面/路由脚手架。
7
+
8
+ ## 适用场景
9
+
10
+ - 新增页面(路由)
11
+ - 新增 API 端点
12
+ - 新增服务层模块(`$lib/server/services/`)
13
+ - 新增数据库表 / 数据模型
14
+ - 新增业务组件
15
+
16
+ ## TDD 开发流程(强制)
17
+
18
+ 创建任何新功能时,必须按以下顺序执行:
19
+
20
+ ### Step 1:需求分析与测试设计
21
+
22
+ 1. 明确功能的输入、输出、边界条件、错误场景
23
+ 2. 确定需要创建的文件(服务、路由、Schema、组件等)
24
+ 3. 设计测试用例清单(参照 `hai-app-tests` 技能的覆盖范围要求)
25
+
26
+ ### Step 2:编写测试(Red 阶段)
27
+
28
+ 1. **创建单元测试**:在 `tests/` 下为服务层、Schema 编写 Vitest 测试
29
+ 2. **创建 E2E 测试**:在 `e2e/` 下为 API 端点、页面交互编写 Playwright 测试
30
+ 3. **创建空的实现文件**:仅包含函数签名和类型定义,不写实际逻辑(确保 import 不报错)
31
+ 4. **运行测试确认新增目标用例因预期行为缺失而失败(既有回归保持通过)**:
32
+ ```bash
33
+ pnpm --filter <app-name> test # 新增目标用例应 FAIL,既有回归应 PASS
34
+ ```
35
+
36
+ ### Step 3:编写实现(Green 阶段)
37
+
38
+ 按照下文的「创建指南」编写实际功能代码,每完成一个功能点立即运行测试确认通过。
39
+
40
+ ### Step 4:重构与验证(Refactor 阶段)
41
+
42
+ 1. 参照 `hai-app-review` 审查代码规范
43
+ 2. 运行质量门禁:`pnpm typecheck && pnpm lint && pnpm test`
44
+ 3. 运行 E2E:`pnpm --filter <app-name> test:e2e`
45
+
46
+ ## 目录结构约定
47
+
48
+ ```
49
+ src/
50
+ hooks.server.ts # `handle` hook 入口
51
+ app.css # 全局样式(TailwindCSS 4)
52
+ lib/
53
+ server/
54
+ init.ts # 应用初始化(模块 init 顺序)
55
+ services/ # 业务服务层(Server-only)
56
+ index.ts # 服务聚合导出
57
+ user.ts # 示例:用户服务
58
+ schemas/ # 请求校验 Schema(Zod)
59
+ components/ # 业务组件(非 @h-ai/ui 通用组件)
60
+ stores/ # 客户端 Store(Svelte 5 Runes)
61
+ paraglide/ # i18n 生成文件(禁止手动修改)
62
+ routes/
63
+ +layout.svelte # 根布局
64
+ +page.svelte # 首页
65
+ (auth)/ # 认证分组路由
66
+ login/+page.svelte
67
+ admin/ # 管理区域
68
+ users/
69
+ +page.svelte # 列表页
70
+ +page.server.ts # 列表数据加载
71
+ [id]/
72
+ +page.svelte # 详情页
73
+ +page.server.ts
74
+ api/ # API 端点
75
+ auth/+server.ts
76
+ health/+server.ts
77
+ iam/
78
+ users/+server.ts
79
+ messages/ # i18n 消息文件
80
+ en-US.json
81
+ zh-CN.json
82
+ config/ # 模块配置文件
83
+ _core.yml
84
+ _db.yml
85
+ _cache.yml
86
+ _iam.yml
87
+ ```
88
+
89
+ ## 创建页面
90
+
91
+ ### 页面路由规则
92
+
93
+ 使用 SvelteKit 文件路由,参考 `src/routes/` 约定:
94
+
95
+ | 类型 | 路径示例 | 说明 |
96
+ | -------- | ---------------------------------- | -------------------- |
97
+ | 静态页面 | `routes/about/+page.svelte` | 常规页面 |
98
+ | 动态路由 | `routes/users/[id]/+page.svelte` | URL 参数 |
99
+ | 分组路由 | `routes/(auth)/login/+page.svelte` | 共享布局,不影响 URL |
100
+ | API 端点 | `routes/api/users/+server.ts` | RESTful API |
101
+
102
+ ### 页面文件模板
103
+
104
+ ```svelte
105
+ <!-- +page.svelte -->
106
+ <script lang="ts">
107
+ // Svelte 5 Runes 语法
108
+ let { data } = $props()
109
+ let loading = $state(false)
110
+
111
+ async function handleAction() {
112
+ loading = true
113
+ try {
114
+ // 业务逻辑
115
+ } finally {
116
+ loading = false
117
+ }
118
+ }
119
+ </script>
120
+
121
+ <div class="container mx-auto p-4">
122
+ <!-- 使用 @h-ai/ui 组件 -->
123
+ </div>
124
+ ```
125
+
126
+ ### 数据加载(+page.server.ts)
127
+
128
+ ```typescript
129
+ import type { PageServerLoad } from './$types'
130
+ import { error, redirect } from '@sveltejs/kit'
131
+
132
+ export const load: PageServerLoad = async ({ locals }) => {
133
+ if (!locals.session)
134
+ redirect(303, '/auth/login')
135
+ const result = await someService.list()
136
+ if (!result.success)
137
+ error(500, result.error.message)
138
+ return { items: result.data }
139
+ }
140
+ ```
141
+
142
+ ## 创建 API 端点
143
+
144
+ ### RESTful 端点模板
145
+
146
+ ```typescript
147
+ // src/routes/api/[resource]/+server.ts
148
+ import type { RequestHandler } from './$types'
149
+ import { kit } from '@h-ai/kit'
150
+ import { z } from 'zod'
151
+
152
+ const CreateSchema = z.object({
153
+ name: z.string().min(1).max(100),
154
+ description: z.string().optional(),
155
+ })
156
+
157
+ // GET - 列表
158
+ export const GET = kit.handler(async ({ locals }) => {
159
+ kit.guard.require(locals.session, 'resource:read')
160
+
161
+ const result = await service.list()
162
+ if (!result.success)
163
+ return kit.response.error(result.error.code, result.error.message)
164
+ return kit.response.ok(result.data)
165
+ })
166
+
167
+ // POST - 创建
168
+ export const POST = kit.handler(async ({ request, locals }) => {
169
+ kit.guard.require(locals.session, 'resource:create')
170
+
171
+ const data = await kit.validate.body(request, CreateSchema)
172
+
173
+ const result = await service.create(data)
174
+ if (!result.success)
175
+ return kit.response.error(result.error.code, result.error.message)
176
+ return kit.response.created(result.data)
177
+ })
178
+ ```
179
+
180
+ ### 要点
181
+
182
+ - 所有端点**必须**用 `kit.handler(async ({ locals, request, ... }) => { ... })` 包裹,由 handler 统一处理 throw 的 Response
183
+ - 权限守卫使用 `kit.guard.require(locals.session, 'xxx:yyy')`,它本身就是 throw 模式(未通过时 throw 403 Response),**无需**检查返回值
184
+ - 输入校验使用 `await kit.validate.body(request, Schema)`,校验失败时 throw 400 Response,**无需**手动判断 valid
185
+ - 返回统一使用 `kit.response.*`
186
+ - HaiResult 错误直接透传,不重新包装
187
+ - HaiResult 型业务操作先检查 result.success;流和显式抛错 API 按各自契约处理
188
+
189
+ ## 创建服务层
190
+
191
+ 服务层位于 `$lib/server/services/`,处理业务逻辑。
192
+
193
+ ```typescript
194
+ import type { HaiResult, PaginatedResult } from '@h-ai/core'
195
+ import { core, ok } from '@h-ai/core'
196
+ import { reldb } from '@h-ai/reldb'
197
+
198
+ // Article/CreateArticleInput/ListParams 为应用类型;已完成建表。
199
+ const articles = reldb.crud.table<Article>({
200
+ table: 'articles',
201
+ idColumn: 'id',
202
+ dbType: 'sqlite', // 与本例初始化后端一致;切换数据库时同步修改
203
+ select: ['id', 'title', 'created_at AS createdAt'],
204
+ })
205
+
206
+ export async function createArticle(input: CreateArticleInput): Promise<HaiResult<Article>> {
207
+ const article = { ...input, id: core.id.generate(), createdAt: new Date().toISOString() }
208
+ // DB 列映射由应用定义;create 返回 ExecuteResult,不是 Article。
209
+ const result = await articles.create({ id: article.id, title: article.title, created_at: article.createdAt })
210
+ if (!result.success) return result
211
+ return ok(article)
212
+ }
213
+
214
+ export async function listArticles(params: ListParams): Promise<HaiResult<PaginatedResult<Article>>> {
215
+ return articles.findPage({ pagination: params })
216
+ }
217
+ ```
218
+
219
+ ### 服务层规则
220
+
221
+ - 统一返回 `HaiResult<T>`
222
+ - 写操作需 `debug`(进入)+ `info`(成功)日志
223
+ - 读操作仅 `debug` 日志
224
+ - 禁止 `console.log`,使用 `core.logger`
225
+ - 服务层不处理 HTTP 响应格式,只返回 HaiResult
226
+
227
+ ## 创建数据模型
228
+
229
+ ### Schema 定义(SQL DDL)
230
+
231
+ 数据库表 Schema 定义在 `$lib/server/init.ts` 中:
232
+
233
+ ```typescript
234
+ const BUSINESS_SCHEMA = `
235
+ CREATE TABLE IF NOT EXISTS articles (
236
+ id TEXT PRIMARY KEY,
237
+ title TEXT NOT NULL,
238
+ content TEXT,
239
+ author_id TEXT NOT NULL,
240
+ status TEXT DEFAULT 'draft',
241
+ created_at TEXT DEFAULT (datetime('now')),
242
+ updated_at TEXT DEFAULT (datetime('now'))
243
+ );
244
+
245
+ CREATE INDEX IF NOT EXISTS idx_articles_author_id ON articles(author_id);
246
+ CREATE INDEX IF NOT EXISTS idx_articles_status ON articles(status);
247
+ `
248
+ ```
249
+
250
+ ### 类型定义
251
+
252
+ ```typescript
253
+ // 在服务文件或独立类型文件中定义
254
+ interface Article {
255
+ id: string
256
+ title: string
257
+ content: string | null
258
+ authorId: string
259
+ status: 'draft' | 'published' | 'archived'
260
+ createdAt: string
261
+ updatedAt: string
262
+ }
263
+
264
+ interface CreateArticleInput {
265
+ title: string
266
+ content?: string
267
+ authorId: string
268
+ }
269
+ ```
270
+
271
+ ## 创建业务组件
272
+
273
+ 业务组件放在 `$lib/components/`,通用 UI 使用 `@h-ai/ui`。
274
+
275
+ ```svelte
276
+ <!-- src/lib/components/ArticleCard.svelte -->
277
+ <script lang="ts">
278
+ import type { Article } from '$lib/server/services/article'
279
+
280
+ let { article, onEdit }: { article: Article, onEdit?: () => void } = $props()
281
+ </script>
282
+
283
+ <div class="card bg-base-100 shadow">
284
+ <div class="card-body">
285
+ <h2 class="card-title">{article.title}</h2>
286
+ <p>{article.content ?? ''}</p>
287
+ {#if onEdit}
288
+ <div class="card-actions justify-end">
289
+ <button class="btn btn-primary" onclick={onEdit}>编辑</button>
290
+ </div>
291
+ {/if}
292
+ </div>
293
+ </div>
294
+ ```
295
+
296
+ ### 组件规则
297
+
298
+ - 使用 Svelte 5 Runes 语法(`$props()`、`$state()`、`$derived()`、`$effect()`)
299
+ - 事件回调通过 props 传入(非 `createEventDispatcher`)
300
+ - 样式使用 TailwindCSS 4 + DaisyUI 5 class
301
+ - 通用 UI 组件优先使用 `@h-ai/ui`,不重复实现
302
+ - i18n 文本使用 `$lib/paraglide/messages.js` 中的 key
303
+
304
+ ## 初始化顺序
305
+
306
+ 在 `$lib/server/init.ts` 中管理模块初始化顺序:
307
+
308
+ ```
309
+ core.init() → reldb.init() → cache.init() → iam.init() → createBusinessTables()
310
+ ```
311
+
312
+ 新增模块时需在此文件中按依赖顺序添加初始化调用。
313
+
314
+ ## 容器交付
315
+
316
+ - 保持脚手架根目录 `Dockerfile`、`.dockerignore` 与 `package.json` 中 `docker:build*` / `podman:build*` 命令同步。
317
+ - Podman 多阶段构建保持 `--format docker --jobs=1`;前者保留 `HEALTHCHECK`,后者避免部分 Podman 5.8/Buildah 组合在并行 stage 构建时触发内部 semaphore panic。
318
+ - 先复制 lockfile 与 workspace 配置执行 `pnpm fetch`,再复制源码并离线安装、构建;避免源码变化重复下载依赖,同时兼容新增 workspace。
319
+ - SvelteKit 服务使用 Node adapter;纯 Vite 前端使用带 SPA fallback 的静态镜像;fullstack 的 Service 与 Web 分别交付,Service 直接监听且不增加转发进程。
320
+ - Web 的 `PUBLIC_*` 部署配置在容器启动时生成静态运行时配置,不作为 build arg 烘焙,确保同一镜像可跨环境部署。
321
+ - 配置文件随镜像提供,并允许只读挂载覆盖;密钥只通过环境变量或 `--env-file` 注入。
322
+ - 普通构建不携带 `data/`;只有用户明确运行 `docker:build:data` / `podman:build:data` 时才通过 named build context 嵌入 SQLite/本地存储初始快照。
323
+ - 数据库和本地存储的持续写入必须落到 volume,不能依赖镜像可写层。
324
+ - 完成前实际启动镜像,验证健康端点、非 root 用户、环境变量覆盖、配置挂载和预置数据读取。
325
+
326
+ ## 检查清单
327
+
328
+ - [ ] **TDD 流程已执行**:先写测试 → 确认失败 → 再实现 → 确认通过
329
+ - [ ] 单元测试已编写(服务层、Schema)
330
+ - [ ] E2E 测试已编写(API 端点、页面交互)
331
+ - [ ] 页面使用 Svelte 5 Runes 语法
332
+ - [ ] API 端点有权限守卫与输入校验
333
+ - [ ] 服务层统一返回 `HaiResult<T>`
334
+ - [ ] 日志级别正确(读 debug / 写 debug+info / 失败 warn|error)
335
+ - [ ] 禁止 `console.log`、`any`、硬编码密钥
336
+ - [ ] 用户可见文本走 i18n
337
+ - [ ] Docker / Podman 镜像可启动,配置/环境变量/数据目录行为已验证
338
+ - [ ] 新增表有索引定义
339
+ - [ ] 组件优先使用 `@h-ai/ui`
340
+ - [ ] `pnpm typecheck && pnpm lint && pnpm test` 通过
341
+
342
+ ## 相关 Skills
343
+
344
+ - `hai-build`:项目架构与模块初始化顺序
345
+ - `hai-app-tests`:TDD 测试规范(Red 阶段详细指引)
346
+ - `hai-app-review`:代码审查规范(Refactor 阶段参照)
347
+ - `hai-kit`:SvelteKit 集成的完整 API
348
+ - `hai-ui`:UI 组件库使用
349
+ - `hai-reldb`:数据库操作详细 API
350
+ - `hai-iam`:认证与权限管理
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hai-app-review
3
- description: 对应用代码进行审查:路由安全 → 认证授权 → i18n → 组件使用 → API 端点 / service workspace → 服务层 → 性能,并补充产品体验与交互走查;当需求涉及代码审查、规范化、质量检查时使用。
3
+ description: "审查 hai 应用的路由、权限、i18n、服务层与交互体验。"
4
4
  ---
5
5
 
6
6
  # hai-app-review — 应用代码审查规范
@@ -9,16 +9,14 @@ description: 对应用代码进行审查:路由安全 → 认证授权 → i18
9
9
 
10
10
  | 项目 | 契约 |
11
11
  | --- | --- |
12
- | 能力 | 对应用代码进行审查:路由安全 → 认证授权 → i18n → 组件使用 → API 端点 / service workspace → 服务层 → 性能,并补充产品体验与交互走查;当需求涉及代码审查、规范化、质量检查时使用。 |
13
- | 适用场景 | 当任务与 `hai-app-review` 的能力描述匹配,并且需要遵循本 Skill 的流程和边界时 |
14
- | 输入 | 用户指定的审查范围、代码/差异、仓库规范与可复现证据 |
15
- | 输出 | 按优先级排列的问题、影响、定位和修正建议;仅在用户要求时实施修改 |
16
- | 限制 | 不把风格偏好当缺陷,不猜测未读取的实现,不在审查请求中擅自发布或改动外部状态 |
12
+ | 能力 | 审查 hai 应用的路由、权限、i18n、服务层与交互体验 |
13
+ | 适用场景 | 用户要求应用代码/体验审查或修复评估 |
14
+ | 输入 | 用户指定范围、代码/差异、运行证据与验收要求 |
15
+ | 输出 | 按优先级列出的证据、影响和修正建议 |
16
+ | 限制 | 只读审查不自动改代码;未读取的实现不下结论,不把偏好当缺陷。实现修复需用户已授权。 |
17
17
 
18
18
  > 面向 AI 助手的应用代码审查指南。用于审查使用 hai-framework 构建的 SvelteKit 应用、纯 Svelte/Vite 客户端与 API service workspace。本技能也是 TDD Refactor 阶段的执行入口。
19
19
 
20
- ---
21
-
22
20
  ## 适用场景
23
21
 
24
22
  - 审查应用代码是否符合 hai-framework 规范
@@ -26,8 +24,6 @@ description: 对应用代码进行审查:路由安全 → 认证授权 → i18
26
24
  - 规范化现有代码(分层、命名、日志、i18n)
27
25
  - 安全审查(权限、输入校验、密钥管理)
28
26
 
29
- ---
30
-
31
27
  ## 工作准则
32
28
 
33
29
  1. **先搜索再改动**:用全局检索确认引用关系,避免遗漏更新。
@@ -35,8 +31,6 @@ description: 对应用代码进行审查:路由安全 → 认证授权 → i18
35
31
  3. **成套更新**:代码 / 测试 / 文档同步。
36
32
  4. **重构后测试必须仍通过**:任何重构都不能破坏已有测试。
37
33
 
38
- ---
39
-
40
34
  ## 审查清单
41
35
 
42
36
  ### TDD 合规性
@@ -49,8 +43,6 @@ description: 对应用代码进行审查:路由安全 → 认证授权 → i18
49
43
  - [ ] `pnpm test` 单元测试全部通过
50
44
  - [ ] `pnpm test:e2e` E2E 测试全部通过
51
45
 
52
- ---
53
-
54
46
  ## 审查清单
55
47
 
56
48
  ### 架构分层
@@ -65,9 +57,9 @@ description: 对应用代码进行审查:路由安全 → 认证授权 → i18
65
57
 
66
58
  - [ ] 投递等业务状态按 `sent` 等字段判断,失败保留用户输入;HTTP/HaiResult 成功不代替业务完成
67
59
 
68
- - [ ] 所有框架模块调用都检查 `result.success`
60
+ - [ ] 返回 HaiResult 的调用先检查 `result.success`
69
61
  - [ ] 上游 HaiResult 错误直接透传,不重新包装
70
- - [ ] 不使用 `try/catch` 来处理框架模块返回的错误(模块 API 不抛异常,统一返回 `HaiResult<T>`)
62
+ - [ ] 不使用 `try/catch` 来处理框架模块返回的错误(HaiResult 型 API 的业务错误在结果中;流/显式抛错 API 另按契约处理)
71
63
 
72
64
  ```typescript
73
65
  // ❌ 重新包装
@@ -84,7 +76,7 @@ if (!result.success)
84
76
 
85
77
  ### 权限与安全
86
78
 
87
- - [ ] 所有 API 端点和 `load` 函数有 `kit.guard.*` 守卫
79
+ - [ ] 受保护端点/load 有与实际框架匹配的守卫;公开路由显式允许匿名,不给 API service 强加 kit.guard
88
80
  - [ ] 所有用户输入通过 Zod Schema 校验(`kit.validate.*`)
89
81
  - [ ] 无硬编码 API Key / 密钥
90
82
  - [ ] 日志不输出密码、token 明文
@@ -152,8 +144,6 @@ if (!result.success)
152
144
  - [ ] 初始化在 `$lib/server/init.ts` 统一管理
153
145
  - [ ] 配置文件路径遵循 `config/_<module>.yml` 约定
154
146
 
155
- ---
156
-
157
147
  ## 质量门禁
158
148
 
159
149
  审查完成后按顺序执行:
@@ -165,8 +155,6 @@ if (!result.success)
165
155
 
166
156
  优先使用 `pnpm --filter <app-name>` 指定应用。
167
157
 
168
- ---
169
-
170
158
  ## 输出要求
171
159
 
172
160
  - 列出改动文件与原因
@@ -174,8 +162,6 @@ if (!result.success)
174
162
  - 明确测试(单元 + E2E)与 lint 结果
175
163
  - 确认重构后所有测试仍然通过
176
164
 
177
- ---
178
-
179
165
  ## 相关 Skills
180
166
 
181
167
  - `hai-build`:项目架构总览与 TDD 工作流导航