feat(core,admin_basic): .env 키 단위 우선 모드 추가

관리자 환경설정 저장값이 config 를 덮는 기존 설계는 공유호스팅을 1차 대상으로
삼은 결과다. .env 를 배포 기준값으로 관리하는 설치에서는 그 설계가 반대로
작동해, 설치기가 defaults 를 시드하는 순간부터 .env 의 28개 항목이 오류도
로그도 없이 사문화된다.

G7_ENV_PRIORITY 옵트인으로 그 소유권을 키 단위로 되돌린다. 스위치를 켜지 않은
설치는 전 경로가 조기 return 이라 동작이 100% 동일하다.

명시 여부는 config 빌드 시점에 캡처한다 — 런타임 env 는 config:cache 환경에서
null 로 고정되어 판정이 영구 미발동한다(attachment.disk_explicit 와 같은 함정).
판정은 strict 라 APP_DEBUG=false·REDIS_DB=0 같은 falsy 명시도 명시로 본다.

잠금은 그 키의 주입만 건너뛰는 것이지만, 제거된 키의 부재를 값으로 읽는 자리가
있으면 형제 설정까지 무너진다. 게이트(웹소켓 토글·메일 드라이버·디버그 모드)와
기본값 주입(mailgun.endpoint·ses.region), 형제 폴백(reverb server endpoint),
파생 판정(storage_driver→attachment.disk)을 유효값으로 보정했다.
This commit is contained in:
HeuJung committed 2026-09-04 10:08:30 +09:00
1 parent b97deee43a
commit 381fcc4e0b
37 files changed
+4026 -118

No files matched your search

+4 -1
View File
@@ -72,7 +72,10 @@ _단건 응답: `data` 객체의 필드._
| notifications | object | `{"channels":[{"id":"mail","is_active":true,"sort_order":1…` | 알림 탭 설정 그룹. channels 는 알림 채널 목록으로 각 원소가 id(채널 식별자)·is_active(활성 여부)·sort_order(표시 순서)를 가짐 |
| identity | object | `{"default_provider":"g7:core.mail","purpose_providers":{"…` | 본인인증(IDV) 탭 설정 그룹 (기본 provider·목적별 provider 매핑(purpose_providers)·챌린지 유효시간(분)·최대 시도 횟수) |
| available_drivers | object | `{"storage":[{"id":"local","label":{"ko":"로컬","en":"Local"…` | 드라이버 선택지 카탈로그 (DriverRegistryService 산물). 종류별(storage/public_asset/cache/session/queue 등) 선택 가능한 드라이버 목록을 id/다국어 label 형태로 제공. `public_asset` 은 공개 자산 직접 URL 서빙 디스크 선택지 (코어 none/public/s3 + 플러그인 훅 등록분) |
| _meta | object | `{"limits":{"upload_max_file_size_min":1,"upload_max_file_…` | 설정값이 아니라 화면이 쓰는 메타. `limits` 는 각 설정 항목의 min/max 경계값 맵 (`config/core.php` 의 `settings_limits` 가 SSoT, 화면 입력 힌트와 FormRequest 검증이 같은 값을 공유) |
| _meta | object | `{"limits":{"upload_max_file_size_min":1,"upload_max_file_…` | 설정값이 아니라 화면이 쓰는 메타. 조회(GET)와 저장(POST) 응답이 같은 모양으로 동봉한다. 아래 세 필드로 구성 |
| _meta.limits | object | `{"upload_max_file_size_min":1,"upload_max_file_size_max":1024,…}` | 각 설정 항목의 min/max 경계값 맵 (`config/core.php` 의 `settings_limits` 가 SSoT, 화면 입력 힌트와 FormRequest 검증이 같은 값을 공유) |
| _meta.env_priority_enabled | boolean | `false` | `.env` 키 단위 우선 모드(`G7_ENV_PRIORITY`) 활성 여부. 화면은 이 값으로 안내 배너 표시를 판정한다. 기본값 false (스위치 미설정 시 종전 동작) |
| _meta.env_locked | object | `{"general.site_name":true,"advanced.debug_mode":true}` | `.env` 에 값이 명시되어 편집이 잠긴 필드 목록. 키는 **화면이 쓰는 프론트엔드 키**(`frontend_key`/`merge_into` 변환 후 — 예: `debug.mode` → `advanced.debug_mode`)이며 값은 항상 true. 병합 대상 카테고리와 원본 카테고리 양쪽에 실린다(설정값 자체가 두 위치에 실리는 것과 같은 규칙). 스위치가 꺼져 있으면 빈 객체. 잠긴 필드는 저장 요청에 포함되어도 서버가 제거하므로 값이 반영되지 않는다. 잠긴 필드의 값은 저장값이 아니라 실제로 적용 중인 값으로 내려가되, 비밀번호·시크릿·토큰 등 민감 항목은 그 대체를 하지 않는다 |
| abilities | object | `{"can_update":true}` | 현재 사용자가 이 리소스에 수행 가능한 작업 불리언 맵 (can_update, can_delete 등 — 권한 맵 기반) |
**응답 예시**