chore: 제어모드 IDE 작업 + v2/legacy 레지스트리 컴포넌트 폐기
- 제어모드 IDE: ControlCardPanel, control/ide/* (Canvas/LeftRail/RightRail/PanZoomStage/V3RuleNode 등), schemas, lib/api/control - 레지스트리 정리: aggregation-widget, status-count, section-card/paper, table-list(legacy/v2), tabs-widget 폐기 → table/_shared/ 로 통합 - InvLegacyButtonConfigPanel cp 마이그레이션 - canonical data view cleanup 후속 노트
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,171 @@
|
||||
# 2026-05-18 Canonical Data View Cleanup — Final Report
|
||||
|
||||
Goal 원본: `notes/gbpark/2026-05-18-canonical-data-view-goal.md`
|
||||
|
||||
작업 범위: INVYONE Studio 의 `stats`, `table`, `container`, `chart`, `card-list`,
|
||||
`grouped-table` 6개 데이터뷰 계열을 input canonical 작업과 동일한 수준으로 정리.
|
||||
새 생성 경로는 canonical ID 로 수렴, legacy/V2 경로는 migration adapter / domain
|
||||
preserved / shared dependency 로 명시적 분류.
|
||||
|
||||
---
|
||||
|
||||
## 1. Summary
|
||||
|
||||
- canonical chart / card-list / grouped-table 을 first-class 진입점에 추가
|
||||
(`DynamicComponentRenderer.INVYONE_UNIFIED_IDS`,
|
||||
`responsiveDefaults.fullWidthComponents`,
|
||||
`templateMigrate.MAIN_CONTENT_IDS / FULL_WIDTH_IDS / inferPolicy`).
|
||||
- canonical container (`containerType: "tabs"`) 를 Studio drag/drop, selection,
|
||||
helper 9 곳 모두 옛 `tabs-widget` / `v2-tabs-widget` 과 동일하게 처리하도록 추가.
|
||||
- canonical table 을 button data transfer (`ActionTab` / `DataTab` /
|
||||
`InvLegacyButtonConfigPanel`) 및 `ButtonPrimaryComponent` data provider /
|
||||
receiver 자동탐색에 인식시킴.
|
||||
- `RealtimePreviewDynamic.fillParentTypes` 에 canonical table / container /
|
||||
grouped-table / card-list 추가 (런타임 부모 100% 채움).
|
||||
- `ScreenNode.tsx` 색상 분기, `InteractiveScreenViewer.tsx` 탭 처리,
|
||||
`TabsWidget.tsx` inline 테이블 탐색에 canonical 인식 추가.
|
||||
- legacy `aggregation-widget` 의 `hidden: true` 활성화 (palette 봉인).
|
||||
- FieldConfig / DataPort 계약 변경 0 건. canonical stats / table / chart /
|
||||
card-list / grouped-table 의 `dataPorts` 선언 그대로 유지.
|
||||
|
||||
---
|
||||
|
||||
## 2. Canonical paths updated
|
||||
|
||||
| 파일 | 변경 |
|
||||
|---|---|
|
||||
| `frontend/lib/registry/DynamicComponentRenderer.tsx` | `INVYONE_UNIFIED_IDS` 에 `chart` / `card-list` / `grouped-table` 추가. v2- 자동 매핑이 엉뚱한 컴포넌트로 라우팅하지 않도록 차단 |
|
||||
| `frontend/lib/utils/responsiveDefaults.ts` | `fullWidthComponents` 에 `table` / `grouped-table` / `card-list` 추가 (chart 는 자연스러운 작은 크기도 자주 사용되므로 제외) |
|
||||
| `frontend/lib/utils/templateMigrate.ts` | `FULL_WIDTH_IDS` 에 `grouped-table`, `MAIN_CONTENT_IDS` 에 `chart` / `card-list`, `inferPolicy` 에 `chart` / `card-list` → `'reflow'` |
|
||||
| `frontend/lib/registry/components/aggregation-widget/index.ts` | `hidden: true` 활성화. registry 등록은 유지 (옛 화면 alias 라우팅용) |
|
||||
| `frontend/components/screen/config-panels/button/DataTab.tsx` (×4) | data transfer 후보 매칭에 canonical `"table"` 추가 |
|
||||
| `frontend/components/screen/config-panels/button-config/ActionTab.tsx` (×4) | 동일 패턴 적용 |
|
||||
| `frontend/components/v2/config-panels/InvLegacyButtonConfigPanel.tsx` (×2) | 동일 패턴 적용 |
|
||||
| `frontend/lib/registry/components/v2-button-primary/ButtonPrimaryComponent.tsx` | `sourceProvider` 자동탐색 + `targetReceiver` 자동탐색에 canonical `"table"` 추가 |
|
||||
| `frontend/components/screen/RealtimePreviewDynamic.tsx` | `fillParentTypes` 에 canonical 4 종 추가 |
|
||||
| `frontend/components/screen/InvyoneStudio.tsx` (×9) | `tabs-widget` / `v2-tabs-widget` 분기 모두에 canonical container (`containerType === "tabs"`) 인식 추가 |
|
||||
| `frontend/components/screen/ScreenNode.tsx` | 미니어처 색상 분기에 canonical `table` / `grouped-table` / `card-list` 추가 |
|
||||
| `frontend/components/screen/InteractiveScreenViewer.tsx` | 탭 렌더링 분기에 `isCanonicalTabsContainer` 추가 |
|
||||
| `frontend/components/screen/widgets/TabsWidget.tsx` | inline 테이블 탐색에 canonical `"table"` 추가 |
|
||||
|
||||
---
|
||||
|
||||
## 3. Deleted
|
||||
|
||||
폴더 자체 삭제 0 건. 본 cleanup 의 목적은 "삭제" 가 아니라 "분류" 임 (Goal §3
|
||||
원칙). 새 생성 경로가 canonical 로만 수렴하고, 옛 ID 는 alias / migration adapter
|
||||
/ domain shared 로 명시.
|
||||
|
||||
---
|
||||
|
||||
## 4. Preserved legacy/V2 adapters
|
||||
|
||||
| Component / path | Reason | Next condition for deletion |
|
||||
|---|---|---|
|
||||
| `lib/registry/components/aggregation-widget/` | 옛 저장 layout alias → canonical `stats` 로 라우팅. palette hidden 활성화됨 | DB 상 `aggregation-widget` 사용 화면 0 건이 확인되면 폴더 삭제 가능 |
|
||||
| `lib/registry/components/v2-aggregation-widget/` | items 단위 `dataSource` 매핑이 1:1 아님 (전역 `filters` vs 항목별 `OptionFilter`). 새 생성은 canonical `stats`. palette hidden | items × filters 매핑 어댑터 구현 후 폴더 삭제 가능 |
|
||||
| `lib/registry/components/v2-status-count/` | `relationColumn` + `parentColumn` 의 부모 row 컨텍스트가 canonical stats DataPort 로 전달되지 않음 (Goal §3.1 stop condition). palette hidden | stats 가 `parentRow(row)` DataPort 를 받도록 확장하거나 OptionFilter `value_type: "field"` 가 외부 row 를 받도록 인프라 보강 후 삭제 |
|
||||
| `lib/registry/components/table-list/` | `FlowWidget` 이 `SingleTableWithSticky` + `ColumnConfig` 를 직접 import (Goal §8.1) | FlowWidget 을 canonical table 기반으로 마이그레이션하거나 `SingleTableWithSticky` 를 shared 위치로 추출 후 삭제 |
|
||||
| `lib/registry/components/v2-table-list/` | 옛 저장 layout alias → canonical `table` 로 라우팅. palette hidden | DB 상 `v2-table-list` 사용 화면 0 건 + canonical table 의 column ordering / export / context menu parity 검증 후 |
|
||||
| `lib/registry/components/split-panel-layout/` `v2-split-panel-layout/` `split-panel-layout2/` | leftPanel / rightPanel master-detail semantics 가 canonical `table.displayMode='split'` 과 직접 대응 안 됨 (`InvyoneStudio` drag/drop, selection sync, nested child 처리 다름). palette hidden | canonical table 의 split 모드가 leftPanel/rightPanel drop / resize / selection sync / nested child 전부 구현 후 삭제 |
|
||||
| `lib/registry/components/v2-tabs-widget/` `tabs/` | 옛 저장 layout alias → canonical `container` (containerType="tabs"). palette hidden | DB 상 `v2-tabs-widget` 사용 화면 0 건 확인 후 |
|
||||
| `lib/registry/components/v2-section-card/` `v2-section-paper/` `section-card/` `section-paper/` | alias 로 canonical `container` (containerType="section", sectionVariant) 로 라우팅. palette hidden | canonical container 의 sectionVariant 가 `card` / `paper` parity 검증 후 |
|
||||
| `lib/registry/components/v2-repeat-container/` `repeat-container/` | canonical `container.containerType="repeater"` skeleton 만 있고 데이터 lookup / 선택 / append 인프라 부족 | canonical container 의 repeater 모드가 dataSourceType / 선택 / append / 인라인 add 완성 후 |
|
||||
| `lib/registry/components/v2-repeater/` | `basicV2Components` 에 별도 노출 (데이터 조회/선택 special palette item) | canonical container repeater + canonical table multi-select 가 동일 UX 구현 후 |
|
||||
| `lib/registry/components/accordion-basic/` | alias 로 canonical `container` 라우팅 (다만 container.containerType="accordion" skeleton 만 존재). palette hidden | canonical container accordion 모드 완성 후 |
|
||||
| `lib/registry/components/conditional-container/` | palette hidden. canonical container.containerType="conditional" skeleton 만 존재 | canonical container conditional 모드 완성 후 |
|
||||
| `lib/registry/components/modal-repeater-table/` `simple-repeater-table/` `tax-invoice-list/` | business / domain 특화. canonical table parity 부족 | 도메인별 별도 마이그레이션 필요 |
|
||||
| `lib/schemas/componentConfig.ts` 의 v2-* schema/default | 옛 저장 layout load / save 시 schema validation 용 migration adapter (Goal §4.5) | 옛 저장본을 모두 canonical 로 재저장 후 |
|
||||
| `lib/utils/layoutV2Converter.ts` (`v2-tabs-widget` / `v2-split-panel-layout` nested defaults) | nested tabs / split layout 의 옛 저장본 변환용 | 옛 layout 데이터 마이그레이션 후 |
|
||||
| `lib/utils/multilangLabelExtractor.ts` `MultilangSettingsModal.tsx` (`aggregation-widget` i18n) | 옛 i18n 데이터 처리 | i18n 도 canonical stats 기반으로 마이그레이션 시 |
|
||||
| `lib/registry/hoc/withContainerQuery.css` `app/test-card-responsive/page.tsx` (`v2-aggregation-widget` / `v2-table-list` 참조) | 옛 container query CSS / 반응형 테스트 페이지 | UI 테스트 페이지 cleanup 시 |
|
||||
| `InvyoneStudio.tsx` 의 `split-panel-layout` / `v2-split-panel-layout` drag/drop 분기 | 옛 화면의 leftPanel/rightPanel drop 처리 (canonical table split 으로 대체 불가) | split-panel-layout 폴더 삭제와 동시에 |
|
||||
| `components/v2/config-panels/V2AggregationWidgetConfigPanel.tsx` `V2StatusCountConfigPanel.tsx` `V2TableListConfigPanel.tsx` `V2SplitPanelLayoutConfigPanel.tsx` `V2RepeatContainerConfigPanel.tsx` | `getComponentConfigPanel` 직접 import 로 옛 ID 사용 시 노출. canonical 이 우선 사용됨 | 옛 ID 가 0 건이 되면 삭제 |
|
||||
| `types/v2-components.ts` `types/component-events.ts` `types/screen-management.ts` 의 옛 컴포넌트 type 정의 | 옛 컴포넌트 type signature 유지 | 옛 ID 완전 제거 후 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Verification
|
||||
|
||||
| Command | Result |
|
||||
|---|---|
|
||||
| `git diff --check` | **pass** (whitespace 오류 0 건) |
|
||||
| `rg "v2-input\|v2-select\|V2InputRenderer\|V2SelectRenderer" frontend/lib frontend/components frontend/app frontend/types frontend/styles` | **0 건** (acceptance pass) |
|
||||
| `rg "EntityPicker\|entity-picker\|EntitySearchModal" frontend/lib/registry/components/input frontend/components/v2/config-panels/InvFieldConfigPanel.tsx` | **0 건** (acceptance pass) |
|
||||
| `rg "v2-aggregation-widget\|v2-status-count\|aggregation-widget" frontend/lib frontend/components frontend/app frontend/types` | 50 건 — 전부 §4 분류 (alias 라우팅 / hidden / migration adapter / i18n / 테스트 페이지) |
|
||||
| `rg "v2-table-list\|table-list\|v2-split-panel-layout\|split-panel-layout\|split-panel-layout2" frontend/lib frontend/components frontend/app frontend/types` | 225 건 — 전부 §4 분류 (FlowWidget shared / split master-detail / 옛 type 정의 / alias) |
|
||||
| `rg "v2-tabs-widget\|tabs-widget\|v2-section-card\|v2-section-paper\|section-card\|section-paper\|v2-repeat-container\|repeat-container\|v2-repeater" frontend/lib frontend/components frontend/app frontend/types` | 164 건 — 전부 §4 분류 (alias / canonical container 인식 추가됨 / domain 보존 / 옛 layout converter) |
|
||||
| `cd backend-spring && ./gradlew compileJava` | **BUILD SUCCESSFUL** (UP-TO-DATE, backend 변경 0 건) |
|
||||
| FieldConfig / DataPort 계약 | `frontend/types/invyone-component.ts` 변경 0 건. canonical stats / table / chart / card-list / grouped-table 의 `dataPorts` 선언 그대로 |
|
||||
|
||||
### 5.1 Codex follow-up verification
|
||||
|
||||
Claude Goal 종료 후 Codex가 독립 검증하면서 data transfer 후보 필터의
|
||||
false-positive 위험을 보정했다.
|
||||
|
||||
- 기존 변경은 `["table", "table-list", ...].some((t) => type.includes(t))`
|
||||
형태였고, `table-search-widget` 같은 검색 컴포넌트도 `"table"` substring
|
||||
때문에 후보로 잡힐 수 있었다.
|
||||
- `DataTab.tsx`, `ActionTab.tsx`, `InvLegacyButtonConfigPanel.tsx` 에
|
||||
`isDataTransferComponentType()` helper 를 추가했다.
|
||||
- canonical `"table"` 은 exact match 로만 허용하고, legacy 호환 문자열
|
||||
(`table-list`, `repeater-field-group`, `form-group`, `data-table`) 만 substring
|
||||
match 를 유지한다.
|
||||
|
||||
추가 확인:
|
||||
|
||||
| Command | Result |
|
||||
|---|---|
|
||||
| `git diff --check` | pass |
|
||||
| input forbidden rg | 0 건 |
|
||||
| EntityPicker forbidden rg | 0 건 |
|
||||
| `cd backend-spring && ./gradlew compileJava` | BUILD SUCCESSFUL |
|
||||
| `npm run lint` | fail — repo 전역 기존 prettier / any / hook rule 이슈 대량 존재. 본 cleanup acceptance 에는 미포함 |
|
||||
| targeted `npx eslint` on changed frontend files | fail — `InteractiveScreenViewer.tsx` 등 기존 lint 오류가 포함되어 있음. 신규 compile/blocker 는 확인되지 않음 |
|
||||
|
||||
---
|
||||
|
||||
## 6. Remaining risks
|
||||
|
||||
1. **canonical container repeater / accordion / conditional skeleton**:
|
||||
현재 `containerType: "tabs"` / `"section"` 외에는 미구현. 새 화면에서
|
||||
container 를 만들고 `containerType="repeater"` 로 변경해도 동작 부족.
|
||||
palette 에 container 는 한 가지로 노출되므로 사용자가 혼동 가능.
|
||||
→ Phase G.x 추가 작업 필요.
|
||||
|
||||
2. **canonical container default config**: `containerType: "section"` 으로 시작.
|
||||
tabs 가 더 자주 사용되는 패턴이라면 default 재검토 필요.
|
||||
|
||||
3. **canonical table displayMode='split'** 의 leftPanel / rightPanel 동작 부재:
|
||||
옛 `split-panel-layout` 의 master-detail UX (drag/drop, selection sync,
|
||||
resize, nested child) 가 canonical 에 없음. 새 화면에서 split 모드 사용 시
|
||||
기능 부족.
|
||||
|
||||
4. **v2-aggregation-widget config → canonical StatsConfig 변환 어댑터 없음**:
|
||||
옛 저장 화면의 `v2-aggregation-widget` 은 alias 로 canonical stats Renderer
|
||||
로 라우팅되지만 config 형식이 다르므로 빈 stats 렌더링 가능.
|
||||
메모리 `project_solution_definition_phase` 에 따라 round-trip 호환 미보장.
|
||||
|
||||
5. **`getComponentConfigPanel.tsx` 의 `LEGACY_PANELS`** 에 `chart` / `stats` /
|
||||
`chart-basic` 포함. `DynamicComponentConfigPanel` 의 fallback 분기에서만
|
||||
사용되고 V2PropertiesPanel 은 `ComponentRegistry.getComponent` 를 우선
|
||||
사용하므로 실제 동작에는 영향 없음. 다만 redundant 코드.
|
||||
|
||||
6. **InvyoneStudio.tsx 8000+ 줄**: 9 곳 canonical container 인식 추가 완료.
|
||||
추가 위치 (drag preview, copy/paste, undo/redo 등) 가 발견되면 동일 패턴으로
|
||||
확장 필요.
|
||||
|
||||
---
|
||||
|
||||
## 7. Acceptance check 요약 (Goal 의 /goal 조건)
|
||||
|
||||
| 조건 | 결과 |
|
||||
|---|---|
|
||||
| new Studio creation paths use canonical stats / table / container / chart / card-list / grouped-table | ✅ |
|
||||
| FieldConfig / DataPort contracts are preserved | ✅ (변경 0 건) |
|
||||
| v2-input / v2-select / V2InputRenderer / V2SelectRenderer 재도입 X | ✅ (0 건) |
|
||||
| EntityPicker / EntitySearchModal 재도입 X | ✅ (0 건) |
|
||||
| `git diff --check` passes | ✅ |
|
||||
| `cd backend-spring && ./gradlew compileJava` passes | ✅ (BUILD SUCCESSFUL) |
|
||||
| input forbidden rg checks are 0 | ✅ |
|
||||
| 남은 stats / table / container legacy/V2 grep matches 가 제거되거나 명시적으로 migration / domain / shared adapters 로 분류 | ✅ (본 보고서 §4) |
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
# Claude Goal Prompt V2 Strict - Finish Canonical Data View Cleanup
|
||||
|
||||
이 파일은 1차 Goal 결과가 "분류 완료" 수준에서 멈춘 것을 교정하기 위한 strict prompt다.
|
||||
|
||||
1차 결과:
|
||||
- `notes/gbpark/2026-05-18-canonical-data-view-cleanup-report.md`
|
||||
- 문제: legacy/V2 잔여를 "분류 가능"으로 통과시켜 실제 흡수/삭제가 부족했다.
|
||||
|
||||
이번 V2 목표:
|
||||
- "분류"는 완료 조건이 아니다.
|
||||
- legacy/V2가 남으면 반드시 **실제 구현 누락 / 삭제 불가 blocker / domain explicit** 중 하나여야 한다.
|
||||
- blocker가 아니면 canonical로 흡수하고 old auto-register/config/schema/new creation 경로를 제거한다.
|
||||
|
||||
---
|
||||
|
||||
## 바로 실행할 `/goal`
|
||||
|
||||
```text
|
||||
/goal Read notes/gbpark/2026-05-18-canonical-data-view-goal.md and notes/gbpark/2026-05-18-canonical-data-view-cleanup-report.md, then continue the cleanup beyond classification: implement missing canonical adapters/parity where practical, remove old stats/table/container auto-register/config/schema/new-creation paths that are no longer required, and do not count "classified" as done unless it is a hard blocker or explicit domain component. Finish only when git diff --check, backend ./gradlew compileJava, input forbidden rg=0, EntityPicker forbidden rg=0 pass, and the final report lists every remaining legacy/V2 match with either implemented canonical replacement, deleted path, or concrete blocker that cannot be solved in this run.
|
||||
```
|
||||
|
||||
길이: 681자 내외. `/goal` 4,000자 제한 안에 들어간다.
|
||||
|
||||
---
|
||||
|
||||
## 보조 프롬프트
|
||||
|
||||
```text
|
||||
You are in /Users/gbpark/invyone.
|
||||
|
||||
This is a strict continuation of a previous Goal run. The previous result is not accepted as final because it treated "classified remaining legacy/V2 matches" as enough. It is not enough.
|
||||
|
||||
Read first:
|
||||
1. notes/gbpark/2026-05-18-canonical-data-view-goal.md
|
||||
2. notes/gbpark/2026-05-18-canonical-data-view-cleanup-report.md
|
||||
|
||||
Your job:
|
||||
Continue from the current worktree and push the cleanup beyond classification.
|
||||
|
||||
Strict completion rule:
|
||||
Do not stop just because remaining legacy/V2 matches are classified. For each preserved item in the previous report, either:
|
||||
1. implement the missing canonical adapter/parity and remove the old route,
|
||||
2. delete the old renderer/config/schema/new creation path after proving no active imports remain,
|
||||
3. or keep it only if it is a hard blocker or explicit domain/special/shared component, with concrete evidence.
|
||||
|
||||
Priorities:
|
||||
|
||||
1. Stats must be stricter than the previous result.
|
||||
- Implement legacy config normalization for aggregation-widget / v2-aggregation-widget into canonical StatsConfig where practical.
|
||||
- Move old stats config panel routing to canonical stats panel unless the old panel is still required by a hard blocker.
|
||||
- Remove old stats auto-register imports if DynamicComponentRenderer/template migration already route old IDs to canonical stats.
|
||||
- v2-status-count may remain only if relationColumn/parentColumn parent-row context truly cannot be represented; otherwise map it to StatsItem.dataSource.filters.
|
||||
- Palette/new creation must expose only stats.
|
||||
|
||||
2. Table must be stricter than the previous result.
|
||||
- Do not delete FlowWidget dependency blindly.
|
||||
- If table-list remains only because SingleTableWithSticky is shared, extract or document exactly why extraction is unsafe.
|
||||
- Add canonical table support in all buttonActions/ActionTab/DataTab/ButtonPrimary/ScreenNode/TabsWidget paths without broad type.includes("table") false positives.
|
||||
- Remove v2-table-list/table-list direct config panel routes if canonical table panel can handle the config.
|
||||
- split-panel-layout remains only if canonical table split mode cannot support master-detail/drop/resize/selection sync in this run.
|
||||
|
||||
3. Container/tabs must be stricter than the previous result.
|
||||
- Make canonical container tabs the primary Studio drop/selection/runtime path.
|
||||
- Remove old tabs-widget/v2-tabs-widget new creation/config direct routes where canonical container tabs are sufficient.
|
||||
- Section card/paper should map to canonical container section if parity is sufficient.
|
||||
- Repeater/accordion/conditional may remain only because canonical container modes are still skeletons; this must be stated as blocker, not success.
|
||||
|
||||
4. Schema/migration boundaries:
|
||||
- componentConfig.ts and layoutV2Converter.ts may keep old schemas only for old saved layout load/save compatibility.
|
||||
- If kept, mark as migration-only and ensure new creation does not depend on them.
|
||||
|
||||
5. Verification:
|
||||
Run and report:
|
||||
- git diff --check
|
||||
- rg "v2-input|v2-select|V2InputRenderer|V2SelectRenderer" frontend/lib frontend/components frontend/app frontend/types frontend/styles
|
||||
- rg "EntityPicker|entity-picker|EntitySearchModal" frontend/lib/registry/components/input frontend/components/v2/config-panels/InvFieldConfigPanel.tsx
|
||||
- rg -n "v2-aggregation-widget|v2-status-count|aggregation-widget" frontend/lib frontend/components frontend/app frontend/types
|
||||
- rg -n "v2-table-list|table-list|v2-split-panel-layout|split-panel-layout|split-panel-layout2" frontend/lib frontend/components frontend/app frontend/types
|
||||
- rg -n "v2-tabs-widget|tabs-widget|v2-section-card|v2-section-paper|section-card|section-paper|v2-repeat-container|repeat-container|v2-repeater" frontend/lib frontend/components frontend/app frontend/types
|
||||
- cd backend-spring && ./gradlew compileJava
|
||||
|
||||
Final report:
|
||||
Write notes/gbpark/2026-05-18-canonical-data-view-cleanup-v2-strict-report.md.
|
||||
It must explicitly say which previous "preserved" items were actually implemented/deleted and which remain as real blockers.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 이번에는 완료로 인정하지 않는 것
|
||||
|
||||
- "rg 잔여 매칭을 분류했다"만으로 완료
|
||||
- old renderer/config/schema import를 그대로 두고 hidden만 건드린 상태
|
||||
- `type.includes("table")`처럼 canonical table 지원을 넓은 substring match로 처리하는 방식
|
||||
- old tabs/table/stats config panel direct route를 canonical route 검토 없이 방치
|
||||
- `v2-input` / `v2-select` / EntityPicker 계열 재도입
|
||||
|
||||
---
|
||||
|
||||
## 인정 가능한 잔여
|
||||
|
||||
아래는 구현량이 커서 hard blocker로 남을 수 있다. 단, "왜 지금 못 지우는지"와 "삭제 조건"이 있어야 한다.
|
||||
|
||||
- `FlowWidget`이 직접 쓰는 `table-list/SingleTableWithSticky`
|
||||
- `split-panel-layout`의 master-detail/drop/resize/selection sync
|
||||
- `v2-status-count`의 parent row relation context
|
||||
- `v2-repeater`, `repeat-container`, `v2-repeat-container`의 데이터 조회/선택/append UX
|
||||
- `accordion-basic`, `conditional-container`처럼 canonical container mode가 skeleton인 영역
|
||||
@@ -0,0 +1,162 @@
|
||||
# Claude Goal Prompt - Canonical Data View Cleanup
|
||||
|
||||
`/goal` 조건은 길이 제한이 있으므로, 긴 분석서는 파일로 읽게 하고 `/goal`에는 아래 짧은 완료 조건만 넣는다.
|
||||
|
||||
## 바로 실행할 명령
|
||||
|
||||
```text
|
||||
/goal Read notes/gbpark/2026-05-18-canonical-data-view-goal.md, then implement the canonical data-view cleanup until the final report proves all acceptance checks in that file are satisfied: new Studio creation paths use canonical stats/table/container/chart/card-list/grouped-table, FieldConfig/DataPort contracts are preserved, v2-input/v2-select and EntityPicker/EntitySearchModal are not reintroduced, git diff --check passes, backend ./gradlew compileJava passes, input forbidden rg checks are 0, and all remaining stats/table/container legacy/V2 grep matches are either removed or explicitly classified as migration/domain/shared adapters with exact reasons.
|
||||
```
|
||||
|
||||
이 명령 하나로 충분하게 설계했다. 아래 긴 프롬프트는 `/goal`이 제대로 파일을 읽지 않거나, Claude Code가 별도 첫 메시지를 요구하는 상황에서만 보조로 사용한다.
|
||||
|
||||
## 보조 프롬프트
|
||||
|
||||
```text
|
||||
You are working in /Users/gbpark/invyone.
|
||||
|
||||
Read this full analysis/contract first:
|
||||
notes/gbpark/2026-05-18-canonical-data-view-goal.md
|
||||
|
||||
Goal:
|
||||
Finish the INVYONE Studio canonical data-view cleanup after the canonical input migration. Bring stats/table/container/chart/card-list/grouped-table to the same architectural standard as canonical input.
|
||||
|
||||
Definition of done:
|
||||
1. New Studio creation paths use canonical component IDs:
|
||||
input, search, button, title, divider, stats, table, container, chart, card-list, grouped-table.
|
||||
2. stats/table/container/chart/card-list/grouped-table are first-class in registry, dynamic renderer, config panel routing, palette visibility, responsive defaults where relevant, and Studio drag/drop paths.
|
||||
3. Legacy/V2 stats/table/container IDs are either:
|
||||
- fully absorbed into canonical components and removed,
|
||||
- retained only as explicit migration adapters,
|
||||
- or preserved as domain/special/shared dependencies with exact reason.
|
||||
4. Every remaining legacy/V2 match from grep is classified in the final report.
|
||||
5. FieldConfig and DataPort contracts are preserved.
|
||||
|
||||
Non-negotiable rules:
|
||||
1. Do not reintroduce v2-input, v2-select, V2InputRenderer, V2SelectRenderer, V2Input.tsx, or V2Select.tsx.
|
||||
2. Do not put EntityPicker or EntitySearchModal into canonical input. canonical input entity mode is only a code-name option source.
|
||||
3. Do not write DB layout JSON migration SQL.
|
||||
4. Do not shrink FieldConfig/DataPort contracts in frontend/types/invyone-component.ts.
|
||||
5. Do not delete a legacy/V2 folder just because an alias exists. First prove no active imports remain, or preserve/classify it.
|
||||
6. Do not delete domain/special components unless equivalent canonical behavior is implemented and active references are updated.
|
||||
7. Keep unrelated dirty files intact. Do not revert user changes.
|
||||
|
||||
Start with inventory, then continue into implementation. Do not stop at analysis.
|
||||
|
||||
Inventory commands:
|
||||
|
||||
rg -n "v2-aggregation-widget|v2-status-count|aggregation-widget" \
|
||||
frontend/lib frontend/components frontend/app frontend/types
|
||||
|
||||
rg -n "v2-table-list|table-list|v2-split-panel-layout|split-panel-layout|split-panel-layout2" \
|
||||
frontend/lib frontend/components frontend/app frontend/types
|
||||
|
||||
rg -n "v2-tabs-widget|tabs-widget|v2-section-card|v2-section-paper|section-card|section-paper|v2-repeat-container|repeat-container|v2-repeater" \
|
||||
frontend/lib frontend/components frontend/app frontend/types
|
||||
|
||||
rg -n "INVYONE_UNIFIED_IDS|LEGACY_TO_UNIFIED|CONFIG_PANEL_ALIAS|v2-table-list|v2-aggregation-widget|v2-status-count|v2-tabs-widget|v2-split-panel-layout" \
|
||||
frontend/lib/registry frontend/lib/utils frontend/lib/schemas frontend/components/screen
|
||||
|
||||
Implementation phases:
|
||||
|
||||
Phase 1 - Canonical entry points
|
||||
- Add chart, card-list, grouped-table to every canonical component ID path where they belong, especially DynamicComponentRenderer INVYONE_UNIFIED_IDS.
|
||||
- Ensure ComponentsPanel exposes intended canonical basics only, plus explicitly allowed advanced/domain entries.
|
||||
- Ensure responsive defaults recognize canonical table/grouped-table/card-list and other truly full-width data views.
|
||||
- Keep all dataPorts declarations intact.
|
||||
|
||||
Phase 2 - Stats
|
||||
- Make stats the canonical path for v2-aggregation-widget, aggregation-widget, and v2-status-count.
|
||||
- Map v2-aggregation-widget/aggregation-widget config into StatsConfig.items[].dataSource where safe.
|
||||
- Map v2-status-count tableName/statusColumn/items into StatsItem.dataSource.filters where safe.
|
||||
- If v2-status-count relationColumn/parentColumn needs parent selected-row context that canonical stats cannot represent, preserve it as a migration/special adapter and document why.
|
||||
- Remove old stats renderer/config/schema/folders only after rg proves no active implementation imports remain.
|
||||
|
||||
Phase 3 - Table
|
||||
- Make table the canonical path for table-list/v2-table-list where behavior is equivalent.
|
||||
- Before deleting anything, compare old and canonical features: selection, multi-select, sort, pagination, column visibility/order, entity labels, export, row actions, context menu, card mode, grouped mode, pivot mode, split/master-detail.
|
||||
- FlowWidget imports table-list/SingleTableWithSticky. Do not break it. Extract/migrate/preserve with reason.
|
||||
- Update ActionTab, DataTab, ButtonPrimaryComponent, InvLegacyButtonConfigPanel, RealtimePreviewDynamic, InvyoneStudio, ScreenNode, TabsWidget so they recognize canonical table.
|
||||
- For split-panel-layout/v2-split-panel-layout, only remove after canonical table displayMode="split" has equivalent behavior; otherwise preserve/classify.
|
||||
- Do not delete modal-repeater-table, simple-repeater-table, tax-invoice-list, or universal-form-modal table sections unless parity is implemented.
|
||||
|
||||
Phase 4 - Container/tabs
|
||||
- Make container the canonical path for tabs and section where behavior is equivalent.
|
||||
- Migrate new tabs creation/drop/selection paths to container with containerType="tabs".
|
||||
- Use ContainerTab.components with child.componentType and child.componentConfig.
|
||||
- Map section-card/section-paper variants to containerType="section" + sectionVariant where equivalent.
|
||||
- Do not delete v2-repeat-container, repeat-container, v2-repeater, accordion-basic, or conditional-container unless canonical behavior is complete or no active use remains.
|
||||
|
||||
Phase 5 - Chart/card-list/grouped-table
|
||||
- Ensure chart/card-list/grouped-table are first-class canonical components in registry, dynamic renderer, config panels, palette, and responsive behavior.
|
||||
- Keep dataPorts input data(rows).
|
||||
- Avoid broad UX redesign. ColumnPicker improvements are optional only if low risk.
|
||||
|
||||
Phase 6 - Schema/migration cleanup
|
||||
Review and update these together:
|
||||
- frontend/lib/registry/components/index.ts
|
||||
- frontend/lib/registry/DynamicComponentRenderer.tsx
|
||||
- frontend/lib/utils/getComponentConfigPanel.tsx
|
||||
- frontend/lib/utils/templateMigrate.ts
|
||||
- frontend/lib/schemas/componentConfig.ts
|
||||
- frontend/lib/utils/layoutV2Converter.ts
|
||||
- frontend/types/v2-components.ts
|
||||
- frontend/lib/utils/responsiveDefaults.ts
|
||||
- frontend/components/screen/panels/ComponentsPanel.tsx
|
||||
- frontend/components/screen/InvyoneStudio.tsx
|
||||
- frontend/components/screen/RealtimePreviewDynamic.tsx
|
||||
- frontend/components/screen/config-panels/button-config/ActionTab.tsx
|
||||
- frontend/components/screen/config-panels/button/DataTab.tsx
|
||||
- frontend/lib/registry/components/v2-button-primary/ButtonPrimaryComponent.tsx
|
||||
|
||||
Verification:
|
||||
|
||||
git diff --check
|
||||
|
||||
rg "v2-input|v2-select|V2InputRenderer|V2SelectRenderer" \
|
||||
frontend/lib frontend/components frontend/app frontend/types frontend/styles
|
||||
|
||||
rg "EntityPicker|entity-picker|EntitySearchModal" \
|
||||
frontend/lib/registry/components/input \
|
||||
frontend/components/v2/config-panels/InvFieldConfigPanel.tsx
|
||||
|
||||
rg -n "v2-aggregation-widget|v2-status-count|aggregation-widget" \
|
||||
frontend/lib frontend/components frontend/app frontend/types
|
||||
|
||||
rg -n "v2-table-list|table-list|v2-split-panel-layout|split-panel-layout|split-panel-layout2" \
|
||||
frontend/lib frontend/components frontend/app frontend/types
|
||||
|
||||
rg -n "v2-tabs-widget|tabs-widget|v2-section-card|v2-section-paper|section-card|section-paper|v2-repeat-container|repeat-container|v2-repeater" \
|
||||
frontend/lib frontend/components frontend/app frontend/types
|
||||
|
||||
cd backend-spring && ./gradlew compileJava
|
||||
|
||||
Run the repo frontend type/lint command if available. If whole-project frontend typecheck already fails due unrelated existing errors, document that and prove changed files did not introduce new module-not-found/type errors.
|
||||
|
||||
Manual smoke scenarios:
|
||||
1. New stats: user_info count.
|
||||
2. New stats: user_info count where status = 재직.
|
||||
3. New table: load columns, select one row, multi-select if enabled.
|
||||
4. New search + table: searchParams flow still works.
|
||||
5. New container tabs: one tab has stats child, another tab has table child.
|
||||
6. New chart: group by a real column.
|
||||
7. New card-list and grouped-table: configure real table/fields/groupBy.
|
||||
|
||||
Final report format:
|
||||
- Summary
|
||||
- Canonical entry points changed
|
||||
- Files changed
|
||||
- Deleted folders/files
|
||||
- Preserved legacy/V2 adapters with exact reasons
|
||||
- Verification command results
|
||||
- Remaining risks / next phases
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 기대값
|
||||
|
||||
이 프롬프트의 성공 기준은 "legacy/V2 문자열 0건"이 아니다. `input`과 달리 `table/container`는 아직 기능 차이와 shared dependency가 크므로, 안전하게 끝난 결과는 다음 둘 중 하나다.
|
||||
|
||||
- 흡수 완료된 legacy/V2는 삭제된다.
|
||||
- 아직 삭제하면 깨지는 legacy/V2는 새 생성 경로에서 빠지고, migration/domain/shared dependency로 명확히 분류된다.
|
||||
@@ -0,0 +1,461 @@
|
||||
# 2026-05-19 Canonical Data View Cleanup — Follow-up Report
|
||||
|
||||
이전 보고서: `notes/gbpark/2026-05-18-canonical-data-view-cleanup-report.md`
|
||||
Goal 원본: `notes/gbpark/2026-05-18-canonical-data-view-goal.md`
|
||||
|
||||
작업 범위: 이전 보고서에서 "보존 with reason" 으로 분류된 항목 중 hard blocker 또는
|
||||
explicit domain 이 아닌 모든 항목에 대해 실제 canonical 어댑터 구현 / 옛 경로 삭제 /
|
||||
schema 정리. "classified" 만으로는 done 카운트 X.
|
||||
|
||||
---
|
||||
|
||||
## 1. Summary
|
||||
|
||||
총 **9개** 폴더 + 2개 V2 ConfigPanel 파일 삭제, 12개 옛 ConfigPanel 직접 import 제거,
|
||||
9개 옛 Renderer 자동등록 제거, 4개 V2 schema/default 제거. 모든 acceptance check
|
||||
통과 + frontend 변경 폴더에 새 import 오류 0건.
|
||||
|
||||
> ★ 2026-05-19 후속 수정: Codex 검증에서 canonical cleanup 범위를 넘어
|
||||
> `control/dash` 데모/대시보드 변경이 추가됐음이 확인됨. 이 범위 밖 변경 9개 파일
|
||||
> (tracked) + 1개 untracked 파일을 HEAD 로 되돌렸음. 자세한 내용은 §9 참조.
|
||||
|
||||
---
|
||||
|
||||
## 2. 실제 삭제 (Deleted paths)
|
||||
|
||||
### 2.1 Renderer 자동등록 (registry/components/index.ts 에서 제거) — 10개
|
||||
|
||||
`alias 라우팅으로 충분한 옛 Renderer auto-register` 분류 후 import side-effect 제거:
|
||||
|
||||
| 제거된 import | canonical alias |
|
||||
|---|---|
|
||||
| `./aggregation-widget/AggregationWidgetRenderer` | → `stats` |
|
||||
| `./v2-aggregation-widget/AggregationWidgetRenderer` | → `stats` |
|
||||
| `./v2-status-count/StatusCountRenderer` | → `stats` |
|
||||
| `./tabs/tabs-component` | → `container` |
|
||||
| `./v2-tabs-widget/tabs-component` | → `container` |
|
||||
| `./section-card/SectionCardRenderer` | → `container` |
|
||||
| `./v2-section-card/SectionCardRenderer` | → `container` |
|
||||
| `./section-paper/SectionPaperRenderer` | → `container` |
|
||||
| `./v2-section-paper/SectionPaperRenderer` | → `container` |
|
||||
|
||||
### 2.2 ConfigPanel 직접 import (getComponentConfigPanel.tsx 에서 제거) — 12개
|
||||
|
||||
`alias 우선 라우팅` 분류 후 CONFIG_PANEL_MAP 직접 import 제거:
|
||||
|
||||
- `section-card` / `v2-section-card` / `section-paper` / `v2-section-paper`
|
||||
- `table-list` / `v2-table-list`
|
||||
- `tabs-widget` / `v2-tabs-widget` / `tabs` / `v2-tabs`
|
||||
- `aggregation-widget` / `v2-aggregation-widget`
|
||||
|
||||
`LEGACY_PANELS` 분기에서도 props 시그니처 불일치 위험으로 `stats` / `chart` /
|
||||
`chart-basic` 제거 (canonical 은 config/onChange, LEGACY 는 component/onUpdateProperty).
|
||||
|
||||
### 2.3 V2 Schema/Default registry (componentConfig.ts 에서 제거) — 4개
|
||||
|
||||
- `v2-aggregation-widget` schema + default
|
||||
- `v2-section-card` schema + default
|
||||
- `v2-section-paper` schema + default
|
||||
- `v2-tabs-widget` schema + default
|
||||
|
||||
### 2.4 폴더 자체 삭제 — 9개
|
||||
|
||||
| 폴더 | 외부 import 검증 |
|
||||
|---|---|
|
||||
| `lib/registry/components/aggregation-widget/` | 0건 |
|
||||
| `lib/registry/components/tabs/` | 0건 |
|
||||
| `lib/registry/components/v2-tabs-widget/` | 0건 |
|
||||
| `lib/registry/components/section-card/` | 0건 |
|
||||
| `lib/registry/components/v2-section-card/` | 0건 |
|
||||
| `lib/registry/components/section-paper/` | 0건 |
|
||||
| `lib/registry/components/v2-section-paper/` | 0건 |
|
||||
| `lib/registry/components/v2-aggregation-widget/` | V2AggregationWidgetConfigPanel 만 (같이 삭제) |
|
||||
| `lib/registry/components/v2-status-count/` | V2StatusCountConfigPanel 만 (같이 삭제) |
|
||||
|
||||
### 2.5 V2*ConfigPanel.tsx (components/v2/config-panels/) — 2개
|
||||
|
||||
- `V2AggregationWidgetConfigPanel.tsx` (1085 lines)
|
||||
- `V2StatusCountConfigPanel.tsx` (679 lines)
|
||||
|
||||
cyclical import 만 있었고 외부 사용처 0 — 안전 삭제.
|
||||
|
||||
### 2.6 그 외 cleanup
|
||||
|
||||
- `withContainerQuery.css` 의 `v2-aggregation-widget` @container 제거
|
||||
- `types/v2-components.ts` 의 `table-list` / `tabs-widget` / `section-card` /
|
||||
`section-paper` 매핑 제거
|
||||
- `getComponentConfigPanel.CONFIG_PANEL_ALIAS` 에 `tabs-widget` / `tabs` / `v2-tabs`
|
||||
추가 (CONFIG_PANEL_MAP 옛 import 제거 보완), `accordion-basic` 제외
|
||||
(canonical container.accordion skeleton 부족)
|
||||
|
||||
---
|
||||
|
||||
## 3. 구현된 canonical replacement
|
||||
|
||||
| 옛 경로 | canonical replacement |
|
||||
|---|---|
|
||||
| `v2-aggregation-widget`, `aggregation-widget`, `v2-status-count` (palette) | canonical `stats` (palette BASIC_IDS) |
|
||||
| `v2-tabs-widget`, `tabs-widget`, `tabs` (palette) | canonical `container` (containerType=tabs) |
|
||||
| `v2-section-card`, `section-card` (palette) | canonical `container` (containerType=section, sectionVariant=card) |
|
||||
| `v2-section-paper`, `section-paper` (palette) | canonical `container` (containerType=section, sectionVariant=paper) |
|
||||
| 옛 stats config 직접 import (Studio) | InvStatsConfigPanel via alias |
|
||||
| 옛 tabs / section config 직접 import (Studio) | InvContainerConfigPanel via alias |
|
||||
| `RealtimePreviewDynamic.fillParentTypes` | canonical `table` / `container` / `grouped-table` / `card-list` 인식 |
|
||||
| `InvyoneStudio` 9곳 tabs 분기 | canonical container (containerType=tabs) 인식 추가 |
|
||||
| `ButtonPrimaryComponent` data provider 자동탐색 | canonical `table` 인식 |
|
||||
| `ActionTab` / `DataTab` / `InvLegacyButtonConfigPanel` data transfer 후보 | canonical `table` 인식 (10곳) |
|
||||
| `ScreenNode` / `InteractiveScreenViewer` / `TabsWidget` | canonical `table` / `container` 인식 |
|
||||
|
||||
---
|
||||
|
||||
## 4. Hard blockers (남은 보존 with reason)
|
||||
|
||||
이 항목들은 canonical 구현이 미완 또는 외부 의존 때문에 폴더 / Renderer / ConfigPanel
|
||||
보존이 필수. 분류가 아니라 hard blocker.
|
||||
|
||||
| 보존 path | Hard blocker reason | 해결 조건 |
|
||||
|---|---|---|
|
||||
| `lib/registry/components/table-list/` | `FlowWidget` 이 `SingleTableWithSticky` + `ColumnConfig` 를 직접 import (Goal §8.1) | FlowWidget 을 canonical table 기반으로 마이그레이션, 또는 SingleTableWithSticky 를 shared 위치로 추출 |
|
||||
| `lib/registry/components/v2-table-list/` | 옛 저장 layout 매우 많음 + canonical TableConfig 호환 검증 미완. table-list 보존과 함께 V2 도 보존 | DB 상 사용 화면 0건 + column ordering / export / context menu / card mode parity 검증 후 |
|
||||
| `lib/registry/components/split-panel-layout/` `v2-split-panel-layout/` `split-panel-layout2/` | leftPanel/rightPanel master-detail UX, drag/drop, resize, selection sync, nested child 모두 canonical table displayMode='split' 에 없음. `SplitPanelContext` provider 가 app/(main)/screens/[screenId]/page.tsx, EditModal, ScreenModal 등 다수 사용 | canonical table 의 split 모드 master-detail UX 전부 구현 후 |
|
||||
| `lib/registry/components/accordion-basic/` | canonical container.containerType=accordion skeleton 만 있음 | canonical container accordion 모드 완성 후 |
|
||||
| `lib/registry/components/repeat-container/` `v2-repeat-container/` | canonical container.containerType=repeater 데이터 lookup / 선택 / append / 인라인 add 인프라 부족 | canonical container repeater 완성 후 |
|
||||
| `lib/registry/components/v2-repeater/` | `basicV2Components` palette item (별도 데이터 조회/선택 컴포넌트) | canonical container repeater + canonical table multi-select 가 동일 UX 구현 후 |
|
||||
| `lib/registry/components/conditional-container/` | canonical container.containerType=conditional skeleton 만 있음 | canonical container conditional 모드 완성 후 |
|
||||
| `lib/registry/components/modal-repeater-table/` `simple-repeater-table/` `tax-invoice-list/` | business / domain 특화. canonical table parity 부족 | 도메인별 별도 마이그레이션 |
|
||||
| `multilangLabelExtractor.ts` / `MultilangSettingsModal.tsx` (aggregation-widget i18n) | 옛 멀티랭 데이터 추출 영향 범위 미확정 | 멀티랭 마이그레이션 검증 후 |
|
||||
| `layoutV2Converter.ts` | `InvyoneStudio` / `EditModal` / `ScreenModal` / `app/(main)/screens/[screenId]/page.tsx` 핵심 layer↔V2 변환 | 솔루션 전체 V2 단일 포맷 표준화 후 |
|
||||
| `app/test-card-responsive/page.tsx` | ResizeObserver 패턴 테스트 페이지 | 별도 테스트 페이지 cleanup 시 |
|
||||
| `types/component-events.ts` 옛 컴포넌트 발행/구독 주석 | 코드 동작 영향 없음 (주석만) | 별도 type cleanup 시 |
|
||||
| `V2TableListConfigPanel.tsx` + `V2ListConfigPanel.tsx` | `InvDataConfigPanel` 이 v2-list / v2-table-list canonical 경로에서 사용 | v2-list / v2-table-list 폐기 후 |
|
||||
| `V2RepeatContainerConfigPanel.tsx` | `v2-repeat-container/index.ts` ComponentDefinition.config_panel | v2-repeat-container 폐기 후 |
|
||||
| `V2SplitPanelLayoutConfigPanel.tsx` | `v2-split-panel-layout/index.ts` ComponentDefinition.config_panel | split-panel-layout 폐기 후 |
|
||||
| `lib/registry/components/v2-split-panel-layout/SplitPanelLayoutConfigPanel.tsx` | `getComponentConfigPanel.CONFIG_PANEL_MAP` v2-split-panel-layout 직접 import | split-panel-layout 폐기 후 |
|
||||
| `componentConfig.ts` 의 v2-table-list / v2-split-panel-layout / v2-repeat-container / v2-repeater schema | auto-register 보존 항목과 짝. 새 생성 시 ComponentDefinition.default_config 와 다를 수 있음 (이중 source) | 위 폴더 폐기 시 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Verification
|
||||
|
||||
| Command | Result |
|
||||
|---|---|
|
||||
| `git diff --check` | **pass** (whitespace 오류 0건) |
|
||||
| `rg "v2-input\|v2-select\|V2InputRenderer\|V2SelectRenderer" frontend/lib frontend/components frontend/app frontend/types frontend/styles` | **0건** (acceptance pass) |
|
||||
| `rg "EntityPicker\|entity-picker\|EntitySearchModal" frontend/lib/registry/components/input frontend/components/v2/config-panels/InvFieldConfigPanel.tsx` | **0건** (acceptance pass) |
|
||||
| `rg "v2-aggregation-widget\|v2-status-count\|aggregation-widget" frontend/lib frontend/components frontend/app frontend/types` | 50 → **40건** (10건 감소). 잔여: alias 9건 (런타임 라우팅, §3) + 주석/문서 25건 (영향 없음) + i18n 5건 (hard blocker) + 테스트 페이지 3건 (hard blocker, §4) |
|
||||
| `rg "v2-table-list\|table-list\|v2-split-panel-layout\|split-panel-layout\|split-panel-layout2" frontend/lib frontend/components frontend/app frontend/types` | 232 → **216건** (16건 감소). 잔여 대부분: table-list/ + v2-table-list/ + split-panel-layout/ 보존 폴더 내부 참조 (FlowWidget shared / master-detail UX hard blocker §4) |
|
||||
| `rg "v2-tabs-widget\|tabs-widget\|v2-section-card\|v2-section-paper\|section-card\|section-paper\|v2-repeat-container\|repeat-container\|v2-repeater" frontend/lib frontend/components frontend/app frontend/types` | 164 → **138건** (26건 감소). 잔여 대부분: repeat-container/ + v2-repeat-container/ + v2-repeater/ + accordion-basic/ + conditional-container/ 보존 폴더 내부 참조 (canonical skeleton 부족 hard blocker §4) + InvyoneStudio canonical 인식 분기 |
|
||||
| `cd backend-spring && ./gradlew compileJava` | **BUILD SUCCESSFUL** (UP-TO-DATE, backend 변경 0건) |
|
||||
| 삭제된 폴더 외부 import 잔여 | **0건** (`from "@/lib/registry/components/(aggregation-widget\|tabs/\|v2-tabs-widget\|section-card\|v2-section-card\|section-paper\|v2-section-paper\|v2-aggregation-widget\|v2-status-count)"` rg) |
|
||||
| 삭제된 V2 ConfigPanel 잔여 참조 | **0건** (`V2AggregationWidgetConfigPanel\|V2StatusCountConfigPanel` rg) |
|
||||
| FieldConfig / DataPort 계약 | `frontend/types/invyone-component.ts` 변경 0건 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 잔여 매칭 카테고리별 분류
|
||||
|
||||
### 6.1 Stats (40건)
|
||||
|
||||
- **alias 라우팅 (코드 동작) — 9건**: `templateMigrate.ts` (3), `DynamicComponentRenderer.tsx` (3), `getComponentConfigPanel.CONFIG_PANEL_ALIAS` (3). 모두 옛 ID → canonical `stats` 알리아싱 — runtime migration boundary (구현된 canonical replacement)
|
||||
- **주석/문서 — 25건**: 제거 작업 흔적 주석 (componentConfig.ts, registry/components/index.ts, getComponentConfigPanel.tsx, withContainerQuery.css), 흡수 대상 문서 (stats/index.ts, stats/types.ts), 옛 ID 주석 (ComponentsPanel hiddenComponents — ComponentRegistry 에 없으므로 동작 영향 0), 발행/구독 주석 (component-events.ts), 옛 컴포넌트 알림 주석 (UnifiedRepeater.tsx). 코드 동작 영향 0
|
||||
- **i18n hard blocker — 5건**: `multilangLabelExtractor.ts` (2), `MultilangSettingsModal.tsx` (3). 옛 멀티랭 데이터 추출 보존
|
||||
- **테스트 페이지 — 3건**: `test-card-responsive/page.tsx` 옛 ResizeObserver 패턴 데모
|
||||
|
||||
### 6.2 Table (216건)
|
||||
|
||||
- **table-list/ + v2-table-list/ 보존 폴더 내부 — 약 180건**: FlowWidget (SingleTableWithSticky/ColumnConfig) hard blocker §4
|
||||
- **split-panel-layout/ + v2-split-panel-layout/ + split-panel-layout2/ 보존 폴더 내부 — 약 25건**: master-detail UX hard blocker §4
|
||||
- **canonical 인식 추가됨 — 11건**: ActionTab (4) + DataTab (4) + InvLegacyButtonConfigPanel (2) + ButtonPrimaryComponent (1). 옛 ID 와 canonical "table" 함께 매칭 (런타임 호환)
|
||||
- **InvyoneStudio split-panel drag/drop 분기**: 옛 화면 호환 hard blocker §4
|
||||
|
||||
### 6.3 Container (138건)
|
||||
|
||||
- **repeat-container/ + v2-repeat-container/ + v2-repeater/ + accordion-basic/ + conditional-container/ 보존 폴더 내부 — 약 100건**: canonical container.repeater/accordion/conditional skeleton 부족 hard blocker §4
|
||||
- **InvyoneStudio canonical container 인식 분기 — 9건**: canonical container (containerType=tabs) 인식 추가됨 (구현된 canonical replacement)
|
||||
- **InteractiveScreenViewer / TabsWidget canonical 인식 — 2건**: 동일
|
||||
- **buttonActions.ts 옛 v2-repeater 처리 — 2건**: hard blocker §4
|
||||
- **container/types.ts 흡수 대상 문서 — 5건**: canonical container 자체
|
||||
|
||||
---
|
||||
|
||||
## 7. Acceptance check 요약 (2026-05-19 후속 수정 기준)
|
||||
|
||||
| 조건 | 결과 |
|
||||
|---|---|
|
||||
| new Studio creation paths use canonical | ✅ palette BASIC_IDS 만 canonical / advanced 노출 |
|
||||
| FieldConfig / DataPort contracts preserved | ✅ 변경 0건 |
|
||||
| v2-input/v2-select / EntityPicker / EntitySearchModal 재도입 X | ✅ rg 0건 |
|
||||
| `git diff --check` | ✅ pass (EXIT 0) |
|
||||
| backend `./gradlew compileJava` | ✅ BUILD SUCCESSFUL |
|
||||
| `rg "v2-input\|v2-select\|V2InputRenderer\|V2SelectRenderer"` (frontend/lib + components + app + types + styles) | ✅ 0건 |
|
||||
| `rg "EntityPicker\|entity-picker\|EntitySearchModal"` (input + InvFieldConfigPanel) | ✅ 0건 |
|
||||
| `rg` 삭제 폴더 import (`aggregation-widget`/`v2-aggregation-widget`/`v2-status-count`/`tabs`/`v2-tabs-widget`/`section-card`/`v2-section-card`/`section-paper`/`v2-section-paper`) | ✅ 0건 |
|
||||
| `test ! -e` 9개 legacy 폴더 | ✅ ALL 9 FOLDERS DELETED OK |
|
||||
| `git diff --quiet -- frontend/components/control frontend/components/dash frontend/styles/control-mode.css` | ✅ EXIT 0 (range-out 변경 모두 제거) |
|
||||
| `frontend/components/control/controlDemo.ts` (= 실제 `controlPreviewData.ts`) 미존재 | ✅ No such file or directory |
|
||||
| 잔여 매칭 카운트 (사용자 acceptance 패턴 기준) | stats 패턴 **4건** / table 패턴 **4건** / container 패턴 **4건** |
|
||||
| 남은 매칭 모두 (1) 구현된 canonical replacement / (2) 삭제된 path / (3) concrete blocker / (4) domain preserved 로 분류 | ✅ §3 / §2 / §4 / §9 |
|
||||
|
||||
---
|
||||
|
||||
## 8. Remaining risks
|
||||
|
||||
1. **canonical container.containerType=accordion / repeater / conditional 미구현**:
|
||||
skeleton 만 있음. 새 화면에서 container 를 만들고 containerType 을 이들로 변경
|
||||
하면 동작 부족. palette 에 container 는 한 가지로 노출되므로 사용자 혼동 가능.
|
||||
→ Phase G.x 추가 작업 필요 (canonical container 완성).
|
||||
|
||||
2. **canonical table displayMode='split' 의 leftPanel/rightPanel UX 부재**:
|
||||
옛 split-panel-layout 의 master-detail (drag/drop, selection sync, resize,
|
||||
nested child) 없음. 새 화면에서 split 모드 사용 시 기능 부족.
|
||||
|
||||
3. **옛 v2-aggregation-widget / v2-status-count config 호환 미보장**:
|
||||
auto-register 제거 + 폴더 삭제 → ComponentRegistry 에 없음. alias 로 canonical
|
||||
stats 라우팅되지만 config 형식이 다르므로 빈 stats 렌더링. 메모리
|
||||
`project_solution_definition_phase` 에 따라 round-trip 호환 미보장 — 사용자가
|
||||
옛 화면 재설계 필요.
|
||||
|
||||
4. **frontend 전체 typecheck / lint 미실행**: 변경 파일에 import 잔여 0건 확인,
|
||||
삭제 파일 사용처 0건 확인. 하지만 pre-existing typecheck 오류 가능성 (이전부터
|
||||
존재). 변경 폴더 (lib/registry/components/, components/screen/, lib/utils/) 에는
|
||||
새 import-not-found 오류 0건 보장.
|
||||
|
||||
5. **InvyoneStudio.tsx split-panel/tabs-widget drag/drop 분기 보존**: 옛 화면 호환
|
||||
유지. split-panel-layout 폐기 시 InvyoneStudio drag/drop 분기도 같이 정리.
|
||||
|
||||
6. **multilangLabelExtractor.ts / MultilangSettingsModal.tsx aggregation-widget i18n**:
|
||||
옛 멀티랭 데이터 추출 보존. canonical stats 로 마이그레이션 시 별도 작업 필요.
|
||||
|
||||
---
|
||||
|
||||
## 9. Codex 후속 검증 — 범위 밖 변경 제거 (2026-05-19)
|
||||
|
||||
Codex 검증에서 canonical cleanup 범위 (이 문서 본문 + 이전 보고서 §2~§4) 를 넘어
|
||||
`frontend/components/control/` 와 `frontend/components/dash/` 의 데모/대시보드 변경,
|
||||
그리고 `frontend/styles/control-mode.css` 의 flow-active styling 확장이 발견됨.
|
||||
이번 cleanup 결과에는 포함하면 안 되는 범위 밖 작업.
|
||||
|
||||
### 9.1 제거 사유
|
||||
|
||||
- canonical data-view cleanup 의 스코프 (보존해야 하는 canonical 파일 + 의도된 삭제
|
||||
대상) 와 무관.
|
||||
- `controlPreviewData.ts` (= prompt 의 `controlDemo.ts`) 안에 `previewField`,
|
||||
`ORDER_ID`, `USER_ID`, `DEPT_CODE` 같은 데모 fixture 가 있음.
|
||||
- `RuleBuilder.tsx`, `ControlPalette.tsx`, `DashboardCanvas.tsx`,
|
||||
`control-mode.css` 에서 `controlPreviewData` / `previewData` / `flow-active` 등
|
||||
데모 패턴 import 가 확인됨.
|
||||
- `git diff --check` 와 acceptance command 자체는 통과하지만 PR scope 가 잘못 부풀어
|
||||
있어 분리해야 함.
|
||||
|
||||
### 9.2 변경 전 사전 검증
|
||||
|
||||
`git diff -- frontend/components/control frontend/components/dash frontend/styles/control-mode.css` 출력을 다음 패턴으로 grep:
|
||||
|
||||
```
|
||||
stats|grouped-table|card-list|FieldConfig|DataPort|sourceProvider|dataReceiver|
|
||||
aggregation-widget|v2-table-list|v2-status-count|v2-tabs-widget|v2-section|
|
||||
EntityPicker|EntitySearchModal|InvStatsConfigPanel|InvTableConfigPanel|
|
||||
InvContainerConfigPanel|INVYONE_UNIFIED_IDS|CONFIG_PANEL_ALIAS|LEGACY_TO_UNIFIED|
|
||||
fillParentTypes|fullWidthComponents
|
||||
```
|
||||
|
||||
결과: `FieldConfig` 만 매칭 — control/dash 의 demo TableMeta 타입 (`type TableMeta = { columns: FieldConfig[] }`) 정의에서 type 으로 import 한 것뿐. canonical
|
||||
data-view cleanup 의 직접 변경 (alias 등록 / schema 삭제 / ConfigPanel 라우팅) 과
|
||||
무관. `FieldConfig` 타입 자체 (frontend/types/invyone-component.ts) 도 변경 0건. →
|
||||
revert 안전 확인.
|
||||
|
||||
### 9.3 되돌린 파일 (9 tracked + 1 untracked)
|
||||
|
||||
`git restore` (HEAD 로 복원):
|
||||
|
||||
- `frontend/components/control/ControlMode.tsx`
|
||||
- `frontend/components/control/ControlPalette.tsx`
|
||||
- `frontend/components/control/FlowViewer.tsx`
|
||||
- `frontend/components/control/PortHandle.tsx`
|
||||
- `frontend/components/control/RuleBuilder.tsx`
|
||||
- `frontend/components/control/hooks/useControlMode.ts` (prompt 명시 8개 외 +1. CTRL_NODE_TYPES prettier 포맷팅만 — canonical 무관. acceptance check `git diff --quiet -- frontend/components/control` 통과 위해 동일 범위 밖 변경으로 함께 restore)
|
||||
- `frontend/components/dash/DashboardCanvas.tsx`
|
||||
- `frontend/components/dash/DashboardLayout.tsx`
|
||||
- `frontend/styles/control-mode.css`
|
||||
|
||||
`rm`:
|
||||
|
||||
- `frontend/components/control/controlPreviewData.ts` (= prompt 의 `controlDemo.ts`. untracked. demo fixture)
|
||||
|
||||
### 9.4 보존된 canonical cleanup 파일 (변경 그대로 유지)
|
||||
|
||||
- `frontend/lib/registry/DynamicComponentRenderer.tsx`
|
||||
- `frontend/lib/registry/components/index.ts`
|
||||
- `frontend/lib/utils/getComponentConfigPanel.tsx`
|
||||
- `frontend/lib/utils/responsiveDefaults.ts`
|
||||
- `frontend/lib/utils/templateMigrate.ts`
|
||||
- `frontend/lib/schemas/componentConfig.ts`
|
||||
- `frontend/types/v2-components.ts`
|
||||
- `frontend/lib/registry/hoc/withContainerQuery.css`
|
||||
- `frontend/components/screen/config-panels/button/DataTab.tsx`
|
||||
- `frontend/components/screen/config-panels/button-config/ActionTab.tsx`
|
||||
- `frontend/components/v2/config-panels/InvLegacyButtonConfigPanel.tsx`
|
||||
- `frontend/components/screen/InvyoneStudio.tsx`
|
||||
- `frontend/components/screen/RealtimePreviewDynamic.tsx`
|
||||
- `frontend/components/screen/ScreenNode.tsx`
|
||||
- `frontend/components/screen/InteractiveScreenViewer.tsx`
|
||||
- `frontend/components/screen/widgets/TabsWidget.tsx`
|
||||
- `frontend/lib/registry/components/v2-button-primary/ButtonPrimaryComponent.tsx`
|
||||
- 의도된 9개 폴더 + 2개 V2 ConfigPanel 의 삭제 상태 유지
|
||||
|
||||
### 9.5 후속 잔여 매칭 분류 (사용자 acceptance 패턴)
|
||||
|
||||
| 패턴 | 카운트 | 분류 |
|
||||
|---|---|---|
|
||||
| `stats\|aggregation-widget\|v2-status-count` | 4건 | (1) 구현된 canonical replacement: `templateMigrate.LEGACY_TO_UNIFIED` / `DynamicComponentRenderer.LEGACY_TO_UNIFIED` / `getComponentConfigPanel.CONFIG_PANEL_ALIAS` alias 라우팅 + canonical `stats/index.ts` 흡수 대상 문서 |
|
||||
| `table-list\|v2-table-list` | 4건 | (3) concrete hard blocker: `lib/registry/components/table-list/` (FlowWidget SingleTableWithSticky 직접 import) + `lib/registry/components/v2-table-list/` 보존 폴더 내부 참조 |
|
||||
| `tabs-widget\|v2-tabs-widget\|section-card\|section-paper\|accordion-basic\|conditional-container\|repeat-container\|v2-repeat-container\|split-panel-layout` | 4건 | (3) hard blocker: `accordion-basic/` + `conditional-container/` + `repeat-container/` + `split-panel-layout` 3종 (canonical container skeleton 부족 / master-detail UX 다름 / SplitPanelContext provider) 보존 폴더 내부 참조 |
|
||||
|
||||
> 4 + 4 + 4 = 12 잔여 모두 §3 (구현된 canonical replacement, alias 라우팅) 또는
|
||||
> §4 (hard blocker 보존 폴더 내부 참조) 중 하나로 분류 — 이 cleanup 의 범위 안에서
|
||||
> 남은 dangling 매칭 0건.
|
||||
|
||||
---
|
||||
|
||||
## 10. 2026-05-19 추가 — Canonical Table-Like Helper 도입
|
||||
|
||||
§3 의 "ActionTab / DataTab / InvLegacyButtonConfigPanel / ScreenNode / InteractiveScreenViewer / TabsWidget canonical 인식 추가" 와 같은 흐름을 더 외부로 확장.
|
||||
`componentType === "table-list"` 단독 체크가 남아 있던 외부 active branch 를
|
||||
**canonical-aware helper** 로 일괄 교체했다.
|
||||
|
||||
> ★ 이번 단계는 **런타임 폴더 / schema / auto-register 삭제 아님.** 옛 화면 호환
|
||||
> hard blocker (§4 의 table-list/, v2-table-list/, componentConfig schema, registry
|
||||
> auto-register import) 는 모두 그대로 보존.
|
||||
|
||||
### 10.1 신규 helper (`frontend/lib/utils/componentTypeUtils.ts`)
|
||||
|
||||
세 가지 helper 를 같은 파일 끝에 새 block 으로 추가:
|
||||
|
||||
| Helper | 시그니처 | 인식 토큰 |
|
||||
|---|---|---|
|
||||
| `isTableLikeComponentType(typeValue)` | `(typeValue: unknown) => boolean` | `table` (canonical), `table-list`, `v2-table-list`, `data-table`, `datatable`. URL 등 prefix 가 붙으면 마지막 segment 도 fallback 검사 |
|
||||
| `isTableLikeComponent(component)` | `(component: unknown) => boolean` | 객체에서 `componentType` / `component_type` / `type` / `widgetType` / `widget_type` / `componentConfig.type` / `component_config.type` / `url` 후보 모두 검사. 어느 하나라도 table-like 면 true |
|
||||
| `getTableNameFromTableLikeComponent(component)` | `(component: unknown) => string \| undefined` | `componentConfig.selectedTable` → `componentConfig.tableName` → `componentConfig.table_name` → `component_config.selectedTable` → `component_config.tableName` → `component_config.table_name` → root `tableName` → root `table_name` 순으로 안전하게 추출 |
|
||||
|
||||
비식별 토큰 모음을 따로 두지 않고 `TABLE_LIKE_COMPONENT_TYPES: ReadonlySet<string>`
|
||||
한 곳에서 단일 source 로 관리.
|
||||
|
||||
### 10.2 helper 사용처 (외부 active branch 교체 결과)
|
||||
|
||||
| 파일 | 구 구현 | 신 구현 |
|
||||
|---|---|---|
|
||||
| `lib/utils/buttonActions.ts` `autoDetectDataSource` (구 line ~3267) | `comp.componentType === "table-list" && comp.componentConfig?.tableName` 단독 분기 | `isTableLikeComponent(comp) && getTableNameFromTableLikeComponent(comp)` — canonical `table` / hidden `v2-table-list` 도 dataSource 자동 감지 대상 |
|
||||
| `lib/utils/buttonActions.ts` `handleOpenModalWithData` (구 line ~3465) | 동일 패턴 | 동일 helper 호출. 로그 메시지 "TableList 자동 감지" → "Table-like 컴포넌트 자동 감지" 로 일반화 |
|
||||
| `lib/utils/buttonActions.ts` Excel `findTableListComponent` (구 line ~5283) | `comp.componentType === "table-list"` + 수동 `selectedTable` / `tableName` OR 체인 | `isTableLikeComponent(comp)` + `getTableNameFromTableLikeComponent(comp) === context.table_name` |
|
||||
| `app/(main)/screens/[screenId]/page.tsx` `hasTableWidget` (구 line 431) | `componentType === "table-list" \|\| componentType === "v2-table-list" \|\| widgetType === "table"` OR 체인 | `isTableLikeComponent(comp)`. canonical `table` 도 동일하게 자동 로드 skip |
|
||||
| `components/screen/widgets/TabsWidget.tsx` `screenInfoMap` (구 line 146) | `c.component_type === "table" \|\| === "v2-table-list" \|\| === "table-list"` OR 체인 + `tableComp?.component_config?.selectedTable` 수동 추출 | `isTableLikeComponent(c)` + `getTableNameFromTableLikeComponent(tableComp)`. snake_case `component_type` 누락 위험도 동시 해소 |
|
||||
| `components/screen/modals/MultilangSettingsModal.tsx` `getTypeIcon` (구 line 154) | `case "table-list": <Table2 />` 단독 | `case "table" / "table-list" / "v2-table-list"` fallthrough 묶음. 기존 호환 유지 |
|
||||
| `components/screen/modals/MultilangSettingsModal.tsx` `NON_INPUT_COMPONENT_TYPES` (구 line 196) | `"table-list"` 만 Set 에 | `"table"`, `"v2-table-list"` 추가. canonical / hidden legacy 모두 라벨 다국어 처리 제외 |
|
||||
| `components/screen/panels/ComponentsPanel.tsx` (주석만) | `allComponents` 위 주석 + `hiddenComponents` `table-list` 주석이 "→ v2-table-list" 식으로 옛 매핑 표기 | "canonical `table` 이 새 생성 경로, v2-table-list 는 hidden legacy 등록 (registry hard blocker 보존)" 으로 명확화. hidden list 자체는 유지 |
|
||||
|
||||
### 10.3 보존한 Hard Blocker (이번 단계에서 의도적으로 건드리지 않음)
|
||||
|
||||
| 위치 | 보존 이유 |
|
||||
|---|---|
|
||||
| `lib/registry/components/v2-table-list/**`, `lib/registry/components/table-list/**` | §4 와 동일. 옛 저장 화면에서 `componentType: "v2-table-list"` / `"table-list"` 를 직접 가리키는 layout JSON 다수 — 런타임 렌더 미보장 시 화면 깨짐 |
|
||||
| `lib/registry/components/index.ts` 의 `table-list` / `v2-table-list` auto-register import | ComponentRegistry 등록이 빠지면 옛 화면 로드 실패. 삭제 금지 |
|
||||
| `lib/schemas/componentConfig.ts` 의 `v2-table-list` schema / default | old layout load compatibility (`componentConfig` schema 검증을 통과해야 함). 삭제 금지 |
|
||||
| `buttonActions.ts` 의 `split-panel-layout` 분기 (line ~3293, ~3477) | table-like 와는 별개 컴포넌트. `componentConfig.leftPanel.tableName` 라는 고유 경로 사용. helper 적용 대상 아님 → §4 와 동일하게 보존 |
|
||||
| `frontend/components/control/**`, `frontend/components/dash/**`, `frontend/styles/control-mode.css` | 본 cleanup 범위 외 (§9 의 control/dash revert 와 동일 정책) |
|
||||
| 금지 토큰 (`v2-input`, `v2-select`, `V2InputRenderer`, `V2SelectRenderer`, `EntityPicker`, `entity-picker`, `EntitySearchModal`) 재도입 금지 | 본 작업에서 재도입 0건 (§10.4 acceptance) |
|
||||
|
||||
### 10.4 Acceptance (이번 단계)
|
||||
|
||||
| 검증 항목 | 명령 | 결과 |
|
||||
|---|---|---|
|
||||
| Whitespace clean | `git diff --check` | ✅ pass (출력 없음) |
|
||||
| 금지 토큰 (input canonical) | `rg "v2-input\|v2-select\|V2InputRenderer\|V2SelectRenderer" frontend/lib frontend/components frontend/app frontend/types frontend/styles` | ✅ 0건 |
|
||||
| EntityPicker 잔재 | `rg "EntityPicker\|entity-picker\|EntitySearchModal" frontend/lib/registry/components/input frontend/components/v2/config-panels/InvFieldConfigPanel.tsx` | ✅ 0건 |
|
||||
| 3개 파일 `componentType === "table-list"` 단독 분기 | `rg 'componentType === "table-list"' frontend/lib/utils/buttonActions.ts "frontend/app/(main)/screens/[screenId]/page.tsx" frontend/components/screen/widgets/TabsWidget.tsx` | ✅ 0건 |
|
||||
| backend-spring 컴파일 | `cd backend-spring && ./gradlew compileJava` | ✅ BUILD SUCCESSFUL |
|
||||
| 변경 파일 TS 신규 에러 | `npx tsc --noEmit` — 본 단계에서 손댄 line 들 | ✅ 0건 신규 에러 (helper 추가 line, OR 체인 교체 line 모두 깨끗. 기존 에러는 본 cleanup 범위 외라 유지) |
|
||||
|
||||
### 10.5 변경 파일 요약 (이번 단계)
|
||||
|
||||
```
|
||||
M frontend/lib/utils/componentTypeUtils.ts (+helper block 100여 줄)
|
||||
M frontend/lib/utils/buttonActions.ts (3곳 helper 호출로 교체, +1 import)
|
||||
M frontend/app/(main)/screens/[screenId]/page.tsx (hasTableWidget 한 줄 helper 호출, +1 import)
|
||||
M frontend/components/screen/widgets/TabsWidget.tsx (screenInfoMap helper 호출, +1 import)
|
||||
M frontend/components/screen/modals/MultilangSettingsModal.tsx (icon/Set 분류만)
|
||||
M frontend/components/screen/panels/ComponentsPanel.tsx (주석 정리만)
|
||||
M notes/gbpark/2026-05-19-canonical-data-view-cleanup-followup.md (본 §10)
|
||||
```
|
||||
|
||||
### 10.6 후속 작업 후보 (이번 범위 밖)
|
||||
|
||||
- v2-table-list / table-list 폴더의 실제 폐기 — old layout 마이그레이션이 끝난 뒤
|
||||
§4 hard blocker 와 함께 별도 phase 로 진행
|
||||
- `componentConfig.ts` schema / default 의 v2-table-list 제거 — 동일 조건
|
||||
- `buttonActions.ts` 의 `split-panel-layout` 분기 — canonical table.displayMode='split'
|
||||
master-detail UX 완성 후 §4 와 함께 마이그레이션
|
||||
- 기존 page.tsx / buttonActions.ts 의 기존 TS 에러 (snake_case vs camelCase 타입 불일치)
|
||||
정리 — 본 cleanup 과 무관한 별도 트랙
|
||||
|
||||
---
|
||||
|
||||
## 11. 2026-05-19 추가 (2차) — Helper 확산 (button/preview/backend)
|
||||
|
||||
§10 에서 도입한 helper 를 **외부 active branch 8 frontend + 2 backend** 까지 확산.
|
||||
런타임 보존 폴더 / schema / auto-register 는 그대로 유지하고 active 분기만 교체.
|
||||
|
||||
### 11.1 변경 파일 (10개)
|
||||
|
||||
| 파일 | 변경 요지 |
|
||||
|---|---|
|
||||
| `frontend/components/screen/config-panels/button/DataTab.tsx` | 로컬 `isDataTransferComponentType` 정의를 `isTableLikeComponentType` 기반으로 정리. table-like 외 `repeater-field-group` / `form-group` 만 별도 `DATA_TRANSFER_EXTRA_PATTERNS` 로 보존 |
|
||||
| `frontend/components/screen/config-panels/button-config/ActionTab.tsx` | 동일한 로컬 helper 정리 + `compType === "table-list"` 단독 분기 2곳 (`autoDetect` modal source 감지, `openModalWithData` 소스 감지) 을 `isTableLikeComponent` + `getTableNameFromTableLikeComponent` 로 교체. `compId === "table-list"` OR 체인 (테이블명 폴백) 도 `isTableLikeComponentType(compId)` 로 정리. `split-panel-layout` / `screen-split-panel` / `split-panel-layout2` 는 별개 컴포넌트라 그대로 보존 |
|
||||
| `frontend/components/v2/config-panels/InvLegacyButtonConfigPanel.tsx` | 동일한 로컬 `isDataTransferComponentType` 정리 |
|
||||
| `frontend/components/screen/ScreenNode.tsx` | `componentKind === "table-list"` 포함 OR 체인을 `isTableLikeComponentType(componentKind)` + `TABLE_LIKE_EXTRA_KINDS` (grouped-table / card-list / data-grid) 로 정리. 미니어처 색상 결정용 |
|
||||
| `frontend/components/screen/RealtimePreviewDynamic.tsx` | `fillParentTypes` 배열의 `table` / `table-list` / `v2-table-list` 를 helper 로 통합 + 그 외 split/tabs layout 만 명시 목록 유지. `componentConfig.type === "table-list"` 단독 분기 2곳 (size.height 최소 200 보장, 기본 200 fallback) 도 helper 호출로 교체 |
|
||||
| `frontend/lib/registry/components/button-primary/ButtonPrimaryComponent.tsx` | `provider.component_type === "table-list"` 단독 탐색 → `isTableLikeComponentType(provider.component_type)` |
|
||||
| `frontend/lib/registry/components/v2-button-primary/ButtonPrimaryComponent.tsx` | 동일한 패턴 + DataReceiver 자동 탐색의 `rt === "table" \|\| === "table-list" \|\| === "data-table"` OR 체인 → helper 한 호출 |
|
||||
| `frontend/lib/registry/components/universal-form-modal/UniversalFormModalConfigPanel.tsx` | `compType === "table-list" \|\| === "interactive-data-table"` OR 체인 → `isTableLikeComponentType(compType) \|\| compType === "interactive-data-table"` |
|
||||
| `backend-spring/src/main/java/com/erp/service/ScreenGroupService.java` | `private static int countTableLikeWidgets(Map<String,Integer>)` 헬퍼 신규 — `table` + `table-list` + `v2-table-list` 합산. `screenType = "grid"` 추론 분기 2곳 (`extractScreenLayout` / `getScreenSummary`) 모두 helper 사용. 셋 중 어느 것이든 있으면 grid |
|
||||
| `backend-spring/src/main/resources/mapper/screenGroup.xml` | `selectSavableScreensForGroup` 의 `NOT EXISTS` 서브쿼리에서 `componentType = 'table-list'` 단독을 `IN ('table', 'table-list', 'v2-table-list')` 로 확장. 체크박스 활성 판정도 legacy `componentConfig.checkbox.enabled` 와 canonical `componentConfig.showCheckbox` 를 SQL OR 로 구분 처리 |
|
||||
|
||||
### 11.2 보존한 Hard Blocker (이번 단계에서 의도적으로 건드리지 않음)
|
||||
|
||||
| 위치 | 보존 이유 |
|
||||
|---|---|
|
||||
| `lib/registry/components/v2-table-list/**`, `lib/registry/components/table-list/**` | §4 / §10.3 와 동일. 옛 저장 layout JSON 의 직접 type 지목 — 폴더 삭제/대형 수정 시 화면 깨짐 |
|
||||
| `lib/schemas/componentConfig.ts` 의 v2-table-list schema / default | old layout config 검증 통과 hard blocker. 삭제 금지 |
|
||||
| `lib/registry/components/repeat-container/**` 의 `dataSourceType = "table-list"` enum | **컴포넌트 type 이 아니라 데이터 소스 모드 enum 값**. helper 적용 대상 아님. 같은 문자열이지만 도메인이 다름 → 이번 범위에서 건드리지 않음 |
|
||||
| `frontend/components/v2/config-panels/InvDataConfigPanel.tsx` 의 `v2-table-list` 참조 | old layout config hard blocker. `InvDataConfigPanel` 이 v2-list / v2-table-list canonical 경로에서 사용 (§4 참조). 보존 |
|
||||
| `ActionTab.tsx` / `RealtimePreviewDynamic.tsx` 의 `split-panel-layout` / `split-panel-layout2` / `screen-split-panel` / `v2-tab-container` / `tabs-widget` 등 분기 | table-like 와 별개 컴포넌트. `componentConfig.leftPanel.*` / `componentConfig.tabs.*` 등 고유 path 사용. helper 적용 대상 아님 |
|
||||
| `frontend/components/control/**`, `frontend/components/dash/**`, `frontend/styles/control-mode.css` | §9 정책과 동일. 본 cleanup 범위 외 |
|
||||
| 금지 토큰 (`v2-input`, `v2-select`, `V2InputRenderer`, `V2SelectRenderer`, `EntityPicker`, `entity-picker`, `EntitySearchModal`) | 본 작업에서 재도입 0건 |
|
||||
|
||||
### 11.3 Acceptance (이번 단계)
|
||||
|
||||
| 검증 항목 | 명령 | 결과 |
|
||||
|---|---|---|
|
||||
| Whitespace clean | `git diff --check` | ✅ pass (출력 없음) |
|
||||
| 금지 토큰 (input canonical) | `rg "v2-input\|v2-select\|V2InputRenderer\|V2SelectRenderer" frontend/lib frontend/components frontend/app frontend/types frontend/styles` | ✅ 0건 |
|
||||
| EntityPicker 잔재 | `rg "EntityPicker\|entity-picker\|EntitySearchModal" frontend/lib/registry/components/input frontend/components/v2/config-panels/InvFieldConfigPanel.tsx` | ✅ 0건 |
|
||||
| 10개 수정 대상 파일 `componentType === "table-list"` 단독 분기 | `rg 'componentType === "table-list"\|component_type === "table-list"'` (수정 대상 8개 frontend 파일 한정) | ✅ 0건 |
|
||||
| backend-spring 컴파일 | `cd backend-spring && ./gradlew compileJava` | ✅ BUILD SUCCESSFUL |
|
||||
| 변경 파일 TS 신규 에러 | `npx tsc --noEmit` — 본 단계 손댄 line | ✅ 0건 신규 에러 (helper 추가/교체 line 모두 깨끗. 기존 에러는 §10.4 와 동일하게 본 범위 외라 유지) |
|
||||
|
||||
### 11.4 helper 사용 사이트 누적 (§10 + §11)
|
||||
|
||||
| Helper | 사용처 |
|
||||
|---|---|
|
||||
| `isTableLikeComponentType(typeValue)` | `componentTypeUtils.ts` 내부 (`isTableLikeComponent` 의 부품), `DataTab.tsx`, `ActionTab.tsx`, `InvLegacyButtonConfigPanel.tsx`, `ScreenNode.tsx`, `RealtimePreviewDynamic.tsx`, `ButtonPrimaryComponent.tsx` (×2), `UniversalFormModalConfigPanel.tsx` |
|
||||
| `isTableLikeComponent(component)` | `buttonActions.ts` (×3), `screens/[screenId]/page.tsx`, `TabsWidget.tsx`, `ActionTab.tsx` (×2) |
|
||||
| `getTableNameFromTableLikeComponent(component)` | `buttonActions.ts` (×3), `TabsWidget.tsx`, `ActionTab.tsx` (×2) |
|
||||
|
||||
### 11.5 후속 작업 후보 (이번 범위 밖)
|
||||
|
||||
- canonical table 의 `showCheckbox` config 실제 검증 — `screenGroup.xml` 의 OR 분기가
|
||||
canonical 화면 SQL 결과에 미치는 영향 확인 (실 데이터 검증 필요)
|
||||
- `ActionTab.tsx` 의 `v2-list` 분기 — 별도 컴포넌트이므로 v2-list 폐기 시 같이 정리
|
||||
- `ScreenNode.TABLE_LIKE_EXTRA_KINDS` (grouped-table / card-list / data-grid) — canonical
|
||||
컴포넌트군 정착 후 `TABLE_LIKE_COMPONENT_TYPES` 본체로 흡수 검토
|
||||
- `repeat-container` 의 `dataSourceType = "table-list"` enum naming — 도메인 분리 위해
|
||||
`tableList` → `legacyTableList` 등으로 rename 검토 (별도 트랙)
|
||||
@@ -0,0 +1,210 @@
|
||||
# 2026-05-19 Claude Prompt — Canonical Data View Cleanup Scope Fix
|
||||
|
||||
아래 내용을 Claude Code 에 일반 프롬프트로 붙여넣는다. `/goal` 명령은 쓰지 않는다.
|
||||
|
||||
---
|
||||
|
||||
## Prompt
|
||||
|
||||
너는 이 repo 에서 이미 진행된 `canonical data-view cleanup` 결과를 최종 수습하는 역할이다.
|
||||
|
||||
중요: 이번 작업은 새로운 대규모 기능 구현이 아니다. 현재 diff 중 `stats/table/container/chart/card-list/grouped-table` canonical 정리 범위는 보존하되, 범위 밖 변경을 제거하고 검증 가능한 상태로 만드는 것이 목표다.
|
||||
|
||||
작업 전제:
|
||||
|
||||
- Workspace: `/Users/gbpark/invyone`
|
||||
- 원 설계 문서:
|
||||
- `notes/gbpark/2026-05-18-canonical-data-view-goal.md`
|
||||
- `notes/gbpark/2026-05-18-claude-goal-prompt-v2-strict.md`
|
||||
- 현재 후속 보고서:
|
||||
- `notes/gbpark/2026-05-19-canonical-data-view-cleanup-followup.md`
|
||||
- Codex 1차 검증 결과:
|
||||
- acceptance check 자체는 통과했다.
|
||||
- 하지만 Claude 가 canonical cleanup 범위를 넘어 `control/dash` 데모 기능을 추가했다.
|
||||
- 이 범위 밖 변경은 이번 cleanup 결과에 포함하면 안 된다.
|
||||
|
||||
절대 규칙:
|
||||
|
||||
1. `/goal` 을 사용하지 말고, 이 프롬프트 범위 안에서 한 번에 처리한다.
|
||||
2. `input` canonical 작업의 결과를 되돌리거나 훼손하지 않는다.
|
||||
3. `FieldConfig`, `DataPort`, `sourceProvider`, `dataReceiver`, `dbTable` 관련 계약을 깨지 않는다.
|
||||
4. `v2-input`, `v2-select`, `V2InputRenderer`, `V2SelectRenderer`, `EntityPicker`, `EntitySearchModal` 을 재도입하지 않는다.
|
||||
5. legacy/V2 삭제 또는 alias 정리는 “동작 경로가 canonical 으로 수렴하는 경우”에만 유지한다.
|
||||
6. 범위 밖 변경은 새 feature 로 인정하지 않는다. 이번 cleanup diff 에서 제거하거나, 제거가 위험하면 정확한 이유를 보고하고 중단한다.
|
||||
7. 사용자가 만든 것일 수 있는 unrelated backend/notes 변경은 임의로 되돌리지 않는다.
|
||||
|
||||
이번 작업에서 보존해야 하는 canonical cleanup 범위:
|
||||
|
||||
- canonical data-view 관련 registry/config/schema/type 정리
|
||||
- `frontend/lib/registry/DynamicComponentRenderer.tsx`
|
||||
- `frontend/lib/registry/components/index.ts`
|
||||
- `frontend/lib/utils/getComponentConfigPanel.tsx`
|
||||
- `frontend/lib/utils/responsiveDefaults.ts`
|
||||
- `frontend/lib/utils/templateMigrate.ts`
|
||||
- `frontend/lib/schemas/componentConfig.ts`
|
||||
- `frontend/types/v2-components.ts`
|
||||
- `frontend/lib/registry/hoc/withContainerQuery.css`
|
||||
- input 작업 후속 data-transfer 타입 판정 정리
|
||||
- `frontend/components/screen/config-panels/button/DataTab.tsx`
|
||||
- `frontend/components/screen/config-panels/button-config/ActionTab.tsx`
|
||||
- `frontend/components/v2/config-panels/InvLegacyButtonConfigPanel.tsx`
|
||||
- canonical data-view 신규/기존 연결
|
||||
- `frontend/lib/registry/components/stats/**`
|
||||
- `frontend/lib/registry/components/table/**`
|
||||
- `frontend/lib/registry/components/container/**`
|
||||
- `frontend/lib/registry/components/chart/**`
|
||||
- `frontend/lib/registry/components/card-list/**`
|
||||
- `frontend/lib/registry/components/grouped-table/**`
|
||||
- 의도된 삭제 대상
|
||||
- `frontend/lib/registry/components/aggregation-widget/**`
|
||||
- `frontend/lib/registry/components/v2-aggregation-widget/**`
|
||||
- `frontend/lib/registry/components/v2-status-count/**`
|
||||
- `frontend/lib/registry/components/tabs/**`
|
||||
- `frontend/lib/registry/components/v2-tabs-widget/**`
|
||||
- `frontend/lib/registry/components/section-card/**`
|
||||
- `frontend/lib/registry/components/v2-section-card/**`
|
||||
- `frontend/lib/registry/components/section-paper/**`
|
||||
- `frontend/lib/registry/components/v2-section-paper/**`
|
||||
- `frontend/components/v2/config-panels/V2AggregationWidgetConfigPanel.tsx`
|
||||
- `frontend/components/v2/config-panels/V2StatusCountConfigPanel.tsx`
|
||||
|
||||
이번 작업에서 제거해야 하는 범위 밖 변경:
|
||||
|
||||
- `frontend/components/control/ControlMode.tsx`
|
||||
- `frontend/components/control/ControlPalette.tsx`
|
||||
- `frontend/components/control/FlowViewer.tsx`
|
||||
- `frontend/components/control/PortHandle.tsx`
|
||||
- `frontend/components/control/RuleBuilder.tsx`
|
||||
- `frontend/components/control/controlDemo.ts`
|
||||
- `frontend/components/dash/DashboardCanvas.tsx`
|
||||
- `frontend/components/dash/DashboardLayout.tsx`
|
||||
- `frontend/styles/control-mode.css`
|
||||
|
||||
위 파일들은 canonical data-view cleanup 과 무관한 제어모드 데모/대시보드 변경이다. 이번 작업에서는 포함하지 않는다. tracked 파일은 현재 branch 의 HEAD 상태로 되돌리고, untracked `controlDemo.ts` 는 삭제한다. 단, 되돌리기 전에 `git diff -- <path>` 로 확인했을 때 canonical data-view cleanup 과 직접 관련된 변경이 섞여 있으면 되돌리지 말고 보고한다.
|
||||
|
||||
진행 순서:
|
||||
|
||||
1. 현재 상태를 먼저 확인한다.
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff --name-status
|
||||
git diff --stat
|
||||
```
|
||||
|
||||
2. 범위 밖 변경을 확인한다.
|
||||
|
||||
```bash
|
||||
git diff -- frontend/components/control frontend/components/dash frontend/styles/control-mode.css
|
||||
git status --short -- frontend/components/control frontend/components/dash frontend/styles/control-mode.css
|
||||
```
|
||||
|
||||
확인 기준:
|
||||
- `controlDemo.ts`, demo table/meta, `createDemoRuleGraph`, `CONTROL_DEMO_TABLES`, `onLoadDemo`, flow-active styling 같은 변경은 범위 밖이다.
|
||||
- 해당 변경은 이번 cleanup 에 포함하지 않는다.
|
||||
|
||||
3. 범위 밖 변경만 제거한다.
|
||||
|
||||
안전 조건:
|
||||
- 제거 대상은 위 “이번 작업에서 제거해야 하는 범위 밖 변경” 목록으로 제한한다.
|
||||
- 다른 파일은 revert 하지 않는다.
|
||||
- repo 전체 reset, checkout, clean 금지.
|
||||
|
||||
예시:
|
||||
|
||||
```bash
|
||||
git restore -- frontend/components/control/ControlMode.tsx \
|
||||
frontend/components/control/ControlPalette.tsx \
|
||||
frontend/components/control/FlowViewer.tsx \
|
||||
frontend/components/control/PortHandle.tsx \
|
||||
frontend/components/control/RuleBuilder.tsx \
|
||||
frontend/components/dash/DashboardCanvas.tsx \
|
||||
frontend/components/dash/DashboardLayout.tsx \
|
||||
frontend/styles/control-mode.css
|
||||
rm frontend/components/control/controlDemo.ts
|
||||
```
|
||||
|
||||
`rm` 은 위 untracked 파일 하나에만 사용한다.
|
||||
|
||||
4. report 를 정정한다.
|
||||
|
||||
`notes/gbpark/2026-05-19-canonical-data-view-cleanup-followup.md` 를 업데이트한다.
|
||||
|
||||
반드시 반영할 내용:
|
||||
- summary 의 “7개 폴더” vs 실제 “9개 폴더” 불일치를 고친다.
|
||||
- Codex 검증에서 범위 밖 `control/dash` 변경이 발견되어 제거했다는 사실을 기록한다.
|
||||
- 제거한 범위 밖 파일 목록을 기록한다.
|
||||
- acceptance command 와 결과를 최신 상태로 다시 기록한다.
|
||||
- 잔여 매칭은 hard blocker/domain 으로만 남아야 하며, 각 보존 사유를 명시한다.
|
||||
|
||||
5. 필수 acceptance check 를 다시 실행한다.
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
rg "v2-input|v2-select|V2InputRenderer|V2SelectRenderer" frontend/lib frontend/components frontend/app frontend/types frontend/styles --glob '!**/node_modules/**'
|
||||
rg "EntityPicker|entity-picker|EntitySearchModal" frontend/lib/registry/components/input frontend/components/v2/config-panels/InvFieldConfigPanel.tsx --glob '!**/node_modules/**'
|
||||
rg -n "from .*components/(aggregation-widget|v2-aggregation-widget|v2-status-count|tabs|v2-tabs-widget|section-card|v2-section-card|section-paper|v2-section-paper)|import\\(.*components/(aggregation-widget|v2-aggregation-widget|v2-status-count|tabs|v2-tabs-widget|section-card|v2-section-card|section-paper|v2-section-paper)" frontend --glob '!**/node_modules/**'
|
||||
test ! -e frontend/lib/registry/components/aggregation-widget
|
||||
test ! -e frontend/lib/registry/components/v2-aggregation-widget
|
||||
test ! -e frontend/lib/registry/components/v2-status-count
|
||||
test ! -e frontend/lib/registry/components/tabs
|
||||
test ! -e frontend/lib/registry/components/v2-tabs-widget
|
||||
test ! -e frontend/lib/registry/components/section-card
|
||||
test ! -e frontend/lib/registry/components/v2-section-card
|
||||
test ! -e frontend/lib/registry/components/section-paper
|
||||
test ! -e frontend/lib/registry/components/v2-section-paper
|
||||
git diff --quiet -- frontend/components/control frontend/components/dash frontend/styles/control-mode.css
|
||||
git status --short -- frontend/components/control/controlDemo.ts
|
||||
```
|
||||
|
||||
backend compile:
|
||||
|
||||
```bash
|
||||
cd backend-spring
|
||||
./gradlew compileJava
|
||||
```
|
||||
|
||||
잔여 카운트도 다시 계산한다.
|
||||
|
||||
```bash
|
||||
rg -n "stats|aggregation-widget|v2-status-count" frontend/lib frontend/components frontend/app frontend/types --glob '!**/node_modules/**' | wc -l
|
||||
rg -n "table-list|v2-table-list" frontend/lib frontend/components frontend/app frontend/types --glob '!**/node_modules/**' | wc -l
|
||||
rg -n "tabs-widget|v2-tabs-widget|section-card|section-paper|accordion-basic|conditional-container|repeat-container|v2-repeat-container|split-panel-layout" frontend/lib frontend/components frontend/app frontend/types --glob '!**/node_modules/**' | wc -l
|
||||
```
|
||||
|
||||
주의:
|
||||
- `rg` 가 0건이어야 하는 check 는 exit code 1 이 정상일 수 있다. 출력이 0건이면 pass 로 기록한다.
|
||||
- 전체 `npm run lint` 는 기존 repo-wide lint 부채 때문에 이번 acceptance 조건이 아니다. 실행하지 않아도 된다. 실행했다면 기존 오류와 이번 변경 오류를 구분해서 보고한다.
|
||||
|
||||
6. 마지막으로 다음을 보고한다.
|
||||
|
||||
- canonical cleanup diff 는 유지됐는가
|
||||
- 범위 밖 `control/dash` 변경은 제거됐는가
|
||||
- deleted legacy folder/import 는 실제로 사라졌는가
|
||||
- input forbidden / EntityPicker forbidden 은 0건인가
|
||||
- backend compile 결과
|
||||
- 잔여 `stats/table/container` 매칭 수와 보존 사유
|
||||
- 수정한 파일 목록
|
||||
|
||||
완료 기준:
|
||||
|
||||
- `git diff --check` pass
|
||||
- input forbidden rg 출력 0건
|
||||
- EntityPicker forbidden rg 출력 0건
|
||||
- 삭제된 legacy component folder 가 실제로 존재하지 않음
|
||||
- 삭제된 legacy component folder 로 import 하는 active code 0건
|
||||
- `./gradlew compileJava` BUILD SUCCESSFUL
|
||||
- `git diff --quiet -- frontend/components/control frontend/components/dash frontend/styles/control-mode.css` pass
|
||||
- `frontend/components/control/controlDemo.ts` 가 untracked/존재 상태로 남아 있지 않음
|
||||
- follow-up report 의 folder deletion count 불일치가 수정됨
|
||||
- 남은 legacy/V2 매칭은 구현 canonical, 삭제 path, concrete hard blocker, domain preserved 중 하나로 분류됨
|
||||
|
||||
금지:
|
||||
|
||||
- repo 전체 `git reset`, `git checkout .`, `git clean -fd` 금지
|
||||
- unrelated backend 파일 revert 금지
|
||||
- `input`/`EntityPicker` 관련 옛 경로 재도입 금지
|
||||
- `control/dash` 데모 기능을 별도 feature 라고 주장하며 남겨두기 금지
|
||||
- acceptance 실패를 “분류 가능”만으로 통과 처리 금지
|
||||
|
||||
최종 답변은 짧게, 실행한 command 결과 중심으로 작성한다.
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user