/** * dependency-cruiser — resolver 기반 임포트 경계 게이트. * 레이어 단방향·cross-slice는 oxlint(fsd 플러그인)가 잡는다. 여기는 oxlint가 못 보는 것: * 순환 의존, 외부 패키지 봉인(radix), 생성물 봉인(type-only 예외). * 규칙을 바꾸면 .claude/scripts/gate-selftest.sh 픽스처도 함께 갱신할 것. */ module.exports = { forbidden: [ { name: 'no-circular', severity: 'error', comment: '순환 의존 금지 — A→B→A는 리팩터 불가 덩어리를 만든다. 한쪽을 아래 레이어로 내려라.', from: {}, to: { circular: true }, }, { name: 'primitives-sealed-in-shared-ui', severity: 'error', comment: '헤드리스 원자재(radix-ui·@base-ui/react·@shadcn/react)는 shared/ui 래퍼 안에서만 import한다 — 화면에서 직수입하면 아나토미가 새서 디자인 시스템이 무너진다 (P-007). 필요한 컴포넌트가 없으면 npx shadcn add. shadcn이 base를 radix에서 Base UI로 옮기며 원자재가 여러 갈래가 됐으므로(현재 이 앱은 radix 37 + base-ui 1 + shadcn 1) 셋을 같이 봉인한다 — 하나만 막으면 나머지로 새어 나간다.', from: { path: '^src', pathNot: '^src/shared/ui' }, // 두 형태를 다 잡는다. 해석된 의존성은 `node_modules//…` 경로로 오지만, // 서브패스 export를 depcruise가 해석하지 못하면(@shadcn/react/message-scroller가 그렇다) // resolved에 맨 specifier가 그대로 남는다 — 그때는 `^@shadcn` 쪽이 잡는다. to: { path: '(^|node_modules/)(radix-ui|@radix-ui|@base-ui|@shadcn)' }, }, { name: 'generated-behind-shared-api', severity: 'error', comment: 'orval 생성물과 ky 클라이언트는 쿼리 팩토리 안에서만 소비한다 — 화면은 postQueries 같은 팩토리를 import (query-factory 스킬). 팩토리 자리는 entities/<도메인>/api/이고, 도메인에 안 붙는 공용 호출만 shared/api에 남는다. 타입 import는 허용.', from: { path: '^src', pathNot: '^src/(shared/api|entities/[^/]+/api)' }, to: { path: '^src/shared/api/(_generated|client)', dependencyTypesNot: ['type-only'], }, }, ], options: { doNotFollow: { path: 'node_modules' }, tsPreCompilationDeps: true, tsConfig: { fileName: 'tsconfig.app.json' }, }, };