fix(core,admin_basic,board,ecommerce,page,gdpr,verification): 설정 미러·자동 정리·탈퇴 원자성·일괄 선택 범위 정비

공개이슈 ··· 및 그 전수 해소분.

- 설정 저장·복원·초기화가 상주 프로세스 미러를 갱신하도록 단일 소유자화
- 만료 데이터 자동 정리 예약 12종 신설, 파기는 기본키 배치로 분할
- 회원 탈퇴를 전 경로 원자화하고 관리자 상태변경 경로를 정식 탈퇴로 통일
- 일괄 처리 목록의 선택을 화면에 보이는 행으로 한정(selectionScope)
- 비밀번호 정책 문구를 도메인 중립 라벨로 정정
- 정적 검사 2종·검증 스킬 설계 정합성 축 신설
This commit is contained in:
HeuJung committed 2026-08-14 11:06:25 +09:00
1 parent 49c155509e
commit 4e1ec6e001
136 files changed
+7016 -504

No files matched your search

+6 -86
View File
@@ -10,7 +10,6 @@ use App\Console\Commands\BenchCommand;
use App\Contracts\Extension\CacheInterface;
use App\Contracts\Extension\ExtensionMiddlewareRegistryInterface;
use App\Contracts\Extension\HookListenerInterface;
use App\Contracts\Extension\ModuleSettingsInterface;
use App\Contracts\Extension\StorageInterface;
use App\Contracts\Extension\TemplateManagerInterface;
use App\Contracts\Repositories\ActivityLogRepositoryInterface;
@@ -97,6 +96,7 @@ use App\Services\DriverRegistryService;
use App\Services\LayoutExtensionService;
use App\Services\TemplateLayoutAttachmentService;
use App\Services\UniqueIdService;
use App\Support\ExtensionSettingsMirror;
use App\Support\PrivilegedDatabaseAccounts;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
@@ -739,69 +739,8 @@ class CoreServiceProvider extends ServiceProvider
*/
protected function loadModuleSettingsToConfig(ModuleManager $moduleManager): void
{
$moduleSettings = [];
foreach (array_keys($moduleManager->getActiveModules()) as $identifier) {
try {
// 모듈별 환경설정 서비스 조회
$settingsService = $this->resolveModuleSettingsService($identifier);
if ($settingsService instanceof ModuleSettingsInterface) {
$settings = $settingsService->getAllSettings();
if (! empty($settings)) {
$moduleSettings[$identifier] = $settings;
}
}
} catch (\Throwable $e) {
Log::warning("모듈 환경설정 로딩 실패: {$identifier}", [
'error' => $e->getMessage(),
]);
}
}
Config::set('g7_settings.modules', $moduleSettings);
}
/**
* 모듈의 환경설정 서비스를 찾아 인스턴스화합니다.
*
* 다음 순서로 설정 서비스를 찾습니다:
* 1. 인터페이스 바인딩: Modules\Vendor\Module\Contracts\ModuleSettingsServiceInterface
* 2. 구체 클래스: Modules\Vendor\Module\Services\ModuleSettingsService
*
* @param string $identifier 모듈 식별자 (예: sirsoft-ecommerce)
* @return ModuleSettingsInterface|null 설정 서비스 인스턴스
*/
protected function resolveModuleSettingsService(string $identifier): ?ModuleSettingsInterface
{
// vendor-module 형식을 네임스페이스로 변환
$parts = explode('-', $identifier);
if (count($parts) < 2) {
return null;
}
$vendor = ucfirst($parts[0]);
$moduleName = ucfirst($parts[1]);
// 1. 인터페이스 바인딩 확인
$interfaceClass = "Modules\\{$vendor}\\{$moduleName}\\Contracts\\{$moduleName}SettingsServiceInterface";
if ($this->app->bound($interfaceClass)) {
$service = $this->app->make($interfaceClass);
if ($service instanceof ModuleSettingsInterface) {
return $service;
}
}
// 2. 구체 클래스 확인
$concreteClass = "Modules\\{$vendor}\\{$moduleName}\\Services\\{$moduleName}SettingsService";
if (class_exists($concreteClass)) {
$service = $this->app->make($concreteClass);
if ($service instanceof ModuleSettingsInterface) {
return $service;
}
}
return null;
// 미러 채움 로직은 ExtensionSettingsMirror 가 단일 소유한다 (공개이슈 #109).
app(ExtensionSettingsMirror::class)->refreshAllModules();
}
/**
@@ -814,28 +753,9 @@ class CoreServiceProvider extends ServiceProvider
*/
protected function loadPluginSettingsToConfig(PluginManager $pluginManager): void
{
$pluginSettings = [];
foreach (array_keys($pluginManager->getActivePlugins()) as $identifier) {
try {
$settingsPath = storage_path("app/plugins/{$identifier}/settings/setting.json");
if (File::exists($settingsPath)) {
$content = File::get($settingsPath);
$settings = json_decode($content, true);
if (json_last_error() === JSON_ERROR_NONE && ! empty($settings)) {
$pluginSettings[$identifier] = $settings;
}
}
} catch (\Throwable $e) {
Log::warning("플러그인 환경설정 로딩 실패: {$identifier}", [
'error' => $e->getMessage(),
]);
}
}
Config::set('g7_settings.plugins', $pluginSettings);
// 종전에는 setting.json 을 raw 로 읽어 defaults 병합·정규화가 빠지고 암호문이 그대로
// 실렸다 — 값의 형태가 전용 게터와 달랐다. 이제 미러 소유자에 위임한다 (공개이슈 #109).
app(ExtensionSettingsMirror::class)->refreshAllPlugins();
}
/**