@ai0x0/utils 0.0.31 → 0.0.33
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/.agents/skills/ai0x0-utils/backend/SKILL.md +366 -0
- package/.agents/skills/antd/SKILL.md +255 -0
- package/.agents/skills/cloudflare/SKILL.md +132 -0
- package/.agents/skills/nextjs/SKILL.md +252 -0
- package/README.md +34 -0
- package/eslint-rules/no-hardcoded-style.js +103 -42
- package/eslint-rules/require-section-divider.js +30 -11
- package/eslint-rules/require-use-form.js +12 -5
- package/package.json +5 -16
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloudflare
|
|
3
|
+
description: Cloudflare Workers、OpenNext、Wrangler、Hyperdrive、Neon Postgres、环境变量、部署、远程迁移和线上故障排查约定。调整 Worker 构建、wrangler 配置、环境绑定、数据库连接、test/prod 发布时使用。
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: Cloudflare Workers 部署与运行时约定
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Cloudflare Workers 约定
|
|
9
|
+
|
|
10
|
+
适用于通过 `@opennextjs/cloudflare` 部署到 Cloudflare Workers,并通过 Hyperdrive 连接 Neon Postgres 的 Next.js 项目。
|
|
11
|
+
|
|
12
|
+
## 架构
|
|
13
|
+
|
|
14
|
+
```txt
|
|
15
|
+
Next.js App Router
|
|
16
|
+
-> @opennextjs/cloudflare build
|
|
17
|
+
-> Cloudflare Worker
|
|
18
|
+
-> Hyperdrive
|
|
19
|
+
-> Neon Postgres
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
本地开发通过 Wrangler 模拟 Worker 环境,`hyperdrive.localConnectionString` 指向本地 Postgres。
|
|
23
|
+
|
|
24
|
+
## 本地环境
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm install
|
|
28
|
+
cp .dev.vars.example .dev.vars
|
|
29
|
+
docker compose up -d my-postgres
|
|
30
|
+
pnpm db:migrate
|
|
31
|
+
pnpm dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
关键配置:
|
|
35
|
+
|
|
36
|
+
- `wrangler.jsonc` 的 `hyperdrive.localConnectionString` 是本地 PG 连接串的唯一定义点。
|
|
37
|
+
- `.dev.vars` 是 Wrangler 本地 secrets,会作为 Cloudflare env binding 注入。
|
|
38
|
+
- `.env.local` 只放品牌变量和 edge/proxy 必须读取的 `SESSION_SECRET`。
|
|
39
|
+
- 线上 secrets 使用 `pnpm exec wrangler secret put <KEY>`。
|
|
40
|
+
|
|
41
|
+
业务代码读取环境变量时,优先走项目封装的 `fileEnv` / `getCloudflareEnv()` / `getCloudflareEnvAsync()`,不要散落 `process.env`。
|
|
42
|
+
|
|
43
|
+
## Worker 构建约束
|
|
44
|
+
|
|
45
|
+
- 使用 `@opennextjs/cloudflare` 把 Next.js 打成 Worker。
|
|
46
|
+
- Worker 免费档 gzip 产物需小于 3 MiB。
|
|
47
|
+
- 管理后台重页面优先 `ssr:false` 动态加载。
|
|
48
|
+
- `scripts/patch-handler.mjs` 用于剔除不适合 Worker 免费档的包或压缩产物。
|
|
49
|
+
- `compatibility_flags` 必须包含 `nodejs_compat`;如果项目依赖公开 fetch 语义,也保留 `global_fetch_strictly_public`。
|
|
50
|
+
- Workers 跑不了原生模块,新增依赖前确认能在 Workers/nodejs_compat 下运行。
|
|
51
|
+
- `bcrypt` 用 `bcryptjs`,避免 `sharp` / `canvas` 这类原生绑定。
|
|
52
|
+
|
|
53
|
+
## 数据库与 Hyperdrive
|
|
54
|
+
|
|
55
|
+
- 线上数据库连接通过 `env.HYPERDRIVE.connectionString`。
|
|
56
|
+
- 本地 Wrangler 会把 `wrangler.jsonc` 的 `hyperdrive.localConnectionString` 注入为 Hyperdrive binding。
|
|
57
|
+
- 不要在业务代码里硬编码数据库连接串。
|
|
58
|
+
- 跨账号或多环境部署时,确认目标 Worker 账号、env 和 Hyperdrive binding 匹配。
|
|
59
|
+
|
|
60
|
+
本地迁移:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pnpm db:generate
|
|
64
|
+
pnpm db:migrate
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
远程 Neon 迁移推荐用 drizzle migrator 跑已生成的 SQL,不直接手工改 Neon:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
DRIZZLE_DATABASE_URL='postgresql://...' \
|
|
71
|
+
node -e "const{drizzle}=require('drizzle-orm/node-postgres');const{migrate}=require('drizzle-orm/node-postgres/migrator');const{Pool}=require('pg');const p=new Pool({connectionString:process.env.DRIZZLE_DATABASE_URL,ssl:{rejectUnauthorized:false}});migrate(drizzle(p),{migrationsFolder:'./app/(backend)/db/migrations'}).then(()=>p.end())"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 部署命令
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm run deploy:test
|
|
78
|
+
pnpm run deploy
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
典型脚本顺序:
|
|
82
|
+
|
|
83
|
+
1. `opennextjs-cloudflare build`
|
|
84
|
+
2. `node scripts/patch-handler.mjs`
|
|
85
|
+
3. `wrangler deploy --env=test` 或生产 env
|
|
86
|
+
|
|
87
|
+
发布前检查:
|
|
88
|
+
|
|
89
|
+
- `pnpm build` 通过。
|
|
90
|
+
- `pnpm exec eslint` 无错误。
|
|
91
|
+
- `pnpm db:generate` 无未提交 diff,schema 与 migrations 同步。
|
|
92
|
+
- 涉及 schema 变更时,migration 已推到对应 Neon 库。
|
|
93
|
+
- 新增 API 已生成 `openapi.json` 和前端 client。
|
|
94
|
+
- `.dev.vars.example` 同步新增 env key。
|
|
95
|
+
- 已确认部署账号、分支、Worker 名称、Hyperdrive 资源和目标域名。
|
|
96
|
+
|
|
97
|
+
## 回滚
|
|
98
|
+
|
|
99
|
+
Cloudflare Dashboard -> Workers -> 对应 Worker -> Deployments -> 选择历史版本 Rollback。
|
|
100
|
+
|
|
101
|
+
数据库变更不会自动回滚。删列、改类型等 migration 必须提前设计回滚或兼容路径。
|
|
102
|
+
|
|
103
|
+
## 常用命令
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pnpm exec wrangler hyperdrive list
|
|
107
|
+
pnpm exec wrangler hyperdrive update <id> --connection-string='...'
|
|
108
|
+
pnpm exec wrangler secret put SESSION_SECRET
|
|
109
|
+
pnpm exec wrangler tail --env=test --format=json
|
|
110
|
+
pnpm run deploy:test
|
|
111
|
+
pnpm run deploy
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 故障排查
|
|
115
|
+
|
|
116
|
+
| 现象 | 常见原因 / 处理 |
|
|
117
|
+
| --------------------------------------- | -------------------------------------------------------------------- |
|
|
118
|
+
| `pnpm dev` 后 `/api/*` 401 | edge proxy 拿不到 `SESSION_SECRET`,`.env.local` 也要写同样的值 |
|
|
119
|
+
| `no local hyperdrive connection string` | `wrangler.jsonc` 未配置 `hyperdrive.localConnectionString` |
|
|
120
|
+
| 登录 200 但列表 401 | `.env.local` 与 `.dev.vars` 的 `SESSION_SECRET` 不一致 |
|
|
121
|
+
| `openapi.json` 生成失败 | 先确保 dev server 已运行,端口与生成器配置一致 |
|
|
122
|
+
| 线上 500 `数据库未初始化` | Hyperdrive binding id、env 或账号不匹配 |
|
|
123
|
+
| Worker bundle 超 3 MiB | 检查重页面是否动态加载、是否引入了不必要的大依赖 |
|
|
124
|
+
| 线上 GET 读到旧数据 | 优先排查 Cloudflare 缓存,API 路径需要明确 `Cache-Control: no-store` |
|
|
125
|
+
|
|
126
|
+
## 运行时注意事项
|
|
127
|
+
|
|
128
|
+
- Cloudflare Workers runtime 里同步 env 读取可能早于 binding 注入,API route 中优先使用 async env 读取封装。
|
|
129
|
+
- 后台任务或 `runInBackground` 里不要重新依赖可能为空的同步 env,必要时在请求上下文缓存连接串。
|
|
130
|
+
- `drizzle-zod` 与 Worker 构建偶尔会有运行时兼容问题,复杂 schema 可退回显式 zod object,但要保留类型意图。
|
|
131
|
+
- 自定义域名上的 API GET 可能被 CDN 缓存;对 `/api/*` 添加 no-cache/no-store 是重要保护。
|
|
132
|
+
- 使用 `wrangler tail --env=<env> --format=json` 看真实 Worker 日志,不只依赖本地推断。
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs
|
|
3
|
+
description: Next.js App Router 项目的目录、路由、后端 API、Drizzle schema、OpenAPI 客户端生成和代码组织约定。新增/修改页面、API、DB schema、业务 action、公共 utils 或调整 Next.js 配置时使用。
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: Next.js 目录、API、DB 与代码组织约定
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js 开发约定
|
|
9
|
+
|
|
10
|
+
适用于 Next.js 16 App Router + Turbopack 项目。前后端共存在 `app/` 下,通过路由分组隔离运行时边界。
|
|
11
|
+
|
|
12
|
+
## 目录分组
|
|
13
|
+
|
|
14
|
+
```txt
|
|
15
|
+
app/
|
|
16
|
+
├── (backend)/ # 后端独占:API 路由 + DB + 服务端 utils
|
|
17
|
+
├── (frontend)/ # 前端独占:页面 + 客户端 utils + 组件
|
|
18
|
+
├── (common)/ # 前后端共享:无运行时依赖的纯逻辑
|
|
19
|
+
├── manifest.ts
|
|
20
|
+
proxy.ts # Next.js 16 Proxy,原 middleware,API 鉴权入口
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
路径别名:
|
|
24
|
+
|
|
25
|
+
- `@backend/*` -> `app/(backend)/*`
|
|
26
|
+
- `@frontend/*` -> `app/(frontend)/*`
|
|
27
|
+
- `@common/*` -> `app/(common)/*`
|
|
28
|
+
- `@/*` -> 项目根
|
|
29
|
+
|
|
30
|
+
跨 `(backend)` / `(frontend)` / `(common)` 边界 import 必须用别名,禁止相对路径跨边界。
|
|
31
|
+
|
|
32
|
+
## 放置位置决策
|
|
33
|
+
|
|
34
|
+
1. 依赖 Node-only API、数据库、环境密钥、`next/server` -> `(backend)`
|
|
35
|
+
2. 依赖浏览器 API、React hooks、antd、`next/navigation` -> `(frontend)`
|
|
36
|
+
3. 前后端都要用且零运行时依赖的类型、常量、纯函数、zod 片段 -> `(common)`
|
|
37
|
+
4. 含糊场景默认留在使用方分组,不要过度抽取
|
|
38
|
+
|
|
39
|
+
所有函数、工具、辅助逻辑必须放进对应分组的 `utils/`。页面、组件、schema、route 里不要导出工具函数。
|
|
40
|
+
|
|
41
|
+
## 文件与命名
|
|
42
|
+
|
|
43
|
+
- 自建文件和目录统一 kebab-case。
|
|
44
|
+
- React 组件导出用 PascalCase。
|
|
45
|
+
- 函数/变量用 camelCase。
|
|
46
|
+
- 常量用 SCREAMING_SNAKE_CASE。
|
|
47
|
+
- hook 文件名用 `use-<name>.tsx`。
|
|
48
|
+
- 路由文件固定 `route.ts`,页面文件固定 `page.tsx` / `layout.tsx`。
|
|
49
|
+
- 私有辅助模块可用 `_helper.ts`。
|
|
50
|
+
|
|
51
|
+
新建文件时按这个顺序判断:
|
|
52
|
+
|
|
53
|
+
```txt
|
|
54
|
+
路由 -> app/(backend)/api/<resource>[/子路径]/route.ts
|
|
55
|
+
页面 -> app/(frontend)/admin/<resource>/page.tsx
|
|
56
|
+
仅本页组件 -> 页面同目录 <kebab-name>.tsx
|
|
57
|
+
复用组件 -> app/(frontend)/components/<kebab-name>.tsx
|
|
58
|
+
React hook -> app/(frontend)/hooks/use-<name>.tsx
|
|
59
|
+
后端业务函数 -> app/(backend)/utils/actions/<name>.ts
|
|
60
|
+
后端工具 -> app/(backend)/utils/<topic>/
|
|
61
|
+
前端工具 -> app/(frontend)/utils/<kebab-name>.ts
|
|
62
|
+
共享纯逻辑 -> app/(common)/<utils|types|constants>/
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 单一职责
|
|
66
|
+
|
|
67
|
+
一个文件只围绕一件事组织,文件名应该能预测文件内容。
|
|
68
|
+
|
|
69
|
+
- 一个文件只有一个主角。
|
|
70
|
+
- 文件名等于主角名。
|
|
71
|
+
- 文件超过约 150 行、出现两组互不调用的功能、导出超过 5 个不强相关 symbol、import 依赖明显分裂时,优先拆分。
|
|
72
|
+
- 页面目录下的子文件默认私有,只服务该页面。
|
|
73
|
+
- `schemas/index.ts`、`apis/index.tsx`、`generator/`、框架配置文件可以聚合,但聚合文件里不要塞业务逻辑。
|
|
74
|
+
|
|
75
|
+
## API 路径规范
|
|
76
|
+
|
|
77
|
+
```txt
|
|
78
|
+
app/(backend)/api/
|
|
79
|
+
├── route.ts -> GET /api,OpenAPI 文档
|
|
80
|
+
├── <resource>/
|
|
81
|
+
│ ├── route.ts -> GET/POST/PUT/DELETE /api/<resource>
|
|
82
|
+
│ └── list/
|
|
83
|
+
│ └── route.ts -> GET /api/<resource>/list
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
强制规则:
|
|
87
|
+
|
|
88
|
+
- 资源名单数、kebab-case:`/api/key`、`/api/api-key`。
|
|
89
|
+
- 列表接口必须是 `GET /api/<resource>/list`,不要把 `GET /api/<resource>` 当列表。
|
|
90
|
+
- 详情接口用 `GET /api/<resource>?id=xxx` 或唯一查询参数,避免 `/api/<resource>/<id>`。
|
|
91
|
+
- 操作类路径用子目录:`/api/key/verify`、`/api/email/code/verify`,不要用 query action。
|
|
92
|
+
- 多级路径必须有父子依赖关系。
|
|
93
|
+
- 标准增删改查尽量放同一个 `app/(backend)/api/<resource>/route.ts`,只有列表固定放 `/list`。
|
|
94
|
+
|
|
95
|
+
## 后端 API
|
|
96
|
+
|
|
97
|
+
每个 `route.ts` 用 `next-rest-framework` 的 `route({...})` 组装命名操作,通过解构 HTTP 动词导出。
|
|
98
|
+
|
|
99
|
+
优先使用 `@backend/utils/route-operation` 的工厂:
|
|
100
|
+
|
|
101
|
+
- `postOperation`
|
|
102
|
+
- `putOperation`
|
|
103
|
+
- `deleteOperation`
|
|
104
|
+
- `getOperation`
|
|
105
|
+
- `getListOperation`
|
|
106
|
+
|
|
107
|
+
只有这些场景才手写 `routeOperation`:
|
|
108
|
+
|
|
109
|
+
- multipart/form-data 上传。
|
|
110
|
+
- upsert 或非标准写入语义。
|
|
111
|
+
- 代理、文件流、非 JSON 响应。
|
|
112
|
+
- 需要完全自定义响应或特殊副作用。
|
|
113
|
+
|
|
114
|
+
`postOperation` / `putOperation` 支持:
|
|
115
|
+
|
|
116
|
+
- `setBody(req)`:写入前合入字段,如随机 key、`userId`、租户 id。
|
|
117
|
+
- `onSuccess(data)`:写入成功后的加工或副作用,必须返回最终响应数据。
|
|
118
|
+
- `onError(error)`:定制错误响应;否则交给默认 PG 约束错误翻译。
|
|
119
|
+
|
|
120
|
+
路由 handler 只做参数验证、组合 action、包装响应;DB 查询和业务逻辑放 `app/(backend)/utils/actions/*.ts`。
|
|
121
|
+
|
|
122
|
+
## DB Schema
|
|
123
|
+
|
|
124
|
+
每张表一个 schema 文件:
|
|
125
|
+
|
|
126
|
+
```txt
|
|
127
|
+
app/(backend)/db/
|
|
128
|
+
├── index.ts
|
|
129
|
+
├── schemas/
|
|
130
|
+
│ ├── <resource>.ts
|
|
131
|
+
│ └── index.ts
|
|
132
|
+
└── migrations/
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
约定:
|
|
136
|
+
|
|
137
|
+
- 用 `createTableSchema` 统一产出 `table` + `selectSchema`,并注入公共字段。
|
|
138
|
+
- 用 `createInsertSchema(table)` 生成 insert schema。
|
|
139
|
+
- 用 `queryListSchema(...)` 生成列表查询 schema。
|
|
140
|
+
- `schemas/*.ts` 只定义表和 zod schema,不写查询函数。
|
|
141
|
+
- 新表后在 `schemas/index.ts` 追加 `export * from "./<resource>"`。
|
|
142
|
+
- 每次 schema 变更必须 `pnpm db:generate`,迁移文件必须由命令生成,不手写或手改 migration/meta。
|
|
143
|
+
|
|
144
|
+
## OpenAPI 与前端 Client
|
|
145
|
+
|
|
146
|
+
后端 OpenAPI 文档入口在 `app/(backend)/api/route.ts`。
|
|
147
|
+
|
|
148
|
+
生成流程:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pnpm dev
|
|
152
|
+
pnpm openapi:json:generate
|
|
153
|
+
pnpm openapi:client:generate
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- `public/openapi.json` 来自运行中的 dev server。
|
|
157
|
+
- `app/(frontend)/apis/generator/` 是 openapi-generator 产物,不手改。
|
|
158
|
+
- 新增 tag 后,在 `app/(frontend)/apis/index.tsx` 追加对应 `XxxApiFactory`。
|
|
159
|
+
|
|
160
|
+
## 认证入口
|
|
161
|
+
|
|
162
|
+
`proxy.ts` 统一拦截 `/api/:path*`:
|
|
163
|
+
|
|
164
|
+
- `publicRoutes` 按 path + method 白名单。
|
|
165
|
+
- Session 通过 `@backend/utils/session` 解密 JWT。
|
|
166
|
+
- API Key 通过 `validateApiKey` 校验。
|
|
167
|
+
- 新路由默认受保护,只有明确需要免登录时才加白名单。
|
|
168
|
+
|
|
169
|
+
## TypeScript 与代码风格
|
|
170
|
+
|
|
171
|
+
- TypeScript `strict: true`,显式处理 null/undefined。
|
|
172
|
+
- import 顺序:外部包 -> `@backend/@frontend/@common/@ai0x0/utils` -> 相对路径。
|
|
173
|
+
- 字符串双引号、两空格缩进、末尾逗号。
|
|
174
|
+
- 注释用简短中文说明段落意图,不逐行翻译代码。
|
|
175
|
+
- 错误提示统一走上层错误处理或前端 app bridge,不要 `alert` / 裸 `console.log`。
|
|
176
|
+
- `ai0x0.configs.recommended` 中所有自定义规则都是 `error`,同时开启 `curly: "error"`。
|
|
177
|
+
- 所有 `if` / `for` / `while` / `else` 块必须写花括号,不写单行裸语句。
|
|
178
|
+
- 禁止 `.then()`,Promise 链统一改成 `async/await`。
|
|
179
|
+
- 禁止单字母变量名,`_`、for 循环迭代变量、泛型类型参数例外。
|
|
180
|
+
|
|
181
|
+
## 禁止 try/catch
|
|
182
|
+
|
|
183
|
+
业务代码不要写 `try { ... } catch { ... }`。
|
|
184
|
+
|
|
185
|
+
- 后端错误交给 `next-rest-framework`、`route-operation` 和 `onError`。
|
|
186
|
+
- 前端请求错误交给 axios 拦截器、`useRequest`、app message。
|
|
187
|
+
- fire-and-forget 副作用只允许 `.catch((e) => console.error(...))` 做最终兜底。
|
|
188
|
+
|
|
189
|
+
允许例外:
|
|
190
|
+
|
|
191
|
+
- `JSON.parse`、`atob`、第三方无类型库等解析容错。
|
|
192
|
+
- setup/proxy 等框架底层入口需要兜住请求生命周期。
|
|
193
|
+
- 测试中优先用 `expect(...).rejects`,不要额外包 try/catch。
|
|
194
|
+
|
|
195
|
+
## 禁止散落 `as`
|
|
196
|
+
|
|
197
|
+
- 不要在业务文件里重复声明 OpenAPI 已生成的 enum union。
|
|
198
|
+
- 前端 enum 使用 generator 导出的 `XxxEnum` 值和 `XxxType` 类型。
|
|
199
|
+
- 禁止散落 `as T`,`as const` 例外。
|
|
200
|
+
- JSONB / unknown 等边界,把断言收敛到命名小帮手,并用 eslint disable 注释说明原因。
|
|
201
|
+
|
|
202
|
+
## 文件分区
|
|
203
|
+
|
|
204
|
+
超过约 150 行、或顶层出现多种代码的 `.ts` / `.tsx`,用中文等号分隔块组织:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
// ==============================================================================
|
|
208
|
+
// 类型 & 常量
|
|
209
|
+
// ==============================================================================
|
|
210
|
+
|
|
211
|
+
// ==============================================================================
|
|
212
|
+
// 主组件 Xxx:一句话描述职责
|
|
213
|
+
// ==============================================================================
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
组件体内分区宽度用 76 个等号,常用分区名:`数据请求`、`副作用`、`派生数据 & 小工具`、`操作`、`渲染`。
|
|
217
|
+
|
|
218
|
+
ESLint 按行数强制分区数量:
|
|
219
|
+
|
|
220
|
+
- 150 行起至少 1 个分区块。
|
|
221
|
+
- 300 行起至少 2 个分区块。
|
|
222
|
+
- 450 行起至少 3 个分区块。
|
|
223
|
+
- 之后每约 150 行再增加 1 个分区块。
|
|
224
|
+
|
|
225
|
+
分区块必须是连续三行 `//` 注释,中间行写中文标题,上下行是 4 个以上等号。
|
|
226
|
+
|
|
227
|
+
## ESLint 规则速查
|
|
228
|
+
|
|
229
|
+
推荐配置会启用这些强制规则:
|
|
230
|
+
|
|
231
|
+
- `ai0x0/no-then`:禁止 `.then()`,使用 `async/await`。
|
|
232
|
+
- `ai0x0/no-one-letter-vars`:禁止单字母变量名。
|
|
233
|
+
- `ai0x0/require-section-divider`:大文件必须用等号注释块分区。
|
|
234
|
+
- `ai0x0/no-hardcoded-style`:前端样式值必须走 antd token。
|
|
235
|
+
- `ai0x0/no-antd-space`:禁止 `<Space>` / `<Space.Compact>`,使用 `<Flex>`。
|
|
236
|
+
- `ai0x0/require-use-form`:表单字段状态不能用 `useState` / `useSetState` 管。
|
|
237
|
+
- `ai0x0/require-form-convention`:Form 必须 `onFinish`,字段必须 rules,禁止 Modal.onOk 提交。
|
|
238
|
+
- `ai0x0/require-pro-components`:业务表单优先 ProComponents。
|
|
239
|
+
- `ai0x0/no-use-request-run`:禁止解构 `run`,使用 `runAsync` 并在调用处 `await`。
|
|
240
|
+
- `ai0x0/no-consecutive-setstate`:连续 `setState({ ... })` 要合并成一次。
|
|
241
|
+
|
|
242
|
+
## 常用命令
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
pnpm exec tsc
|
|
246
|
+
pnpm exec eslint
|
|
247
|
+
pnpm exec eslint --fix
|
|
248
|
+
pnpm db:generate
|
|
249
|
+
pnpm db:migrate
|
|
250
|
+
pnpm openapi:json:generate
|
|
251
|
+
pnpm openapi:client:generate
|
|
252
|
+
```
|
package/README.md
CHANGED
|
@@ -17,6 +17,36 @@ Declarative CRUD factories on top of `next-rest-framework`, `drizzle-orm/pg-core
|
|
|
17
17
|
|
|
18
18
|
See [SKILL.md](./SKILL.md) for detailed workflow, setup, and escape hatches.
|
|
19
19
|
|
|
20
|
+
## Agent Skills
|
|
21
|
+
|
|
22
|
+
This package also ships reusable project skills under `.agents/skills`:
|
|
23
|
+
|
|
24
|
+
| Skill | Covers |
|
|
25
|
+
| --------------------- | ------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| `ai0x0-utils/backend` | CRUD factories, drizzle schemas, route-operation setup, action helpers |
|
|
27
|
+
| `nextjs` | App Router directories, API routes, drizzle schemas, OpenAPI client generation, code organization |
|
|
28
|
+
| `antd` | Ant Design forms, ProTable, ModalForm, token-based styling, ahooks data flow |
|
|
29
|
+
| `cloudflare` | OpenNext, Cloudflare Workers, Wrangler, Hyperdrive, Neon, deploy and runtime troubleshooting |
|
|
30
|
+
|
|
31
|
+
To use them in a project, copy the packaged skills into the project root:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cp -R node_modules/@ai0x0/utils/.agents ./
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
After copying, Codex/agents can load them from `.agents/skills/<name>/SKILL.md`.
|
|
38
|
+
|
|
39
|
+
If the project already has local skills, copy only the packaged skill folders you need:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
mkdir -p .agents/skills
|
|
43
|
+
cp -R node_modules/@ai0x0/utils/.agents/skills/nextjs .agents/skills/
|
|
44
|
+
cp -R node_modules/@ai0x0/utils/.agents/skills/antd .agents/skills/
|
|
45
|
+
cp -R node_modules/@ai0x0/utils/.agents/skills/cloudflare .agents/skills/
|
|
46
|
+
mkdir -p .agents/skills/ai0x0-utils
|
|
47
|
+
cp -R node_modules/@ai0x0/utils/.agents/skills/ai0x0-utils/backend .agents/skills/ai0x0-utils/
|
|
48
|
+
```
|
|
49
|
+
|
|
20
50
|
## ESLint Rules & Config
|
|
21
51
|
|
|
22
52
|
### Plugin (`eslint-rules/`)
|
|
@@ -88,3 +118,7 @@ Peer dependencies: `drizzle-orm ^0.45.x`, `drizzle-zod ^0.8.x`, `zod ^4.x`.
|
|
|
88
118
|
## Docs
|
|
89
119
|
|
|
90
120
|
- [SKILL.md](./SKILL.md) — full backend CRUD workflow and API reference
|
|
121
|
+
- [.agents/skills/ai0x0-utils/backend/SKILL.md](./.agents/skills/ai0x0-utils/backend/SKILL.md) — packaged backend CRUD skill
|
|
122
|
+
- [.agents/skills/nextjs/SKILL.md](./.agents/skills/nextjs/SKILL.md) — Next.js project conventions
|
|
123
|
+
- [.agents/skills/antd/SKILL.md](./.agents/skills/antd/SKILL.md) — Ant Design frontend conventions
|
|
124
|
+
- [.agents/skills/cloudflare/SKILL.md](./.agents/skills/cloudflare/SKILL.md) — Cloudflare Workers deployment conventions
|