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`] = ` {