chore(release): 7.0.10 출시일 정렬 + 공개 배포본 누출 정정
7.0.9 페이로드 대비 버전이 오른 패키지 31종과 코어의 CHANGELOG 최상단 절 날짜를 2026-09-04 로 맞췄다. 이어서 릴리즈 스크립트의 게이트를 브랜치 생성 없이 전수 실행한 결과, 파일 본문 누출 검사가 error 25건으로 릴리즈를 막고 있었다. 전부 이번 사이클에 들어온 것이다. - 확장 문서·코어 주석 20건이 공개 배포본에 없는 를 가리켰다. 공개되는 AGENTS.md 참조로 바꾸고, 참조된 9개 절의 실재를 전수 확인했다. 유일하게 빠져 있던 「독립 레이아웃의 글로벌 호스트 컴포넌트」절은 원래 동기화 대상이었으므로 AGENTS.md 에 반영했다. - 시나리오 매니페스트의 내부 문서 포인터는 소비자가 하나도 없어 제거했다. - 공개 테스트 3건이 내부 검사 스크립트를 열어 도구 간 리터럴을 대조하고 있었다. tests/** 는 배포 페이로드에 포함되고 는 제외되므로 배포본에서 원리상 성립할 수 없는 검사다. 대조를 그 도구 옆으로 옮기고 공개 테스트에는 자기 동작 단언만 남겼다. 존재 가드로 무마하지 않은 것은 그 경우 배포본에서 검사가 조용히 건너뛰어져 "검사하지 않음" 과 "통과" 가 구분되지 않기 때문이다. 옮긴 대조는 돌지 않으면 잠그지 못하므로 대상 파일 편집 시 자동 실행되도록 등록했다. 누출 검사 자체도 릴리즈 시점에만 돌아 위반이 다음 릴리즈까지 드러나지 않았으므로, 룰을 복제하지 않고 실행 시점만 세션 종료로 앞당겼다. 같은 검증 중 드러난 선행 결함 하나(이커머스 문서의 집계 블록 드리프트)도 함께 정리했다.
This commit is contained in:
@@ -981,6 +981,20 @@ Added/Changed/Fixed 내 항목이 10개를 초과하면 `####` 서브 헤딩으
|
||||
필수: data_sources ID 고유성 유지, 조건부 렌더링은 if 속성만 사용 (type: "conditional" 미지원)
|
||||
```
|
||||
|
||||
### 독립 레이아웃(extends 없음)의 글로벌 호스트 컴포넌트
|
||||
|
||||
`toast`, `openModal` 등 글로벌 상태 기반 핸들러(`_global.toasts`, `_global.modal`)는 호스트 컴포넌트(`Toast`, `ModalRoot` 등)가 마운트되어야 화면에 렌더된다. 베이스 레이아웃(`_user_base`, `_admin_base`)은 일반적으로 이들을 마운트하므로 자식 레이아웃은 별도 작업이 필요 없지만, `extends` 없이 정의된 독립 레이아웃(예: `admin_login.json`)은 호스트 컴포넌트가 자동 주입되지 않는다.
|
||||
|
||||
```text
|
||||
필수: 독립 레이아웃에서 toast/modal 사용 시 components 최상단에 호스트 컴포넌트를 직접 추가
|
||||
- Toast: { type: "composite", name: "Toast", props: { toasts: "{{_global.toasts}}", ... } }
|
||||
- 누락 시 핸들러는 success 로 기록되나 화면에는 미노출 (조용한 실패)
|
||||
|
||||
필수: 의심 시 베이스 레이아웃의 호스트 컴포넌트 정의를 그대로 복사
|
||||
- sirsoft-admin_basic: layouts/_admin_base.json 의 #global_toast 블록
|
||||
- sirsoft-basic: layouts/_user_base.json 의 토스트 컴포넌트 블록
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 테스트 프로토콜
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [7.0.10] - 2026-08-25
|
||||
## [7.0.10] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ use App\Rules\AllowedTemplateFileType;
|
||||
*
|
||||
* 라우트 캐시 안전: `where()` 인자는 **정의 시점**에 평가되어 컴파일된 정규식으로 캐시에
|
||||
* 박히므로, 캐시 로드 경로는 이 클래스를 참조하지 않는다. 라우트 파일에 전역 함수를
|
||||
* 선언하지도 않는다 (CLAUDE.md "라우트 캐시 안전성").
|
||||
* 선언하지도 않는다 (AGENTS.md "라우트 캐시 안전성").
|
||||
*
|
||||
* 환경 의존 게터(`getAllowedExtensions()`)를 쓰지 않는 이유도 같다 — 그것은 로컬에서
|
||||
* 소스맵(`map`)을 덧붙이므로, 패턴이 **캐시를 구운 환경**에 따라 달라진다.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.9] - 2026-08-25
|
||||
## [1.0.9] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.4] - 2026-09-01
|
||||
## [1.0.4] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.1.4] - 2026-09-02
|
||||
## [1.1.4] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.2] - 2026-08-25
|
||||
## [1.0.2] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.1] - 2026-08-25
|
||||
## [1.0.1] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.2] - 2026-08-31
|
||||
## [1.0.2] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.1.2] - 2026-09-02
|
||||
## [1.1.2] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.4] - 2026-09-02
|
||||
## [1.0.4] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.4] - 2026-09-02
|
||||
## [1.0.4] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.3] - 2026-09-02
|
||||
## [1.0.3] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.8] - 2026-08-26
|
||||
## [1.0.8] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [0.1.2] - 2026-08-31
|
||||
## [0.1.2] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.1.1] - 2026-08-31
|
||||
## [1.1.1] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ _프론트 엔트리포인트가 없습니다._
|
||||
<!-- @intent START -->
|
||||
액션 핸들러가 없는 것과 같은 이유로 `window.__[Name]` 재등록 진입점도 없습니다 — 로케일
|
||||
전환 후 재등록해야 할 자체 핸들러가 이 모듈에는 없기 때문입니다. 프론트 전용 코드
|
||||
(`resources/js/`)를 신설하면 그 순간부터 이 자리에 진입점을 만들어야 합니다(§CLAUDE.md
|
||||
(`resources/js/`)를 신설하면 그 순간부터 이 자리에 진입점을 만들어야 합니다(§코어 AGENTS.md
|
||||
"확장 미들웨어는..." 항목 인근의 재등록 진입점 규정 참고) — 없으면 로케일 전환 후 그 확장의
|
||||
액션이 전부 무반응이 됩니다.
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -94,5 +94,5 @@ board 의 라우트가 20개 안팎으로 한 파일에서 관리 가능한 규
|
||||
**필터 훅 위임** 소비자(이커머스 문의)는 `dependencies` 로 선언되지 않습니다 — 이커머스는
|
||||
board 를 자기 도메인으로 대체할 뿐 board API 계약에 실제로 묶여 있지 않기 때문입니다.
|
||||
이 모듈의 공개 표면(라우트·API 응답 구조)을 바꿀 때는 `sirsoft-basic` 의 최소 버전 상향을
|
||||
검토해야 합니다(§CLAUDE.md "확장 → 확장 동기화").
|
||||
검토해야 합니다(§코어 AGENTS.md "확장 → 확장 동기화").
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -198,7 +198,7 @@ CRUD 를 바꾸고 싶으면 이 4종 중 하나를 잡으면 되고, 이 모듈
|
||||
| PHPUnit | 400개 | `modules/_bundled/sirsoft-ecommerce/tests` |
|
||||
| Vitest | 140개 | `vitest.config.ts` |
|
||||
| Playwright | 42개 | `tests/Playwright` |
|
||||
| 시나리오 매니페스트 | 91개 | `tests/scenarios` |
|
||||
| 시나리오 매니페스트 | 92개 | `tests/scenarios` |
|
||||
|
||||
기저 TestCase: `tests/ModuleTestCase.php` — 확장 테스트는 이 클래스를 상속합니다 (`Tests\TestCase` 직접 상속 금지).
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.2.1] - 2026-08-28
|
||||
## [1.2.1] - 2026-09-04
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.1.1] - 2026-08-31
|
||||
## [1.1.1] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [0.1.2] - 2026-08-31
|
||||
## [0.1.2] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.3] - 2026-08-25
|
||||
## [1.0.3] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.3] - 2026-08-25
|
||||
## [1.0.3] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.4] - 2026-08-31
|
||||
## [1.0.4] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ iframe·1st-party 저장소 게이팅)은 이 액션 핸들러가 아니라 `dis
|
||||
<!-- @generated:frontend-entry END -->
|
||||
|
||||
<!-- @intent START -->
|
||||
`initPlugin()` 이 "핸들러 재등록만" 하도록 좁혀 둔 것은 코어 규정(§CLAUDE.md "확장 미들웨어는
|
||||
`initPlugin()` 이 "핸들러 재등록만" 하도록 좁혀 둔 것은 코어 규정(§코어 AGENTS.md "확장 미들웨어는
|
||||
...")을 그대로 따른 결과입니다 — 자동 차단 스크립트의 부팅(도메인 카탈로그 로드, DOM 스캔
|
||||
시작)을 여기 넣으면 로케일 전환마다 그 부팅이 중복 실행됩니다. 자동 차단 부팅은 `blocker.ts`/
|
||||
`preblocker.ts` 가 페이지 최초 로드 시 1회만 수행합니다.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.4] - 2026-08-31
|
||||
## [1.0.4] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.1] - 2026-08-31
|
||||
## [1.0.1] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.1.3] - 2026-08-31
|
||||
## [1.1.3] - 2026-09-04
|
||||
|
||||
### Security
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ CBT 인증 URL로 이동할지는 핸들러 내부에서 서버 응답(§API `/p
|
||||
|
||||
<!-- @intent START -->
|
||||
`window.__SirsoftKginicis` 로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로 재등록
|
||||
진입점을 찾기 때문입니다(§CLAUDE.md "재등록 진입점"). `initPlugin()`이 KG 이니시스 결제창
|
||||
진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). `initPlugin()`이 KG 이니시스 결제창
|
||||
스크립트(`INIStdPay.js`) 자체를 미리 로드하지 않는 것도 의도입니다 — 그 스크립트는
|
||||
`requestPayment` 핸들러가 실제 결제 시도 시점에만 동적으로 로드합니다(모든 방문자가 결제
|
||||
페이지에 오는 것은 아니므로 전역 부팅에서 미리 불러올 필요가 없습니다).
|
||||
|
||||
@@ -115,5 +115,5 @@ _등록하는 메뉴가 없습니다._
|
||||
`sirsoft-ecommerce >=1.1.0` 하드 의존은 §data-model.md 에서 설명한 구조(결제 상태는 이커머스가
|
||||
소유, 이 플러그인은 절차만 소유)의 직접적 결과입니다 — 이커머스 없이는 이 플러그인이 다룰
|
||||
주문 자체가 존재하지 않습니다. 이커머스의 PG 등록 훅(`registered_pg_providers` 등)이나
|
||||
`Order` 모델 구조가 바뀌면 이 최소 버전을 올려야 합니다(§CLAUDE.md "확장 → 확장 동기화").
|
||||
`Order` 모델 구조가 바뀌면 이 최소 버전을 올려야 합니다(§코어 AGENTS.md "확장 → 확장 동기화").
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.4] - 2026-08-31
|
||||
## [1.0.4] - 2026-09-04
|
||||
|
||||
### Security
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
<!-- @intent START -->
|
||||
`window.__SirsoftNhnkcp`로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로 재등록
|
||||
진입점을 찾기 때문입니다(§CLAUDE.md "재등록 진입점"). KCP 결제창 스크립트 자체는 이
|
||||
진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). KCP 결제창 스크립트 자체는 이
|
||||
진입점이 미리 로드하지 않습니다 — 모든 방문자가 결제 페이지에 오는 것은 아니므로 전역
|
||||
부팅에서 미리 불러올 필요가 없습니다(`requestPayment` 핸들러가 실제 결제 시도 시점에만
|
||||
동적으로 로드).
|
||||
|
||||
@@ -97,5 +97,5 @@ _등록하는 메뉴가 없습니다._
|
||||
`sirsoft-ecommerce >=1.1.0` 하드 의존은 §data-model.md 에서 설명한 구조(결제 상태는
|
||||
이커머스가 소유, 이 플러그인은 절차만 소유)의 직접적 결과입니다 — 이커머스 없이는 이
|
||||
플러그인이 다룰 주문 자체가 존재하지 않습니다. 이커머스의 PG 등록 훅이나 `Order` 모델
|
||||
구조가 바뀌면 이 최소 버전을 올려야 합니다(§CLAUDE.md "확장 → 확장 동기화").
|
||||
구조가 바뀌면 이 최소 버전을 올려야 합니다(§코어 AGENTS.md "확장 → 확장 동기화").
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.3] - 2026-08-31
|
||||
## [1.0.3] - 2026-09-04
|
||||
|
||||
### Security
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
<!-- @intent START -->
|
||||
`window.__SirsoftNicepayments`로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로 재등록
|
||||
진입점을 찾기 때문입니다(§CLAUDE.md "재등록 진입점"). 나이스페이먼츠 결제창 스크립트
|
||||
진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). 나이스페이먼츠 결제창 스크립트
|
||||
자체는 이 진입점이 미리 로드하지 않습니다 — `requestPayment` 핸들러가 결제 시도 시점에
|
||||
동적으로 스크립트를 삽입한 뒤 `goPay()`를 호출합니다.
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -98,5 +98,5 @@ _등록하는 메뉴가 없습니다._
|
||||
`sirsoft-ecommerce >=1.1.0` 하드 의존은 §data-model.md 에서 설명한 구조(결제 상태는
|
||||
이커머스가 소유, 이 플러그인은 절차만 소유)의 직접적 결과입니다 — 이커머스 없이는 이
|
||||
플러그인이 다룰 주문 자체가 존재하지 않습니다. 이커머스의 PG 등록 훅이나 `Order` 모델
|
||||
구조가 바뀌면 이 최소 버전을 올려야 합니다(§CLAUDE.md "확장 → 확장 동기화").
|
||||
구조가 바뀌면 이 최소 버전을 올려야 합니다(§코어 AGENTS.md "확장 → 확장 동기화").
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
토스 호출이 일어나지 않습니다. `core.plugin_settings.before_save`를 `ValidateTossSettingsListener`
|
||||
가 구독하는 것은 다른 PG 플러그인에는 없는 패턴입니다 — 이 훅은 코어 `PluginSettingsService`
|
||||
가 발행하며, `sync: true`가 없으면 큐로 비동기 디스패치되어 `ValidationException`이 워커
|
||||
안에서 죽고 저장은 그대로 진행됩니다(§CLAUDE.md "Listener 데이터 접근 규정" 의 sync 훅
|
||||
안에서 죽고 저장은 그대로 진행됩니다(§코어 AGENTS.md "Listener 데이터 접근 규정" 의 sync 훅
|
||||
규칙과 동일한 이유).
|
||||
<!-- @intent END -->
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.3] - 2026-08-31
|
||||
## [1.0.3] - 2026-09-04
|
||||
|
||||
### Security
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
<!-- @intent START -->
|
||||
`window.__SirsoftTosspayments`로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로 재등록
|
||||
진입점을 찾기 때문입니다(§CLAUDE.md "재등록 진입점"). 토스 SDK(`js.tosspayments.com/v2/standard`)
|
||||
진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). 토스 SDK(`js.tosspayments.com/v2/standard`)
|
||||
자체는 이 진입점이 미리 로드하지 않습니다 — `requestPayment` 핸들러가 결제 시도 시점에
|
||||
동적으로 로드합니다.
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -102,5 +102,5 @@ Bearer 토큰으로 직접 호출하는 엔드포인트(예: 관리자 거래조
|
||||
`sirsoft-ecommerce >=1.1.0` 하드 의존은 §data-model.md 에서 설명한 구조(결제 상태는
|
||||
이커머스가 소유, 이 플러그인은 절차만 소유)의 직접적 결과입니다 — 이커머스 없이는 이
|
||||
플러그인이 다룰 주문 자체가 존재하지 않습니다. 이커머스의 PG 등록 훅이나 `Order` 모델
|
||||
구조가 바뀌면 이 최소 버전을 올려야 합니다(§CLAUDE.md "확장 → 확장 동기화").
|
||||
구조가 바뀌면 이 최소 버전을 올려야 합니다(§코어 AGENTS.md "확장 → 확장 동기화").
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -4,7 +4,7 @@ All notable changes to this plugin will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [1.0.5] - 2026-08-31
|
||||
## [1.0.5] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -91,5 +91,5 @@
|
||||
(완료된 PII), `InicisIdentityLogQueryRepository`(동일인 검증 전용 `IdentityVerificationLog`
|
||||
조회, 코어 로그 테이블을 이 플러그인 관점으로 좁혀 읽는 어댑터). 결제 플러그인들이
|
||||
Repository 를 하나도 두지 않는 것과 대조적으로, 이 플러그인은 실제 PII 를 소유하므로
|
||||
Repository 인터페이스 주입 원칙(§CLAUDE.md "Service-Repository 패턴")이 그대로 적용됩니다.
|
||||
Repository 인터페이스 주입 원칙(§코어 AGENTS.md "Service-Repository 패턴")이 그대로 적용됩니다.
|
||||
<!-- @intent END -->
|
||||
|
||||
@@ -75,7 +75,7 @@ PII 레코드를 흡수하거나 정리하는 대칭 구조입니다 — 하나
|
||||
<!-- @generated:layout-extensions END -->
|
||||
|
||||
<!-- @intent START -->
|
||||
`identity_provider_inicis.json`은 코어 IDV 팝업(§CLAUDE.md "본인인증(IDV) 공통 UI 가이드")이
|
||||
`identity_provider_inicis.json`은 코어 IDV 팝업(§코어 AGENTS.md "본인인증(IDV) 공통 UI 가이드")이
|
||||
provider 별로 다른 안내 문구·로고를 보여줘야 할 때 이 플러그인이 자기 몫을 주입하는
|
||||
조각입니다. `mypage_identity_card.json`은 마이페이지에 "본인확인 완료" 상태 카드를
|
||||
보여주는 조각으로, `sirsoft-verification_nhnkcp`도 동일한 명명 규칙의 자기 조각을 갖습니다
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
<!-- @intent START -->
|
||||
`window.__SirsoftVerificationKginicis`로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로
|
||||
재등록 진입점을 찾기 때문입니다(§CLAUDE.md "재등록 진입점"). 이 플러그인은 결제 PG
|
||||
재등록 진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). 이 플러그인은 결제 PG
|
||||
플러그인들과 달리 결제창 SDK 를 동적 로드하지 않습니다 — 이니시스 인증 폼은 팝업
|
||||
안에서 서버가 렌더링한 페이지로 제출되므로 프론트가 별도 스크립트를 불러올 필요가
|
||||
없습니다.
|
||||
|
||||
@@ -4,7 +4,7 @@ All notable changes to this plugin will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [1.0.2] - 2026-08-31
|
||||
## [1.0.2] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<!-- @intent START -->
|
||||
`sirsoft-verification_kginicis`가 세 번째 마이그레이션으로 부가 필드를 nullable 완화한
|
||||
것과 달리, 이 플러그인은 두 테이블 생성만으로 끝났습니다 — 아직 같은 종류의 스키마 보정이
|
||||
필요했던 적이 없습니다. 향후 유사한 nullable 완화가 필요해지면 kginicis 의 사례(§CLAUDE.md
|
||||
필요했던 적이 없습니다. 향후 유사한 nullable 완화가 필요해지면 kginicis 의 사례(§코어 AGENTS.md
|
||||
"소스 교정만으로는 기설치본이 낫지 않는다")를 참고합니다.
|
||||
<!-- @intent END -->
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ IDV 공통 팝업 UI로 존재합니다.
|
||||
|
||||
<!-- @intent START -->
|
||||
`window.__SirsoftVerificationNhnkcp`로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로
|
||||
재등록 진입점을 찾기 때문입니다(§CLAUDE.md "재등록 진입점"). `sirsoft-verification_kginicis`와
|
||||
재등록 진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). `sirsoft-verification_kginicis`와
|
||||
마찬가지로 이 플러그인은 결제창 SDK 를 동적 로드하지 않습니다 — 인증 화면 자체가 서버
|
||||
렌더링 페이지(팝업 안) 또는 리다이렉트 대상(모바일)이므로 프론트가 별도 스크립트를 불러올
|
||||
필요가 없습니다.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [0.1.1] - 2026-08-25
|
||||
## [0.1.1] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [0.1.1] - 2026-08-25
|
||||
## [0.1.1] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.0.8] - 2026-08-25
|
||||
## [1.0.8] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
`FilterGroup`(선택) → `DataGrid`/`CardGrid`(목록) → `Pagination`. data_sources 는
|
||||
`auto_fetch: true` + `params`에 `_local.page`/`per_page` 바인딩. 삭제·상태변경은 `apiCall`,
|
||||
상세/수정 이동은 `navigate`, 필터·페이지네이션은 `setState`. 목록 컨텍스트 왕복 규약
|
||||
(`mergeQuery`)을 지킵니다(§CLAUDE.md).
|
||||
(`mergeQuery`)을 지킵니다(§코어 AGENTS.md).
|
||||
|
||||
**상세 화면**: `extends: _admin_base`, `data_sources`에 `route.id` 기반 상세 API,
|
||||
`slots.content`에 `PageHeader` + `Card` 여러 개(기본 정보/활동 내역/권한 정보 등 섹션별 분리).
|
||||
@@ -203,7 +203,7 @@
|
||||
|
||||
**에러 화면**(`errors/*.json`): `extends` 없는 독립 레이아웃. `Div`(중앙 정렬) 안에
|
||||
`Icon`+`H1`(코드)+`P`(메시지)+`Button`(홈 이동). 독립 레이아웃이므로 `Toast`/`Modal` 같은
|
||||
전역 호스트 컴포넌트가 필요하면 직접 마운트해야 합니다(§CLAUDE.md "독립 레이아웃의 글로벌
|
||||
전역 호스트 컴포넌트가 필요하면 직접 마운트해야 합니다(§코어 AGENTS.md "독립 레이아웃의 글로벌
|
||||
호스트 컴포넌트").
|
||||
|
||||
### `_admin_base.json` 에 대한 정정
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
|
||||
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
|
||||
|
||||
## [1.1.3] - 2026-08-25
|
||||
## [1.1.3] - 2026-09-04
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -378,59 +378,44 @@ class ExtensionDocContractTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* 미채움 마커 목록이 PHP · 검사 스크립트 · audit 룰 세 곳에서 일치해야 합니다.
|
||||
* 미채움 마커 목록이 5종으로 고정되고 서로 겹치지 않아야 합니다.
|
||||
*
|
||||
* 세 곳이 갈라지면 한쪽이 세지 않는 마커가 생기고, 그 자리는 영영 집계되지 않습니다.
|
||||
* 이 목록은 자동 생성 블록이 채우지 못하는 사람 서술 자리를 가리킵니다. 항목이
|
||||
* 늘거나 줄면 문서 완비 판정의 모집단이 조용히 바뀝니다.
|
||||
*
|
||||
* 내부 검사 도구(`check-extension-docs.cjs` · 미채움 audit 룰)가 같은 목록을
|
||||
* 쓰는지는 그 도구들과 함께 있는 하네스 테스트가 대조합니다.
|
||||
*/
|
||||
public function test_todo_marker_list_is_consistent_across_tooling(): void
|
||||
public function test_todo_marker_list_is_fixed_and_distinct(): void
|
||||
{
|
||||
$markers = ExtensionDocScaffolder::todoMarkers();
|
||||
|
||||
$this->assertCount(5, $markers, '미채움 마커는 5종으로 고정입니다.');
|
||||
|
||||
$script = (string) file_get_contents(base_path('.claude/scripts/check-extension-docs.cjs'));
|
||||
$rule = (string) file_get_contents(base_path('.claude/scripts/audit/rules/extension-doc-unfilled-markers.cjs'));
|
||||
$this->assertSame(
|
||||
$markers,
|
||||
array_values(array_unique($markers)),
|
||||
'미채움 마커가 중복되면 그 자리는 두 번 세어집니다.',
|
||||
);
|
||||
|
||||
foreach ($markers as $marker) {
|
||||
$this->assertStringContainsString(
|
||||
"'{$marker}'",
|
||||
$script,
|
||||
"check-extension-docs.cjs 에 마커 '{$marker}' 가 없습니다.",
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
"'{$marker}'",
|
||||
$rule,
|
||||
"extension-doc-unfilled-markers.cjs 에 마커 '{$marker}' 가 없습니다.",
|
||||
);
|
||||
}
|
||||
|
||||
// 포함만 단언하면 방향이 하나뿐이라 JS 쪽 **초과** 항목(6번째 마커·오탈자 잔여)이
|
||||
// 그대로 살아 있다. 두 도구가 세는 모집단이 갈라지면 잔량 집계가 서로 다른 답을
|
||||
// 내는데, 그 차이는 어느 쪽 출력에도 드러나지 않는다.
|
||||
foreach ([$script, $rule] as $i => $source) {
|
||||
preg_match_all("/'(TODO: [^']+)'/u", $source, $m);
|
||||
$found = array_values(array_unique($m[1]));
|
||||
sort($found);
|
||||
$expected = $markers;
|
||||
sort($expected);
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$found,
|
||||
($i === 0 ? 'check-extension-docs.cjs' : 'extension-doc-unfilled-markers.cjs')
|
||||
.' 의 마커 목록이 PHP SSoT 와 다릅니다 (초과 또는 누락).',
|
||||
$this->assertStringStartsWith(
|
||||
'TODO: ',
|
||||
$marker,
|
||||
"마커 '{$marker}' 가 공통 접두를 잃으면 잔량 검사가 그 자리를 놓칩니다.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 빈 서술 축이 PHP 와 검사 스크립트 양쪽에 존재하고 같은 판정을 내려야 합니다.
|
||||
* 빈 서술 축이 마커 잔량과 별개로 세어져야 합니다.
|
||||
*
|
||||
* 미채움은 두 축입니다 — `TODO:` 마커 잔량과, 마커를 지우고 서술을 쓰지 않은 빈
|
||||
* `@intent` 블록. 후자가 한쪽에만 있으면 그 도구만 통과시키는데, 결과가 "다 채웠다"
|
||||
* 와 구분되지 않아 비어 있는 문서가 완비로 집계됩니다.
|
||||
* `@intent` 블록. 후자를 세지 않으면 스캐폴딩 직후 마커만 지운 문서가 골격·블록
|
||||
* 검사를 전부 통과해, 비어 있는 문서가 완비로 집계됩니다.
|
||||
*
|
||||
* 내부 검사 도구가 같은 수를 세는지는 그 도구와 함께 있는 하네스 테스트가 대조합니다.
|
||||
*/
|
||||
public function test_empty_intent_axis_agrees_across_tooling(): void
|
||||
public function test_empty_intent_blocks_are_counted(): void
|
||||
{
|
||||
$filled = '<!-- @intent START -->
|
||||
서술이 있다.
|
||||
@@ -445,19 +430,6 @@ class ExtensionDocContractTest extends TestCase
|
||||
'.$empty));
|
||||
$this->assertSame(1, ExtensionDocScaffolder::emptyIntentBlocks($filled.'
|
||||
'.$empty));
|
||||
|
||||
$script = (string) file_get_contents(base_path('.claude/scripts/check-extension-docs.cjs'));
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'countEmptyIntentBlocks',
|
||||
$script,
|
||||
'check-extension-docs.cjs 에 빈 서술 축이 없습니다 — PHP 만 세면 하네스가 통과시킵니다.',
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
"id: 'emptyIntent'",
|
||||
$script,
|
||||
'check-extension-docs.cjs 의 빈 서술 축 식별자가 없습니다.',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -614,50 +586,25 @@ class ExtensionDocContractTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* 프로세스 경계를 넘는 리터럴 2종이 PHP·JS 양쪽에서 일치하는지 단언합니다.
|
||||
* 수집 실패 통지가 실제로 방출되는 블록마다 실려야 합니다.
|
||||
*
|
||||
* 코어 인덱스 스캐너는 `@generated:stats` 마커와 "확인하지 못했습니다" 문장을 **문자열로**
|
||||
* 다시 적어 두고 파싱합니다. 생성기 쪽 문구가 바뀌면 스캐너가 조용히 실패해 인덱스가
|
||||
* 다시 `훅 0 · 라우트 0` 을 사실로 싣습니다 — 미채움 마커 5종에는 이미 양방향 집합
|
||||
* 단언이 있는데 같은 성질의 이 두 리터럴만 그 취급을 받지 못했습니다.
|
||||
* 수집 실패는 수치가 아니라 문장으로 옵니다. 통지는 둘(표면 전체 실패 · 개별 getter
|
||||
* 실패)이고, 어느 한쪽이 다른 어구로 시작하면 그 문서는 "발행 훅 N종 …" 같은 거짓
|
||||
* 문장을 경고 없이 싣습니다.
|
||||
*
|
||||
* 그 어구와 집계 블록 마커를 내부 인덱스 스캐너가 그대로 알고 있는지는 그 스캐너와
|
||||
* 함께 있는 하네스 테스트가 대조합니다.
|
||||
*/
|
||||
public function test_cross_process_literals_match_the_index_scanner(): void
|
||||
public function test_surface_notice_reaches_every_measured_block(): void
|
||||
{
|
||||
$scanner = base_path('.claude/scripts/generate-docs-index.cjs');
|
||||
|
||||
if (! is_file($scanner)) {
|
||||
$this->markTestSkipped('내부 스캐너가 없는 배포본입니다.');
|
||||
}
|
||||
|
||||
$js = (string) file_get_contents($scanner);
|
||||
|
||||
// 생성기가 실제로 방출하는 마커에서 키 부분을 뽑아 스캐너 소스와 대조한다.
|
||||
// (스캐너는 정규식으로 공백을 흡수하므로 마커 전문이 리터럴로 있지는 않다.)
|
||||
// 집계 블록은 마커로 감싸여 방출된다 — 스캐너가 그 구간을 잘라 수치를 읽는다.
|
||||
$wrapped = ExtensionDocScaffolder::wrap('stats', '**훅 수**: 1');
|
||||
|
||||
$this->assertStringContainsString('@generated:stats START', $wrapped);
|
||||
$this->assertStringContainsString('@generated:stats END', $wrapped);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'@generated:stats',
|
||||
$js,
|
||||
'인덱스 스캐너가 집계 블록 마커를 그대로 알고 있어야 합니다.',
|
||||
);
|
||||
|
||||
// 수집 실패 문구 — 통지는 둘(표면 전체 실패 · 개별 getter 실패)이고 스캐너는 그
|
||||
// 둘이 공유하는 어구를 찾는다. 소스에 리터럴이 있는지만 보면 "어딘가에 그 문자열이
|
||||
// 있다" 만 확인할 뿐, **실제로 방출되는 문장**이 그것을 담는지는 보지 않는다 —
|
||||
// 개별 getter 실패 통지가 다른 어구로 시작해 스캐너에 통째로 새던 것이 그 사각이다.
|
||||
$marker = ExtensionDocScaffolder::SURFACE_NOTICE_MARKER;
|
||||
|
||||
$this->assertStringContainsString(
|
||||
// 스캐너 정규식은 `**` 를 이스케이프하므로 그 형태로 대조한다.
|
||||
str_replace('**', '\*\*', $marker),
|
||||
$js,
|
||||
'인덱스 스캐너가 표면 실패 판정 어구를 읽지 못하면 점검 불가가 0 으로 굳습니다.',
|
||||
);
|
||||
|
||||
// 두 통지가 실제로 그 어구를 담고 방출되는지 렌더 결과로 단언한다.
|
||||
$inventory = new ExtensionInventory;
|
||||
$record = $inventory->find('module', 'sirsoft-board');
|
||||
|
||||
|
||||
@@ -74,6 +74,3 @@ test_files:
|
||||
- tests/Unit/Installer/RequirementsResponseUtf8Test.php
|
||||
- tests/Unit/Installer/AddLogUtf8ScrubTest.php
|
||||
- tests/Unit/Services/SettingsServiceCpuInfoTest.php
|
||||
|
||||
validation:
|
||||
browser_matrix: .claude/docs/chrome-mcp-inspection-matrix.md
|
||||
|
||||
Reference in New Issue
Block a user