# Template Engine Changelog > 이 문서는 그누보드7 템플릿 엔진의 내부 개발 버전 이력입니다. > `engine-v1.x.x` 버전은 그누보드7 릴리스 버전과 독립적입니다. > > 형식: [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) ## [engine-v1.63.2] - 2026-08-27 ### Fixed #### 정적 게시본이 200 인데 본문이 손상된 경우 폴백하지 못하던 문제 (#122) - `fetchStaticFirst()` 가 정적 응답의 본문이 **JSON 으로 파싱되는지까지** 확인한 뒤 돌려준다. 종전에는 `response.ok` 만 보았는데, 디스크가 가득 찼거나 quota 를 넘긴 상태에서 만들어진 게시본은 내용이 중간에 잘린 채로도 웹서버가 정상 200 으로 서빙한다. 그러면 폴백이 걸리지 않은 채 호출부의 `response.json()` 이 예외를 던지고, 그 지점에는 폴백 계층이 없어 화면 전체가 뜨지 않았다 — 정적·API·태그 3층 폴백이 유일하게 개입하지 못하던 경로다. 이제 손상이 확인되면 종전 API 로 폴백하고, 폴백 사실을 콘솔 경고 한 줄로 남긴다(조용한 폴백 금지). - 검증을 위해 본문을 읽더라도 호출부가 그대로 다시 소비할 수 있다 — 응답 본문은 1회용 스트림이라, 읽고 그대로 돌려주면 호출부에서 빈 본문이 된다. ## [engine-v1.63.1] - 2026-08-27 ### Fixed #### 정적 게시 미스에서 운영자 추가 자산이 복구되지 않던 문제 (#123) - `staticToLegacy()` 가 세 확장 타입을 모두 역변환한다 — 종전에는 `templates/{id}/assets/**` 만 처리했다. 모듈·플러그인의 `custom/**` 도 같은 형태(`{type}/{id}/assets/**`)로 게시되는데 그 규칙이 없어, 게시본이 GC(현재+직전 1개 보존)로 사라지면 되돌릴 주소를 만들지 못했다. blade 인라인 복구기(`partials/asset-url-recovery.blade.php`)도 동형으로 갱신했다 — 두 구현이 갈리면 코어 번들 로드 전 경로만 조용히 다르게 동작한다. - `ModuleAssetLoader.loadCustomAssets()` 가 정적 → 종전 API 폴백 계층을 갖는다. 형제 경로(`loadBundleCss`)는 이미 갖고 있었고 이 경로만 비어 있었다: 정적 URL 이 404 가 확정된 뒤에도 같은 URL 을 3회 재시도할 뿐이라 복구가 원리상 불가능했고, 화면은 정상 렌더되면서 운영자가 덧붙인 스타일만 조용히 빠졌다. - 자산 실패 배너의 [다시 시도]가 **복구 가능한 주소**를 다시 부른다. 종전에는 정적 미스로 실패한 경우에도 원본 정적 URL 을 넘겨, 버튼은 있는데 눌러도 구조적으로 항상 실패했다. ## [engine-v1.63.0] - 2026-08-26 ### Added #### 서버가 심은 템플릿 externals 의 로드 실패 표면화 (#123) - `drainExternalAssetFailures()` 신설 — 템플릿 `externals`(아이콘 폰트 CSS·웹폰트·부팅 스크립트)는 서버가 HTML 에 직접 심으므로 엔진 번들보다 먼저 평가된다. 실패해도 자바스크립트에는 아무 신호가 오지 않아, engine-v1.62.0 이 세운 실패 표면화 계층이 **이 경로만 통째로 비어 있었다**: 아이콘 58개가 0×0 으로 사라진 화면이 배너도 로그도 없이 남았고(아이콘만으로 조작하는 버튼이 있는 화면에서는 곧 조작 불능), 자체 서버 로그에도 흔적이 없어 운영자가 원인을 특정할 수 없었다. 이제 각 태그의 `onerror` 가 부트스트랩 대기열에 쌓이고, 엔진이 뜨면 그 대기열을 배너로 흘려보낸 뒤 이후 실패용 sink 를 건다. 배너의 [다시 시도]는 해당 태그를 캐시 무효화 쿼리와 함께 다시 심어 복구되면 배너를 해제한다. - 힌트(`preload`/`preconnect`/`dns-prefetch`)는 대상에서 제외한다 — 실패해도 화면 기능이 사라지지 않으므로, 여기까지 알리면 안내가 잡음이 되어 정작 조작 불능을 만드는 실패가 묻힌다. #### 커스텀 자산 관리가 모듈·플러그인까지 확장 (#123) - 편집기 [커스텀 자산] 모달이 **대상 선택기**를 갖는다 — 편집 중인 템플릿과 활성 모듈·플러그인을 오간다. 같은 기능이 확장 타입에 따라 화면에서 되고 안 되면 운영자는 그 이유를 알 수 없고, 모듈·플러그인 `custom/` 은 그동안 FTP 말고 경로가 없었다. - 관리 API 가 확장 공통 엔드포인트(`/api/admin/extensions/{type}/{id}/custom-assets`)로 재편됐다. 타입별로 나누면 같은 검증·문서·테스트가 세 벌로 갈리고, 그중 하나만 약해지면 그 경로가 조용한 우회로가 된다. - 대상을 바꾸면 이전 확장의 선택·초안을 버린다. 남겨 두면 A 확장에서 열어 둔 본문을 B 확장에 저장하게 되고, 경로가 유효하면 서버는 정상 200 으로 받아들인다. ### Changed #### 레이아웃 편집기 번들 로드의 재시도 계층 + 실패 문구 정리 (#123) - `loadLayoutEditorBundle()` 이 `loadScriptWithRetry` 를 쓴다 — 이 경로만 재시도 계층이 없어(원시 `