kdyconecttest — 웹 프로젝트 연결성 정적 검증
모듈 수준의 정적 연결성을 검증합니다. Import/Export 체인, API↔프론트엔드 매칭, DB 스키마↔코드 정합성, 환경변수 커버리지, 데드코드/고아파일을 탐지하여 보고합니다.
┌─────────────────────────────────────────────────────┐
│ 프로젝트 검증 레이어 │
├──────────┬──────────┬──────────┬──────────┬──────────┤
│ kdyweb │kdyconven │kdyconect │ kdye2e │code- │
│ (라우팅) │ (스타일) │ (연결성) │ (런타임) │reviewer │
│ 페이지↔ │ 코드규칙 │ 모듈정적 │ E2E │ (심층) │
│ 네비 │ 컨벤션 │ 체인 │ 시나리오 │ 품질분석 │
└──────────┴──────────┴──────────┴──────────┴──────────┘
5개 검증 영역
| 코드 | 영역 | 핵심 검사 |
|---|---|---|
| IC | Import/Export Chain | 미사용 import, 미사용 export, path alias 미스매치, barrel 누락 |
| AC | API Route ↔ Frontend | HTTP 메서드 불일치, 호출 경로 불일치, 존재하지 않는 route 호출 |
| SC | Schema ↔ Code | 컬럼명 불일치, 타입 불일치, enum 불일치 |
| EC | Env Var Coverage | 미정의 env 참조, 미사용 env, NEXT_PUBLIC_ 시크릿 노출 |
| DC | Dead Code / Orphan | 소스 없는 테스트, 미사용 path alias, 미설치 도구 config |
인수 처리
사용자가 제공한 인수: $ARGUMENTS
| 인수 | 설명 |
|---|---|
| (없음) | 전체 영역 자동 검증 (스택 기반 활성 영역 결정) |
--scope <area> | 특정 영역만 검증 (ic, ac, sc, ec, dc 또는 쉼표 구분) |
--project <path> | 대상 프로젝트 경로 지정 (기본: CWD) |
Phase 0: 컨텍스트 탐지
진행 표시:
🔍 Phase 0: 프로젝트 컨텍스트 탐지 중...
0-1. 프로젝트 루트 결정
1. --project 인수가 있으면 해당 경로 사용
2. 없으면 CWD 사용
3. package.json 존재 확인 → 없으면 사용자에게 경로 질문
0-2. 프로젝트 스택 감지
Glob/Read로 다음 파일 병렬 확인:
| 파일 | 감지 대상 |
|---|---|
package.json | dependencies/devDependencies → React, Next.js, Vue, Svelte 등 |
tsconfig.json | TypeScript 여부, paths alias 목록 |
next.config.* | Next.js App Router vs Pages Router |
nuxt.config.* | Nuxt 여부 |
vite.config.* | Vite 여부 |
supabase/ 또는 .env* | Supabase 사용 여부 |
결과를 STACK_PROFILE 객체로 구성:
STACK_PROFILE = {
framework: "nextjs-app" | "nextjs-pages" | "vite-react" | "nuxt" | ...,
typescript: true/false,
hasPathAlias: true/false,
pathAliases: { "@/*": ["./src/*"], ... },
db: "supabase" | "prisma" | "drizzle" | "none",
apiPattern: "app-router" | "pages-api" | "standalone" | "none"
}
0-3. 활성 영역 자동 결정
| 영역 | 활성 조건 |
|---|---|
| IC | 항상 활성 (TypeScript/JavaScript 프로젝트이면) |
| AC | apiPattern !== "none" |
| SC | db !== "none" AND _SCHEMA_REFERENCE.md 존재 |
| EC | .env* 파일 또는 _ENV_REFERENCE.md 존재 |
| DC | 항상 활성 |
--scope 인수가 있으면 해당 영역만 활성화.
0-4. 레퍼런스 문서 로드
존재하는 레퍼런스 파일을 Read:
docs/references/_SCHEMA_REFERENCE.md→ SC 영역용docs/references/_API_REFERENCE.md→ AC 영역용docs/references/_ENV_REFERENCE.md→ EC 영역용tsconfig.json→ IC/DC 영역용
0-5. 스캔 대상 디렉토리 설정
프레임워크별 소스 디렉토리 결정:
Next.js App Router: src/app/, src/components/, src/lib/, src/hooks/, src/utils/
Next.js Pages: src/pages/, src/components/, src/lib/
Vite React: src/
일반: src/ 또는 프로젝트 루트
제외 디렉토리: node_modules/, .next/, dist/, build/, .git/
Phase 1: IC — Import/Export Chain 검증
진행 표시:
🔗 Phase 1: Import/Export 체인 검증 중...
참조: references/check-patterns.md → IC 섹션
1-1. 미사용 import 탐지
1. Grep: 모든 소스 파일에서 import 구문 수집
패턴: ^import .+ from ['"]
패턴: const .+ = require\(['"]
2. 각 import된 식별자가 파일 내에서 실제 사용되는지 확인
3. 면제: React (JSX 변환), 타입 import (type-only), CSS/스타일 import, 사이드이펙트 import
이슈 기록 형식: [IC-001] {파일}:{라인} — 미사용 import: {identifier} from {module}
1-2. Path alias 유효성 검증
1. tsconfig.json에서 paths 추출
2. 각 alias의 실제 대상 경로 존재 확인
3. 코드 내 alias 사용과 실제 경로 매칭
이슈 기록 형식: [IC-002] tsconfig paths "{alias}" → 실제 경로 없음: {target}
1-3. Barrel 파일 완전성
1. Glob: **/index.ts, **/index.tsx 수집
2. 각 index 파일의 re-export 목록 추출
3. 형제 모듈 중 re-export 안 된 것 탐지
면제: __tests__/, *.test.*, *.spec.*, *.stories.*, 내부 유틸
이슈 기록 형식: [IC-003] {dir}/index.ts — barrel 미포함 모듈: {module}
1-4. 미사용 export 탐지
1. Grep: 모든 소스 파일에서 export 구문 수집
패턴: export (function|const|class|type|interface|enum) (\w+)
패턴: export default
2. 프로젝트 전체에서 해당 식별자 import 여부 검색
3. 면제: page.tsx/layout.tsx의 default export, API route handler,
컴포넌트 Props 타입, 패키지 진입점
이슈 기록 형식: [IC-004] {파일}:{라인} — 미사용 export: {identifier}
Phase 2: AC — API Route ↔ Frontend Call 매칭
진행 표시:
🌐 Phase 2: API↔Frontend 매칭 검증 중...
참조: references/check-patterns.md → AC 섹션
2-1. API route 인벤토리 구축
프레임워크별 API 파일 탐지:
Next.js App Router: app/**/route.ts → export async function GET|POST|PUT|PATCH|DELETE
Next.js Pages: pages/api/**/*.ts → export default handler (req.method 기반)
Standalone: 사용자 지정 패턴
결과 형식:
API_INVENTORY = [
{ path: "/api/users", methods: ["GET", "POST"], file: "app/api/users/route.ts" },
...
]
2-2. Frontend 호출 인벤토리 구축
소스 파일에서 API 호출 패턴 수집:
패턴: fetch(['"]/api/ | fetch(`/api/
패턴: axios.(get|post|put|patch|delete)(['"]/api/
패턴: .(get|post|put|patch|delete)(['"]/api/ (커스텀 클라이언트)
결과 형식:
CALL_INVENTORY = [
{ path: "/api/users", method: "GET", file: "src/hooks/useUsers.ts", line: 15 },
...
]
2-3. 교차 검증
1. Frontend에서 호출하는 경로가 API_INVENTORY에 존재하는지 확인
2. HTTP 메서드가 일치하는지 확인
3. API route 중 Frontend에서 호출하지 않는 것 탐지 (orphan route)
심각도 분류:
- CRITICAL: 존재하지 않는 API route 호출
- HIGH: HTTP 메서드 불일치
- MINOR: 호출되지 않는 API route (의도적일 수 있음)
이슈 기록 형식: [AC-001] {파일}:{라인} — 존재하지 않는 route 호출: {method} {path}
2-4. _API_REFERENCE.md 교차 검증 (존재 시)
1. _API_REFERENCE.md에 문서화된 엔드포인트 vs 실제 API route 파일 비교
2. 문서에는 있지만 코드에 없는 route → IMPORTANT
3. 코드에는 있지만 문서에 없는 route → MINOR
Phase 3: SC — DB Schema ↔ Code 정합성
진행 표시:
🗄️ Phase 3: 스키마↔코드 정합성 검증 중...
참조: references/check-patterns.md → SC 섹션
3-1. 스키마 정보 파싱
소스별 우선순위:
1순위: docs/references/_SCHEMA_REFERENCE.md (있으면 파싱)
2순위: supabase/migrations/*.sql (SQL DDL 파싱)
3순위: prisma/schema.prisma (Prisma 스키마 파싱)
4순위: drizzle 스키마 파일
추출 대상: 테이블명, 컬럼명, 컬럼 타입, enum 값
3-2. 코드 내 쿼리 패턴 수집
DB 클라이언트별 패턴:
Supabase: .from('테이블명'), .select('컬럼'), .eq('컬럼', 값), .insert({컬럼: 값})
Prisma: prisma.모델명.findMany({ select: { 컬럼: true } })
Drizzle: db.select().from(테이블), eq(테이블.컬럼, 값)
Raw SQL: SELECT 컬럼 FROM 테이블, INSERT INTO 테이블 (컬럼)
3-3. 교차 검증
1. 코드에서 참조하는 테이블명이 스키마에 존재하는지
2. 코드에서 참조하는 컬럼명이 해당 테이블에 존재하는지
3. enum 값이 스키마 정의와 일치하는지
심각도 분류:
- CRITICAL: 존재하지 않는 테이블 참조
- CRITICAL: 존재하지 않는 컬럼 참조
- HIGH: enum 값 불일치
이슈 기록 형식: [SC-001] {파일}:{라인} — 미존재 컬럼 참조: {테이블}.{컬럼}
Phase 4: EC — 환경변수 커버리지
진행 표시:
🔐 Phase 4: 환경변수 커버리지 검증 중...
참조: references/check-patterns.md → EC 섹션
4-1. 코드 내 env 참조 수집
패턴: process.env.VARIABLE_NAME
패턴: process.env['VARIABLE_NAME']
패턴: import.meta.env.VARIABLE_NAME
패턴: Deno.env.get('VARIABLE_NAME')
결과: CODE_ENV_REFS = [{ name: "DATABASE_URL", file: "src/lib/db.ts", line: 5 }, ...]
4-2. env 정의 수집
소스: .env.example, .env.local.example, _ENV_REFERENCE.md
파싱: KEY=value 또는 KEY= (빈 값) 또는 # KEY (주석)
결과: DEFINED_ENVS = ["DATABASE_URL", "NEXT_PUBLIC_API_URL", ...]
4-3. 교차 검증
1. 코드에서 참조하지만 정의에 없는 env → HIGH (미정의 참조)
2. 정의에 있지만 코드에서 사용하지 않는 env → MINOR (미사용 정의)
3. NEXT_PUBLIC_ 접두사에 SECRET/KEY/PASSWORD 포함 → CRITICAL (시크릿 노출)
4. 서버 전용 env를 클라이언트 코드에서 참조 → HIGH
이슈 기록 형식: [EC-001] {파일}:{라인} — 미정의 환경변수: {name}
이슈 기록 형식: [EC-003] {파일}:{라인} — 시크릿 클라이언트 노출: {name}
Phase 5: DC — Dead Code / Orphan 탐지
진행 표시:
🧹 Phase 5: 데드코드/고아파일 탐지 중...
참조: references/check-patterns.md → DC 섹션
5-1. 소스 없는 테스트 파일
1. Glob: **/*.{test,spec}.{ts,tsx,js,jsx} 수집
2. 각 테스트 파일의 대상 소스 파일 추론:
- foo.test.ts → foo.ts
- __tests__/foo.test.ts → ../foo.ts 또는 형제 디렉토리
3. 대상 소스 파일 존재 여부 확인
이슈 기록 형식: [DC-001] {테스트파일} — 대상 소스 파일 없음: {추론경로}
5-2. 미사용 tsconfig path alias
1. tsconfig.json paths 전체 목록
2. 각 alias가 코드에서 실제 import에 사용되는지 Grep
3. 미사용 alias 보고
이슈 기록 형식: [DC-002] tsconfig paths — 미사용 alias: {alias}
5-3. 미설치 도구의 config 파일
1. Glob: 루트의 *.config.{js,ts,mjs,cjs} 수집
2. 각 config 파일의 대상 도구 추론:
- jest.config.ts → jest, vitest.config.ts → vitest, etc.
3. package.json devDependencies에 해당 도구 존재 확인
면제: tsconfig.json, package.json, next.config.* (프레임워크 필수)
이슈 기록 형식: [DC-003] {config파일} — 미설치 도구: {도구명}
5-4. 고아 컴포넌트 탐지
1. Glob: src/components/**/*.{tsx,jsx} 수집
2. 각 컴포넌트가 다른 파일에서 import 되는지 검색
3. 어디에서도 import 안 되는 컴포넌트 보고
면제: page.tsx, layout.tsx, Storybook stories, 테스트 파일에서만 사용되는 것은 OK
이슈 기록 형식: [DC-004] {파일} — 고아 컴포넌트: 어디에서도 import 안 됨
Phase 6: 보고서 출력
진행 표시:
📊 Phase 6: 보고서 생성 중...
참조: references/report-template.md
6-1. 심각도 분류
| 심각도 | 기준 | 예시 |
|---|---|---|
| CRITICAL | 런타임 에러 유발 가능 | 미존재 API 호출, 미존재 컬럼 참조, 시크릿 노출 |
| HIGH | 빌드 실패 또는 로직 오류 가능 | 미정의 env, HTTP 메서드 불일치, 미존재 path alias |
| IMPORTANT | 유지보수 부채 | 미사용 export, 문서↔코드 불일치 |
| MINOR | 코드 정리 권장 | 미사용 env 정의, 고아 config, 호출 안 되는 API |
6-2. 요약 + 상세 보고서 출력
references/report-template.md 템플릿에 따라:
- 요약 매트릭스: 영역 × 심각도 교차표
- CRITICAL/HIGH 이슈 상세: 파일:라인, 이슈 설명, 권장 조치
- IMPORTANT/MINOR 이슈 목록: 축약 테이블
- 전체 통과 시: 축하 메시지 + 통과 영역 목록
6-3. 아카이브 (조건부)
조건: CRITICAL 또는 HIGH 이슈가 1개 이상 존재
대상: docs/logs/connectivity-check-YYYY-MM-DD.md
내용: 요약 매트릭스 + CRITICAL/HIGH 이슈 목록
docs/logs/ 디렉토리 없으면 생성하지 않고 스킵.
6-4. 다음 권장 작업
이슈 상황에 따라 권장 작업 제안:
| 조건 | 권장 |
|---|---|
| CRITICAL 2개 이상 | code-reviewer 에이전트 실행 권장 |
| AC 영역 이슈 다수 | /kdyweb --verify 실행 권장 |
| IC 영역 이슈 다수 | /kdyconvention 실행 권장 |
| 전체 통과 | /kdye2e 런타임 검증 권장 |
| SC 영역 이슈 | _SCHEMA_REFERENCE.md 업데이트 권장 |
Superpowers 연계
이 스킬 실행 중 아래 superpowers 원칙을 적용한다.
| 원칙 | 적용 시점 | 적용 방법 |
|---|---|---|
verification-before-completion | 5개 도메인 검사 후 | 각 도메인 결과를 증거와 함께 보고 |
dispatching-parallel-agents | 5개 도메인 스캔 시 | IC/AC/SC/EC/DC를 독립 에이전트로 병렬 검사 고려 |
예외사항
다음은 이 스킬이 검사하지 않는 항목입니다:
- 코드 스타일/포매팅 →
/kdyconvention영역 - 페이지 라우팅 연결성 →
/kdyweb --verify영역 - 런타임 동작 검증 →
/kdye2e영역 - 보안 취약점 분석 →
security-reviewer에이전트 영역 - 동적 import/lazy loading → 정적 분석으로 추적 불가, 면제
- node_modules 내부 → 외부 패키지는 검사 대상 아님
- 생성된 파일 (
.next/,dist/,build/) → 빌드 산출물 제외
관련 스킬/에이전트
| 도구 | 역할 | 관계 |
|---|---|---|
/kdyweb --verify | 페이지 라우팅 연결성 | Ref (페이지 수준은 kdyweb에 위임) |
/kdyconvention | 코드 스타일/품질 규칙 | Ref (스타일은 kdyconvention에 위임) |
/kdye2e | 런타임 E2E 검증 | Recommend (정적 분석 후 런타임 확인) |
/kdynext | 프로젝트 건강 진단 | Trigger (D4 의존성 결함 시 호출) |
code-reviewer | 코드 품질 심층 분석 | Invoke (CRITICAL 2+ 시 위임) |
/inception | 의존성 맵 갱신 | Recommend (구조 변경 후 맵 동기화) |
사용 예시
# 전체 연결성 검증 (자동 영역 감지)
/kdyconecttest
# Import/Export 체인만 검증
/kdyconecttest --scope ic
# 여러 영역 지정
/kdyconecttest --scope ic,ac,ec
# 특정 프로젝트 경로 지정
/kdyconecttest --project /path/to/my-app
# 스키마 정합성만 검증
/kdyconecttest --scope sc
# 데드코드만 탐지
/kdyconecttest --scope dc
주의사항
- 대규모 프로젝트: 파일 수가 500개 이상이면 Phase별 진행 표시로 사용자에게 상황 알림
- 모노레포: 루트가 아닌 개별 패키지 경로를
--project로 지정할 것 - false positive 최소화:
references/check-patterns.md의 면제 조건을 반드시 적용 - 레퍼런스 부재:
_SCHEMA_REFERENCE.md등이 없으면 해당 영역 스킵 (에러 아님) - 수정은 하지 않음: 이 스킬은 탐지/보고만 수행. 자동 수정은 사용자 확인 후 별도 작업