スキル一覧に戻る
keidsondesigner

code-review

by keidsondesigner

0🍴 0📅 2026年1月16日
GitHubで見るManusで実行

SKILL.md


name: code-review description: Realiza revisão de código completa seguindo as diretrizes Bewear, verificando padrões de arquitetura, TypeScript, React, Next.js, segurança e boas práticas. Use para revisar PRs ou código antes de merge. tools: Read, Grep, Glob

Code Review Skill

Esta skill realiza revisão de código abrangente seguindo todas as diretrizes do projeto Bewear E-commerce.

Quando Usar

  • Revisar Pull Requests
  • Auditar código antes de merge
  • Verificar conformidade com padrões
  • Identificar code smells e anti-patterns

Categorias de Revisão

1. Arquitetura e Estrutura

Organização de Arquivos

✅ CORRETO
src/actions/add-cart-product/
  ├── index.ts
  └── schema.ts

src/hooks/
  ├── queries/use-cart.ts
  └── mutations/use-increase-product-quantity-cart.ts

src/app/cart/identification/
  ├── page.tsx (Server Component)
  └── components/addresses.tsx (Client Component)

❌ INCORRETO
src/actions/addCartProduct.ts (PascalCase errado)
src/hooks/useCart.tsx (Deveria estar em queries/)
src/components/CartAddresses.tsx (Page-specific, deveria estar em app/cart/components/)

Server vs Client Components

REGRA CRÍTICA: NUNCA adicione "use client" em page.tsx

// ✅ CORRETO - page.tsx é Server Component
// src/app/cart/identification/page.tsx
import Header from "@/components/header";
import Addresses from "./components/addresses";

const CartIdentificationPage = async () => {
  const session = await auth.api.getSession({
    headers: await headers(),
  });

  if (!session?.user) {
    redirect("/auth");
  }

  return (
    <>
      <Header />
      <Addresses />
    </>
  );
};

export default CartIdentificationPage;

Verificar:

  • Arquivos em pastas corretas
  • Nomenclatura kebab-case para arquivos
  • PascalCase para componentes
  • Server Actions em src/actions/[nome]/
  • Hooks em src/hooks/queries/ ou src/hooks/mutations/
  • Sem "use client" em page.tsx

Referência: docs/development-guidelines.md (linhas 58-62)


2. TypeScript

// ✅ CORRETO
const formSchema = z.object({
  email: z.string().email("Email inválido"),
});

type FormValues = z.infer<typeof formSchema>;

const handleSubmit = async (values: FormValues) => {
};

// ❌ INCORRETO
const handleSubmit = async (values: any) => {
};

Verificar:

  • Sem uso de any
  • Tipos explícitos em parâmetros
  • z.infer usado para tipos de schema Zod
  • Interfaces/types para objetos complexos
  • Return types explícitos em funções exportadas

3. React e Next.js

Verificar:

  • Componentes têm nomes descritivos
  • Export default no final
  • Props tipadas com interface/type
  • Hooks no topo do componente
  • Não usar hooks dentro de condicionais

4. Styling e UI

shadcn/ui Components:

// ✅ CORRETO - Usar shadcn/ui
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";

<Button>Click me</Button>

// ❌ INCORRETO
<button className="px-4 py-2 bg-blue-500">Click me</button>

Tailwind CSS:

// ✅ CORRETO
<div className="max-w-[1280px] mx-auto p-5 flex flex-col md:flex-row gap-4">
</div>

// ✅ CORRETO - cn() para classes condicionais
import { cn } from "@/lib/utils";

<div className={cn(
  "base-classes",
  isActive && "active-classes",
  className
)}>
</div>

// ❌ INCORRETO
<div style={{ maxWidth: "1280px", margin: "0 auto" }}>
</div>

Verificar:

  • shadcn/ui usado quando disponível
  • Imports corretos de @/components/ui/
  • Usar Tailwind utility classes
  • Evitar inline styles
  • Usar cn() para classes condicionais

5. Formulários

Arquivo de referência: src/app/auth/components/sign-in-form.tsx

// ✅ CORRETO
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import z from "zod";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";

const formSchema = z.object({
  email: z.string().email("Email inválido"),
});

type FormValues = z.infer<typeof formSchema>;

const MyForm = () => {
  const form = useForm<FormValues>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      email: "",
    },
  });

  async function onSubmit(values: FormValues) {
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit" disabled={form.formState.isSubmitting}>
          {form.formState.isSubmitting ? "Enviando..." : "Enviar"}
        </Button>
      </form>
    </Form>
  );
};

Verificar:

  • Usa React Hook Form
  • Validação com Zod
  • shadcn/ui Form components
  • zodResolver configurado
  • z.infer para tipagem
  • Estados de loading (isSubmitting)

6. Database (Drizzle ORM)

// ✅ CORRETO - Query builder
const product = await db.query.productTable.findFirst({
  where: eq(productTable.id, productId),
  with: {
    variants: true,
  },
});

// ✅ CORRETO - Insert
await db.insert(productTable).values({
  name: data.name,
  categoryId: data.categoryId,
});

// ❌ INCORRETO - SQL direto
await db.execute(`SELECT * FROM products WHERE id = '${productId}'`);

Verificar:

  • Usa query builder Drizzle
  • Operadores corretos (eq, and, or, gt, etc.)
  • with para relations
  • Transactions para operações múltiplas
  • Nunca SQL direto/concatenação

7. React Query

Arquivos de referência:

  • Query: src/hooks/queries/use-cart.ts
  • Mutation: src/hooks/mutations/use-increase-product-quantity-cart.ts
// ✅ CORRETO - Query Hook
export const getUseCartQueryKey = () => ["cart"] as const;

export const useCart = () => {
  return useQuery({
    queryKey: getUseCartQueryKey(),
    queryFn: () => getCart(),
  });
};

// ✅ CORRETO - Mutation Hook
export const getCreateMutationKey = () => ["create"] as const;

export const useCreateMutation = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationKey: getCreateMutationKey(),
    mutationFn: (data: Schema) => createAction(data),
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: getUseCartQueryKey()
      });
    },
  });
};

Verificar:

  • Query key function exportada
  • Mutation key function exportada
  • as const nos keys
  • useQueryClient em mutations
  • invalidateQueries em onSuccess

8. Segurança

Ver detalhes completos em "validate-security" skill.

Checklist rápido:

  • Server Actions têm "use server"
  • Autenticação verificada
  • Validação com Zod
  • Ownership verificado
  • Sem SQL injection
  • Environment variables validadas
  • Mensagens de erro genéricas
  • Sem IDOR vulnerabilities

9. Code Quality

DRY (Don't Repeat Yourself)

// ✅ CORRETO - Extrair lógica reutilizável
const formatPrice = (cents: number) => {
  return new Intl.NumberFormat('pt-BR', {
    style: 'currency',
    currency: 'BRL',
  }).format(cents / 100);
};

<span>{formatPrice(product.priceInCents)}</span>

// ❌ INCORRETO - Duplicar lógica
<span>
  {new Intl.NumberFormat('pt-BR', {
    style: 'currency',
    currency: 'BRL',
  }).format(product.priceInCents / 100)}
</span>

Comentários

REGRA: Não escreva comentários. O código deve ser auto-explicativo.

// ❌ INCORRETO
// Buscar o carrinho do usuário
const cart = await db.query.cartTable.findFirst({
  where: eq(cartTable.userId, session.user.id),
});

// ✅ CORRETO - Código auto-explicativo, sem comentários
const userCart = await db.query.cartTable.findFirst({
  where: eq(cartTable.userId, session.user.id),
});

Nomenclatura

// ✅ CORRETO - Nomes descritivos
const isUserAuthenticated = !!session?.user;
const hasItemsInCart = cart.items.length > 0;

// ❌ INCORRETO - Nomes vagos
const flag = !!session?.user;
const check = cart.items.length > 0;

Verificar:

  • Lógica duplicada extraída
  • Código sem comentários desnecessários
  • Nomes descritivos

10. Performance

// ✅ CORRETO - Memoize expensive calculations
const expensiveValue = useMemo(() => {
  return items.reduce((sum, item) => sum + item.price, 0);
}, [items]);

// ✅ CORRETO - Server Component busca dados
const Page = async () => {
  const data = await fetchData();
  return <ClientComponent data={data} />;
};

Verificar:

  • useMemo para cálculos caros
  • useCallback para callbacks
  • Server Components quando possível
  • Data fetching no servidor

11. Error Handling

// ✅ CORRETO
async function handleSubmit(values: FormValues) {
  try {
    await createAction(values);
    toast.success("Criado com sucesso!");
  } catch (error) {
    console.error("Error:", error);
    toast.error("Erro ao criar");
  }
}

Verificar:

  • Try/catch em operações assíncronas
  • Toast notifications para feedback
  • Logs apropriados
  • Error boundaries quando necessário

Processo de Revisão

Passo 1: Análise Inicial

  1. Identificar tipo de mudança
  2. Verificar arquivos modificados: git diff --name-only main...feature-branch
  3. Entender contexto

Passo 2: Revisão por Categoria

Percorrer as 11 categorias acima.

Passo 3: Gerar Relatório

## Code Review Report

### ✅ Aprovado com Minor Changes

#### Pontos Positivos
- Seguiu padrões de arquitetura Bewear
- Server Action com segurança adequada
- TypeScript type-safe

#### Changes Requested

**Crítico**:
1. `src/actions/delete-order/index.ts` - Falta validação de ownership

**Recomendado**:
1. `src/components/product-card.tsx` - Extrair lógica de formatação

**Sugestões**:
1. Considerar useMemo para cálculo de total

#### Arquivos Revisados
- ✅ `src/actions/create-product/index.ts` - OK
- 🚨 `src/app/admin/page.tsx` - "use client" em page.tsx

Arquivos de Referência Principais

  • Development Guidelines: docs/development-guidelines.md
  • Form Pattern: src/app/auth/components/sign-in-form.tsx
  • Server Action: src/actions/add-cart-product/
  • Query Hook: src/hooks/queries/use-cart.ts
  • Mutation Hook: src/hooks/mutations/use-increase-product-quantity-cart.ts

Checklist Final

Antes de aprovar PR:

Arquitetura

  • Estrutura de arquivos correta
  • Nomenclatura kebab-case
  • Server vs Client Components correto
  • Sem "use client" em page.tsx

TypeScript

  • Type-safe (sem any)
  • z.infer usado
  • Imports com path aliases

React/Next.js

  • Componentes bem nomeados
  • Hooks usados corretamente
  • Server Actions seguros

UI

  • shadcn/ui usado
  • Tailwind CSS
  • Responsive design

Formulários

  • React Hook Form + Zod
  • shadcn/ui Form components
  • Loading states

Database

  • Drizzle query builder
  • Sem SQL injection

React Query

  • Query/Mutation key functions
  • Cache invalidation

Segurança

  • Autenticação verificada
  • Ownership validado
  • Sem IDOR

Quality

  • DRY
  • Sem comentários desnecessários
  • Nomes descritivos

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です