# Template Engine Changelog > 이 문서는 그누보드7 템플릿 엔진의 내부 개발 버전 이력입니다. > `engine-v1.x.x` 버전은 그누보드7 릴리스 버전과 독립적입니다. > > 형식: [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) ## [engine-v1.66.0] - 2026-09-08 ### Added #### `number` 위젯 — 숫자 prop 편집 - `number` 위젯을 코어 레지스트리에 등록 — 종전 미등록이라 `widget:"number"` 컨트롤이 속성 모달에서 「지원하지 않는 컨트롤」로 폴백해 편집 자체가 불가했다 (registerCoreWidgets.ts) - `NumberWidget` 신설 — blur/Enter 커밋, `0` 은 유효값이라 삭제되지 않고, 비숫자는 미방출(저장본 무손실), 바인딩 문자열은 읽기전용 디그레이드 (StyleControlWidgets.tsx) - `EditorControlSpec` 에 `min`/`max`/`step` 명시 선언 (specTypes.ts) #### `nodeKey` apply 프리미티브 — 노드 최상위 구조키 패치 - `applyRecipe`/`reverseResolve` 에 `nodeKey` 분기 구현 — `coreProps` 가 선언만 하고 엔진 switch 에 case 가 없어 무음 no-op 이던 것을 실동작으로 (recipeEngine.ts) - 예약 노드키(`children`/`props`/`type` 등) 가드 — 템플릿이 그 키를 선언해도 노드가 파괴되지 않는다 (recipeEngine.ts) - 전용 UI 소유 키(`isolatedState`/`isolatedScopeId`)를 `resolveCorePropKeys` 렌더 목록에서 제외 — 같은 노드 키를 두 UI 가 쓰는 이중 경로 차단 (coreProps.ts) ### Fixed #### `image` 위젯 값이 `[object Object]` 로 기록되던 문제 - 단일 값 슬롯(`propValue`/`cssVar`/단일 `styleProp`)에 이미지 값 객체가 통째로 기록되던 문제 — 공용 헬퍼 `scalarizeImageValue` 로 url 만 축약한다. 게이트는 위젯 이름이며 값 형태 sniffing 이 아니다(`{position:'left'}` 같은 정당한 객체 prop 오인 삭제 방지) (recipeEngine.ts) - 축약 저장된 문자열을 위젯이 읽지 못하던 문제 — `propValue` 역해석이 `{url}` 로 되감는다. 표현식 문자열도 감싸 빈 피커로 보이지 않게 한다 (recipeEngine.ts) - 단일 값 슬롯 컨트롤에서 표시모드(채움/맞춤/타일) 버튼이 저장되지 않는데도 눌리던 문제 — 컨테이너째 미렌더하고 미리보기는 `contain` 으로 고정한다(저장되지 않는 값을 흉내내는 거짓 미리보기 제거) (ImagePickerControl.tsx) - 데이터 연결 값이 빈 피커로 보여 업로드 1클릭에 표현식이 소실되던 문제 — 원문 배지 표시 + 파괴적 조작 잠금 + 「직접 지정으로 바꾸기」 해제 경로 (ImagePickerControl.tsx) #### 레이아웃 편집기가 열린 직후 백지가 되던 문제 - 편집기 모드에서 `updateTemplateData` 가 빈 레이아웃(`components: []`)으로 재렌더해 같은 reactRoot 에 빈 트리를 커밋, `LayoutEditorChrome` 을 통째로 제거하던 문제 — 편집기 모드면 데이터 병합 후 렌더만 건너뛴다. `renderTemplate` 의 편집기 분기가 비동기라 부팅 중 `setGlobalState` 가 그 커밋 뒤에 도착할 때만 발현하는 경합이었다 (template-engine.ts) #### 데이터 연결 값이 조작 한 번에 소실되던 문제 - prop 자리에 저장된 `{{...}}`·설정 참조를 위젯이 해석하지 못해 빈 컨트롤로 보이고, 조작 시 그 연결이 사라지던 문제 — `ControlRenderer` 단일 게이트에서 원문 배지로 디그레이드하고 「직접 지정으로 바꾸기」로만 연다. 위젯마다 구현하지 않으므로 신규 위젯에도 자동 적용된다 (ControlRenderer.tsx, boundValueGuard.tsx) - 「직접 지정으로 바꾸기」가 편도라 원문을 되찾을 수 없던 문제 — 「되돌리기」 추가(해제 직후엔 취소, 값을 넣은 뒤엔 원문 복구) - `image` 위젯에서 업로드·제거·썸네일만 잠기고 「이미지 관리」 진입이 열려 있어, 그 창의 「배경」 버튼이 같은 값을 덮어쓰던 문제 — 진입 자체를 함께 잠근다 (ImagePickerControl.tsx) - `number` 위젯의 자체 바인딩 분기가 공용 해제 경로를 막던 문제 — 위젯 자체 분기를 제거하고 공용 게이트로 일원화 (StyleControlWidgets.tsx) #### 공통·확장 레이아웃 노드를 편집해도 저장되지 않던 문제 - 라우트 편집 모드에서 상속(base)·주입(extension) 노드 중 바인딩을 가진 것이 `data_bound`(편집 허용)로 분류되던 문제 — 출처 잠금이 항상 우선하도록 판정 순서를 통일했다. 저장 시 마스킹이 그 노드를 통째로 폐기하므로 편집분이 오류도 경고도 없이 사라졌다 (useElementSelection.ts) - 잠긴 노드의 드래그·인라인 편집·복제·`Delete` 키·잘라내기가 무방비이던 문제 — 단일 판정 헬퍼 `isEditableLockKind` 로 전 표면 게이트 (EditorCanvasOverlay.tsx, useCanvasDnd.ts, DndCanvasLayer.tsx) - 거부된 드래그가 `activeDragPath` 를 남겨 「옮길 수 있다」는 거짓 어포던스를 주던 문제 (useCanvasDnd.ts) - 조상 산출 구현이 두 벌로 갈라져 잠금 판정 입력이 어긋날 수 있던 문제 — `collectAncestors` 로 승격 (layoutTreeUtils.ts) ## [engine-v1.65.0] - 2026-09-07 ### Added #### 2단계 인증 로그인 단계 지원 - 로그인 응답을 `LoginResult` 판별 유니온으로 표현 — 정상 로그인과 인증번호 요구(challenge)를 타입으로 구분 (AuthManager.ts) - `completeTwoFactor()` / `resendTwoFactor()` 추가 — 인증번호 확인·재발송 (AuthManager.ts) - `AuthConfig` 에 `twoFactorEndpoint` / `twoFactorResendEndpoint` 추가 (AuthManager.ts) - 액션 핸들러 `loginTwoFactor` / `loginTwoFactorResend` 추가 — 레이아웃에서 인증번호 확인·재발송 (ActionDispatcher.ts) - `login` 핸들러 반환에 `two_factor_required` / `challenge_id` / `provider_id` / `expires_at` 추가 (기존 `user` 필드 유지) (ActionDispatcher.ts) - 레이아웃 편집기 [화면 동작] 탭에 두 핸들러 등록 (coreActionRecipes.ts, ActionAddPicker.tsx) ### Fixed #### 2단계 인증이 켜진 사이트에서 로그인 화면이 영문 오류로 멈추던 문제 - 로그인 응답 형태를 하나로 가정해 인증번호 요구 응답에서 `TypeError` 원문이 오류 박스에 노출되던 문제 (AuthManager.ts) - 문자열이 아닌 토큰이 저장되어 이후 모든 요청이 401 로 튕기던 문제 (ApiClient.ts) - `updateConfig({ loginEndpoint })` 로 지정한 엔드포인트가 무시되던 문제 (AuthManager.ts) - axios 네트워크 오류가 네트워크 실패로 판정되지 않아 영문 원문이 노출되던 문제 (networkResilience.ts, ActionDispatcher.ts) - 다국어 파라미터 값의 파이프 필터(`$t:key|until={{x | datetime}}`)가 평가되지 않아 문장에서 값만 사라지던 문제 (TranslationEngine.ts) ## [engine-v1.64.7] - 2026-09-04 ### Fixed #### 확장 번들 스타일 실패 안내에 내부 구분 이름이 노출되던 문제 - 병합 CSS 번들 로드에 끝내 실패했을 때 안내 배너의 항목명이 번들 구분 키(`module`/`plugin`)였다. 사용자 어휘(`core.assets.module_styles` · `core.assets.plugin_styles`, 번역 미적재 시 폴백 문구)로 바꾼다 (ModuleAssetLoader.ts, AssetFailureNotice.ts) ## [engine-v1.64.0] - 2026-09-02 ### Security #### 동적 스크립트 주입 경로 전부에 출처 게이트 적용 (KVE-2026-1915 B-2 후속) - 레이아웃 `scripts[]` 에만 있던 원격 스크립트 차단 게이트를 **브라우저에 새 `