@su-record/vibe 2.8.16 → 2.8.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "2.8.16",
3
+ "version": "2.8.18",
4
4
  "description": "AI Coding Framework for Claude Code — 49 agents, 41+ tools, multi-LLM orchestration",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -24,8 +24,8 @@ tier: standard
24
24
 
25
25
  AskUserQuestion (options 사용 금지, 자유 텍스트만):
26
26
  ```
27
- question: "📋 스토리보드 Figma URL을 입력해주세요. (없으면 '없음')"
28
- ⏸️ 응답 대기 (응답 받기 전 다음 진행 금지)
27
+ question: "스토리보드 Figma URL을 입력해주세요. (없으면 '없음')"
28
+ → 응답 대기 (응답 받기 전 다음 진행 금지)
29
29
  → figma.com URL → storyboardUrl 저장
30
30
  → "없음" → storyboardUrl = null
31
31
  ```
@@ -39,45 +39,24 @@ URL에서 fileKey, nodeId 추출:
39
39
 
40
40
  1. get_metadata(fileKey, nodeId) → 전체 프레임 목록
41
41
  2. 관련 섹션별 get_design_context 또는 get_screenshot:
42
- - "해상도 대응" / "Media Query" → 브레이크포인트 + ⚠️ 디자인 시안 사이즈
42
+ - "해상도 대응" / "Media Query" → 브레이크포인트 + 디자인 시안 사이즈
43
43
  - "인터랙션" / "Interaction" → 호버/클릭/스크롤 스펙
44
44
  - "애니메이션" / "Animation" / "Motion" → 트랜지션 스펙
45
45
  - "상태" / "State" → 로딩/에러/성공 UI
46
46
  - "컬러" / "Color" / "타이포" / "Typography" → 디자인 가이드
47
47
  ```
48
48
 
49
- ### ⚠️ 해상도 대응 프레임에서 반드시 추출해야 하는 값
49
+ ### 해상도 대응 프레임 추출
50
50
 
51
- ```
52
- Media Query Guide에서 추출:
53
- 1. PC Main Target: 1920px (실제 타겟 해상도)
54
- 2. Breakpoint: 1024px (PC↔Mobile 경계)
55
- 3. Mobile Portrait: ~480px
56
- 4. Mobile Minimum: 360px~
57
- 5. ⚠️ 디자인 시안 PC: 2560px (Figma 아트보드 크기)
58
- 6. ⚠️ 디자인 시안 Mobile: 720px (Figma 아트보드 크기)
59
-
60
- 디자인 시안 사이즈가 없으면 Step B에서 스케일 팩터를 계산할 수 없음:
61
- Figma 값 × (타겟 / 시안) = 실제 코드 값
62
- 예: Figma PC font-size 48px × (1920/2560) = 36px
63
- 예: Figma Mobile font-size 28px × (480/720) = 18.67px → 19px
64
- ```
51
+ 해상도 프레임에서 브레이크포인트 + 스케일 팩터 정보를 추출한다.
52
+ 계산 공식과 기본값은 **vibe-figma-rules R-3** 참조.
65
53
 
66
- 추출 결과를 `storyboardSpec`으로 저장:
67
54
  ```
55
+ 추출 결과를 storyboardSpec으로 저장:
56
+
68
57
  storyboardSpec = {
69
- breakpoints: {
70
- pcTarget: 1920, // PC 타겟 해상도
71
- breakpoint: 1024, // PC↔Mobile 경계
72
- mobilePortrait: 480, // Mobile portrait max
73
- mobileMinimum: 360, // Mobile minimum
74
- designPc: 2560, // ⚠️ Figma PC 시안 사이즈
75
- designMobile: 720, // ⚠️ Figma Mobile 시안 사이즈
76
- },
77
- scaleFactor: {
78
- pc: 1920 / 2560, // = 0.75 (PC 스케일)
79
- mobile: 480 / 720, // = 0.667 (Mobile 스케일)
80
- },
58
+ breakpoints: { pcTarget, breakpoint, mobilePortrait, mobileMinimum, designPc, designMobile },
59
+ scaleFactor: { pc, mobile },
81
60
  interactions: [ ... ],
82
61
  animations: [ ... ],
83
62
  states: { ... },
@@ -89,9 +68,9 @@ storyboardSpec = {
89
68
  ## A-3. 프로젝트 스택 감지 + Base 구조 설계
90
69
 
91
70
  ```
92
- 1. 프로젝트 스택 감지 (vibe-figma-rules Phase 3 참조)
71
+ 1. 프로젝트 스택 감지 (vibe-figma-rules R-2 참조)
93
72
  2. 디자인 시스템 감지 (--new 미지정 시)
94
- 3. 브레이크포인트 로드 (vibe-figma-rules Phase 3-3 참조, 스토리보드 우선)
73
+ 3. 브레이크포인트 로드 (vibe-figma-rules R-3 참조, 스토리보드 우선)
95
74
  4. 피처명 결정 (Figma 파일명에서 추출)
96
75
  5. → 파일 생성은 vibe-figma-analyze 스킬에서 실행 (이 스킬은 추출까지만)
97
76
  ```
@@ -101,46 +80,26 @@ storyboardSpec = {
101
80
  Figma 파일명에서 피처명 자동 추출 → kebab-case 변환.
102
81
 
103
82
  ```
104
- 예: Figma 파일명 "PUBG 9주년 이벤트" → pubg-anniversary
83
+ 예: "Winter Sale Campaign" → winter-sale
84
+ 예: "Dashboard Redesign v2" → dashboard-redesign
105
85
  ```
106
86
 
107
- ### 파일 구조 감지 및 생성
108
-
109
- **페이지 디렉토리:**
110
- ```
111
- Next.js → pages/ or app/
112
- Nuxt → pages/
113
- React → src/pages/ or src/views/
114
- Vue → src/views/
115
- ```
87
+ ### 파일 구조 생성
116
88
 
117
- **컴포넌트 디렉토리:**
118
- ```
119
- Next.js → components/ or src/components/
120
- Nuxt → components/
121
- React → src/components/
122
- Vue → src/components/
123
- ```
124
-
125
- **스타일 디렉토리:**
126
- ```
127
- SCSS → assets/scss/ or src/scss/ or src/styles/
128
- CSS → src/styles/ or styles/
129
- Tailwind → tailwind.config.* (extend)
130
- ```
89
+ 디렉토리는 **vibe-figma-rules R-2.2** 감지 결과에 따라 결정.
131
90
 
132
- **생성 예시 (Nuxt 프로젝트):**
91
+ **생성 예시 (Nuxt):**
133
92
  ```
134
- pages/pubg-anniversary.vue ← 루트 페이지 (빈 shell)
135
- components/pubg-anniversary/ ← 컴포넌트 디렉토리 (빈 폴더)
136
- assets/scss/_pubg-anniversary-tokens.scss ← 스토리보드 기반 초기 토큰
93
+ pages/{feature-name}.vue ← 루트 페이지 (빈 shell)
94
+ components/{feature-name}/ ← 컴포넌트 디렉토리 (빈 폴더)
95
+ assets/scss/_{feature-name}-tokens.scss ← 스토리보드 기반 초기 토큰
137
96
  ```
138
97
 
139
- **생성 예시 (React + Next.js):**
98
+ **생성 예시 (Next.js):**
140
99
  ```
141
- app/pubg-anniversary/page.tsx ← 루트 페이지 (빈 shell)
142
- components/pubg-anniversary/ ← 컴포넌트 디렉토리 (빈 폴더)
143
- styles/pubg-anniversary-tokens.css ← 스토리보드 기반 초기 토큰
100
+ app/{feature-name}/page.tsx ← 루트 페이지 (빈 shell)
101
+ components/{feature-name}/ ← 컴포넌트 디렉토리 (빈 폴더)
102
+ styles/{feature-name}-tokens.css ← 스토리보드 기반 초기 토큰
144
103
  ```
145
104
 
146
- Step A 완료 후 → Step B (vibe-figma-mobile) 로 진행.
105
+ Step A 완료 후 → Step B (vibe-figma-frame) 로 진행.
@@ -10,22 +10,19 @@ triggers: []
10
10
  스토리보드 URL 하나로 **실제 동작하는 레이아웃 코드**를 생성.
11
11
  빈 shell이 아니라, 스토리보드에서 파악 가능한 모든 정보를 코드에 반영.
12
12
 
13
- > **⛔ 실행 지시: 이 스킬은 분석만 하는 게 아님. 반드시 Write 도구로 파일을 생성해야 함.**
14
- > Phase 1~4에서 분석 → Phase 5에서 **Write 도구로 실제 파일 생성** → Phase 6에서 인터랙션 테이블 출력.
15
- > 분석 결과를 텍스트로 보여주기만 하면 안 됨. 파일이 디스크에 생성되어야 Step A 완료.
13
+ > **실행 지시: 이 스킬은 분석만 하는 게 아님. 반드시 Write 도구로 파일을 생성해야 함.**
14
+ > A-1~A-4에서 분석 → A-5에서 **Write 도구로 실제 파일 생성** → A-6에서 인터랙션 테이블 출력.
16
15
 
17
16
  ## 입력
18
17
 
19
18
  - 스토리보드 URL의 get_metadata 결과 (전체 프레임 목록)
20
19
  - storyboardSpec (브레이크포인트 등, vibe-figma에서 추출)
21
20
 
22
- ## Phase 1: 프레임 전수 조사
21
+ ## A-1. 프레임 전수 조사
23
22
 
24
23
  get_metadata에서 얻은 **모든 최상위 프레임**을 분류:
25
24
 
26
25
  ```
27
- 각 프레임을 카테고리로 분류:
28
-
29
26
  SKIP — "개요", "Cover", "변경 이력" (문서 관리용)
30
27
  SPEC — "기능 정의", "정책" → 기능 스펙 텍스트 추출 대상
31
28
  CONFIG — "해상도", "Media Query", "브라우저" → 설정값 추출
@@ -38,50 +35,46 @@ PAGE — "메인", "화면설계" 하위 → 핵심 섹션 (코드 생성 대
38
35
  → 해당 PAGE 섹션의 상태 변형 / 인터랙션 결과 화면
39
36
  ```
40
37
 
41
- ## Phase 2: SPEC 프레임 세밀 분석 (기능 정의서)
38
+ ## A-2. SPEC 프레임 세밀 분석
42
39
 
43
40
  **기능 정의서 프레임**에 대해 get_design_context 호출:
44
41
 
45
42
  ```
46
43
  추출 대상:
47
- - Overview: 이벤트 개요, 대상, 일정
44
+ - Overview: 개요, 대상, 일정
48
45
  - Spec: 각 섹션별 기능 정의 (로직, 조건, 보상 구조)
49
- - Event 일정: 시작/종료 시간, 단계별 기간
46
+ - 일정: 시작/종료 시간, 단계별 기간
50
47
 
51
48
  추출한 텍스트를 섹션별로 분리:
52
49
  {
53
- "overview": "겨울 PC방 이벤트...",
50
+ "overview": "...",
54
51
  "sections": {
55
- "hero": "키 비주얼 영역, 로그인 연동, 가맹 PC방 확인...",
56
- "dailyCheckIn": "매일 ON 게임 진입 + 출석란 터치 → 스노우 토큰 즉시 지급...",
57
- "playTimeMission": "일일 플레이 타임 달성 시 보상...",
58
- "tokenExchange": "스노우 토큰으로 아이템 교환...",
59
- "tokenRaffle": "스노우 토큰으로 상품 응모..."
52
+ "hero": "키 비주얼 영역, CTA 버튼...",
53
+ "featureA": "섹션 A 기능 설명...",
54
+ "featureB": "섹션 B 기능 설명..."
60
55
  }
61
56
  }
62
57
 
63
- 이 정보가 Phase 5에서 각 컴포넌트의 기능 주석이 됨
58
+ A-5에서 각 컴포넌트의 기능 주석이 됨
64
59
  ```
65
60
 
66
- ## Phase 3: SHARED 프레임 분석 (공통 컴포넌트)
61
+ ## A-3. SHARED 프레임 분석
67
62
 
68
63
  공통 요소 프레임들의 get_screenshot으로 구조 파악:
69
64
 
70
65
  ```
71
- GNB: 네비게이션 구조, 메뉴 항목, 언어 변경, 로그인 버튼
72
- Footer: 소셜 링크, 법적 고지, 시간 표시 (UTC/KST)
66
+ GNB: 네비게이션 구조, 메뉴 항목, 로그인 버튼
67
+ Footer: 링크, 법적 고지
73
68
  Popup: 패턴 분류 (확인/취소, 상세 모달, 알림, 입력 폼)
74
- Error: 에러 페이지 구조
75
69
 
76
70
  → 프로젝트에 이미 있는 컴포넌트 확인 (Glob으로 탐색)
77
71
  → 있으면 import 재사용, 없으면 새로 생성
78
72
  ```
79
73
 
80
- ## Phase 4: PAGE 프레임 세밀 분석 (화면설계)
74
+ ## A-4. PAGE 프레임 세밀 분석
81
75
 
82
- > **⛔ 모든 PAGE 프레임을 빠짐없이 분석한다. 일부만 처리하고 넘어가면 안 됨.**
83
- > Phase 1에서 PAGE로 분류된 프레임 수 = Phase 5에서 생성하는 섹션 컴포넌트 수.
84
- > 분석 완료 후 "PAGE 프레임 N개 중 N개 분석 완료" 카운트를 출력하여 누락 확인.
76
+ > **모든 PAGE 프레임을 빠짐없이 분석한다. 일부만 처리하고 넘어가면 안 됨.**
77
+ > A-1에서 PAGE로 분류된 프레임 수 = A-5에서 생성하는 섹션 컴포넌트 수.
85
78
 
86
79
  **각 PAGE 프레임**에 대해 get_screenshot + get_design_context:
87
80
 
@@ -92,297 +85,144 @@ Error: 에러 페이지 구조
92
85
  - 섹션 경계 (배경 변화 지점)
93
86
  - 요소 배치 방향 (vertical stack / grid / positioned)
94
87
  - 이미지 배경 영역 vs 콘텐츠 영역
95
- - 대략적인 비율 (hero 50vh, section padding 등)
96
88
 
97
89
  2. 인터랙션 스펙 (우측 주석):
98
90
  - 번호 태그 (①②③) → 인터랙션 ID
99
91
  - 동작 설명 → 이벤트 타입 + 결과
100
92
  - 조건 분기 (로그인 여부, 기간 내/외 등)
101
93
 
102
- 3. 상태 변형 (서브 프레임 3.x.1, 3.x.2):
94
+ 3. 상태 변형 (서브 프레임):
103
95
  - 기본 → 클릭 후 → 성공 → 에러 등
104
96
  - 팝업 트리거 조건
105
97
 
106
98
  결과를 섹션별로 저장:
107
99
  sections[sectionName] = {
108
100
  layout: "vertical-stack, bg-image + overlay + content",
109
- children: ["Title", "Description", "RewardGrid", "CTAButton"],
101
+ children: ["Title", "Description", "Grid", "CTAButton"],
110
102
  interactions: [
111
- { id: "①", trigger: "클릭", action: "출석 처리", result: "보상 표시" }
103
+ { id: "①", trigger: "클릭", action: "처리", result: "결과 표시" }
112
104
  ],
113
- states: ["default", "checked", "reward-claimed"],
105
+ states: ["default", "active", "completed"],
114
106
  popups: ["ConfirmDialog"]
115
107
  }
116
108
  ```
117
109
 
118
- ## Phase 5: 파일 생성 (Write 도구 사용 — 필수)
110
+ ## A-5. 파일 생성 (Write 도구 사용 — 필수)
119
111
 
120
- > **⛔ Write 도구로 아래 파일들을 실제로 생성한다. 코드를 보여주기만 하면 안 됨.**
112
+ > **Write 도구로 아래 파일들을 실제로 생성한다. 코드를 보여주기만 하면 안 됨.**
121
113
 
122
- 스토리보드 분석 결과로 **실제 동작하는 레이아웃 코드** 파일을 Write.
123
- 스타일은 Step B에서 채우지만, **구조/로직/주석은 이 단계에서 완성**.
114
+ 디렉토리는 **vibe-figma-rules R-2.2** 감지 결과에 따라 결정.
124
115
 
125
116
  ### 생성할 파일 목록
126
117
 
127
118
  ```
128
119
  필수 생성 (Write 도구):
129
- 1. pages/{feature-name}.vue (또는 .tsx) ← 루트 페이지
130
- 2. components/{feature-name}/각섹션.vue ← 섹션별 컴포넌트 (Phase 4에서 파악한 수만큼)
131
- 3. components/{feature-name}/popups/각팝업.vue ← 팝업 컴포넌트
132
- 4. styles/{feature-name}/index.scss ← 스타일 진입점 (빈 import 목록)
133
- 5. styles/{feature-name}/_tokens.scss ← 빈 토큰 파일 (Step B에서 채움)
120
+ 1. pages/{feature-name}.{vue|tsx} ← 루트 페이지
121
+ 2. components/{feature-name}/각섹션.{vue|tsx} ← 섹션별 컴포넌트
122
+ 3. components/{feature-name}/popups/각팝업 ← 팝업 컴포넌트
123
+ 4. styles/{feature-name}/index.scss ← 스타일 진입점 (빈 import 목록)
124
+ 5. styles/{feature-name}/_tokens.scss ← 빈 토큰 파일 (Step B에서 채움)
134
125
  ```
135
126
 
136
- ### 루트 페이지
137
-
138
- ```vue
139
- <!-- pages/{feature-name}.vue -->
140
- <template>
141
- <div class="eventPage">
142
- <GnbHeader />
143
-
144
- <HeroSection />
145
- <DailyCheckInSection />
146
- <PlayTimeMissionSection />
147
- <TokenExchangeSection />
148
- <TokenRaffleSection />
149
- <CautionSection />
150
-
151
- <EventFooter />
152
-
153
- <!-- Popups -->
154
- <ConfirmDialog v-if="showConfirm" @close="showConfirm = false" />
155
- <TokenDetailModal v-if="showTokenDetail" @close="showTokenDetail = false" />
156
- </div>
157
- </template>
158
-
159
- <script setup lang="ts">
160
- /**
161
- * {이벤트명} 메인 페이지
162
- *
163
- * [개요] Phase 2에서 추출한 overview 텍스트
164
- * [일정] 시작일 ~ 종료일
165
- * [대상] 대상자 설명
166
- */
167
-
168
- import HeroSection from '~/components/{feature-name}/HeroSection.vue'
169
- // ... 모든 섹션 import
170
-
171
- const showConfirm = ref(false)
172
- const showTokenDetail = ref(false)
173
- </script>
127
+ ### 루트 페이지 구조
128
+
129
+ ```
130
+ - 모든 섹션 컴포넌트 import
131
+ - 팝업 조건부 렌더링 (v-if/&&)
132
+ - 개요 JSDoc 주석 (A-2에서 추출한 overview)
174
133
  ```
175
134
 
176
- ### 섹션 컴포넌트 (기능 주석 포함)
177
-
178
- ```vue
179
- <!-- components/{feature-name}/DailyCheckInSection.vue -->
180
- <template>
181
- <section class="dailyCheckInSection">
182
- <div class="dailyCheckInSection__title">
183
- <!-- Step B: 모바일 디자인에서 타이틀 이미지/텍스트 반영 -->
184
- </div>
185
-
186
- <div class="dailyCheckInSection__calendar">
187
- <div
188
- v-for="day in checkInDays"
189
- :key="day.date"
190
- class="dailyCheckInSection__day"
191
- :class="{ 'is-checked': day.checked, 'is-today': day.isToday }"
192
- @click="handleCheckIn(day)"
193
- >
194
- <!-- Step B: 일별 UI (아이콘, 날짜, 보상) -->
195
- </div>
196
- </div>
197
-
198
- <div class="dailyCheckInSection__accumulated">
199
- <div
200
- v-for="milestone in milestones"
201
- :key="milestone.days"
202
- class="dailyCheckInSection__milestone"
203
- :class="{ 'is-claimable': milestone.claimable, 'is-claimed': milestone.claimed }"
204
- @click="handleClaimReward(milestone)"
205
- >
206
- <!-- Step B: 누적 보상 UI -->
207
- </div>
208
- </div>
209
- </section>
210
- </template>
211
-
212
- <script setup lang="ts">
213
- /**
214
- * 일일 출석 미션 섹션
215
- *
216
- * [기능 정의]
217
- * - 매일 ON 게임 진입, 대상 출석란 터치 시 출석 처리
218
- * - 스노우 토큰이 즉시 지급됨
219
- * - 누적 출석일 보상: 3일/5일/7일 달성 시 추가 보상
220
- *
221
- * [인터랙션]
222
- * ① 출석하기 클릭 → 출석 처리 API 호출 → 토큰 지급 표시
223
- * ② 누적 보상 달성 시 → 보상받기 버튼 활성화 → 클릭 시 수령
224
- *
225
- * [상태]
226
- * - default: 오늘 미출석
227
- * - checked: 오늘 출석 완료
228
- * - reward-claimed: 누적 보상 수령 완료
229
- *
230
- * [조건]
231
- * - 이벤트 기간 내에만 출석 가능
232
- * - 가맹 PC방에서만 출석 가능 (비가맹 시 안내 팝업)
233
- */
234
-
235
- interface CheckInDay {
236
- date: string
237
- checked: boolean
238
- isToday: boolean
239
- reward: number
240
- }
241
-
242
- interface Milestone {
243
- days: number
244
- claimable: boolean
245
- claimed: boolean
246
- reward: string
247
- }
248
-
249
- const checkInDays = ref<CheckInDay[]>([])
250
- const milestones = ref<Milestone[]>([])
251
-
252
- function handleCheckIn(day: CheckInDay): void {
253
- // TODO: 출석 API 호출
254
- }
255
-
256
- function handleClaimReward(milestone: Milestone): void {
257
- // TODO: 누적 보상 수령 API 호출
258
- }
259
- </script>
260
-
261
- <style lang="scss" scoped>
262
- /* Step B: 모바일 디자인 URL 반영 시 스타일 구현 */
263
- .dailyCheckInSection {
264
- /* layout will be filled in Step B */
265
- }
266
- </style>
135
+ ### 섹션 컴포넌트 필수 포함 사항
136
+
267
137
  ```
138
+ 각 섹션 컴포넌트에 반드시 포함:
268
139
 
269
- ### 핵심 원칙: 스타일 없이 동작하는 코드
140
+ 1. JSDoc 주석:
141
+ - [기능 정의] — A-2에서 추출한 기능 설명
142
+ - [인터랙션] — ①②③ 번호 + 동작 설명
143
+ - [상태] — 해당 섹션의 상태 목록
144
+
145
+ 2. TypeScript 인터페이스:
146
+ - 섹션에서 사용하는 데이터 구조 정의
147
+
148
+ 3. 이벤트 핸들러:
149
+ - 인터랙션 스펙에 맞는 함수 (body는 // TODO:)
150
+
151
+ 4. 목 데이터 (빈 배열 금지):
152
+ - 기능 정의서에서 추출한 아이템/보상/상품 정보로 채움
153
+ - 빈 배열 = UI가 안 보임 = Step A 미완성
154
+ ```
155
+
156
+ ### 스타일 분리 규칙
270
157
 
271
158
  ```
272
- 클릭 팝업 열림/닫힘이 실제로 동작
273
- 전환, 아코디언 펼침/접기가 동작
274
- 상태 변경 (체크, 선택, 비활성화)이 반영됨
275
- ✅ 모달/팝업 open/close가 v-if/ref로 연결됨
276
- ✅ emit으로 부모-자식 이벤트가 실제 연결됨
277
- ✅ 리스트 렌더링 (v-for)이 더미 데이터로 동작 — ⚠️ 빈 배열 금지, 반드시 목 데이터 채움
278
- ✅ 조건부 렌더링 (v-if)이 상태에 따라 전환됨
279
-
280
- ⚠️ 목 데이터 필수:
281
- 스토리보드 기능 정의서에서 아이템/보상/상품 정보를 추출하여 목 데이터로 사용.
282
- 빈 배열 = UI가 안 보임 = Step A 미완성.
283
- 예:
284
- exchangeItems = [
285
- { id: 1, name: '스노우 토큰 100', cost: 100, image: '' },
286
- { id: 2, name: '스노우 토큰 500', cost: 500, image: '' },
287
- ]
288
- raffleItems = [
289
- { id: 1, name: '1주차 경품', prize: 'PlayStation 5', entries: 0 },
290
- ]
291
-
292
- → 브라우저에서 열면 스타일은 없지만 클릭/인터랙션은 동작하는 상태
293
-
294
- ✅ 기능 정의서 내용 → 컴포넌트 JSDoc 주석
295
- ✅ 인터랙션 스펙 → 이벤트 핸들러 함수 (API 호출은 TODO)
296
- ✅ 상태 목록 → TypeScript 인터페이스 + ref + 더미 데이터
297
- ✅ 스타일은 빈 블록 → Step B에서 채움
298
- ✅ 이미지는 placeholder → Step B에서 교체
159
+ 컴포넌트 파일에 <style> 블록을 작성하지 않는다.
160
+ 스타일은 Step B에서 외부 파일로 생성.
161
+ 컴포넌트는 template + script 포함.
299
162
  ```
300
163
 
301
- ### 팝업/모달 구현 수준
302
-
303
- ```vue
304
- <!-- 팝업이 실제로 열리고 닫히는 코드 -->
305
- <template>
306
- <!-- 트리거 버튼 -->
307
- <button @click="showConfirm = true">교환하기</button>
308
-
309
- <!-- 모달 v-if로 제어, 실제 동작 -->
310
- <Teleport to="body">
311
- <div v-if="showConfirm" class="modalOverlay" @click.self="showConfirm = false">
312
- <div class="modalContent">
313
- <p>정말 교환하시겠습니까?</p>
314
- <button @click="handleConfirm">확인</button>
315
- <button @click="showConfirm = false">취소</button>
316
- </div>
317
- </div>
318
- </Teleport>
319
- </template>
320
-
321
- <script setup lang="ts">
322
- const showConfirm = ref(false)
323
-
324
- function handleConfirm(): void {
325
- // TODO: 교환 API 호출
326
- showConfirm.value = false
327
- }
328
- </script>
164
+ ### 핵심 원칙: 스타일 없이 동작하는 코드
165
+
166
+ ```
167
+ 클릭/탭/아코디언 인터랙션이 실제로 동작
168
+ ✅ 모달/팝업 open/close가 연결됨
169
+ 리스트 렌더링이 목 데이터로 동작
170
+ 조건부 렌더링이 상태에 따라 전환
171
+ ✅ emit으로 부모-자식 이벤트 연결
172
+ 브라우저에서 열면 스타일은 없지만 인터랙션은 동작하는 상태
329
173
  ```
330
174
 
331
- ## Phase 6: 인터랙션 매핑 테이블
175
+ ## A-6. 인터랙션 매핑 테이블
332
176
 
333
177
  코드 생성 후, 전체 인터랙션을 테이블로 출력:
334
178
 
335
179
  ```markdown
336
- ## 인터랙션 매핑
337
-
338
180
  | 섹션 | ID | 트리거 | 동작 | 컴포넌트 | 함수 |
339
181
  |------|-----|--------|------|---------|------|
340
- | Hero | ① | 공유 클릭 | 공유하기 팝업 | HeroSection | handleShare() |
341
- | 출석 | ① | 출석하기 클릭 | API 호출 → 토큰 지급 | DailyCheckInSection | handleCheckIn() |
342
- | 출석 | ② | 누적 보상 클릭 | 보상 수령 | DailyCheckInSection | handleClaimReward() |
343
- | 교환소 | ① | 교환하기 클릭 | 확인 팝업 → 교환 처리 | TokenExchangeSection | handleExchange() |
344
- | 응모 | ① | 응모하기 클릭 | 응모 처리 → 이메일 수집 | TokenRaffleSection | handleRaffle() |
182
+ | Hero | ① | 클릭 | 공유하기 팝업 | HeroSection | handleShare() |
183
+ | 섹션A | ① | 클릭 | API 호출 | FeatureASection | handleAction() |
345
184
 
346
- → Step B/C에서 코드 생성 시 이 함수들의 body를 구현
185
+ → Step B/C에서 이 함수들의 body를 구현
347
186
  ```
348
187
 
349
- ## Phase 7: Step A 검증 루프
188
+ ## A-7. Step A 검증
189
+
190
+ > **아래 검증을 도구로 실제 실행해야 함.**
350
191
 
351
- > **⛔ 아래 조건을 모두 만족해야 Step B로 진행. 하나라도 실패 시 수정 후 재검증.**
192
+ ### 검증 항목
352
193
 
353
194
  ```
354
- 🔄 검증 체크리스트:
355
-
356
- 1. 파일 생성 완료 확인:
357
- 루트 페이지 파일 존재 (pages/{feature}.vue)
358
- PAGE 프레임 수 = 생성된 섹션 컴포넌트 (1개도 빠짐 없음)
359
- 팝업 컴포넌트 생성됨 (스토리보드에 팝업이 있으면)
360
- □ 스타일 디렉토리 생성됨 (styles/{feature}/)
361
-
362
- 2. 코드 품질 확인 (각 컴포넌트 Read로 확인):
363
- 모든 컴포넌트에 기능 정의 JSDoc 주석 있음
364
- □ v-for 리스트에 목 데이터 채워짐 (빈 배열 없음)
365
- 이벤트 핸들러 함수 정의됨 (handleXxx)
366
- TypeScript 인터페이스 정의됨
367
- 팝업 open/close가 v-if + ref로 연결됨
368
-
369
- 3. 빌드 확인:
370
- 프로젝트 빌드 에러 없음 (Bash: npm run build 또는 nuxt build)
371
-
372
- 실패 항목 → Edit으로 수정 → 재검증 (횟수 제한 없음)
373
- 동일 항목 3회 연속 실패 → 사용자에게 확인 계속
195
+ 1. 파일 존재 확인 (Glob 도구):
196
+ □ 루트 페이지 파일 존재
197
+ PAGE 프레임 = 컴포넌트 파일 수
198
+ styles 디렉토리 존재
199
+ 팝업 컴포넌트 존재 (스토리보드에 팝업이 있었으면)
200
+ 누락 Write로 생성
201
+
202
+ 2. 기능 주석 확인 (Read 도구):
203
+ 모든 컴포넌트에 [기능 정의] + [인터랙션] + [상태] JSDoc
204
+ 누락 Edit으로 추가
205
+
206
+ 3. 데이터 확인 (Grep 도구):
207
+ 배열 (ref([]) 패턴) 검색 → 0건
208
+ 발견 데이터 채움
209
+
210
+ 4. 스타일 분리 확인 (Grep 도구):
211
+ 컴포넌트 <style> 블록 0건
212
+ → 발견 시 제거
213
+
214
+ 5. 빌드 확인 (Bash 도구):
215
+ □ npm run build 성공
216
+ → 에러 시 수정 후 재빌드
374
217
  ```
375
218
 
376
- ## 출력 요약
219
+ ### 완료 조건
377
220
 
378
221
  ```
379
- 루트 페이지 (실제 레이아웃 + 섹션 배치 + 팝업 조건부 렌더링)
380
- 섹션 컴포넌트 (구조 코드 + 기능 주석 + 이벤트 핸들러 + TypeScript 인터페이스)
381
- 공통 컴포넌트 (GNB, Footer, Popup — 기존 재사용 또는 신규)
382
- 인터랙션 매핑 테이블
383
- ✅ 목 데이터 채워짐 (빈 배열 없음)
222
+ 파일 = PAGE 프레임
223
+ 모든 JSDoc 주석 완비
224
+ 배열 0개
225
+ <style> 블록 0개
384
226
  ✅ 빌드 성공
385
- ✅ 스타일은 빈 블록 → Step B에서 디자인 URL 받고 채움
386
- ✅ 이미지는 placeholder → Step B에서 다운로드 후 교체
387
227
  → Step B 진행 가능
388
228
  ```