문서 목차
이 페이지에서목차

figma-widgetbook-alignment Reference

[SKILL.md](./SKILL.md) 의 참조 자료입니다. 레지스트리 컬럼 스키마와 검증 항목 전체를 담습니다.

SKILL.md 의 참조 자료입니다. 레지스트리 컬럼 스키마와 검증 항목 전체를 담습니다.


레지스트리 컬럼#

화면 하나 = 한 행. 파일은 리포에 두고(CSV 또는 그에 준하는 텍스트 포맷), 디자인 파일에는 목차 페이지로 미러링합니다.

컬럼주체내용
key 사람 (1회) app/store/home , console/book/book-list . 절대 변경하지 않는다 — 이 값이 행의 정체성이다
surface자동app / console
roles 사람 이 화면을 보는 역할. 세미콜론 구분 (admin;publisher_manager)
domain 사람 도메인 키 (store, book, settlement)
order사람도메인 내 정렬 번호
label_ko사람한글 라벨. 섹션 이름·usecase_name 과 같은 문자열
figma_page사람디자인 파일의 페이지 (020 book-도서)
figma_section사람섹션 이름
figma_node 사람 node ID — 결합의 실체. 이름이 바뀌어도 이건 안 변한다
dart_class자동Page 위젯 클래스명
usecase_name자동@UseCase(name:) 값
platforms 자동 Device Addon 값 집합 ( Mobile;Tablet;Web ) — 코드 쪽 집합이다. 시안의 프레임 플랫폼은 Mobile · Web 뿐이다
states 자동 상태 Knob 의 시나리오 enum 이 든 상태 이름 집합 (Default;Loading;Empty;Error) — SKILL §2-1
status 사람 todo → designing → review → done , 또는 dead
note사람이슈·근거·판정 사유

자동/사람 구분이 이 표의 생존 조건#

dart_class · usecase_name · platforms · states 를 사람이 적기 시작하면 표가 죽습니다. 클래스 이름 하나만 바뀌어도 표가 거짓말을 시작하고, 거짓말하는 표는 아무도 안 봅니다.

시드 단계에서는 자동 컬럼이 비어 있는 게 정상입니다. 코드 스캔이 채웁니다.

key 는 왜 불변인가#

figma_node 는 섹션을 지웠다 다시 만들면 바뀝니다. dart_class 는 리네임되면 바뀝니다. figma_page 는 도메인 재편으로 옮겨집니다. 모든 컬럼이 변할 수 있으므로, 행을 추적할 불변 축이 하나 필요합니다. 그게 key 입니다. 도메인이 바뀌어도 key 는 두고 domain 만 고칩니다.


검증 항목#

L0 — 결합 (PR 차단)#

결합이 끊긴 것만 여기 둡니다. 이 계층이 붉으면 표를 신뢰할 수 없다는 뜻입니다.

검사실패 시 의미
모든 figma_node 가 실제 존재하는가섹션이 삭제·재생성됐다
모든 dart_class 가 실제 존재하는가클래스가 삭제·리네임됐다
figma_section == usecase_name 누군가 한쪽 이름만 바꿨다
usecase_name 중복 없음 서로 다른 두 화면이 같은 이름을 쓴다 — 이름 기반 대조가 무너진다
designLink 누락링크 미입력. 도입 단계에서는 경고로 시작해 0 이 되면 차단으로 승격
표에 빈 값 + allowlist 미등재신규 feature 가 등록되지 않았다
디자인에 있으나 미등록인 섹션 (_ 페이지 제외)미등록 디자인
코드에 있으나 미등록인 UseCase ([Lab] 제외)미등록 구현
코드에 화면이 있으나 UseCase 가 없음위젯북 누락 — 살아 있는 화면이 전시장에 없다

L1 — 축 집합 (경고)#

프레임 여러 장과 use_case 하나는 1:1 이 아니므로 집합 포함 관계를 봅니다. 두 집합의 원소는 같은 어휘(SKILL §2-1)라, 어느 상태가 빠졌는지까지 이름으로 짚어 낼 수 있습니다.

검사리포트
states ⊇ 디자인 프레임에서 파싱한 상태 집합—
platforms ⊇ 디자인 프레임에서 파싱한 플랫폼 집합 — 코드의 Tablet 은 시안에 없는 것이 정상이라 세지 않는다
코드에 있고 디자인에 없는 상태 "디자인 미지정" — 코드가 4상태를 강제하므로 이 리포트가 디자인 부채를 그대로 드러낸다
디자인에 있고 코드에 없는 상태"구현 누락"

차단으로 올리지 마세요. 도입 초기에 이 검사는 거의 모든 화면에서 걸립니다. 차단하면 팀이 검사를 끕니다. 경고로 두면 같은 정보가 부채 리포트로 남습니다.

L2 — 위생 (주 1회 배치)#

검사의미
path 표기 오류([A/B] 형태) 잔존 여부트리가 깨진 use_case 가 남아 있다
페이지 번호 정렬 일치두 트리의 순서가 어긋났다
디자인시스템 라이브러리 버전 ↔ 패키지 버전 화면 이름이 다 맞는데 결과가 다른 원인. 화면 단위 대조로는 절대 못 찾는다
승격 대기 로컬 컴포넌트 개수 추이증가 추세 = 디자인시스템이 제품 속도를 못 따라간다
status: dead 화면에 작업이 들어갔는지아무도 못 보는 화면을 그리고 있다

프레임 이름 파싱#

L1 이 성립하려면 프레임 이름이 기계로 읽혀야 합니다.

{플랫폼}-{상태}
  • 구분자는 하이픈. 첫 하이픈에서만 자른다 — 상태 이름에 하이픈이 들어가도 안전하다(cc-blueprint rules/figma-workflow.md §5 R2 와 같은 규칙)
  • ·(공백 + 가운뎃점 + 공백)으로 적은 옛 프레임은 같은 이름으로 읽되 경고로 리포트한다 — 고칠 대상이다
  • 플랫폼 어휘: Mobile · Web — 태블릿 프레임은 그리지 않는다(cc-blueprint rules/figma-workflow.md §5 R2). 옛 파일의 Tablet-… 프레임은 어휘 밖으로 리포트한다
  • 상태 어휘: SKILL §2-1 의 표 — 공통 어휘(Default · Loading · Empty · Error · Long · Typing · Collapsed · NoPermission)와 그 제품이 DDR 에 남긴 제품 전용 어휘
  • 어휘 밖의 값은 경고로 리포트하고 집합에서 제외 — 조용히 버리면 오탐이 된다
Section: 도서 목록
  Frame: Web-Default        → platforms{Web},    states{Default}
  Frame: Web-Empty          → platforms{Web},    states{Empty}
  Frame: Mobile-Default     → platforms{Mobile}, states{Default}

파싱 결과: platforms = {Web, Mobile}, states = {Default, Empty}. 코드 쪽 states = {Default, Loading, Empty, Error} 이므로 Loading·Error 가 "디자인 미지정" 으로 리포트됩니다.


스캐너가 읽어야 할 것#

좌측(자동) 컬럼 생성기는 @UseCase 어노테이션에서 다음을 뽑습니다.

대상출처
usecase_namename: 인자
dart_classtype: 인자
surface path: 의 첫 대괄호 세그먼트 ([App] → app)
featurepath: 의 두 번째 세그먼트
states상태 Knob 이 고르는 시나리오 enum — 값마다 첫 인자(상태 이름 문자열)
platformsDevice Addon 설정 (조립 앱 공통) 또는 use_case 의 명시적 제약
designLinkdesignLink: 인자

states 는 Knob 이 고르는 시나리오 enum 에서 읽습니다. 상태 Knob 은 context.knobs.object.dropdown<{화면}Scenario>(options: {화면}Scenario.values, …) 한 줄이고, 스캐너는 그 타입의 enum 선언에서 값마다 첫 인자 문자열을 읽습니다 — 그 문자열이 프레임의 상태 이름입니다. 본문의 문자열 목록이 아니라 선언된 enum 을 읽으므로 파싱이 흔들리지 않습니다.

enum BookListScenario {
  data('Default', '데이터'),   // → states 에 Default
  loading('Loading', '로딩'),
  empty('Empty', '빈'),
  error('Error', '에러');
  // …
}

한국어 문자열 목록으로 Knob 을 만든 옛 use_case(['로딩', '데이터', '빈', '에러'])는 SKILL §2-1 표의 라벨로 상태 이름을 읽되 경고로 리포트합니다 — 라벨은 대조의 키가 아니므로 고칠 대상입니다.


짝짓기 예제 — 행 · 프레임 · use_case · 캡처#

화면 하나를 끝까지 따라갑니다. 기계가 쓰는 키는 셋뿐입니다 — 섹션 node ID = figma_node, 섹션 이름 = name:, 상태 이름 = enum 의 frameState.

① 레지스트리 행 — 사람 칸은 화면당 1회, 자동 칸은 스캔이 채웁니다(나머지 칸 생략).

key label_ko figma_page figma_node dart_class usecase_name platforms states
console/book/book-list 도서 목록 020 book-도서 1234:5678 BookListPage 도서 목록 Mobile;Tablet;Web Default;Loading;Empty;Error

② 섹션의 프레임 — node 1234:5678, 섹션 이름 도서 목록.

Section: 도서 목록
  Frame: Web-Default
  Frame: Web-Empty
  Frame: Web-Error
  Frame: Tablet-Default     ← 옛 파일에 남은 태블릿 프레임

③ use_case — 섹션 이름 · 클래스 · 상태가 행의 자동 칸이 됩니다.

@UseCase(
  name: '도서 목록',              // → usecase_name. figma_section 과 공백까지 같다 (L0)
  type: BookListPage,            // → dart_class
  path: '[Console]/Book',
  designLink: 'https://www.figma.com/design/<key>/...?node-id=1234-5679',   // Web-Default 프레임
)
Widget buildWidgetbookBookListPageUseCase(BuildContext context) {
  final scenario = context.knobs.object.dropdown<BookListScenario>(
    label: '상태',
    options: BookListScenario.values,   // → states = Default;Loading;Empty;Error
    initialOption: BookListScenario.data,
    labelBuilder: (s) => s.label,
  );
  return BookListPage(bloc: scenario.bloc());
}

④ Figma 대조 캡처 — 같은 enum 의 같은 bloc() 으로 그립니다(cc-pixel-loop:visual-verify §3).

for (final s in BookListScenario.values) {
  figmaFrames.scenario(s.captureScenario, build: (_) => BookListPage(bloc: s.bloc()));
}

⑤ 짝 — 프레임의 상태 이름이 enum 값과 캡처 폴더를 정합니다.

프레임 시나리오 Knob 라벨 대조 캡처 (<captureScenario>/<device>__<theme>__<locale>.png) 결과
Web-Default BookListScenario.data 데이터 default/web-1440x1024__light__ko.png · …__dark__ko.png 대조
Web-Empty BookListScenario.empty 빈 empty/web-1440x1024__… 대조
Web-Error BookListScenario.error 에러 error/web-1440x1024__… 대조
— BookListScenario.loading 로딩 프레임이 없다 L1 "디자인 미지정"
Tablet-Default — — — 플랫폼이 어휘 밖 — 경고하고 집합에서 뺀다. 대조에서는 비교 목록에 들지 않아 판정 불가로 남는다(프레임을 지우거나 plan --ignore-frame 에 이유와 함께)

파싱 결과는 platforms = {Web} · states = {Default, Empty, Error} 이고 코드 쪽 platforms 와 states 가 둘 다 포함합니다. 경고는 둘입니다 — Loading 의 "디자인 미지정", 그리고 어휘 밖 프레임 Tablet-Default.

짝이 맞지 않으면 어디서 드러나는지:

  • 섹션 이름 ≠ name: → L0 (결합이 끊겼다)
  • 시안에만 있는 상태(예: Web-Long 인데 enum 에 Long 이 없음) → L1 "구현 누락". 대조에서도 long/ 캡처가 없어 figma_compare.py ingest 가 그 비교를 판정 불가로 남긴다
  • enum 에만 있는 상태 → L1 "디자인 미지정" — 그 상태는 대조할 프레임이 없다

도입 시 흔한 실패#

실패왜 생기나대응
표가 3개월 만에 죽음자동으로 알 수 있는 걸 사람이 채우게 했다자동 컬럼을 늘리고, 사람 칸은 화면당 1회로
L1 이 붉어서 검사를 끔축 검사를 차단으로 걸었다L1 은 경고
이름을 바꾸자 결합이 전부 끊김이름으로 결합했다node ID 결합 (§0)
제외 구역이 없어 미등록 경고가 수백 개 와이어프레임·디버그 화면까지 대조 대상 _ 페이지 / [Lab] 먼저 확보
대표 화면 없이 도메인 순차로 그림갭을 늦게 발견1차 수직 슬라이스 (SKILL.md §9)

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기