用途:针对从 @remix-run/* 导入的 TypeScript 路由模块,审查 Remix v2 的数据流正确性。范围包括 app/routes/ 下导出 loader、action、shouldRevalidate、headers 的路由模块,以及消费 useLoaderData、useActionData、useNavigation、useFetcher、useRevalidator、<Await> 的组件。表单交互与路由约定由其他技能覆盖,不在本技能范围内。
主要能力:
- loader 审查:是否在 loader 中做写操作、缺少校验、泄露服务端字段、抛出原始类型、缺少 params 检查。
- action 审查:FormData 是否未经校验、成功时是否应重定向、缺少错误分支、泄露 actionData。
- 重新验证审查:useTransition v1 遗留、缺少 pending 状态、滥用 shouldRevalidate: false、误用 useRevalidator。
- defer/<Await> 审查:对已很快的数据使用 defer、缺少 <Suspense>、<Await> 无 errorElement。
使用方式:按清单逐项核查,如首次渲染数据应放在 loader 而非 useEffect;loader 只读,写操作放 action;request.formData() 结果需校验;返回值应为投影后的 DTO,不含密码哈希、令牌、internal_* 字段;使用 useLoaderData<typeof loader>() 泛型注解形式而非 as 断言;404/鉴权短路应抛 Response 而非普通 Error 或字符串;action 成功返回 redirect(...),校验失败返回 json({ errors }, { status: 400 });pending UI 读取 useNavigation()/fetcher.state,不用 useTransition;formMethod 比较用大写;shouldRevalidate 默认返回 defaultShouldRevalidate;defer() 仅在至少一个 promise 流式传输时使用,每个 <Await> 包在 <Suspense> 中并有 errorElement;useRevalidator().revalidate() 仅用于聚焦/轮询/SSE。
不应标记的正确用法:useEffect 仅用于客户端数据;loader 返回 null;<typeof loader> 泛型参数;裸 new Response;action 中 return redirect;loader 不声明 request 参数;父 loader 在无关 action 后重新验证;action 返回 400 校验错误;useRevalidator 用于聚焦/轮询/跨标签同步;SerializeFrom 引起的类型变化。
限制:审查需有位置证据(文件路径与行号或逐字引用);需逐项确认不在豁免清单内;需区分类型注解与类型断言;需检查 v1 遗留;需先完成预报告验证清单再输出结论。具体命令与工具用法官方资料未提供。