next-stack

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Next 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)

不可违反的规则(技术栈规范)

  1. Server Components first
  • Default to Server Components.
  • Add
    "use client"
    only when you need interactivity, local state, effects, or client-only libraries.
  1. 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:
      • export const runtime = "nodejs"
        (where applicable in your codebase conventions).
  1. 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.
  1. React Query hygiene
  • Stable, deterministic query keys (no unstable objects in keys).
  • Precise invalidation (invalidate the smallest relevant scope).
  1. Forms & validation
  • Use React Hook Form + Zod resolver.
  • Maintain one Zod schema shared between client & server.
  • Server must re-validate (do not trust client).
  1. Styling & UI
  • Tailwind default.
  • shadcn/ui lives under
    frontend/components/ui/*
    .
  • Preserve accessibility props/labels and semantic structure.
  1. 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).
  1. 优先使用Server Components
  • 默认使用Server Components。
  • 仅当需要交互性、本地状态、副作用或仅客户端可用的库时,才添加
    "use client"
    指令。
  1. Prisma仅在服务端使用
  • 绝不在Client Components中导入Prisma。
  • 确保所有Prisma操作运行在Node运行时(而非Edge运行时):
    • 对于可能运行在Edge的Route Handlers,需显式声明:
      • export const runtime = "nodejs"
        (需符合代码库的约定)。
  1. 数据获取路径拆分
  • 对于静态/确定性数据读取,优先使用服务端读取(RSC、路由处理器、服务端操作)。
  • TanStack Query适用于以下场景:
    • 数据变更(mutations),
    • 乐观更新流程,
    • 客户端重校验,
    • “准实时”/频繁变化的UI状态。
  1. React Query规范
  • 使用稳定、确定性的查询键(query keys),避免在键中使用不稳定对象。
  • 精准失效:仅使最小范围的相关缓存失效。
  1. 表单与校验
  • 使用React Hook Form + Zod resolver
  • 维护单一Zod schema,在客户端与服务端共享。
  • 服务端必须重新校验(不可信任客户端校验结果)。
  1. 样式与UI
  • 默认使用Tailwind。
  • shadcn/ui组件需放置在
    frontend/components/ui/*
    目录下。
  • 保留无障碍(a11y)属性/标签与语义化结构。
  1. 开发约定
  • 使用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
    "use client"
    to the smallest component subtree.
选择最小的客户端代码范围:
  • 如果无需交互性:保持使用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
      cache: "no-store"
      / revalidate strategy as appropriate to the app conventions.
Writes / mutations
  • Implement server action or route handler as the mutation boundary.
  • Client uses React Query
    useMutation
    and invalidates exact keys.
读取操作
  • 优先使用RSC/服务端fetch。
  • 对于用户特定或频繁变化的数据,需明确缓存策略:
    • 根据应用约定,合理使用
      cache: "no-store"
      / 重校验策略。
写入/变更操作
  • 实现server action或路由处理器作为数据变更的边界。
  • 客户端使用React Query的
    useMutation
    ,并使精确的查询键失效。

Step 4 — Implement with shared schema

步骤4 — 基于共享Schema实现

  • Create/locate a shared
    zod
    schema module (single source of truth).
  • Client:
    • RHF + zodResolver(schema)
  • Server:
    • schema.parse(...) (or safeParse with structured error return)
  • 创建/找到共享的
    zod
    schema模块(单一事实来源)。
  • 客户端:
    • 使用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
package.json
/ lockfiles and follow existing patterns.)
完成实现后:
  • 运行lint与类型检查
  • 适用时编写单元/组件测试(Vitest + RTL)
  • 为关键流程编写Playwright端到端测试
(使用代码库的包管理器与脚本;查看
package.json
/ 锁文件并遵循现有模式。)

Step 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
    "use client"
    at high-level layouts/pages without necessity
  • 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——但需保持查询键稳定,缓存失效精准。