Communitygithub.com

prakashjune8/test-agent-skills

使用 TypeScript 和 JavaScript 进行现代全栈 Web 应用开发的综合指南与工作流程。涵盖前端 UI(React、Vite、Next.js、组件架构、现代 CSS、可访问性、状态管理)和后端服务(Node.js、Express、Fastify、REST/GraphQL API、数据库建模、身份验证、安全性和端到端类型安全)。在搭建、开发、重构或审查全栈 Web 应用时使用此技能。

test-agent-skills 是什么?

此技能为全栈 Web 应用开发提供了端到端的架构指南、工作流手册和编码标准,重点关注现代 TypeScript/JavaScript 技术栈。它强调了端到端类型安全(通过 Zod 等库实现)、关注点分离(前端通过组件与数据层分离,后端通过路由/控制器、服务层和数据访问层分离)、以及 API 契约优先的开发方法。该技能涵盖了从项目结构搭建、共享模式定义、后端服务与端点构建、前端 UI 组件开发、集成与数据获取,到最终验证与加固的完整步骤。支持的主流平台包括基于 React 的前端技术栈(Vite、Next.js)和基于 Node.js 的后端框架(Express、Fastify),并且提供了如日志记录、错误处理、安全配置和表单交互等生产级最佳实践。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/prakashjune8/test-agent-skills/tree/HEAD/.agents/skills/fullstack-development

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

全栈开发技能(UI 和后端)

本技能提供了端到端的架构指南、工作流手册和编码标准,用于使用现代 TypeScript/JavaScript 在前端(UI)和后端开发生产级 Web 应用。


1. 核心架构原则

  1. 端到端类型安全:
    • 领域模型和数据传输对象(DTO)单一事实来源。
    • 使用模式验证库(如 Zod)在运行时解析和验证请求,并在编译时推断 TypeScript 类型。
  2. 分层关注点分离:
    • 前端: 严格分离展示性原语、业务/容器组件和数据获取钩子。
    • 后端: 严格分离路由/控制器(HTTP 传输)、服务层(业务逻辑)和数据访问/仓库层(数据库/ORM)。
  3. API 契约优先:
    • 在实现 UI 或后端细节之前建立请求和响应契约。
    • 统一响应信封: { success: true, data: T } 或 { success: false, error: { message, code, details } }。
  4. 弹性和错误处理:
    • 前端: 错误边界、骨架屏加载状态、优雅降级和用户友好的通知。
    • 后端: 集中式错误中间件、操作性错误与程序员错误分类、结构化日志和安全默认值。
  5. 默认安全:
    • 安全标头(Helmet)、明确的 CORS 策略、输入验证/清理、速率限制和安全认证(HTTP-only cookie 或 bearer token)。

2. 推荐目录结构

对于全栈仓库(单体仓库或拆分结构):

├── packages/ or apps/
│   ├── client/                  # 前端 UI(React / Next.js / Vite)
│   │   ├── src/
│   │   │   ├── assets/          # 静态资源(图片、图标、字体)
│   │   │   ├── components/      # UI 组件(原子、分子、有机体)
│   │   │   │   ├── ui/          # 核心设计系统原语(Button, Input, Modal)
│   │   │   │   └── features/    # 领域特定复合组件
│   │   │   ├── hooks/           # 自定义 React 钩子(useAuth, useDebounce 等)
│   │   │   ├── services/        # API 客户端和服务集成
│   │   │   ├── store/           # 全局状态管理(Zustand, Context 等)
│   │   │   ├── types/           # 客户端特定类型
│   │   │   ├── utils/           # 辅助函数和格式化工具
│   │   │   ├── App.tsx          # 主要应用组件和路由
│   │   │   ├── main.tsx         # 入口点
│   │   │   └── index.css        # 全局 CSS 和设计令牌
│   │   └── package.json
│   │
│   ├── server/                  # 后端 API(Node.js / Express / Fastify)
│   │   ├── src/
│   │   │   ├── config/          # 环境变量和运行时配置
│   │   │   ├── controllers/     # HTTP 路由处理器(提取参数,调用服务)
│   │   │   ├── middleware/      # 认证、验证、错误处理器、速率限制器
│   │   │   ├── models/          # 数据库模型/模式(Prisma, Drizzle 等)
│   │   │   ├── routes/          # Express/Fastify 路由定义
│   │   │   ├── services/        # 业务逻辑和外部 API 交互
│   │   │   ├── utils/           # 后端辅助工具(jwt, logger, crypto)
│   │   │   ├── app.ts           # Express/Fastify 应用配置
│   │   │   └── server.ts        # 服务器入口点和优雅关闭
│   │   └── package.json
│   │
│   └── shared/                  # 共享模式、DTO 和 TypeScript 契约
│       ├── src/
│       │   ├── schemas/         # Zod 模式(user.schema.ts, auth.schema.ts)
│       │   └── types/           # 推断类型(export type User = z.infer<...>)
│       └── package.json

3. 分步开发工作流

实现任何全栈功能时,按顺序执行以下阶段:

阶段 1: 定义共享契约和模式

  1. 在 shared/ 或 common/ 中定义表示请求负载和响应实体的 Zod 模式。
  2. 导出推断的 TypeScript 类型。
import { z } from 'zod';

export const CreateUserSchema = z.object({
  email: z.string().email('邮箱地址无效'),
  name: z.string().min(2, '姓名至少需要 2 个字符'),
  role: z.enum(['admin', 'user']).default('user'),
});

export type CreateUserInput = z.infer<typeof CreateUserSchema>;
export type UserResponse = CreateUserInput & { id: string; createdAt: string };

阶段 2: 构建后端服务和端点

  1. 验证中间件: 使用 Zod 模式应用验证中间件,以 HTTP 400 早期拒绝格式错误的输入。
  2. 服务层: 在服务类或模块中编写纯业务逻辑。将数据库查询与 HTTP 概念(req、res)隔离。
  3. 控制器: 处理 HTTP 输入提取,调用服务,并使用 sendSuccess() 返回标准化响应。
  4. 错误处理: 使用自定义错误(NotFoundError、BadRequestError、UnauthorizedError),让集中式错误中间件捕获并格式化响应。

阶段 3: 构建前端 UI 组件

  1. 设计系统令牌: 确保存在用于颜色、排版、间距和阴影的 CSS 自定义属性或设计系统变量。
  2. 原子/UI 原语: 构建或复用基础 UI 组件(按钮、输入框、徽章、对话框),并支持键盘导航和 ARIA 属性。
  3. 功能视图/页面: 组合复合组件,具有清晰的视觉层次、充足的空白、现代排版和响应式网格/弹性布局。
  4. 状态和微交互:
    • 为悬停、激活、焦点可见和禁用状态提供视觉反馈。
    • 在等待提交期间包含骨架屏、加载指示器和禁用按钮。

阶段 4: 集成和数据获取

  1. API 客户端: 使用集中式 fetch 包装器或配置了基本 URL、超时、凭据和拦截器的 Axios 实例。
  2. 服务器状态: 使用 TanStack Query (React Query) 或标准钩子来查询和变更数据。
    • 成功变更后使缓存失效。
    • 在适当的情况下使用乐观更新以获得流畅的用户体验。
  3. 表单处理: 将表单与 React Hook Form + Zod resolver 集成,以在客户端和服务器之间共享完全相同的验证规则。

阶段 5: 验证和加固

  1. 后端验证: 使用单元/集成测试或 curl/fetch 测试端点,以验证边界情况(无效输入、缺少令牌、重复键)。
  2. 前端验证: 验证在桌面、平板和移动设备视口宽度下的响应性。
  3. 安全检查: 确认 CORS、速率限制和认证守卫已激活。

4. 快速代码模式

标准 API 响应辅助函数(后端)

// server/src/utils/response.ts
import { Response } from 'express';

export function sendSuccess<T>(res: Response, data: T, statusCode = 200, meta?: unknown) {
  return res.status(statusCode).json({
    success: true,
    data,
    ...(meta ? { meta } : {}),
  });
}

export function sendError(res: Response, message: string, statusCode = 500, details?: unknown) {
  return res.status(statusCode).json({
    success: false,
    error: {
      message,
      statusCode,
      details: details ?? null,
    },
  });
}

集中式 Express 错误中间件

// server/src/middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';
import { ZodError } from 'zod';

export class AppError extends Error {
  constructor(public message: string, public statusCode = 500, public details?: unknown) {
    super(message);
    this.name = 'AppError';
  }
}

export function errorHandler(err: unknown, req: Request, res: Response, next: NextFunction) {
  if (err instanceof ZodError) {
    return res.status(400).json({
      success: false,
      error: {
        message: '验证失败',
        statusCode: 400,
        details: err.flatten().fieldErrors,
      },
    });
  }

  if (err instanceof AppError) {
    return res.status(err.statusCode).json({
      success: false,
      error: {
        message: err.message,
        statusCode: err.statusCode,
        details: err.details ?? null,
      },
    });
  }

  console.error('未处理的服务器错误:', err);
  return res.status(500).json({
    success: false,
    error: {
      message: '内部服务器错误',
      statusCode: 500,
    },
  });
}

类型安全 API 客户端(前端)

// client/src/services/apiClient.ts
interface ApiResponse<T> {
  success: boolean;
  data: T;
  error?: {
    message: string;
    statusCode: number;
    details?: unknown;
  };
}

export async function apiRequest<T>(url: string, options?: RequestInit): Promise<T> {
  const res = await fetch(url, {
    headers: {
      'Content-Type': 'application/json',
      ...options?.headers,
    },
    ...options,
  });

  const body: ApiResponse<T> = await res.json();

  if (!res.ok || !body.success) {
    throw new Error(body.error?.message || `HTTP ${res.status}: 请求失败`);
  }

  return body.data;
}

5. 参考和深入阅读

有关深入的架构模式,请查阅:

相关技能