@lark-apaas/coding-steering 0.1.7-beta.0 → 0.1.8
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/package.json
CHANGED
|
@@ -365,9 +365,59 @@ async createArticle(@Req() req: Request, @Body() dto: CreateArticleDto) {
|
|
|
365
365
|
- **最后一页时 nextCursor 必须为 undefined**
|
|
366
366
|
- DESC 降序配 LessThan(游标),ASC 升序配 GreaterThan(游标)
|
|
367
367
|
|
|
368
|
+
## 本地 dev API 调试
|
|
369
|
+
|
|
370
|
+
### 入口端口:**只走 vite/rspack dev server**
|
|
371
|
+
|
|
372
|
+
本地 dev 跑起来有**两个端口**:
|
|
373
|
+
|
|
374
|
+
| 端口 | 进程 | env | 默认 | 角色 |
|
|
375
|
+
|---|---|---|---|---|
|
|
376
|
+
| **client dev port** | vite / rspack | `CLIENT_DEV_PORT` | `8080` | **唯一入口**:serve 前端 + 反代 `/api/*` 给 NestJS + 注入 `x-larkgw-suda-webuser` 模拟登录态 |
|
|
377
|
+
| nest server port | NestJS | `SERVER_PORT` | `3000` | 仅 vite/rspack 反代用,不直接给 agent / curl 用 |
|
|
378
|
+
|
|
379
|
+
启动日志里 vite/rspack 打印的 `Local: http://localhost:<CLIENT_DEV_PORT>/...` 才是入口
|
|
380
|
+
(具体端口看 `.env.local` 的 `CLIENT_DEV_PORT`,常见值是 `8080` 或 `8001`)。
|
|
381
|
+
|
|
382
|
+
**绕过 vite/rspack 直连 NestJS 端口的后果**:vite/rspack dev server 是从
|
|
383
|
+
`SUDA_WEBUSER` env 读出 webuser 拼到 `x-larkgw-suda-webuser` header 再转发给 NestJS 的,
|
|
384
|
+
NestJS 自己不读 env。直连 NestJS 端口 → header 缺失 → `req.userContext.userId === ""` →
|
|
385
|
+
任何依赖 `userContext` 的逻辑(`drizzle eq(table.createdBy, userId)`、`@NeedLogin()` 拒
|
|
386
|
+
访等)行为异常,但表面看接口是 200 / 返回值正常,**症状难追到根因**。
|
|
387
|
+
|
|
388
|
+
### CSRF token(double-submit cookie)
|
|
389
|
+
|
|
390
|
+
后端 csrf 中间件用 **double-submit cookie** 模式守门所有 `/api/*` 请求:
|
|
391
|
+
`Cookie: suda-csrf-token=<X>` 和 `X-Suda-Csrf-Token: <X>` header 两个值**字面相等**
|
|
392
|
+
才放行。缺 cookie 直接 403;cookie 在但 header 跟它不等也 403。
|
|
393
|
+
|
|
394
|
+
- **浏览器侧零感知**:首页加载时后端 Set-Cookie 写入 csrf cookie + 把同值注入到
|
|
395
|
+
`window.csrfToken`,前端 axios 拦截器读取这个值塞到 `X-Suda-Csrf-Token` header,
|
|
396
|
+
浏览器又自动随请求带上 cookie —— 业务代码不需要管。**优先用浏览器/DevTools Network
|
|
397
|
+
调试**:cookie 链由浏览器一次性建立,是验证接口最自然的方式。
|
|
398
|
+
|
|
399
|
+
- **`curl` / 第三方 HTTP 客户端 / agent 工具直接打 `/api/*` 接口**:必须同时塞 cookie
|
|
400
|
+
和 header,值字面相等才放行。任意非空相等值都行(注意打**client dev port**,不是
|
|
401
|
+
NestJS 端口):
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# <PORT> = .env.local 里的 CLIENT_DEV_PORT,常见 8080 / 8001
|
|
405
|
+
curl -H 'Cookie: suda-csrf-token=x' \
|
|
406
|
+
-H 'X-Suda-Csrf-Token: x' \
|
|
407
|
+
http://localhost:<PORT>/app/<app_id>/api/notes
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**不要**因为撞 403 就去改后端 csrf 中间件或者怀疑业务逻辑 —— csrf 保护是有意的,
|
|
411
|
+
业务本身没问题。
|
|
412
|
+
|
|
413
|
+
- **依赖用户信息的接口**(看 `req.userContext` 的)即便过了 csrf 也拿不到用户身份,
|
|
414
|
+
浏览器才能补齐 webuser header。这种接口直接 `curl` 永远拿不到合理响应,**用浏览器
|
|
415
|
+
或者 `think` 工具推理**,别陷在 curl 里反复调。
|
|
416
|
+
|
|
368
417
|
## 问题排查指引
|
|
369
418
|
|
|
370
|
-
1. 用 `curl` / 浏览器 DevTools / 第三方 HTTP
|
|
419
|
+
1. 用 `curl` / 浏览器 DevTools / 第三方 HTTP 客户端测试不依赖用户信息的接口(**必须**
|
|
420
|
+
带 csrf cookie + header + 打 client dev port,见上节"本地 dev API 调试")
|
|
371
421
|
2. 查看 `logs/server.log` / `logs/server.std.log` 找后端报错;无有效日志时主动补 logger 打印
|
|
372
422
|
3. dev 服务无响应:在跑 `npm run dev` 的终端 Ctrl+C 后重新启动
|
|
373
423
|
4. API 测试返回 HTML 内容时:检查模块注册顺序、路由顺序、请求路径。禁止修改内置 ViewController
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# NestJS + React 全栈技术栈说明
|
|
2
|
-
|
|
3
|
-
本 stack 对应 miaoda CLI 的 **application scene(MIAODA_APP_TYPE=3)**。
|
|
4
|
-
|
|
5
|
-
## 技术构成
|
|
6
|
-
|
|
7
|
-
- **客户端**:Vite 7 + React 18 + TypeScript 5;shadcn/ui + Tailwind v4
|
|
8
|
-
- **服务端**:NestJS 10 + Express + Drizzle ORM + PostgreSQL
|
|
9
|
-
- **共享**:`shared/` 子目录放跨端类型 / 常量;客户端用 vite-tsconfig-paths 解析,服务端走 NestJS 编译输出
|
|
10
|
-
- **构建**:`@lark-apaas/fullstack-{vite-preset,nestjs-core,cli}` 三件套;本地 dev 由 `scripts/dev.js` 编排 server + client,本地纯净 dev 走 `scripts/dev-local.sh`
|
|
11
|
-
|
|
12
|
-
## 关键 env
|
|
13
|
-
|
|
14
|
-
- `MIAODA_LOCAL_DEV=1`:本地 dev 总开关,开启 SDK 内置的 sandbox 反代 / cookie+webuser 兜底
|
|
15
|
-
- `FORCE_AUTHN_PREVIEW_SESSION_ID`:后端下发的 session id,SDK 自动拼成 sandbox cookie
|
|
16
|
-
- `SANDBOX_PUBLIC_URL`:沙箱公网域,反代 `/__runtime__/*` 的 target
|
|
17
|
-
- `CLIENT_BASE_PATH=/app/<app_id>/`:路径前缀,决定 React Router basename + Vite base
|
|
18
|
-
|
|
19
|
-
## 待补 skills
|
|
20
|
-
|
|
21
|
-
本目录 `skills/` 目前是 .gitkeep 占位。stack 专属编码规则(DTO 装饰器、ORM 用法、view-engine 模板等)后续按需补充。
|