Files
Gnuboard7/app/Console/Commands/LanguagePack/ListLanguagePackCommand.php
T
HeuJung 3d8890b118 feat(core,admin_basic): 번들 비-ko 언어팩 자동 프로비저닝 + 미설치·드리프트 발견성
신규 설치/복구 시 비-ko/en 번들 언어팩(ja 등)이 자동으로 채워지지 않아
런타임에 오류 없이 조용히 ko 로 폴백하고, 운영자가 이를 알아채기 어려웠다.
두 결손을 함께 해소한다.

프로비저닝(SSoT):
- language-pack:provision 멱등 커맨드 신설. supported_locales ∖ {ko,en} 의
 미설치 번들 팩을 설치하고, 설치본 파일이 사라진 드리프트 팩(슬롯 점유로
 getUninstalledBundledPacks 가 못 잡는)도 복구 경로로 겸한다. 재실행 시 0건 수렴.

발견성:
- CLI language-pack:list 를 Service::list 경유로 전환해 미설치(uninstalled)와
 드리프트(active·파일 없음)를 함께 표면화.
- files_missing / bundled_source_available 파생 플래그를 Resource 에 노출.
- 관리자 언어팩 목록에 "파일 없음" 배지 + 원클릭 재설치(기존 install-bundled 모달
 재사용). 재설치 경로만 auto_activate 로 바인딩해 복구 후 active 를 유지한다.

회귀 방지:
- 정적 룰 lang-pack-supported-locale-has-bundle(선언 로케일 ↔ 번들 소스 부재) 신설,
 lang-pack-installed-version-drift 를 프로비저닝된 환경 한정으로 확장.
- 백엔드/레이아웃/E2E/시나리오 테스트 + 룰 fixture 추가.

부수 수정:
- 프로비저닝 작업 중 표면화된 ecommerce 언어팩 시더 테스트 격리결함 수정
 (modules 등록 행을 매 테스트가 직접 보장 — 프로세스당 1회 시딩 전제 붕괴 대응).
2026-07-27 14:58:48 +09:00

94 lines
2.5 KiB
PHP

<?php
namespace App\Console\Commands\LanguagePack;
use App\Models\LanguagePack;
use App\Services\LanguagePackService;
use Illuminate\Console\Command;
/**
* 언어팩 목록을 출력합니다.
*
* 모듈/플러그인/템플릿의 list 커맨드와 동일한 운영 도구. Service::list() 를 경유하므로
* 설치된 DB 행뿐 아니라 "번들에 있으나 미설치"(uninstalled) 및 "active 로 기록됐으나
* 설치본 파일 부재(드리프트)" 상태를 함께 표면화한다(이슈 #496).
*/
class ListLanguagePackCommand extends Command
{
/**
* @var string
*/
protected $signature = 'language-pack:list {--scope= : 특정 스코프만 (core/module/plugin/template)}';
/**
* @var string
*/
protected $description = '언어팩 목록을 출력합니다 (미설치 번들 및 드리프트 상태 포함).';
/**
* @param LanguagePackService $service 언어팩 Service
*/
public function __construct(
private readonly LanguagePackService $service,
) {
parent::__construct();
}
/**
* 커맨드를 실행합니다.
*
* @return int 종료 코드
*/
public function handle(): int
{
$filters = [];
if ($scope = $this->option('scope')) {
$filters['scope'] = $scope;
}
$paginator = $this->service->list($filters, 100);
$packs = $paginator->items();
if (empty($packs)) {
$this->info('언어팩이 없습니다.');
return self::SUCCESS;
}
$rows = [];
foreach ($packs as $pack) {
$rows[] = [
$pack->identifier,
$pack->scope,
$pack->target_identifier ?? '-',
$pack->locale,
$pack->vendor,
$pack->version,
$this->formatStatus($pack),
];
}
$this->table(
['Identifier', 'Scope', 'Target', 'Locale', 'Vendor', 'Version', 'Status'],
$rows
);
return self::SUCCESS;
}
/**
* 표시용 상태 문자열을 만듭니다. 드리프트(active + 설치본 부재)는 명시적으로 표기합니다.
*
* @param LanguagePack $pack 대상 팩
* @return string 표시 상태
*/
private function formatStatus(LanguagePack $pack): string
{
if ((bool) $pack->getAttribute('files_missing')) {
return $pack->status.' (파일 없음)';
}
return (string) $pack->status;
}
}