next-stack
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNext Stack (App Router + Prisma + TanStack Query)
Next技术栈(App Router + Prisma + TanStack Query)
Intent
目标
Provide a consistent decision framework + implementation checklist for this stack, so changes stay:
- correct in server/client boundaries,
- consistent with UI & data patterns,
- testable and PR-ready.
为此技术栈提供一套统一的决策框架与实施检查清单,确保代码变更符合:
- 服务端/客户端边界规则,
- 统一的UI与数据模式,
- 可测试性与PR提交标准。
When to use
适用场景
Activate this skill when the task involves any of:
- Next.js App Router pages/layouts/route handlers/server actions
- Prisma-backed reads/writes
- client mutations, optimistic UI, live updates (TanStack Query)
- forms & validation (RHF + Zod)
- shadcn/ui + Tailwind components under
frontend/
当任务涉及以下任意内容时,启用此工作流:
- Next.js App Router页面/布局/路由处理器(Route Handlers)/服务端操作(server actions)
- 基于Prisma的读写操作
- 客户端数据变更、乐观UI、实时更新(TanStack Query)
- 表单与校验(RHF + Zod)
- frontend/目录下的shadcn/ui + Tailwind组件
Non-negotiables (stack rules)
不可违反的规则(技术栈规范)
- Server Components first
- Default to Server Components.
- Add only when you need interactivity, local state, effects, or client-only libraries.
"use client"
- Prisma is server-only
- Never import Prisma in Client Components.
- Ensure any Prisma usage runs in Node runtime (not Edge):
- For Route Handlers that might run on Edge, explicitly set:
- (where applicable in your codebase conventions).
export const runtime = "nodejs"
- For Route Handlers that might run on Edge, explicitly set:
- Data fetching split
- Prefer server-side reads (RSC, route handlers, server actions) for static/deterministic reads.
- Use TanStack Query for:
- mutations,
- optimistic flows,
- client revalidation,
- “live-ish” / frequently changing UI state.
- React Query hygiene
- Stable, deterministic query keys (no unstable objects in keys).
- Precise invalidation (invalidate the smallest relevant scope).
- Forms & validation
- Use React Hook Form + Zod resolver.
- Maintain one Zod schema shared between client & server.
- Server must re-validate (do not trust client).
- Styling & UI
- Tailwind default.
- shadcn/ui lives under .
frontend/components/ui/* - Preserve accessibility props/labels and semantic structure.
- Conventions
- ESLint (AirBnB-style) + Prettier.
- React component files in PascalCase (e.g., ).
UserCard.tsx - Prefer named exports (unless Next.js route file conventions force defaults).
- 优先使用Server Components
- 默认使用Server Components。
- 仅当需要交互性、本地状态、副作用或仅客户端可用的库时,才添加指令。
"use client"
- Prisma仅在服务端使用
- 绝不在Client Components中导入Prisma。
- 确保所有Prisma操作运行在Node运行时(而非Edge运行时):
- 对于可能运行在Edge的Route Handlers,需显式声明:
- (需符合代码库的约定)。
export const runtime = "nodejs"
- 对于可能运行在Edge的Route Handlers,需显式声明:
- 数据获取路径拆分
- 对于静态/确定性数据读取,优先使用服务端读取(RSC、路由处理器、服务端操作)。
- TanStack Query适用于以下场景:
- 数据变更(mutations),
- 乐观更新流程,
- 客户端重校验,
- “准实时”/频繁变化的UI状态。
- React Query规范
- 使用稳定、确定性的查询键(query keys),避免在键中使用不稳定对象。
- 精准失效:仅使最小范围的相关缓存失效。
- 表单与校验
- 使用React Hook Form + Zod resolver。
- 维护单一Zod schema,在客户端与服务端共享。
- 服务端必须重新校验(不可信任客户端校验结果)。
- 样式与UI
- 默认使用Tailwind。
- shadcn/ui组件需放置在目录下。
frontend/components/ui/* - 保留无障碍(a11y)属性/标签与语义化结构。
- 开发约定
- 使用ESLint(AirBnB风格) + Prettier。
- React组件文件采用大驼峰命名(如)。
UserCard.tsx - 优先使用命名导出(除非Next.js路由文件约定强制要求默认导出)。
Workflow (how to execute tasks in this stack)
工作流(在此技术栈中执行任务的步骤)
Step 1 — Clarify & make it verifiable
步骤1 — 明确需求并使其可验证
- Ask 1–3 clarifying questions if critical requirements are missing.
- Define acceptance criteria as verifiable checks:
- “what page shows what state”
- “what API returns what”
- “which tests prove it”
- 如果关键需求缺失,提出1-3个澄清问题。
- 将验收标准定义为可验证的检查项:
- “哪个页面展示什么状态”
- “哪个API返回什么内容”
- “哪些测试可以验证功能正确性”
Step 2 — Decide server vs client boundary
步骤2 — 确定服务端与客户端边界
Choose the minimum client surface area:
- If no interactivity: stay in RSC.
- If interaction/mutation: isolate to the smallest component subtree.
"use client"
选择最小的客户端代码范围:
- 如果无需交互性:保持使用RSC。
- 如果需要交互/数据变更:仅在最小的组件子树中添加。
"use client"
Step 3 — Pick the data path
步骤3 — 选择数据路径
Reads
- Prefer RSC/server fetch.
- Be explicit about caching behavior for user-specific or frequently changing data:
- use / revalidate strategy as appropriate to the app conventions.
cache: "no-store"
- use
Writes / mutations
- Implement server action or route handler as the mutation boundary.
- Client uses React Query and invalidates exact keys.
useMutation
读取操作
- 优先使用RSC/服务端fetch。
- 对于用户特定或频繁变化的数据,需明确缓存策略:
- 根据应用约定,合理使用/ 重校验策略。
cache: "no-store"
- 根据应用约定,合理使用
写入/变更操作
- 实现server action或路由处理器作为数据变更的边界。
- 客户端使用React Query的,并使精确的查询键失效。
useMutation
Step 4 — Implement with shared schema
步骤4 — 基于共享Schema实现
- Create/locate a shared schema module (single source of truth).
zod - Client:
- RHF + zodResolver(schema)
- Server:
- schema.parse(...) (or safeParse with structured error return)
- 创建/找到共享的schema模块(单一事实来源)。
zod - 客户端:
- 使用RHF + zodResolver(schema)
- 服务端:
- 使用schema.parse(...)(或safeParse并返回结构化错误)
Step 5 — UI integration (shadcn + Tailwind)
步骤5 — UI集成(shadcn + Tailwind)
- Use shadcn components for primitives; Tailwind for layout/spacing.
- Keep a11y intact: labels, aria attributes, keyboard focus, form errors.
- 使用shadcn组件作为基础组件;使用Tailwind处理布局/间距。
- 保持无障碍(a11y)完整性:标签、aria属性、键盘焦点、表单错误提示。
Step 6 — Verification
步骤6 — 验证
Before finalizing:
- run lint + typecheck
- unit/component tests (Vitest + RTL) where applicable
- Playwright e2e for critical flows
(Use the repo’s package manager and scripts; inspect / lockfiles and follow existing patterns.)
package.json完成实现后:
- 运行lint与类型检查
- 适用时编写单元/组件测试(Vitest + RTL)
- 为关键流程编写Playwright端到端测试
(使用代码库的包管理器与脚本;查看 / 锁文件并遵循现有模式。)
package.jsonStep 7 — PR output expectations
步骤7 — PR提交要求
PR should include:
- runnable code and relevant tests,
- a short rationale: what you changed, why it matches this stack,
- explicit trade-offs (e.g., “RSC read chosen over React Query because X”).
PR应包含:
- 可运行的代码与相关测试,
- 简短的说明:变更内容、为何符合此技术栈规范,
- 明确的权衡说明(例如:“选择RSC读取而非React Query,原因是X”)。
Anti-patterns (reject these)
反模式(需避免)
- Prisma imported from any Client Component module graph
- Blanket at high-level layouts/pages without necessity
"use client" - React Query used for deterministic static reads with no client interactivity need
- Unstable query keys (objects/functions/dates) causing cache misses
- Over-broad invalidation (invalidate everything) instead of precise keys
- Duplicate schemas (one for client, one for server)
- 从任何Client Component模块依赖图中导入Prisma
- 在高层级布局/页面中无必要地全局添加
"use client" - 对于无需客户端交互的确定性静态读取使用React Query
- 使用不稳定的查询键(对象/函数/日期)导致缓存未命中
- 过度宽泛的缓存失效(使所有缓存失效)而非精准键失效
- 重复的schema(客户端一个,服务端一个)
Quick decision rules
快速决策规则
- Start with RSC; promote to client only when you hit a real constraint.
- If Prisma is involved, ensure Node runtime and keep the boundary server-side.
- If you need optimistic UI or repeated client refresh, use React Query—but keep keys stable and invalidation precise.
- 从RSC开始;仅当遇到实际限制时,才切换到客户端组件。
- 如果涉及Prisma,确保使用Node运行时并保持边界在服务端。
- 如果需要乐观UI或客户端重复刷新,使用React Query——但需保持查询键稳定,缓存失效精准。