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 재동기화로 기설치본의 소실
 번역 자동 복구 (멱등·운영자 수정 보존·팩별 실패 격리)
This commit is contained in:
HeuJung
2026-08-24 14:51:37 +09:00
parent 40f62e79aa
commit e7fa1b5535
71 changed files with 7155 additions and 8693 deletions
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace App\Upgrades;
use App\Extension\AbstractUpgradeStep;
/**
* 코어 7.0.9 업그레이드 스텝
*
* 모든 비즈니스 로직은 본 클래스 파일이 아닌 `upgrades/data/7.0.9/` 안에 격리된다:
*
* - migrations/
* 01_ResyncActiveLanguagePackTranslations.php
* 활성 언어팩의 seed 번역을 DB JSON 컬럼에 재동기화한다. 7.0.9 이전의
* [기본값 복원] 결함(복원 기본값에 언어팩 로케일 미포함)과 코어 시더 필터
* 주입 불능으로 이미 소실된 팩 번역(ja 등)을 병합 복구한다. 병합은 운영자
* 수정(user_overrides)을 보존하며 멱등이다.
*
* 실행 순서는 파일명 정렬(`sort()`)을 따른다.
*
* 본 클래스는 `AbstractUpgradeStep` 의 default `run()` 에 위임 — 별도 override 없음.
*
* @upgrade-path 7.0.x → 7.0.9
*
* 의존성 제약: 본 스텝은 변환/핫픽스를 `data/7.0.9/migrations/` 의 버전 namespace
* 클래스에 위임한다. 미래 버전에서 *그 디렉토리는 동결* (수정 금지) 되어 "각 스텝별 동작
* 100% 동일 보장" invariant 가 성립.
*
* 상세: docs/extension/upgrade-step-guide.md §13 "버전별 데이터 스냅샷"
*/
class Upgrade_7_0_9 extends AbstractUpgradeStep
{
// 모든 로직 위임 — data/7.0.9/ 가 SSoT.
}
@@ -0,0 +1,84 @@
<?php
namespace App\Upgrades\Data\V7_0_9\Migrations;
use App\Extension\HookManager;
use App\Extension\Upgrade\DataMigration;
use App\Extension\UpgradeContext;
use App\Models\LanguagePack;
use Illuminate\Support\Facades\Schema;
use Throwable;
/**
* 활성 언어팩의 seed 번역을 DB JSON 컬럼에 재동기화합니다.
*
* 7.0.9 이전 버전에는 언어팩 번역이 DB 에서 소실되는 두 결함이 있었다:
*
* 1) 알림/본인인증 템플릿의 [기본값 복원]이 복원 기본값에 활성 언어팩 로케일을
* 포함하지 않아, 복원 시 팩이 주입해 둔 로케일(ja 등)과 보존 선언(user_overrides)이
* config 의 ko/en 대체로 영구 소실됐다.
* 2) 코어 시더의 언어팩 필터 주입이 페이로드 형태 불일치로 전면 불능이라, 팩 활성화
* 이후 코어 업그레이드가 추가한 알림 정의 행에는 팩 로케일이 주입되지 않았다.
*
* 소스 교정(7.0.9)만으로는 이미 소실된 설치본 데이터가 낫지 않으므로, 활성 언어팩마다
* 활성화 훅(core.language_packs.activated)을 재발화해 seed 번역을 병합 복구한다 —
* 정상 활성화와 완전히 같은 경로이므로 활성화 시점과 동일한 결과가 재현된다.
*
* idempotent + 운영자 수정 보존: 병합 리스너(SyncDatabaseTranslations → applySeedFromPack)는
* - locale 키 부재 → 추가 (소실분 복구)
* - locale 키 존재 + user_overrides 에 컬럼 등록 → 건너뜀 (운영자 수정 보존)
* - locale 키 존재 + user_overrides 미등록 → seed 값으로 갱신
* 이라 여러 번 실행해도 결과가 같고 운영자가 직접 수정한 번역을 덮지 않는다.
*
* V-1 안전: 상태값은 enum 참조 대신 'active' 리터럴을 쓴다 (본 디렉토리는 릴리즈 후
* 동결되므로 스냅샷 시점의 DB 저장값 자체를 고정). LanguagePack 모델과 HookManager 는
* 언어팩 도입 시점부터 존재하는 기존 클래스의 기존 표면만 사용한다.
*/
class ResyncActiveLanguagePackTranslations implements DataMigration
{
/**
* 마이그레이션 식별자를 반환합니다.
*
* @return string 마이그레이션 이름
*/
public function name(): string
{
return 'ResyncActiveLanguagePackTranslations';
}
/**
* 활성 언어팩 전수에 활성화 훅을 재발화해 seed 번역을 병합 복구합니다.
*
* @param UpgradeContext $context 업그레이드 컨텍스트
* @return void
*/
public function run(UpgradeContext $context): void
{
if (! Schema::hasTable('language_packs')) {
$context->logger->info('[core:7.0.9] language_packs 테이블 부재 — 언어팩 seed 재동기화 스킵');
return;
}
$packs = LanguagePack::query()->where('status', 'active')->get();
if ($packs->isEmpty()) {
$context->logger->info('[core:7.0.9] 활성 언어팩 없음 — 언어팩 seed 재동기화 스킵');
return;
}
foreach ($packs as $pack) {
try {
HookManager::doAction('core.language_packs.activated', $pack);
$context->logger->info('[core:7.0.9] 언어팩 seed 번역 재동기화 완료: '.$pack->identifier);
} catch (Throwable $e) {
// 개별 팩 실패(디렉토리 손상 등)가 업그레이드 전체를 막지 않도록 격리 —
// 남은 팩은 계속 처리하고, 실패 팩은 로그로 남겨 운영자가 후속 조치한다.
$context->logger->warning(
'[core:7.0.9] 언어팩 seed 재동기화 실패(건너뜀): '.$pack->identifier.' — '.$e->getMessage()
);
}
}
}
}