.claude/skills/verify-ssot/SKILL.md
SSOT(Single Source of Truth) 임포트 소스를 검증합니다. 타입/enum/상수가 올바른 패키지에서 임포트되는지 확인. 타입/enum 추가/수정 후 사용.
npx skillsauth add junnv93/equipment_management_system verify-ssotInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
타입, enum, 상수가 올바른 패키지에서 임포트되는지 검증합니다:
UserRole, EquipmentStatus 등은 @equipment-management/schemas에서 임포트@equipment-management/shared-constants에서 임포트@equipment-management/shared-constants에서 임포트하드코딩 값 탐지는
/verify-hardcoding에서 수행합니다.
핵심 SSOT 패키지 요약 (전체 파일 목록: references/ssot-file-map.md):
| Package / Layer | SSOT 항목 |
|---|---|
| packages/schemas/ | Enum, 타입, ErrorCode, 설정 기본값, VM 검증 메시지, DocumentType, AuditLogUserRole |
| packages/shared-constants/ | Permission, API 경로, 스코프 정책, 비즈니스 규칙, 엔티티 라우트, Test Users |
| packages/db/ | DB enum 배열, AppDatabase 타입, varchar 컬럼 .$type<T>() 타입 좁힘 |
| apps/backend/src/common/scope/scope-enforcer.ts | enforceScope() 정책 함수 + EnforcedScope 타입 (요청 경계 — cross-site/cross-team 차단 SSOT) |
| apps/backend/src/common/scope/scope-sql-builder.ts | buildScopePredicate / dispatchScopePredicate (쿼리 계층 — 정책 상태기계 SSOT, 2026-04-08~) |
| apps/backend/src/common/decorators/site-scoped.decorator.ts | @SiteScoped 데코레이터 + SiteScopedOptions (failLoud 옵션 포함) |
| apps/backend/src/common/decorators/current-scope.decorator.ts | @CurrentScope() / @CurrentEnforcedScope() parameter decorator |
패키지에 정의된 핵심 타입(UserRole, EquipmentStatus, SystemSettings 등)이 로컬에서 재정의되는지 확인. PASS: 0개 결과. FAIL: 로컬 타입 정의 발견 시 패키지 임포트로 변경.
상세: references/ssot-checks.md Step 1
PASS: 모든 Permission이 @equipment-management/shared-constants에서 import. FAIL: 다른 소스 사용.
상세: references/ssot-checks.md Step 2
hasRole() 금지 (role literal 기반 권한 게이트 탐지)PASS: 프론트엔드 컴포넌트/페이지에 useAuth().hasRole 사용 0건. role 리터럴 배열을 권한 게이트로 쓰는 패턴 0건. FAIL: client code에서 hasRole 또는 [URVal.XXX, ...]로 권한 결정.
규칙 근거: 2026-04-08 (49fb6d7e)에 role-based client gating이 전면 can(Permission.X)로 마이그레이션되어 백엔드 @RequirePermissions와 단일 SSOT를 공유.
상세: references/ssot-checks.md Step 2a
API_ENDPOINTS, Audit Log 타입, Field Labels, Entity Routes, Data Scope, SSOT 상수의 import 소스 확인. PASS: 모두 올바른 패키지에서 import. FAIL: 잘못된 소스 사용.
상세: references/ssot-checks.md Step 3
react-icons(deprecated) 사용 및 비표준 icon library 탐지. PASS: lucide-react만 사용. FAIL: react-icons 또는 비표준 라이브러리 사용.
상세: references/ssot-checks.md Step 4
| Step | 검증 대상 |
|---|---|
| 5 | AppDatabase SSOT 타입 (NodePgDatabase 직접 import 금지) |
| 6 | ApiResponse 로컬 재정의 |
| 7 | APPROVAL_KPI 임포트 소스 |
| 8 | 신규 shared-constants SSOT (APPROVAL_CATEGORIES, BUSINESS_RULES 등) |
| 9 | DB Enum 배열 SSOT 참조 |
| 10 | REJECTION_STAGE_VALUES SSOT |
| 11 | VM (Validation Messages) 임포트 소스 |
| 12 | Test User Constants SSOT |
| 13 | DocumentTypeValues SSOT |
| 14 | Scope enforcement + query-layer SSOT — EnforcedScope / enforceScope 로컬 재정의 금지, controller helper로 _resolveXxxScope 사본 정의 금지, service 계층의 switch (scope.type) 정책 상태기계 사본 정의 금지 (2026-04-08 추가) |
Step 14 탐지 명령어:
# (a) EnforcedScope/enforceScope 로컬 재정의 (scope-enforcer.ts 외)
grep -rn "interface EnforcedScope\|export function enforceScope" apps/backend/src/ \
| grep -v "common/scope/scope-enforcer.ts"
# (b) controller 가 _resolveXxxScope 같은 inline scope helper 를 정의 (도메인 특수 예외 외)
grep -rn "private _resolve.*Scope\|private resolveDataScope" apps/backend/src/modules/ \
| grep -v "audit-logs" # AUDIT_LOG_SCOPE 인라인은 의도적 예외
# (c) query-layer 정책 상태기계 사본 — service 가 buildScopePredicate/dispatchScopePredicate 우회하고
# scope.type 4-case switch 를 인라인 구현. 0건이 PASS.
grep -rn "switch.*scope\.type\|scope\.type === 'team'\|scope\.type === 'site'" apps/backend/src/modules/ \
--include="*.ts" \
| grep -v "checkout-scope.util.ts" # 도메인 특수 3-case OR builder, dispatch 위에 얹힘
# common/scope/ 외에서 hit 가 있으면 buildScopePredicate / dispatchScopePredicate 로 마이그레이션 권장.
규칙 근거:
buildScopePredicate + dispatchScopePredicate 가 query 계층 정책 상태기계 SSOT 로 승격. approvals.service 18 callsite 마이그레이션 + checkout-scope.util.ts 통합으로 drift 차단.상세: references/ssot-checks.md Step 5~13
| # | 검사 | 상태 | 상세 |
| --- | ----------------------------- | --------- | -------------------------------------- |
| 1 | 로컬 타입 재정의 | PASS/FAIL | 재정의 위치 목록 |
| 2 | Permission 임포트 | PASS/FAIL | 잘못된 임포트 위치 |
| 3 | API_ENDPOINTS 임포트 | PASS/FAIL | 잘못된 임포트 위치 |
| 3a | Audit Log 타입 임포트 | PASS/FAIL | 잘못된 임포트 위치 |
| 3b | Field Labels 임포트 | PASS/FAIL | 잘못된 임포트 위치 |
| 3c | Entity Routes 임포트 | PASS/FAIL | 잘못된 임포트 위치 |
| 3d | Data Scope 임포트 | PASS/FAIL | 잘못된 임포트 위치 |
| 3e | Audit Log SSOT 상수 | PASS/FAIL | 잘못된 임포트 위치 |
| 4 | Icon Library 통합 | PASS/FAIL | 비표준 library 위치 |
| 5 | AppDatabase SSOT 타입 | PASS/FAIL | NodePgDatabase 직접 import 위치 |
| 6 | ApiResponse 로컬 재정의 | PASS/FAIL | 재정의 위치 |
| 7 | APPROVAL_KPI 임계값 | PASS/FAIL | 잘못된 import 위치 |
| 8 | 신규 shared-constants SSOT | PASS/FAIL | 로컬 재정의 위치 |
| 9 | DB Enum 배열 SSOT 참조 | PASS/FAIL | 하드코딩 enum 배열 위치 |
| 10 | REJECTION_STAGE_VALUES SSOT | PASS/FAIL | 로컬 선언 위치 |
| 11 | VM 임포트 소스 | PASS/FAIL | 잘못된 VM import 위치 |
| 12 | Test User Constants SSOT | PASS/FAIL | 로컬 재정의 위치 |
| 13 | DocumentTypeValues SSOT | PASS/FAIL | 문자열 하드코딩 위치 |
| 14 | Scope enforcement SSOT | PASS/FAIL | 로컬 enforceScope/EnforcedScope 재정의 또는 controller inline scope helper |
다음은 위반이 아닙니다:
SITE_OPTIONS, CLASSIFICATION_OPTIONS 등 레이블+값 쌍 UI 표시용 객체는 로컬 정의 허용export type { UserRole } from '@equipment-management/schemas' 같은 재내보내기는 정상Promise<unknown> 허용 케이스 — private 헬퍼 메서드나 단순 delete/count 반환은 면제resolveDataScope 호출 — AUDIT_LOG_SCOPE + 'none → 빈 보고서' fallback 정책으로 인터셉터 통합 불가, 의도적 예외 (reports.controller.exportAuditLogs)testing
Verifies Zod validation pattern compliance — ZodValidationPipe usage (no class-validator), versionedSchema inclusion in state-change DTOs, controller pipe application, query DTO consistency. Run after adding/modifying DTOs or controller endpoints.
testing
Verifies cross-feature workflow E2E test coverage against critical-workflows.md checklist. Checks WF-01~WF-35 coverage, step completeness, role correctness, side-effect verification, and status transition assertions. Run after adding workflow tests or before PR.
development
Verifies SQL safety — LIKE wildcard escaping, N+1 query pattern detection, COUNT(DISTINCT) for fan-out JOINs, RBAC INNER JOIN enforcement. Run after adding/modifying search or list API endpoints.
testing
테스트 시드 인프라의 3자 SSOT 정합성을 검증합니다 — seed-data 파일 ↔ seed-test-new.ts 의 truncate/insert wiring ↔ verification.ts 의 count check 가 한 세트로 움직여야 함. 새 seed 파일 추가 후, verification.ts 편집 후 사용.