비즈뿌리오 알림톡 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 재동기화로 기설치본의 소실 번역 자동 복구 (멱등·운영자 수정 보존·팩별 실패 격리)
85 lines
3.8 KiB
PHP
85 lines
3.8 KiB
PHP
<?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()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|