@su-record/vibe 2.8.17 → 2.8.19
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/dist/infra/lib/config/GlobalConfigManager.d.ts +8 -0
- package/dist/infra/lib/config/GlobalConfigManager.d.ts.map +1 -1
- package/dist/infra/lib/config/GlobalConfigManager.js +37 -0
- package/dist/infra/lib/config/GlobalConfigManager.js.map +1 -1
- package/hooks/scripts/context-save.js +88 -1
- package/hooks/scripts/pre-tool-guard.js +30 -5
- package/hooks/scripts/sentinel-guard.js +28 -4
- package/hooks/scripts/utils.js +48 -0
- package/package.json +1 -1
- package/skills/vibe-figma/SKILL.md +25 -66
- package/skills/vibe-figma-analyze/SKILL.md +95 -318
- package/skills/vibe-figma-codegen/SKILL.md +112 -782
- package/skills/vibe-figma-consolidate/SKILL.md +53 -90
- package/skills/vibe-figma-frame/SKILL.md +454 -181
- package/skills/vibe-figma-pipeline/SKILL.md +4 -45
- package/skills/vibe-figma-rules/SKILL.md +363 -159
- package/skills/vibe-figma-style/SKILL.md +107 -476
|
@@ -10,22 +10,19 @@ triggers: []
|
|
|
10
10
|
스토리보드 URL 하나로 **실제 동작하는 레이아웃 코드**를 생성.
|
|
11
11
|
빈 shell이 아니라, 스토리보드에서 파악 가능한 모든 정보를 코드에 반영.
|
|
12
12
|
|
|
13
|
-
>
|
|
14
|
-
>
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
-
|
|
46
|
+
- 일정: 시작/종료 시간, 단계별 기간
|
|
50
47
|
|
|
51
48
|
추출한 텍스트를 섹션별로 분리:
|
|
52
49
|
{
|
|
53
|
-
"overview": "
|
|
50
|
+
"overview": "...",
|
|
54
51
|
"sections": {
|
|
55
|
-
"hero": "키 비주얼 영역,
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"tokenExchange": "스노우 토큰으로 아이템 교환...",
|
|
59
|
-
"tokenRaffle": "스노우 토큰으로 상품 응모..."
|
|
52
|
+
"hero": "키 비주얼 영역, CTA 버튼...",
|
|
53
|
+
"featureA": "섹션 A 기능 설명...",
|
|
54
|
+
"featureB": "섹션 B 기능 설명..."
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
57
|
|
|
63
|
-
→
|
|
58
|
+
→ A-5에서 각 컴포넌트의 기능 주석이 됨
|
|
64
59
|
```
|
|
65
60
|
|
|
66
|
-
##
|
|
61
|
+
## A-3. SHARED 프레임 분석
|
|
67
62
|
|
|
68
63
|
공통 요소 프레임들의 get_screenshot으로 구조 파악:
|
|
69
64
|
|
|
70
65
|
```
|
|
71
|
-
GNB: 네비게이션 구조, 메뉴 항목,
|
|
72
|
-
Footer:
|
|
66
|
+
GNB: 네비게이션 구조, 메뉴 항목, 로그인 버튼
|
|
67
|
+
Footer: 링크, 법적 고지
|
|
73
68
|
Popup: 패턴 분류 (확인/취소, 상세 모달, 알림, 입력 폼)
|
|
74
|
-
Error: 에러 페이지 구조
|
|
75
69
|
|
|
76
70
|
→ 프로젝트에 이미 있는 컴포넌트 확인 (Glob으로 탐색)
|
|
77
71
|
→ 있으면 import 재사용, 없으면 새로 생성
|
|
78
72
|
```
|
|
79
73
|
|
|
80
|
-
##
|
|
74
|
+
## A-4. PAGE 프레임 세밀 분석
|
|
81
75
|
|
|
82
|
-
>
|
|
83
|
-
>
|
|
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,365 +85,149 @@ 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. 상태 변형 (서브 프레임
|
|
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", "
|
|
101
|
+
children: ["Title", "Description", "Grid", "CTAButton"],
|
|
110
102
|
interactions: [
|
|
111
|
-
{ id: "①", trigger: "클릭", action: "
|
|
103
|
+
{ id: "①", trigger: "클릭", action: "처리", result: "결과 표시" }
|
|
112
104
|
],
|
|
113
|
-
states: ["default", "
|
|
105
|
+
states: ["default", "active", "completed"],
|
|
114
106
|
popups: ["ConfirmDialog"]
|
|
115
107
|
}
|
|
116
108
|
```
|
|
117
109
|
|
|
118
|
-
##
|
|
110
|
+
## A-5. 파일 생성 (Write 도구 사용 — 필수)
|
|
119
111
|
|
|
120
|
-
>
|
|
112
|
+
> **Write 도구로 아래 파일들을 실제로 생성한다. 코드를 보여주기만 하면 안 됨.**
|
|
121
113
|
|
|
122
|
-
|
|
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
|
|
130
|
-
2. components/{feature-name}/각섹션.vue
|
|
131
|
-
3. components/{feature-name}/popups
|
|
132
|
-
4. styles/{feature-name}/index.scss
|
|
133
|
-
5. styles/{feature-name}/_tokens.scss
|
|
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
|
+
|
|
174
129
|
```
|
|
130
|
+
- 모든 섹션 컴포넌트 import
|
|
131
|
+
- 팝업 조건부 렌더링 (v-if/&&)
|
|
132
|
+
- 개요 JSDoc 주석 (A-2에서 추출한 overview)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 섹션 컴포넌트 필수 포함 사항
|
|
175
136
|
|
|
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> 블록을 컴포넌트에 넣지 않는다 -->
|
|
262
|
-
<!-- 스타일은 외부 파일에서 관리: styles/{feature}/layout/, components/ -->
|
|
263
|
-
</script>
|
|
264
137
|
```
|
|
138
|
+
각 섹션 컴포넌트에 반드시 포함:
|
|
265
139
|
|
|
266
|
-
|
|
140
|
+
1. JSDoc 주석:
|
|
141
|
+
- [기능 정의] — A-2에서 추출한 기능 설명
|
|
142
|
+
- [인터랙션] — ①②③ 번호 + 동작 설명
|
|
143
|
+
- [상태] — 해당 섹션의 상태 목록
|
|
267
144
|
|
|
145
|
+
2. TypeScript 인터페이스:
|
|
146
|
+
- 섹션에서 사용하는 데이터 구조 정의
|
|
147
|
+
|
|
148
|
+
3. 이벤트 핸들러:
|
|
149
|
+
- 인터랙션 스펙에 맞는 함수 (body는 // TODO:)
|
|
150
|
+
|
|
151
|
+
4. 목 데이터 (빈 배열 금지):
|
|
152
|
+
- 기능 정의서에서 추출한 아이템/보상/상품 정보로 채움
|
|
153
|
+
- 빈 배열 = UI가 안 보임 = Step A 미완성
|
|
268
154
|
```
|
|
269
|
-
Step A에서 컴포넌트 파일에 <style> 블록을 작성하지 않는다.
|
|
270
|
-
스타일은 Step B에서 외부 파일로 생성:
|
|
271
|
-
--new 모드: styles/{feature}/layout/_daily-checkin.scss
|
|
272
|
-
기본 모드: 기존 프로젝트 스타일 패턴을 따름
|
|
273
155
|
|
|
274
|
-
|
|
275
|
-
|
|
156
|
+
### 스타일 분리 규칙
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
컴포넌트 파일에 <style> 블록을 작성하지 않는다.
|
|
160
|
+
스타일은 Step B에서 외부 파일로 생성.
|
|
161
|
+
컴포넌트는 template + script 만 포함.
|
|
276
162
|
```
|
|
277
163
|
|
|
278
164
|
### 핵심 원칙: 스타일 없이 동작하는 코드
|
|
279
165
|
|
|
280
166
|
```
|
|
281
|
-
✅
|
|
282
|
-
✅
|
|
283
|
-
✅
|
|
284
|
-
✅
|
|
285
|
-
✅ emit으로 부모-자식
|
|
286
|
-
|
|
287
|
-
✅ 조건부 렌더링 (v-if)이 상태에 따라 전환됨
|
|
288
|
-
|
|
289
|
-
⚠️ 목 데이터 필수:
|
|
290
|
-
스토리보드 기능 정의서에서 아이템/보상/상품 정보를 추출하여 목 데이터로 사용.
|
|
291
|
-
빈 배열 = UI가 안 보임 = Step A 미완성.
|
|
292
|
-
예:
|
|
293
|
-
exchangeItems = [
|
|
294
|
-
{ id: 1, name: '스노우 토큰 100', cost: 100, image: '' },
|
|
295
|
-
{ id: 2, name: '스노우 토큰 500', cost: 500, image: '' },
|
|
296
|
-
]
|
|
297
|
-
raffleItems = [
|
|
298
|
-
{ id: 1, name: '1주차 경품', prize: 'PlayStation 5', entries: 0 },
|
|
299
|
-
]
|
|
300
|
-
|
|
301
|
-
→ 브라우저에서 열면 스타일은 없지만 클릭/인터랙션은 동작하는 상태
|
|
302
|
-
|
|
303
|
-
✅ 기능 정의서 내용 → 컴포넌트 JSDoc 주석
|
|
304
|
-
✅ 인터랙션 스펙 → 이벤트 핸들러 함수 (API 호출은 TODO)
|
|
305
|
-
✅ 상태 목록 → TypeScript 인터페이스 + ref + 더미 데이터
|
|
306
|
-
✅ 스타일은 빈 블록 → Step B에서 채움
|
|
307
|
-
✅ 이미지는 placeholder → Step B에서 교체
|
|
308
|
-
```
|
|
167
|
+
✅ 클릭/탭/아코디언 등 인터랙션이 실제로 동작
|
|
168
|
+
✅ 모달/팝업 open/close가 연결됨
|
|
169
|
+
✅ 리스트 렌더링이 목 데이터로 동작
|
|
170
|
+
✅ 조건부 렌더링이 상태에 따라 전환
|
|
171
|
+
✅ emit으로 부모-자식 이벤트 연결
|
|
172
|
+
→ 브라우저에서 열면 스타일은 없지만 인터랙션은 동작하는 상태
|
|
309
173
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
<template>
|
|
315
|
-
<!-- 트리거 버튼 -->
|
|
316
|
-
<button @click="showConfirm = true">교환하기</button>
|
|
317
|
-
|
|
318
|
-
<!-- 모달 — v-if로 제어, 실제 동작 -->
|
|
319
|
-
<Teleport to="body">
|
|
320
|
-
<div v-if="showConfirm" class="modalOverlay" @click.self="showConfirm = false">
|
|
321
|
-
<div class="modalContent">
|
|
322
|
-
<p>정말 교환하시겠습니까?</p>
|
|
323
|
-
<button @click="handleConfirm">확인</button>
|
|
324
|
-
<button @click="showConfirm = false">취소</button>
|
|
325
|
-
</div>
|
|
326
|
-
</div>
|
|
327
|
-
</Teleport>
|
|
328
|
-
</template>
|
|
329
|
-
|
|
330
|
-
<script setup lang="ts">
|
|
331
|
-
const showConfirm = ref(false)
|
|
332
|
-
|
|
333
|
-
function handleConfirm(): void {
|
|
334
|
-
// TODO: 교환 API 호출
|
|
335
|
-
showConfirm.value = false
|
|
336
|
-
}
|
|
337
|
-
</script>
|
|
174
|
+
Step A에서는 이미지 자리에 빈 영역이 있을 수 있다.
|
|
175
|
+
→ Step B에서 반드시 실제 이미지로 교체해야 함.
|
|
176
|
+
→ Step B 완료 후 "placeholder", "Key Visual Image", 빈 dashed box가
|
|
177
|
+
코드에 남아있으면 = 미완성 (vibe-figma-frame HARD RULES 참조)
|
|
338
178
|
```
|
|
339
179
|
|
|
340
|
-
##
|
|
180
|
+
## A-6. 인터랙션 매핑 테이블
|
|
341
181
|
|
|
342
182
|
코드 생성 후, 전체 인터랙션을 테이블로 출력:
|
|
343
183
|
|
|
344
184
|
```markdown
|
|
345
|
-
## 인터랙션 매핑
|
|
346
|
-
|
|
347
185
|
| 섹션 | ID | 트리거 | 동작 | 컴포넌트 | 함수 |
|
|
348
186
|
|------|-----|--------|------|---------|------|
|
|
349
|
-
| Hero | ① |
|
|
350
|
-
|
|
|
351
|
-
| 출석 | ② | 누적 보상 클릭 | 보상 수령 | DailyCheckInSection | handleClaimReward() |
|
|
352
|
-
| 교환소 | ① | 교환하기 클릭 | 확인 팝업 → 교환 처리 | TokenExchangeSection | handleExchange() |
|
|
353
|
-
| 응모 | ① | 응모하기 클릭 | 응모 처리 → 이메일 수집 | TokenRaffleSection | handleRaffle() |
|
|
187
|
+
| Hero | ① | 클릭 | 공유하기 팝업 | HeroSection | handleShare() |
|
|
188
|
+
| 섹션A | ① | 클릭 | API 호출 | FeatureASection | handleAction() |
|
|
354
189
|
|
|
355
|
-
→ Step B/C에서
|
|
190
|
+
→ Step B/C에서 이 함수들의 body를 구현
|
|
356
191
|
```
|
|
357
192
|
|
|
358
|
-
##
|
|
193
|
+
## A-7. Step A 검증
|
|
359
194
|
|
|
360
|
-
>
|
|
195
|
+
> **아래 검증을 도구로 실제 실행해야 함.**
|
|
361
196
|
|
|
362
|
-
###
|
|
197
|
+
### 검증 항목
|
|
363
198
|
|
|
364
199
|
```
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
□ 루트 페이지 파일 존재
|
|
372
|
-
□ PAGE 프레임 수 = 컴포넌트 .vue 파일 수 (카운트 비교)
|
|
373
|
-
□ styles/{feature}/ 디렉토리 존재
|
|
374
|
-
□ 팝업 컴포넌트 존재 (스토리보드에 팝업이 있었으면)
|
|
375
|
-
|
|
376
|
-
누락 시 → Write로 생성
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### 7-2. 기능 주석 확인 (각 파일 Read 도구로 실제 열기)
|
|
200
|
+
1. 파일 존재 확인 (Glob 도구):
|
|
201
|
+
□ 루트 페이지 파일 존재
|
|
202
|
+
□ PAGE 프레임 수 = 컴포넌트 파일 수
|
|
203
|
+
□ styles 디렉토리 존재
|
|
204
|
+
□ 팝업 컴포넌트 존재 (스토리보드에 팝업이 있었으면)
|
|
205
|
+
→ 누락 시 Write로 생성
|
|
380
206
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
각 파일에서 체크:
|
|
385
|
-
□ JSDoc 주석 블록 존재 (/** ... */)
|
|
386
|
-
□ [기능 정의] 섹션 있음 — 스토리보드 기능 정의서에서 추출한 내용
|
|
387
|
-
□ [인터랙션] 섹션 있음 — ①②③ 번호 + 동작 설명
|
|
388
|
-
□ [상태] 섹션 있음 — 해당 섹션의 상태 목록
|
|
389
|
-
|
|
390
|
-
실제 확인 예시:
|
|
391
|
-
Read: components/{feature}/DailyCheckInSection.vue
|
|
392
|
-
→ /** 블록 검색
|
|
393
|
-
→ "[기능 정의]" 텍스트 존재 확인
|
|
394
|
-
→ "[인터랙션]" 텍스트 존재 확인
|
|
395
|
-
→ "handleCheckIn" 함수 존재 확인
|
|
396
|
-
|
|
397
|
-
하나라도 누락 → Edit으로 추가 → 다시 Read로 재확인
|
|
398
|
-
```
|
|
207
|
+
2. 기능 주석 확인 (Read 도구):
|
|
208
|
+
□ 모든 컴포넌트에 [기능 정의] + [인터랙션] + [상태] JSDoc
|
|
209
|
+
→ 누락 시 Edit으로 추가
|
|
399
210
|
|
|
400
|
-
|
|
211
|
+
3. 목 데이터 확인 (Grep 도구):
|
|
212
|
+
□ 빈 배열 (ref([]) 패턴) 검색 → 0건
|
|
213
|
+
→ 발견 시 목 데이터 채움
|
|
401
214
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
215
|
+
4. 스타일 분리 확인 (Grep 도구):
|
|
216
|
+
□ 컴포넌트 내 <style> 블록 0건
|
|
217
|
+
→ 발견 시 제거
|
|
405
218
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
→ 다시 Grep으로 재확인
|
|
219
|
+
5. 빌드 확인 (Bash 도구):
|
|
220
|
+
□ npm run build 성공
|
|
221
|
+
→ 에러 시 수정 후 재빌드
|
|
410
222
|
```
|
|
411
223
|
|
|
412
|
-
###
|
|
413
|
-
|
|
414
|
-
```
|
|
415
|
-
컴포넌트에 <style> 블록이 없는지 확인:
|
|
416
|
-
Grep: "<style" in components/{feature}/**/*.vue
|
|
417
|
-
|
|
418
|
-
<style> 발견 시:
|
|
419
|
-
→ Edit으로 제거
|
|
420
|
-
→ 해당 스타일을 styles/{feature}/ 외부 파일로 이동
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
### 7-5. 빌드 확인 (Bash 도구)
|
|
424
|
-
|
|
425
|
-
```
|
|
426
|
-
Bash: npm run build (또는 nuxt build, next build)
|
|
427
|
-
→ 에러 있으면 수정 → 재빌드
|
|
428
|
-
→ 성공해야 Step B 진행
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
### 검증 완료 조건
|
|
224
|
+
### 완료 조건
|
|
432
225
|
|
|
433
226
|
```
|
|
434
227
|
✅ 파일 수 = PAGE 프레임 수
|
|
435
|
-
✅ 모든
|
|
228
|
+
✅ 모든 JSDoc 주석 완비
|
|
436
229
|
✅ 빈 배열 0개
|
|
437
|
-
✅
|
|
438
|
-
✅ 빌드 성공
|
|
439
|
-
→ Step B 진행 가능
|
|
440
|
-
|
|
441
|
-
실패 항목 → 수정 → 재검증 (횟수 제한 없음)
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
## 출력 요약
|
|
445
|
-
|
|
446
|
-
```
|
|
447
|
-
✅ 루트 페이지 (실제 레이아웃 + 섹션 배치 + 팝업 조건부 렌더링)
|
|
448
|
-
✅ 각 섹션 컴포넌트 (구조 코드 + 기능 주석 + 이벤트 핸들러 + TypeScript 인터페이스)
|
|
449
|
-
✅ 공통 컴포넌트 (GNB, Footer, Popup — 기존 재사용 또는 신규)
|
|
450
|
-
✅ 인터랙션 매핑 테이블
|
|
451
|
-
✅ 목 데이터 채워짐 (빈 배열 없음)
|
|
230
|
+
✅ <style> 블록 0개
|
|
452
231
|
✅ 빌드 성공
|
|
453
|
-
✅ 스타일은 빈 블록 → Step B에서 디자인 URL 받고 채움
|
|
454
|
-
✅ 이미지는 placeholder → Step B에서 다운로드 후 교체
|
|
455
232
|
→ Step B 진행 가능
|
|
456
233
|
```
|