
code-review
by keidsondesigner
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/ousrc/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 constnos 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
- Identificar tipo de mudança
- Verificar arquivos modificados:
git diff --name-only main...feature-branch - 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
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です