@designfever/web-review-kit 0.1.0

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.
@@ -0,0 +1,267 @@
1
+ # Review feedback 2026-06-20
2
+
3
+ `packages/df-web-review-kit`를 독립 package로 분리하기 전에 확인할 리뷰 메모다.
4
+
5
+ 검토자:
6
+
7
+ - 빵빵: package source와 host wiring typecheck 확인
8
+ - 팡팡: 기능 버그와 adapter edge case 리뷰
9
+ - 오빵: package 경계, 구조, concept 방향 리뷰
10
+
11
+ ## 결론
12
+
13
+ 컨셉은 유지할 만하다. 차별점은 browser extension이나 외부 SaaS가 아니라 host project 안에 `/review` shell을 심어서 route, viewport, DOM anchor, style context를 그대로 쓰는 점이다.
14
+
15
+ 다만 0.1 안정성은 `anchor restore` 신뢰도에 걸려 있다. DOM anchor가 흔들리면 이 package는 좌표 메모장 수준으로 내려간다.
16
+
17
+ ## High priority
18
+
19
+ ### 1. DOM anchor restore 조건 수정
20
+
21
+ 파일:
22
+
23
+ ```txt
24
+ src/react-shell/anchor-restore.ts
25
+ ```
26
+
27
+ 현재 문제:
28
+
29
+ ```ts
30
+ if (!anchor || item.scope !== 'dom') return undefined;
31
+ ```
32
+
33
+ element mode로 만든 item은 `anchor`와 `selection`을 가지지만, `scope`는 `mobile`, `tablet`, `desktop`, `wide` 같은 viewport preset으로 저장된다. 그래서 restore 시 anchor 기반 scroll 복원이 early return으로 막힐 수 있다.
34
+
35
+ 판정 기준은 shell의 `isDomReviewItem`과 맞춰야 한다.
36
+
37
+ 권장 방향:
38
+
39
+ ```ts
40
+ const isAnchorRestorable =
41
+ item.scope === 'dom' ||
42
+ (item.kind === 'note' && Boolean(item.anchor && item.selection));
43
+
44
+ if (!anchor || !isAnchorRestorable) return undefined;
45
+ ```
46
+
47
+ 검증:
48
+
49
+ - element mode로 QA 생성
50
+ - scroll 이동 후 item 클릭
51
+ - 원래 DOM element 기준으로 scroll restore 되는지 확인
52
+ - viewport를 바꿔도 selector candidate가 같은 element를 찾는지 확인
53
+
54
+ ### 2. Supabase review number fallback 정책 정리
55
+
56
+ 파일:
57
+
58
+ ```txt
59
+ src/adapters/supabase.ts
60
+ ```
61
+
62
+ 현재 fallback:
63
+
64
+ ```ts
65
+ const reviewNumber = await getNextReviewNumber(...);
66
+ await fromTable().insert(row).select('*').single();
67
+ ```
68
+
69
+ `SELECT max(review_number)`와 `INSERT` 사이에 gap이 있어서 동시 생성 시 unique conflict가 날 수 있다. retry는 있지만 fallback 이름이 `unsafeClientReviewNumberFallback`이라 운영 경로가 아니란 뜻은 전달된다.
70
+
71
+ 권장 방향:
72
+
73
+ - default는 지금처럼 RPC 유지
74
+ - client fallback은 문서상 dev/test only로 못 박기
75
+ - 이름은 유지해도 되지만, "optimistic retry fallback" 성격을 docs에 명시
76
+ - package 외부 공개 시 fallback option을 숨기거나 experimental로 내리기
77
+
78
+ 검증:
79
+
80
+ - concurrent create 2개 이상이 서로 다른 remote `reviewNumber`를 받는지 확인
81
+ - 삭제 후 다음 번호가 재사용되지 않는지 확인
82
+
83
+ ### 3. Shell adapter update 분기 단순화
84
+
85
+ 파일:
86
+
87
+ ```txt
88
+ src/react-shell/adapters.ts
89
+ ```
90
+
91
+ 현재 문제:
92
+
93
+ - `patch.status`가 있고 `updateStatus`가 있으면 status 전용 path를 탄다.
94
+ - `updateStatus`가 없으면 `syncSubmission`으로 generic patch를 보내는 구조다.
95
+ - status patch와 submission patch가 같은 `update` method 안에서 섞여 있어, adapter capability가 늘어날수록 디버깅이 어려워진다.
96
+
97
+ 권장 방향:
98
+
99
+ - shell UI에서 status 변경은 `activeAdapterEntry.updateStatus`만 직접 호출한다.
100
+ - `adapter.update` wrapper는 submission sync 같은 generic patch만 담당한다.
101
+ - remote adapter가 generic update를 지원해야 하면 `syncSubmission`보다 `updateItem` 같은 명시적 이름을 검토한다.
102
+
103
+ 검증:
104
+
105
+ - local status dropdown 변경
106
+ - remote status dropdown 변경
107
+ - local item remote 등록 실패 후 `submitStatus: failed` 저장
108
+
109
+ ### 4. Submit success 후 UI refresh 흐름 확인
110
+
111
+ 파일:
112
+
113
+ ```txt
114
+ src/react-shell.tsx
115
+ ```
116
+
117
+ 현재 flow:
118
+
119
+ ```ts
120
+ await remoteAdapterEntry.adapter.create(...);
121
+ await localAdapterEntry.adapter.remove(item.id);
122
+ await refreshReviewData();
123
+ ```
124
+
125
+ 성공 후 local draft를 바로 삭제하므로, remote list 반영 타이밍이 늦으면 UI에서 item이 잠깐 사라질 수 있다.
126
+
127
+ 권장 방향:
128
+
129
+ - `remote.create`의 반환 item을 받아서 remote source로 즉시 이동하거나
130
+ - 성공 직후 selected item을 clear하면서 "remote 등록됨" state를 명확히 보여주거나
131
+ - refresh 순서를 local remove와 분리해 깜빡임을 줄인다.
132
+
133
+ 검증:
134
+
135
+ - local item 생성
136
+ - remote 등록 클릭
137
+ - 등록 직후 list/sitemap count가 어색하게 튀지 않는지 확인
138
+ - network delay가 있을 때도 local item이 실패/성공 상태를 분명히 보여주는지 확인
139
+
140
+ ## Medium priority
141
+
142
+ ### 5. `getItemSelection` normalize 책임 정리
143
+
144
+ 파일:
145
+
146
+ ```txt
147
+ src/core/web-review-kit-app.ts
148
+ ```
149
+
150
+ 현재는 legacy `RelativeSelection`과 현재 `ReviewSelection`을 core에서 즉석 판정한다. local adapter에도 migration/normalize가 있어 책임이 분산돼 있다.
151
+
152
+ 권장 방향:
153
+
154
+ - `normalizeReviewSelection(value)` helper를 core 또는 shared module로 분리
155
+ - adapter migration과 render/restore path가 같은 helper를 쓰게 정리
156
+
157
+ ### 6. Local presence fallback 문서화
158
+
159
+ 파일:
160
+
161
+ ```txt
162
+ src/react-shell/presence.ts
163
+ ```
164
+
165
+ `BroadcastChannel`이 없으면 local presence는 현재 tab 내부 상태만 가진다. 이건 큰 버그는 아니지만, fallback 동작으로 문서화해야 한다.
166
+
167
+ 권장 문구:
168
+
169
+ - `BroadcastChannel` available: same-origin tab/window 간 공유
170
+ - unavailable: current tab only
171
+ - Supabase presence 실패 시 local fallback으로 degrade
172
+
173
+ ## Package split
174
+
175
+ 현재 package 경계는 나쁘지 않다.
176
+
177
+ - host hardcoding은 거의 없다.
178
+ - `core/adapters`는 React에 의존하지 않는다.
179
+ - Supabase adapter는 `@supabase/supabase-js`를 직접 import하지 않고 client interface를 주입받는다.
180
+ - host project wiring은 `/review` route에서만 담당한다.
181
+
182
+ 분리 전 체크:
183
+
184
+ - `private: true` 제거 여부 결정
185
+ - package name/scope 확정
186
+ - `files`에 `src`, `dist`, `docs`를 모두 넣을지 결정
187
+ - `react`, `react-dom`은 peerDependency 유지
188
+ - `lucide-react`는 peer로 둘지 bundle할지 결정
189
+ - export map에서 `.`와 `./react-shell` 유지
190
+ - root project에서 `pnpm install --frozen-lockfile --ignore-scripts` 후 typecheck 통과 확인
191
+
192
+ 확인된 사항:
193
+
194
+ ```txt
195
+ pnpm --dir packages/df-web-review-kit typecheck
196
+ pnpm exec tsc --noEmit
197
+ ```
198
+
199
+ 둘 다 통과한다. 단, pull 직후 stale `node_modules` 상태에서는 새 export를 못 볼 수 있으므로 install이 필요했다.
200
+
201
+ ## Structure debt
202
+
203
+ 독립 package로 공개하기 전에 가장 큰 구조 문제는 파일 크기다.
204
+
205
+ - `src/react-shell.tsx`: shell UI가 한 파일에 몰려 있다.
206
+ - `src/core/web-review-kit-app.ts`: overlay core가 한 파일에 크다.
207
+ - `src/react-shell/style.ts`: CSS string이 크다.
208
+ - `src/core/overlay-style.ts`: overlay CSS string이 크다.
209
+
210
+ 우선 분리 후보:
211
+
212
+ - `react-shell/Topbar`
213
+ - `react-shell/SitemapModal`
214
+ - `react-shell/SettingsModal`
215
+ - `react-shell/PromptModal`
216
+ - `react-shell/ItemList`
217
+ - `react-shell/ViewportStage`
218
+ - `react-shell/RulerOverlay`
219
+
220
+ 목표는 추상화가 아니라 리뷰 가능한 단위로 쪼개는 것이다.
221
+
222
+ ## Product direction
223
+
224
+ ### 0.1 focus
225
+
226
+ 0.1은 "QA issue capture and restore"에 집중한다.
227
+
228
+ 필수:
229
+
230
+ - local draft 생성
231
+ - remote source 등록
232
+ - canonical remote number
233
+ - page/viewport/source deep link
234
+ - DOM anchor restore
235
+ - prompt copy
236
+
237
+ 보류 또는 optional:
238
+
239
+ - screenshot upload
240
+ - full collaboration presence
241
+ - source code edit automation
242
+
243
+ Presence는 있으면 좋지만, 0.1의 핵심 가치는 아니다. anchor restore 안정화가 우선이다.
244
+
245
+ ### Visual editing idea
246
+
247
+ 마진, 폰트, spacing 같은 값을 review shell에서 임시 조정하고 저장하는 방향은 가능하다. 다만 이건 두 층으로 나눠야 한다.
248
+
249
+ 1층: override and proposal
250
+
251
+ - 브라우저에서 element style을 임시 조정한다.
252
+ - 저장하면 review item에 before/after value가 구조화 데이터로 붙는다.
253
+ - AI 없이도 review-kit scope 안에서 자연스럽다.
254
+
255
+ 2층: source patch suggestion
256
+
257
+ - 실제 source 수정은 별도 AI/codegen adapter가 맡는다.
258
+ - review-kit은 `anchor`, `DOM path`, `source hint`, `before/after`를 넘긴다.
259
+ - AI는 "어느 컴포넌트의 어느 token/style을 바꿀지" diff나 PR 제안을 만든다.
260
+ - 사람이 확인하고 merge한다.
261
+
262
+ 중요한 경계:
263
+
264
+ - review-kit core는 "제안 생산"까지 담당한다.
265
+ - 실제 source 반영은 package core 밖 adapter 또는 별도 package로 둔다.
266
+
267
+ 이 경계를 지키면 review-kit이 issue editor나 visual builder로 비대해지는 걸 막을 수 있다.
@@ -0,0 +1,41 @@
1
+ # Smoke baseline 2026-06-20
2
+
3
+ Scope: `packages/df-web-review-kit` task 761, before UI token/chrome changes.
4
+
5
+ Environment:
6
+
7
+ - Branch: `uforgot/feat/review-kit-stabilize-ui`
8
+ - Dev URL: `http://127.0.0.1:5181/review/?target=%2F&w=540&h=1080`
9
+ - Timestamp: `2026-06-20 11:31:21 KST`
10
+ - `.env`: Supabase URL, anon key, table, presence-private flags were present. Secret values were not logged.
11
+
12
+ Commands:
13
+
14
+ ```bash
15
+ pnpm review-kit:build
16
+ pnpm exec vite --host 127.0.0.1 --port 5181 --strictPort
17
+ ```
18
+
19
+ Checklist result:
20
+
21
+ | Check | Result | Note |
22
+ | --- | --- | --- |
23
+ | Local note create | Pass | Created `smoke-761 local note` from review shell UI. |
24
+ | Local element QA create | Pass | Created `smoke-761 local element`; item had `anchor` and `selection`. |
25
+ | Local area QA create | Pass* | CDP drag event was unreliable for the area drawer, so a synthetic area item was inserted through the same local storage shape to validate listing/rendering baseline. Manual browser drag still needs a quick human pass if this becomes a regression point. |
26
+ | Item restore after scroll | Pass | Stable lower-page item restored from `scrollY 0` to `6487`, target top `517`. |
27
+ | Remote submit to Supabase | Pass | Local item submitted; remote source showed canonical `#10`. |
28
+ | Remote source list | Pass | `source=supabase` listed the smoke item plus existing remote items. |
29
+ | Remote status change | Pass | Status changed from `todo` to `doing` and persisted after refresh. |
30
+ | Remote delete | Pass | Smoke item deleted from Supabase; no longer present after refresh. |
31
+ | `/review?source=supabase&target=...&item=...` restore | Pass | Remote item URL restored to the lower-page anchor before deletion: `/review/?target=%2F&w=540&h=1080&source=supabase&item=852662d1-410a-46b9-b047-b0abba55e83f`. |
32
+
33
+ Cleanup:
34
+
35
+ - Deleted the remote smoke item from Supabase.
36
+ - Removed local `smoke-761` items from localStorage.
37
+
38
+ Notes:
39
+
40
+ - Figma overlay loaded because the local token was available; this was not part of the 761 smoke scope.
41
+ - The area creation interaction should be manually spot-checked once UI chrome work starts, because automated pointer drag did not open the area note drawer reliably in CDP.
@@ -0,0 +1,243 @@
1
+ # Stabilize UI work guide
2
+
3
+ Branch:
4
+
5
+ ```txt
6
+ uforgot/feat/review-kit-stabilize-ui
7
+ ```
8
+
9
+ Purpose:
10
+
11
+ `df-web-review-kit`를 package로 분리하기 전에 0.1 기반을 안정화하고, review shell chrome을 token 기반 UI로 정리한다.
12
+
13
+ ## Scope
14
+
15
+ In scope:
16
+
17
+ - Fix DOM anchor restore bug.
18
+ - Establish smoke test baseline for current review workflow.
19
+ - Introduce `df-review-token` layer inspired by Vercel Geist tokens.
20
+ - Apply tokenized UI to review shell chrome.
21
+ - Split only the React shell parts that block the UI cleanup.
22
+ - Prepare package split checklist.
23
+
24
+ Out of scope:
25
+
26
+ - Figma overlay module migration.
27
+ - Editing proposal feature.
28
+ - Source patch AI adapter.
29
+ - Full rewrite of `react-shell.tsx`.
30
+
31
+ Follow-up branches:
32
+
33
+ ```txt
34
+ uforgot/feat/review-kit-figma-module
35
+ uforgot/feat/review-kit-editing-proposal
36
+ ```
37
+
38
+ ## Work order
39
+
40
+ ### 0. Fix anchor restore
41
+
42
+ Files:
43
+
44
+ ```txt
45
+ src/react-shell/anchor-restore.ts
46
+ src/core/web-review-kit-app.ts
47
+ ```
48
+
49
+ Goal:
50
+
51
+ Element-mode review items must restore by DOM anchor even when their `scope` is a viewport scope such as `mobile` or `desktop`.
52
+
53
+ Context:
54
+
55
+ Current `queryReviewItemAnchorElement` exits unless `item.scope === 'dom'`, but element-mode items can be stored as `kind: note` with `anchor + selection` and viewport scope.
56
+
57
+ Deliverable:
58
+
59
+ - Shared or local predicate that treats `scope === 'dom'` or `kind === 'note' && anchor && selection` as anchor-restorable.
60
+ - Anchor restore path uses that predicate.
61
+
62
+ Verification:
63
+
64
+ - Create an element-mode QA item.
65
+ - Scroll away.
66
+ - Click the item in the QA list.
67
+ - The target element is restored by selector/anchor, not only by stale coordinates.
68
+
69
+ ### 1. Capture smoke baseline
70
+
71
+ Goal:
72
+
73
+ Before UI changes, confirm the current workflow still works.
74
+
75
+ Deliverable:
76
+
77
+ - Manual smoke checklist result in the PR/commit notes or a short docs note.
78
+
79
+ Verification checklist:
80
+
81
+ - Local note create.
82
+ - Local element QA create.
83
+ - Local area QA create.
84
+ - Item restore after scroll.
85
+ - Remote submit to Supabase.
86
+ - Remote source list.
87
+ - Remote status change.
88
+ - Remote delete.
89
+ - `/review?source=supabase&target=...&item=...` restore.
90
+
91
+ ### 2. Add review token layer
92
+
93
+ Files:
94
+
95
+ ```txt
96
+ src/react-shell/style.ts
97
+ src/core/overlay-style.ts
98
+ ```
99
+
100
+ Goal:
101
+
102
+ Adopt a developer-tool UI tone using Vercel Geist as reference, without depending on Vercel token names at runtime.
103
+
104
+ Rules:
105
+
106
+ - Use `df-review-token` or `--df-review-*` naming.
107
+ - Do not expose `geist` or `vercel` as public API names.
108
+ - Keep light/dark theme support.
109
+ - Use neutral surfaces, restrained color, clear state colors.
110
+ - Do not change target page styling.
111
+
112
+ Deliverable:
113
+
114
+ - CSS custom properties for color, spacing, radius, typography, shadow/border.
115
+ - Existing chrome components consume those variables.
116
+
117
+ Verification:
118
+
119
+ - Dark and light themes render correctly.
120
+ - Buttons, selects, cards, modals, and overlay controls keep usable contrast.
121
+ - Target iframe content is not affected.
122
+
123
+ ### 3. Apply UI chrome refresh
124
+
125
+ Files:
126
+
127
+ ```txt
128
+ src/react-shell.tsx
129
+ src/react-shell/style.ts
130
+ src/core/overlay-style.ts
131
+ ```
132
+
133
+ Goal:
134
+
135
+ Refresh only the review tool UI, not the host website UI.
136
+
137
+ Targets:
138
+
139
+ - Topbar.
140
+ - Path input and load/copy buttons.
141
+ - Source select and refresh button.
142
+ - Viewport preset buttons.
143
+ - Grid, Figma, ruler, settings controls.
144
+ - QA cards.
145
+ - Prompt/settings/sitemap modals.
146
+
147
+ Deliverable:
148
+
149
+ - More consistent developer-tool chrome.
150
+ - Icon buttons stay compact.
151
+ - Text does not overflow in compact panels.
152
+
153
+ Verification:
154
+
155
+ - Mobile, tablet, desktop, wide review presets.
156
+ - QA list open/closed states.
157
+ - Empty state and filtered state.
158
+ - Prompt/settings/sitemap modals.
159
+
160
+ ### 4. Split only blocking React shell parts
161
+
162
+ Goal:
163
+
164
+ Reduce `react-shell.tsx` risk without turning this branch into a rewrite.
165
+
166
+ Allowed splits:
167
+
168
+ - `Topbar`.
169
+ - `ItemList`.
170
+ - `SettingsModal`.
171
+ - `PromptModal`.
172
+ - `SitemapModal`.
173
+
174
+ Rules:
175
+
176
+ - Split only when the UI token work becomes hard to review in one file.
177
+ - Keep behavior unchanged.
178
+ - Avoid new state architecture in this branch.
179
+
180
+ Deliverable:
181
+
182
+ - Smaller reviewable components if needed.
183
+ - No broad refactor.
184
+
185
+ Verification:
186
+
187
+ - Typecheck passes.
188
+ - Existing interactions still work.
189
+
190
+ ### 5. Package split checkpoint
191
+
192
+ Goal:
193
+
194
+ Make the package ready to split after this branch, before Figma module migration.
195
+
196
+ Checklist:
197
+
198
+ - `package.json` export map is accurate.
199
+ - `files` list is intentional.
200
+ - `react` and `react-dom` stay peer dependencies.
201
+ - Decide whether `lucide-react` is peer or bundled.
202
+ - `src`, `dist`, and `docs` publishing policy is explicit.
203
+ - Host project consumes the package through the same exported API.
204
+
205
+ Deliverable:
206
+
207
+ - Short package split note or checklist update.
208
+
209
+ Verification:
210
+
211
+ ```bash
212
+ pnpm --dir packages/df-web-review-kit typecheck
213
+ pnpm exec tsc --noEmit
214
+ pnpm review-kit:build
215
+ ```
216
+
217
+ ## Figma module boundary for next branch
218
+
219
+ Figma overlay migration should start only after this branch is stable.
220
+
221
+ Boundary:
222
+
223
+ - Package core renders overlay.
224
+ - Host provides image URL/blob or a Figma asset adapter.
225
+ - Browser-exposed Figma token and Figma REST fetch do not enter package core.
226
+ - Current viewport replaces host zustand `isMobile/clientWidth` dependency.
227
+
228
+ Expected next branch:
229
+
230
+ ```txt
231
+ uforgot/feat/review-kit-figma-module
232
+ ```
233
+
234
+ ## Completion criteria
235
+
236
+ This branch is ready for review when:
237
+
238
+ - Anchor restore bug is fixed.
239
+ - Smoke baseline is documented.
240
+ - UI token layer is in place.
241
+ - Review shell chrome is visually consistent.
242
+ - Typecheck and build pass.
243
+ - Figma migration remains out of scope.