Files
Gnuboard7/database/seeders/IdentityMessageDefinitionSeeder.php
T
HeuJung e7fa1b5535 feat(message_bizppurio): 알림 템플릿 편집 통합·검수 의견·관리탭 개선 및 언어팩 번역 보존 결함군 수정
비즈뿌리오 알림톡 UX 개편 후속:
- 코어/게시판/이커머스 알림 템플릿 [편집] 모달에 확장 채널 편집 영역
 (extension_point 2종 + hidden_template_editor 채널 메타)을 신설하고,
 알림톡 템플릿·문자(SMS)·수신자 규칙을 한 창에서 통합 저장하도록 개정
 (행 하단은 상태 요약 전용, 승인 여부 2단 배지)
- 검수 신청에 검수자 전달 의견(comment) 동봉 — kapi request 로만 전달,
 행에는 저장하지 않음 (FormRequest 신설 + API 문서 백필)
- 관리 탭 모바일 카드뷰·도구줄 코어 관례 통일, 사이트맵 알림 정의
 다국어 라벨 결측 수정 + 코어 정의 라벨 패리티 테스트 신설

언어팩 번역 소실·보존 결함군 (보완 실측 → 커밋 전 점검에서 연쇄 확정,
전부 실패 테스트 선행 후 수정):
- [기본값 복원]이 활성 언어팩 번역(ja)을 영구 소실 → 복원 기본값에
 시딩과 같은 주입기(SSoT)로 팩 로케일 병합 (notification·identity)
- 코어 알림/본인인증 시더의 언어팩 주입 전면 불능 → 주입기가 연관/리스트
 양형태 수용 + identity 시더의 config 복합 키 보존
- 실패한 언어팩 업데이트가 active 팩을 installed 로 방치 → 상태 복원 확장
- 병합·제거의 사용자 수정 보존 판정 사문(연관 전제 isset) → dot-path 판정
 교정, 팩 주입 저장의 user_overrides 오염 차단(시딩 바인딩), 템플릿
 2모델 translatableTrackableFields 선언(beta.4 설계 누락), 같은 프로세스
 활성화 시 시더 번역 필터 stale(캡처 인스턴스 캐시) 교정
- 7.0.9 업그레이드 스텝 신설 — 활성 팩 seed 재동기화로 기설치본의 소실
 번역 자동 복구 (멱등·운영자 수정 보존·팩별 실패 격리)
2026-08-24 14:51:37 +09:00

119 lines
4.5 KiB
PHP

<?php
namespace Database\Seeders;
use App\Extension\Helpers\IdentityMessageSyncHelper;
use App\Extension\HookManager;
use Illuminate\Database\Seeder;
/**
* IDV 메시지 정의 시더.
*
* config/core.php 의 `identity_messages` 블록을 SSoT 로 읽어 DB 로 동기화합니다.
* IdentityPolicySeeder / NotificationDefinitionSeeder 와 동일한 config-기반 패턴.
*
* 운영자가 관리자 UI 에서 수정한 값은 user_overrides 로 보존되어 재시딩 시 덮어써지지 않습니다.
*
* @since 7.0.0-beta.4
*/
class IdentityMessageDefinitionSeeder extends Seeder
{
/**
* 시드 실행.
*
* @return void
*/
public function run(): void
{
$this->command?->info('코어 IDV 메시지 정의 시딩 시작...');
$helper = app(IdentityMessageSyncHelper::class);
$definitions = $this->getDefaultDefinitions();
// 언어팩 시스템: 활성 코어 언어팩의 seed/identity_messages.json 으로 다국어 키 병합.
// NotificationDefinitionSeeder 와 동일 패턴.
$definitions = HookManager::applyFilters('seed.identity_messages.translations', $definitions);
$definedScopes = [];
if (empty($definitions)) {
$this->command?->warn('config/core.php 에 identity_messages 선언이 없습니다.');
return;
}
foreach ($definitions as $data) {
$definition = $helper->syncDefinition($data);
$definedScopes[] = [
'provider_id' => $definition->provider_id,
'scope_type' => $definition->scope_type->value,
'scope_value' => $definition->scope_value,
];
$definedChannels = [];
foreach ($data['templates'] as $template) {
$helper->syncTemplate($definition->id, $template);
$definedChannels[] = $template['channel'];
}
$helper->cleanupStaleTemplates($definition->id, $definedChannels);
$this->command?->info(" - {$definition->provider_id} | {$definition->scope_type->value} | {$definition->scope_value} 등록 완료");
}
$helper->cleanupStaleDefinitions('core', 'core', $definedScopes);
$this->command?->info('코어 IDV 메시지 정의 시딩 완료 ('.count($definitions).'종)');
}
/**
* 코어 기본 메시지 정의 데이터를 config/core.php 에서 조회합니다.
*
* `extension_type='core'` / `extension_identifier='core'` 자동 주입.
* `variables: '__common__'` 마커는 commonVariables() 로 expand.
*
* @return array<int, array<string, mixed>>
*/
private function getDefaultDefinitions(): array
{
$messages = config('core.identity_messages', []);
$result = [];
foreach ($messages as $key => $data) {
if (($data['variables'] ?? null) === '__common__') {
$data['variables'] = $this->commonVariables();
}
$data['extension_type'] = 'core';
$data['extension_identifier'] = 'core';
// config 복합 키('mail.purpose.signup' 등)를 보존 — 언어팩 주입 필터
// (seed.identity_messages.translations)가 이 키로 seed 를 매칭한다.
// 리스트로 만들면 전 항목이 매칭 불가로 스킵되어 팩 로케일이 오류 없이
// 주입되지 않는다 (#597 에서 실측·교정 — IdentityMessageTemplateService
// ::loadCoreMessageDefinitions 의 동형 보존과 짝을 이룬다).
$result[$key] = $data;
}
return $result;
}
/**
* 표준 변수 메타데이터 (모든 mail 정의 공통).
*
* config/core.php 에서 `'variables' => '__common__'` 마커로 참조됩니다.
*
* @return array<int, array{key: string, description: string}>
*/
protected function commonVariables(): array
{
return [
['key' => 'code', 'description' => '인증 코드 (text_code 흐름)'],
['key' => 'action_url', 'description' => '검증 링크 URL (link 흐름)'],
['key' => 'expire_minutes', 'description' => '만료까지 남은 분'],
['key' => 'purpose_label', 'description' => '인증 목적 라벨 (다국어)'],
['key' => 'app_name', 'description' => '사이트명'],
['key' => 'site_url', 'description' => '사이트 URL'],
['key' => 'recipient_email', 'description' => '수신자 이메일'],
];
}
}