Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问clear审计未展示

design-patterns设计模式

Agent Skill

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。它适合让 Agent 根据产品场景整理页面结构、生成 UI 方案、检查视觉一致性或改进组件层级。使用时需要结合现有品牌、设计系统和用户任务,不应只堆装饰元素;涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出、对齐和响应式表现。

总安装

517

周安装

22

GitHub Stars

公开资料未说明

下载量

181
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:design-patterns(设计模式)
来源仓库:https://github.com/lorenzogirardi/ai-ecom-demo
仓库路径:skills/design-patterns
安装命令:
npx skills add lorenzogirardi/ai-ecom-demo --skill "design-patterns"
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

AgentSkills.tonpx skills
npx skills add lorenzogirardi/ai-ecom-demo --skill "design-patterns"

简介

发现并安装 AI 代理的技能,扩展智能体在电商设计领域的应用能力。

  • 适用于 Codex、Claude、Cursor、Gemini CLI 等宿主环境中的界面优化需求。
  • 支持 UI 结构梳理、视觉规范生成与交互逻辑验证等功能。
  • 通过 GitHub 指定路径安装,需关注代码兼容性与宿主框架匹配度。
  • 建议结合具体业务场景测试输出效果,防止过度装饰影响可用性。

SKILL.md

name
design-patterns
description
>-
allowed-tools
Read

ABOUTME: Architectural patterns skill for TypeScript ecommerce

ABOUTME: Covers DI, error handling, testing, and common anti-patterns

Design Patterns (Ecommerce)

Architectural patterns for the TypeScript/Node.js ecommerce stack.

Quick Reference

PatternFrontend (Next.js)Backend (Fastify)
DIReact ContextConstructor injection
ErrorsError boundariesFastify error handler
Configenv.localdotenv + config module
StateReact QueryIn-memory + Redis
TestingTesting LibraryTestcontainers

1. Dependency Injection

Backend (Fastify)

// Define interface
interface UserRepository {
  findById(id: string): Promise<User | null>;
  create(data: CreateUserDto): Promise<User>;
}

// Constructor injection
class UserService {
  constructor(
    private readonly userRepo: UserRepository,
    private readonly logger: Logger
  ) {}

  async getUser(id: string): Promise<User> {
    this.logger.info({ id }, 'Getting user');
    const user = await this.userRepo.findById(id);
    if (!user) throw new NotFoundError(`User ${id} not found`);
    return user;
  }
}

// Wire up in app
const userRepo = new PrismaUserRepository(prisma);
const userService = new UserService(userRepo, logger);

Frontend (React Context)

// Context for dependency injection
const CartContext = createContext<CartContextValue | null>(null);

export function CartProvider({ children }: { children: React.ReactNode }) {
  const [items, setItems] = useState<CartItem[]>([]);

  const addItem = useCallback((product: Product, quantity: number) => {
    setItems((prev) => [...prev, { product, quantity }]);
  }, []);

  return (
    <CartContext.Provider value={{ items, addItem }}>
      {children}
    </CartContext.Provider>
  );
}

export function useCart() {
  const context = useContext(CartContext);
  if (!context) throw new Error('useCart must be used within CartProvider');
  return context;
}

2. Error Handling

Backend (Fastify)

// Custom error classes
class AppError extends Error {
  constructor(
    message: string,
    public statusCode: number = 500,
    public code: string = 'INTERNAL_ERROR'
  ) {
    super(message);
    this.name = 'AppError';
  }
}

class NotFoundError extends AppError {
  constructor(message: string) {
    super(message, 404, 'NOT_FOUND');
  }
}

class ValidationError extends AppError {
  constructor(message: string) {
    super(message, 400, 'VALIDATION_ERROR');
  }
}

// Error handler middleware
function errorHandler(error: Error, request: FastifyRequest, reply: FastifyReply) {
  if (error instanceof AppError) {
    return reply.status(error.statusCode).send({
      statusCode: error.statusCode,
      error: error.code,
      message: error.message,
    });
  }

  // Log unexpected errors
  request.log.error(error);
  return reply.status(500).send({
    statusCode: 500,
    error: 'INTERNAL_ERROR',
    message: 'An unexpected error occurred',
  });
}

Frontend (Error Boundaries)

// Error boundary for React
class ErrorBoundary extends React.Component<Props, State> {
  state = { hasError: false, error: null };

  static getDerivedStateFromError(error: Error) {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    console.error('Error caught:', error, info);
  }

  render() {
    if (this.state.hasError) {
      return <ErrorFallback error={this.state.error} />;
    }
    return this.props.children;
  }
}

// React Query error handling
const { data, error } = useQuery({
  queryKey: ['products'],
  queryFn: fetchProducts,
  retry: 3,
  onError: (error) => {
    toast.error(error.message);
  },
});

3. Configuration

Backend

// config/index.ts
import { z } from 'zod';

const ConfigSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.coerce.number().default(4000),
  DATABASE_URL: z.string(),
  REDIS_HOST: z.string().default('localhost'),
  REDIS_PORT: z.coerce.number().default(6379),
  JWT_SECRET: z.string(),
});

export type Config = z.infer<typeof ConfigSchema>;

export function loadConfig(): Config {
  const result = ConfigSchema.safeParse(process.env);
  if (!result.success) {
    console.error('Invalid configuration:', result.error.format());
    process.exit(1);
  }
  return result.data;
}

export const config = loadConfig();

Frontend

// next.config.js handles env
// Access via process.env.NEXT_PUBLIC_*

// For runtime config
const config = {
  apiUrl: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000',
  environment: process.env.NODE_ENV,
};

4. Testing Patterns

Prefer Real Over Mocks

// GOOD: Real database with Testcontainers
describe('UserRepository', () => {
  let container: StartedPostgreSqlContainer;
  let prisma: PrismaClient;

  beforeAll(async () => {
    container = await new PostgreSqlContainer().start();
    prisma = new PrismaClient({
      datasources: { db: { url: container.getConnectionUri() } },
    });
  });

  afterAll(async () => {
    await prisma.$disconnect();
    await container.stop();
  });

  it('creates a user', async () => {
    const repo = new PrismaUserRepository(prisma);
    const user = await repo.create({ email: ' [email protected] ' });
    expect(user.email).toBe(' [email protected] ');
  });
});

// BAD: Excessive mocking
it('creates a user', async () => {
  const mockPrisma = { user: { create: jest.fn().mockResolvedValue({ id: '1' }) } };
  // This tests mock behavior, not real behavior
});

Test Behavior, Not Implementation

// GOOD: Tests observable behavior
it('rejects invalid email', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/auth/register',
    payload: { email: 'invalid', password: 'secret123' },
  });
  expect(response.statusCode).toBe(400);
  expect(response.json()).toMatchObject({
    error: 'VALIDATION_ERROR',
  });
});

// BAD: Tests internal implementation
it('calls validateEmail function', async () => {
  const spy = jest.spyOn(validator, 'validateEmail');
  await register({ email: ' [email protected] ' });
  expect(spy).toHaveBeenCalled(); // Who cares?
});

5. Common Anti-Patterns

TypeScript

Anti-PatternProblemSolution
any typeNo type safetyUse unknown + guards
// @ts-ignoreHidden bugsFix the type issue
Optional chaining abuseHides nullsExplicit null checks
as castingRuntime errorsType guards

React

Anti-PatternProblemSolution
Prop drillingCouplingContext or state lib
useEffect for dataRace conditionsReact Query
Inline stylesNo reuseTailwind classes
Index as keyRender bugsStable IDs

Fastify

Anti-PatternProblemSolution
Sync in handlersBlocks event loopAlways async
Global stateRace conditionsInject dependencies
No validationSecurity riskZod schemas
Catching all errorsHides bugsLet Fastify handle

6. Naming Conventions

Files

# Components: PascalCase
src/components/ProductCard.tsx
src/components/CartSummary.tsx

# Hooks: camelCase with use prefix
src/hooks/useProducts.ts
src/hooks/useCart.ts

# Modules: kebab-case
src/modules/auth/auth.routes.ts
src/modules/catalog/catalog.service.ts

# Types: PascalCase
src/types/Product.ts
src/types/Order.ts

Variables

// Constants: SCREAMING_SNAKE_CASE
const MAX_RETRIES = 3;
const DEFAULT_PAGE_SIZE = 20;

// Functions: camelCase
function calculateTotal(items: CartItem[]): number {}
async function fetchProducts(categoryId?: string): Promise<Product[]> {}

// Classes: PascalCase
class OrderService {}
class ProductRepository {}

// Interfaces: PascalCase (no I prefix)
interface User {}
interface CartItem {}

Resources

See references/typescript-patterns.md for more detailed examples.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Antigravity

30.39%
按下载量换算55

Claude Code

20.68%
按下载量换算37

Codex

19.06%
按下载量换算34

Gemini CLI

13.31%
按下载量换算24

trae

8.34%
按下载量换算15

windsurf

3.61%
按下载量换算7

安全审计

暂无安全审计结果可展示。

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills