관리자 환경설정 저장값이 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)을 유효값으로 보정했다.
56 lines
3.4 KiB
YAML
56 lines
3.4 KiB
YAML
feature: .env 키 단위 우선 (G7_ENV_PRIORITY 옵트인)
|
|
|
|
description: |
|
|
관리자 환경설정(storage/app/settings/*.json)이 `.env` 유래 config 를 덮는 기존 설계를
|
|
키 단위로 되돌리는 옵트인 스위치. `.env` 에 값이 명시된 항목만 settings 주입에서 빠지고,
|
|
관리자 화면은 그 필드를 편집 불가 + 잠금 배지로 표시하며, 저장 API 는 서버측에서 필터한다.
|
|
|
|
핵심 동작:
|
|
- 명시 판별은 config 빌드 시점 캡처(config/env-priority.php) — env() 런타임 호출은
|
|
config:cache 환경에서 null 로 고정되어 판별이 영구 미발동한다
|
|
- 판별은 strict: `KEY=`(빈 값)·`KEY=null`·미설정만 미명시. `APP_DEBUG=false`·`REDIS_DB=0`
|
|
같은 falsy 명시는 명시로 취급
|
|
- env 두 개가 한 설정을 나누는 키(redis_database)는 any-of 로 판정
|
|
- 스위치 OFF 면 전 경로 조기 return — 현행 동작 100% 동일
|
|
- 잠긴 키의 화면 표시값은 유효값(런타임 config). 단 민감 키는 값을 싣지 않는다
|
|
- 웹소켓 마스터 토글 잠금 시 OFF 강제 3종 오진입 금지 (`.env` 권위)
|
|
- 디버그 모드 잠금 시 2차 효과(로그 레벨 강제·프록시 게이트)를 유효값으로 보정
|
|
|
|
axes:
|
|
switch: [off, on]
|
|
key_state: [unlocked, locked_plain, locked_sensitive, locked_falsy]
|
|
surface: [inject, get_meta, get_effective_value, post_filter, ui_lock]
|
|
|
|
exclusions:
|
|
- { switch: off, key_state: locked_plain, reason: "스위치 OFF 는 잠금 판정 자체를 하지 않는다 — 전 key_state 가 unlocked 와 동일 경로" }
|
|
- { switch: off, key_state: locked_sensitive, reason: "동일" }
|
|
- { switch: off, key_state: locked_falsy, reason: "동일" }
|
|
- { key_state: locked_sensitive, surface: inject, reason: "민감 여부는 표시 경로에서만 갈린다 — 주입 스킵은 locked_plain 과 같은 코드 경로" }
|
|
- { key_state: locked_sensitive, surface: post_filter, reason: "동일 — 저장 필터는 민감 여부를 보지 않는다" }
|
|
- { key_state: locked_sensitive, surface: ui_lock, reason: "동일 — 화면 잠금 표시는 민감 여부와 무관" }
|
|
- { key_state: locked_falsy, surface: get_effective_value, reason: "falsy 명시는 판별 축이라 표시값 경로에서는 locked_plain 과 같다 — 유효값 오버레이는 민감 여부만 본다" }
|
|
- { key_state: locked_falsy, surface: ui_lock, reason: "falsy 명시는 판별 축이라 화면 표시에서는 locked_plain 과 구분되지 않는다" }
|
|
|
|
effects:
|
|
- switch_off_behaves_identically
|
|
- explicit_env_skips_injection
|
|
- empty_string_env_not_explicit
|
|
- false_env_is_explicit
|
|
- map_parity_covers_every_injected_default_key
|
|
- env_examples_document_env_priority_switch
|
|
- websocket_enabled_lock_skips_off_branch
|
|
- debug_mode_lock_corrects_outbound_gate
|
|
- locked_key_filtered_on_save_including_advanced
|
|
- locked_plain_shows_effective_value
|
|
- locked_sensitive_hides_effective_value
|
|
- meta_env_locked_uses_frontend_keys
|
|
- badge_and_disabled_rendered
|
|
|
|
test_files:
|
|
- tests/Unit/Support/EnvPriorityTest.php
|
|
- tests/Unit/Providers/SettingsServiceProviderEnvPriorityTest.php
|
|
- tests/Feature/Settings/EnvPriorityContractTest.php
|
|
- tests/Feature/Settings/SettingsEnvLockedMetaTest.php
|
|
- templates/_bundled/sirsoft-admin_basic/__tests__/layouts/admin-settings-env-locked.test.tsx
|
|
- tests/Playwright/specs/admin/settings-env-priority.spec.ts
|