From 28d6a7752cb5fcb0c41ecd71a6154a763894a4a5 Mon Sep 17 00:00:00 2001 From: HeuJung Date: Mon, 24 Aug 2026 17:03:42 +0900 Subject: [PATCH] =?UTF-8?q?fix(core,message=5Fbizppurio):=20=EB=B8=8C?= =?UTF-8?q?=EB=9E=9C=EC=B9=98=20=EA=B2=80=EC=A6=9D=20=EB=B0=9C=EA=B2=AC=20?= =?UTF-8?q?=EA=B2=B0=ED=95=A8=204=EA=B1=B4=20=E2=80=94=20=EC=8A=A4?= =?UTF-8?q?=EB=83=85=EC=83=B7=20=ED=9A=8C=EA=B7=80=C2=B7=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EB=B6=80=20skip=C2=B7=EB=82=A1=EC=9D=80=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 출시 전 /validate-branch 통합 검증에서 발견한 결함을 처리한다. - BindingShape 라우팅 diff 스냅샷이 중간 상태에서 구워져 HEAD 가 red 였다. 발산 517건을 덤프해 신규 41건이 전부 객체·배열 리터럴 바인딩(구 정규식 오판 계열)이고 유해 지점 스냅샷은 이미 green 임을 확인한 뒤 기록값을 맞춘다. - 채널 잔재 정리 검증이 게시판 모듈 활성 환경에서만 실행돼 대부분의 실행에서 미검증으로 남았다. 정리 로직이 소유자를 묻지 않는 실제 계약대로 모듈 소유 정의를 테스트 안에서 구성해 무조건 실행되게 한다. - activity_log 주석이 폐기된 설계(조회 전용 전환·콘솔 위임)를 서술하고 있어 현행 사실로 정정한다. 사용자 문구는 바뀌지 않는다. - 설정성 테이블의 상한 없는 조회 근거와 seeder 반환 키 타입을 코드에 남긴다. --- .../IdentityMessageDefinitionSeeder.php | 2 +- .../lang/en/activity_log.php | 6 +-- .../lang/ko/activity_log.php | 5 +- .../BizppurioTemplateRepository.php | 6 +++ .../ChannelTemplateCleanupOnUninstallTest.php | 50 +++++++++++++++---- .../BindingShape.routingParity.test.ts.snap | 2 +- 6 files changed, 55 insertions(+), 16 deletions(-) diff --git a/database/seeders/IdentityMessageDefinitionSeeder.php b/database/seeders/IdentityMessageDefinitionSeeder.php index 449a75f4..9b1bf65b 100644 --- a/database/seeders/IdentityMessageDefinitionSeeder.php +++ b/database/seeders/IdentityMessageDefinitionSeeder.php @@ -72,7 +72,7 @@ class IdentityMessageDefinitionSeeder extends Seeder * `extension_type='core'` / `extension_identifier='core'` 자동 주입. * `variables: '__common__'` 마커는 commonVariables() 로 expand. * - * @return array> + * @return array> config 복합 키('mail.purpose.signup' 등) => 정의 */ private function getDefaultDefinitions(): array { diff --git a/plugins/_bundled/sirsoft-message_bizppurio/lang/en/activity_log.php b/plugins/_bundled/sirsoft-message_bizppurio/lang/en/activity_log.php index d6b0cae2..d798ced0 100644 --- a/plugins/_bundled/sirsoft-message_bizppurio/lang/en/activity_log.php +++ b/plugins/_bundled/sirsoft-message_bizppurio/lang/en/activity_log.php @@ -1,9 +1,9 @@ [], 'description' => [], diff --git a/plugins/_bundled/sirsoft-message_bizppurio/lang/ko/activity_log.php b/plugins/_bundled/sirsoft-message_bizppurio/lang/ko/activity_log.php index 6619eb3b..14c72a84 100644 --- a/plugins/_bundled/sirsoft-message_bizppurio/lang/ko/activity_log.php +++ b/plugins/_bundled/sirsoft-message_bizppurio/lang/ko/activity_log.php @@ -1,8 +1,9 @@ [], 'description' => [], diff --git a/plugins/_bundled/sirsoft-message_bizppurio/src/Repositories/BizppurioTemplateRepository.php b/plugins/_bundled/sirsoft-message_bizppurio/src/Repositories/BizppurioTemplateRepository.php index 75a56036..aa150d52 100644 --- a/plugins/_bundled/sirsoft-message_bizppurio/src/Repositories/BizppurioTemplateRepository.php +++ b/plugins/_bundled/sirsoft-message_bizppurio/src/Repositories/BizppurioTemplateRepository.php @@ -137,6 +137,9 @@ class BizppurioTemplateRepository implements BizppurioTemplateRepositoryInterfac * 설정성 테이블 예외). 요약에 불필요한 대형 JSON(content/approved_content)은 제외하되, * 반려 사유(inspection_detail)는 행 UI 의 [사유 보기]가 소비하므로 포함한다. * + * 행 수는 알림 정의 수(notification_type UNIQUE)에 묶인다 — 코어·확장이 선언한 알림 + * 개수만큼만 존재하는 설정성 테이블이므로 상한 없는 get() 이 데이터 증가에 비례하지 않는다. + * * @return Collection 요약 컬럼만 실린 행 컬렉션 */ public function allSummaries(): Collection @@ -153,6 +156,9 @@ class BizppurioTemplateRepository implements BizppurioTemplateRepositoryInterfac /** * 특정 상태의 행 전체를 조회합니다 (동기화 커맨드 대상 선별). * + * allSummaries() 와 같은 근거로 상한을 두지 않는다 — 알림 정의 수에 묶인 설정성 테이블의 + * 부분집합이다. + * * @param string $status BizppurioTemplateStatus value * @return Collection */ diff --git a/plugins/_bundled/sirsoft-message_bizppurio/tests/Feature/Installation/ChannelTemplateCleanupOnUninstallTest.php b/plugins/_bundled/sirsoft-message_bizppurio/tests/Feature/Installation/ChannelTemplateCleanupOnUninstallTest.php index f19bfff6..5446ce8d 100644 --- a/plugins/_bundled/sirsoft-message_bizppurio/tests/Feature/Installation/ChannelTemplateCleanupOnUninstallTest.php +++ b/plugins/_bundled/sirsoft-message_bizppurio/tests/Feature/Installation/ChannelTemplateCleanupOnUninstallTest.php @@ -72,30 +72,62 @@ class ChannelTemplateCleanupOnUninstallTest extends PluginTestCase /** * 게시판·이커머스처럼 코어가 아닌 다른 모듈이 소유한 알림 정의도 동일하게, * 정의 자체는 남고 우리 채널만 제거된다. + * + * 정리 로직(cleanupChannelContributions)은 소유자를 묻지 않고 "우리 채널 template 을 + * 가진 정의" 를 대상으로 하므로, 실제 모듈 설치 여부에 의존하지 않고 모듈 소유 정의를 + * 직접 구성해 검증한다 — 모듈이 활성화된 환경에서만 실행되는 조건부 테스트였다면 이 + * 경로가 대부분의 실행에서 미검증으로 남는다(#597 브랜치 검증에서 교정). */ public function test_uninstall_시_모듈_소유_알림도_채널만_정리되고_정의는_보존된다(): void { $this->plugin->activate(); - $boardDefinition = NotificationDefinition::where('extension_identifier', 'sirsoft-board')->first(); + $moduleDefinition = NotificationDefinition::create([ + 'type' => 'module_owned_notification_for_cleanup', + 'hook_prefix' => 'sirsoft-board.post', + 'extension_type' => 'module', + 'extension_identifier' => 'sirsoft-board', + 'name' => ['ko' => '모듈 소유 알림', 'en' => 'Module owned'], + 'variables' => [], + 'channels' => ['mail', 'sms', 'alimtalk'], + 'hooks' => ['sirsoft-board.post.after_create'], + 'is_active' => true, + ]); - if (! $boardDefinition) { - $this->markTestSkipped('sirsoft-board 모듈이 활성화되지 않은 테스트 환경입니다.'); + foreach (['mail', 'sms', 'alimtalk'] as $channel) { + NotificationTemplate::create([ + 'definition_id' => $moduleDefinition->id, + 'channel' => $channel, + 'subject' => ['ko' => '제목'], + 'body' => ['ko' => '본문'], + 'recipients' => [['type' => 'trigger_user']], + 'is_active' => true, + 'is_default' => true, + ]); } - $this->assertContains('sms', $boardDefinition->channels); - $this->plugin->uninstall(); - $boardDefinition->refresh(); - $this->assertNotContains('sms', $boardDefinition->channels); - $this->assertNotContains('alimtalk', $boardDefinition->channels); + $moduleDefinition->refresh(); + $this->assertNotContains('sms', $moduleDefinition->channels); + $this->assertNotContains('alimtalk', $moduleDefinition->channels); + $this->assertContains( + 'mail', + $moduleDefinition->channels, + '모듈이 원래 갖고 있던 채널은 그대로 보존되어야 한다.' + ); $this->assertSame( 0, - NotificationTemplate::where('definition_id', $boardDefinition->id) + NotificationTemplate::where('definition_id', $moduleDefinition->id) ->whereIn('channel', ['sms', 'alimtalk']) ->count() ); + $this->assertNotNull( + NotificationTemplate::where('definition_id', $moduleDefinition->id) + ->where('channel', 'mail') + ->first(), + '모듈 소유 정의의 mail 템플릿은 보존되어야 한다.' + ); } /** diff --git a/resources/js/core/template-engine/__tests__/__snapshots__/BindingShape.routingParity.test.ts.snap b/resources/js/core/template-engine/__tests__/__snapshots__/BindingShape.routingParity.test.ts.snap index ef9ba3bf..cb4e511e 100644 --- a/resources/js/core/template-engine/__tests__/__snapshots__/BindingShape.routingParity.test.ts.snap +++ b/resources/js/core/template-engine/__tests__/__snapshots__/BindingShape.routingParity.test.ts.snap @@ -86,7 +86,7 @@ exports[`BindingShape 라우팅 diff 하네스 > 단일 바인딩 판정: greedy ] `; -exports[`BindingShape 라우팅 diff 하네스 > 단일 바인딩 판정: 구 정규식과 신 정본이 갈리는 총량 1`] = `516`; +exports[`BindingShape 라우팅 diff 하네스 > 단일 바인딩 판정: 구 정규식과 신 정본이 갈리는 총량 1`] = `517`; exports[`BindingShape 라우팅 diff 하네스 > 판정이 갈리는 식의 분류별 건수 요약 1`] = ` {