3 Commits
Author SHA1 Message Date
HeuJung 5d14d01d50 fix(core): 디버그 라우트 그룹 게이트 일원화 + 확장 자산 CSS 상대 참조 치환
https://github.com/gnuboard/g7/issues/128 (제보자 glitter-gim) 과 그 부수의무
전수조사에서 확정한 결함군을 닫는다.

## 디버그 라우트 게이트 (F1~F5)

게이트가 핸들러 안에 흩어져 있어 8개 라우트 중 3개에만 붙어 있었다. 빠진 쪽에
`File::cleanDirectory(storage/debug-dump)` 를 수행하는 `DELETE clear` 가 있었고,
production·APP_DEBUG=false 에서도 미인증 200 으로 덤프 전체가 지워졌다. GET 4종은
User SPA catch-all 이 등록 순서상 앞서 가려 주고 있었을 뿐이라, 보호를 우연에 맡긴
구조였다.

게이트를 `bootstrap/app.php` 의 devtools 래퍼 한 곳(`debug.gate` 그룹 미들웨어)으로
올린다. 새 라우트는 자동으로 덮이고, 부착 지점이 하나라 훼손이 곧바로 드러난다.
`withRouting(channels:)` 인자가 함께 등록하던 게이트 없는 `/broadcasting/auth` 는
제거하고, 채널 정의 로드만 `BroadcastServiceProvider` 로 옮겨 웹소켓 킬스위치
우회로를 없앤다. catch-all 제외 패턴에는 예약 프리픽스를 전수 추가했다.

## 확장 자산 CSS 상대 참조 (범위 추가 — 결정)

`asset_url_mode=extensionless` 에서 자산 URL 이 쿼리 형태가 되면 브라우저의 기준
디렉토리가 `/api/{타입}/assets/` 로 잡혀, CSS 안의 `url('./woff2/f.woff2')` 가
존재하지 않는 주소가 된다. 사용자 템플릿 웹폰트 1건과 관리자 템플릿 국기 아이콘
약 500건이 이 상태였다. 병합 CSS 번들은 더 나빴다 — 상대 참조를 가진 확장을 번들에서
통째로 제외하고 있었는데, 번들 URL 이 내려오면 프론트는 개별 로딩을 아예 타지 않으므로
제외는 곧 그 확장 스타일이 하나도 적용되지 않음을 뜻했다.

둘 다 서빙 시점에 절대 자산 URL 로 치환한다. 최종 URL 은 런타임 모드와 캐시 버전이
정하므로 빌드 시점에는 알 수 없고, 동봉 자산은 제3자 산출물이라 원본을 손대면 상류
갱신마다 재작업이 된다. 개별 서빙 3경로와 병합 번들이 같은 해석 규칙을 공유한다 —
갈라지면 한쪽만 고쳐진 채 남는다.

이 결함군은 공통적으로 예외도 서버 로그 흔적도 남기지 않는다. 열린 엔드포인트가
정상 응답하는 것, 404 로 글꼴이 기본 서체가 되는 것이 유일한 증상이다.

## 회귀 잠금

되돌림 red 를 모집단 전원에 대해 실측했다 — 그룹 미들웨어 제거, 개별 게이트 재주입,
`channels:` 복원, catch-all 예외 제거, 컨트롤러 3원의 `fileResponse` 회귀, 번들
치환 제거가 각각 어느 테스트를 red 로 만드는지 확인하고 원상 복구했다.

게이트 부착 축은 행위 테스트로 대체할 수 없다 — 가려진 라우트는 행위상 "막힌 것" 과
구분되지 않으므로, `gatherMiddleware` 를 직접 보는 등록 계약 테스트를 둔다. 치환
배선도 같은 이유로 라우트 이름 규약에서 모집단을 도출하는 계약 검사를 둔다(손으로 적은
목록은 네 번째 경로가 생기는 순간 조용히 낡는다).
2026-09-03 07:42:28 +09:00
HeuJung 3f29f9fd1e chore(core,board,ecommerce,page,gdpr): 7.0.6 공개 릴리즈 누출 검사 차단 요인 제거
prepare-release.sh 의 파일 본문 누출 검사가 error 10건으로 릴리즈를 차단하고 있었다.
공개 저장소는 를 제외하므로, 배포되는 파일이 그 경로나 를 참조하면
공개본에서 깨진 참조가 된다.

- 시나리오 매니페스트 4건: test_files 의 내부 하네스 테스트 경로 제거
- Playwright spec 3건: 룰 파일 경로/@see 포인터를 자기완결 서술로 교체
 (@see 2건은 이미 stale — 가리키던 사례 번호가 실제와 달랐다)
- 소스/테스트 주석 3건: 파일명 노출 제거

내부 역할 호칭이 공개본에 영구 노출되는 warn 23건 중 21건도 함께 중립 표현으로
정정했다. API 표면 파일 2건은 주석만 고쳐도 문서 커버리지 게이트에 영구 면제가
필요해져 보류한다 — warn 은 릴리즈를 차단하지 않는다.

부수로 드러난 기존 결함 둘을 같은 세션에서 처리:
- gdpr Playwright config 에 locale 고정 누락 — 첫 로드가 en-US 로 나가 화면이 영어로
 굳으면 한국어 문구를 단언하는 spec 이 전부 실패한다
- 언어팩 시나리오의 정적 검사 계층 전용 효과 2건을 effects 에서 rules_layer_coverage
 로 이관 — 런타임 테스트로 성립하지 않는 항목이라 그 칸이 정합 위치다

검증: 누출 검사 error 0, audit --working 위반 0(룰 192), 시나리오 매니페스트 8건
errors 0, gdpr Vitest 148 green, PHP lint/JSON/YAML 정상.
버전 정합은 코어 working 7.0.6 / 공개 latest 7.0.5 = new-bump 로 릴리즈 가능 상태.
2026-08-10 17:46:17 +09:00
HeuJung 4744e7bf85 fix(core): 라우트 캐시 상태에서 DevTools 덤프·브라우저 로그 수집 복구
route:cache 가 걸리면 RouteServiceProvider 가 캐시 로드로 분기해 라우트 파일이
실행되지 않는다. routes/devtools.php 는 전역 함수 5개를 정의하고 핸들러가 호출했고,
boost 의 browser-logs 는 프로바이더 boot 등록분이라 setCompiledRoutes 교체로
폐기됐다. 7.0.6 의 RouteCacheHelper 가 12개 라이프사이클 지점에서 캐시를 자동
생성하면서, 확장을 한 번이라도 건드린 사이트에서 항상 재현됐다.

로직을 오토로드되는 App\Support\DevTools\* 로 옮기고 browser-logs URI 를 G7 가
직접 소유해 캐시에 함께 구워지게 했다. 게이트가 참조하던 App\Models\Setting 은
저장소에 없는 유물이라 ConfigRepositoryInterface 로 교체했다.

같은 부류의 재발은 정적 검사(route-file-local-function)로 차단하고, 재현이
in-process 로 불가능하므로 서브프로세스 하네스로 회귀를 고정했다.
2026-08-07 10:13:52 +09:00