good-debug
Use when encountering a bug, unexpected behavior, or error in the frontend - before attempting any fix
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use when encountering a bug, unexpected behavior, or error in the frontend - before attempting any fix
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
TanStack Query 쿼리 정의·훅을 팀 컨벤션대로 스캐폴드한다. Use when connecting an API or creating useQuery/useMutation hooks (예:"API 연동해줘", "쿼리 훅 만들어줘", "서버 데이터 불러와줘"). 폼 상태는 /new-form, 로컬 UI 상태(useState)·익스텐션 코드에는 사용하지 않는다.
react-hook-form + zod 폼을 팀 컨벤션대로 스캐폴드한다. Use when creating a form or adding input validation (예:"폼 만들어줘", "입력 검증 추가해줘", "로그인 폼 구현", "검색 입력 구현"). 검색어 같은 단일 입력도 폼 상태(RHF)로 구성한다. 서버 상태 조회는 /new-query, 익스텐션 코드에는 사용하지 않는다.
이 프로젝트 고유의 Expo·NativeWind·RN 함정과 패키지 도입 기준 (자동 트리거). Use when writing/modifying app-web UI code, when a style works on web but not native (or vice versa), when adding a new package, or when upgrading expo/nativewind/react-native-css. 일반 Expo API 사용법은 expo 공식 플러그인 skill 을 쓴다. 익스텐션 코드에는 해당 없다.
NativeWind 기반 React Native 컴포넌트를 팀 컨벤션대로 스캐폴드한다. Use when creating a new UI component for the app/web. 익스텐션 UI 에는 사용하지 않는다.
expo-router 화면(라우트)을 팀 컨벤션대로 추가한다. Use when adding a new screen/route to the app/web. app/ 은 라우팅 껍데기로 두고 로직은 features 로 분리한다.
Creates a GitHub Pull Request by analyzing branch changes and filling in the project PR template. TRIGGER when: user invokes /pr directly, or says 'PR 만들어줘', 'PR 작성해줘'.
| name | good-debug |
| description | Use when encountering a bug, unexpected behavior, or error in the frontend - before attempting any fix |
증상이 아닌 원인을 수정한다. 에러를 숨기거나 우회하지 않는다.
에러 메시지를 첫 줄만 보지 말고 전체를 읽는다.
| 에러 종류 | 확인 포인트 |
|---|---|
SyntaxError | 괄호/따옴표 불일치, 잘못된 키워드 |
TypeError | 객체가 undefined인데 접근, await 누락 |
ReferenceError | 변수 선언 위치, 스코프 |
| 네트워크 에러 | CORS, 인증, 4xx vs 5xx 구분 |
| 모듈 에러 | ESM vs CommonJS, 경로, 확장자 |
에러 메시지를 통째로 검색하기 전에: 무슨 의미인지 → 어떤 상황인지 → 가능한 원인을 순서대로 생각한다.
재현 조건을 최소화한다. 관련 없는 비동기 처리, 상태 관리, UI를 제거하고 핵심 로직만 남긴다.
// 복잡한 컴포넌트 대신 핵심 함수만 분리해서 테스트
const result = calculateDiscount(price, coupon);
console.log(result);
특정 데이터/상태에서만 발생하면 그 조건을 고정한다. 재현이 빠를수록 원인 파악도 빠르다.
증상만 고치면 버그는 다른 형태로 다시 나타난다.
// ❌ 증상만 숨김 — 왜 undefined인지 파악하지 않음
const user = selectedUser as User; // assertion으로 에러 회피
const name = selectedUser!.name; // non-null assertion
// ✅ 근본 원인 처리
if (!selectedUser) throw new Error("selectedUser is required");
const name = selectedUser.name;
// ❌ 레이스 컨디션을 setTimeout으로 임시 방편
setTimeout(() => refetch(), 300);
// ✅ AbortController로 이전 요청 취소
const controller = new AbortController();
fetch(url, { signal: controller.signal });
비즈니스 로직을 순수 함수로 분리하면 독립적으로 테스트할 수 있고, 같은 버그가 재발하면 테스트로 잡을 수 있다.
| 상황 | 도구 |
|---|---|
| 컴포넌트 상태 | React DevTools (npx react-devtools / 브라우저 확장) |
| 서버 상태 / 캐싱 | React Query Devtools (@tanstack/react-query-devtools, 별도 설치 필요) |
| 라우팅 문제 | Expo dev menu (네이티브: Cmd+M / iOS: Cmd+D) |
| 네트워크 요청 | 브라우저 Network 탭 (웹) |
| 번들 에러 | pnpm start (Metro 로그) |
| 타입 에러 | npx tsc --noEmit |
// @ts-ignore 로 타입 에러 무시try { } catch(e) {} 빈 catchkey 바꿔서 리렌더링 강제! (non-null assertion) 남용setTimeout으로 타이밍 문제 임시 해결