fix(core,board,ecommerce): 조건부 검증 결함 패밀리 일괄 수정 및 실패 안내 노출

여러 화면에서 조건부(FormRequest) 검증이 우회되거나 과도하게 제한되던 결함을 한 계열로 묶어 수정한다.

- 검증 규칙 확장 필터 이름 10개를 나머지 92개와 동일 규칙으로 통일
- 설명 길이를 바이트가 아닌 글자 수로 계산(한글 오검출 해소)
- 비활성 언어팩 번역 보존한 채 수정 허용
- 알림 템플릿 제목 nullable 존중, 미지원 발송 수단 저장 차단
- 일정/실행 이력 목록 조회 검증 정합
- 게시판 첨부 미사용 시 빈 확장자 통과, new_display_hours/최소 길이 0 허용, 일괄 적용 override_values 범위 검증(SSoT)
- 이커머스 클레임 사유 조회 검증, 용어 정정
- 원문 i18n 키 노출 다수 해소, 저장/삭제 실패 시 사유 화면 노출
- 아이콘 크기/다크모드 대비 회귀 수정

번들 확장(모듈3·플러그인6·템플릿2·언어팩5) 버전 new-bump 및 CHANGELOG 반영, ja 언어팩 동기.
This commit is contained in:
HeuJung
2026-07-23 10:54:17 +09:00
parent c001b30a87
commit 7f8fb6870f
288 changed files with 5339 additions and 1049 deletions
+4
View File
@@ -13,6 +13,10 @@ return [
'ids_required' => 'Please select activity logs to delete.',
'ids_min' => 'Please select at least one activity log to delete.',
'id_not_found' => 'The selected activity log was not found.',
'log_type_invalid' => 'The selected log type is invalid.',
'date_range_invalid' => 'The end date must be the same as or after the start date.',
'per_page_min' => 'Items per page must be at least 1.',
'per_page_max' => 'Items per page must not exceed 100.',
],
// Log type labels
+11 -12
View File
@@ -126,17 +126,6 @@ return [
'install_failed' => 'Plugin installation failed: :error',
],
// Validation messages (FormRequest)
'validation' => [
'github_url_required' => 'GitHub URL is required.',
'github_url_invalid' => 'Invalid URL format.',
'github_url_format' => 'Must be a GitHub repository URL. (e.g., https://github.com/owner/repo)',
'file_required' => 'Please select a file to install.',
'file_invalid' => 'Invalid file.',
'file_must_be_zip' => 'Only ZIP files can be uploaded.',
'file_max_size' => 'File size must not exceed :sizeMB.',
],
// Artisan command messages
'commands' => [
'list' => [
@@ -249,8 +238,18 @@ return [
'updated' => 'Plugin settings updated successfully.',
],
// Validation messages
// Validation messages (FormRequest)
'validation' => [
// GitHub / file upload installation
'github_url_required' => 'GitHub URL is required.',
'github_url_invalid' => 'Invalid URL format.',
'github_url_format' => 'Must be a GitHub repository URL. (e.g., https://github.com/owner/repo)',
'file_required' => 'Please select a file to install.',
'file_invalid' => 'Invalid file.',
'file_must_be_zip' => 'Only ZIP files can be uploaded.',
'file_max_size' => 'File size must not exceed :sizeMB.',
// Plugin name / listing
'plugin_name_required' => 'Plugin name is required.',
'plugin_name_string' => 'Plugin name must be a string.',
'plugin_name_max' => 'Plugin name must not exceed :max characters.',
+32 -17
View File
@@ -566,6 +566,12 @@ return [
'data_source_id_must_be_string' => 'data_sources[:index].id must be a string.',
],
// Notification channel validation messages
'notification_channel' => [
'invalid' => 'The notification channel identifier is invalid.',
'unavailable' => "Unavailable notification channel: ':value'",
],
// Translatable field validation messages
'translatable' => [
'must_be_array' => 'Translatable field must be an array.',
@@ -577,25 +583,13 @@ return [
'current_locale_required' => 'The :locale language value is required.',
],
// Template validation messages
'template' => [
'type' => [
'in' => 'The type parameter must be either user or admin.',
],
'description' => [
'string' => 'The template description must be a string.',
'max' => 'The template description may not be greater than :max characters.',
],
'metadata' => [
'array' => 'metadata must be an array.',
],
'status' => [
'in' => 'status must be either active or inactive.',
],
],
// Menu validation messages
'menu' => [
'roles' => [
'array' => 'The roles must be an array.',
'integer' => 'Each role ID must be an integer.',
'exists' => 'The selected role could not be found.',
],
'name' => [
'required' => 'Please enter a menu name.',
],
@@ -736,7 +730,19 @@ return [
],
// Module path validation messages
// Extension identifier validation messages (ValidExtensionIdentifier Rule)
'extension_identifier' => [
'max' => 'The extension identifier must not exceed 255 characters.',
'must_be_string' => 'The extension identifier must be a string.',
'min_parts' => 'The extension identifier must be in vendor-name format (e.g., sirsoft-board).',
'empty_part' => 'The extension identifier has an empty part. Hyphens cannot be consecutive or at the edges.',
'invalid_characters' => 'The extension identifier may only contain lowercase letters, numbers, and underscores (_).',
'empty_word' => 'The extension identifier has consecutive or edge underscores.',
'word_starts_with_digit' => 'Each word in the extension identifier must not start with a digit.',
],
'module_path' => [
'file_type_not_allowed' => 'File type not allowed. Extension: :extension (Allowed: :allowed)',
'must_be_string' => 'The path must be a string.',
'traversal_detected' => 'Path traversal detected: :pattern',
'absolute_path_not_allowed' => 'Absolute paths are not allowed.',
@@ -746,6 +752,7 @@ return [
// Plugin path validation messages
'plugin_path' => [
'file_type_not_allowed' => 'File type not allowed. Extension: :extension (Allowed: :allowed)',
'must_be_string' => 'The path must be a string.',
'traversal_detected' => 'Path traversal detected: :pattern',
'absolute_path_not_allowed' => 'Absolute paths are not allowed.',
@@ -1177,5 +1184,13 @@ return [
// Changelog fields
'from_version' => 'start version',
'to_version' => 'end version',
'layout' => 'layout',
'module' => 'module',
'token' => 'token',
'mailgun_domain' => 'Mailgun domain',
'mailgun_secret' => 'Mailgun secret',
'ses_key' => 'SES access key',
'ses_secret' => 'SES secret key',
'ses_region' => 'SES region',
],
];
+4
View File
@@ -13,6 +13,10 @@ return [
'ids_required' => '삭제할 활동 로그를 선택해주세요.',
'ids_min' => '삭제할 활동 로그를 하나 이상 선택해주세요.',
'id_not_found' => '선택한 활동 로그를 찾을 수 없습니다.',
'log_type_invalid' => '선택한 로그 유형이 올바르지 않습니다.',
'date_range_invalid' => '종료일은 시작일과 같거나 이후여야 합니다.',
'per_page_min' => '페이지당 표시 개수는 1개 이상이어야 합니다.',
'per_page_max' => '페이지당 표시 개수는 100개를 초과할 수 없습니다.',
],
// 로그 유형 라벨
+11 -12
View File
@@ -126,17 +126,6 @@ return [
'install_failed' => '플러그인 설치에 실패했습니다: :error',
],
// validation 메시지 (FormRequest)
'validation' => [
'github_url_required' => 'GitHub URL은 필수입니다.',
'github_url_invalid' => '유효한 URL 형식이 아닙니다.',
'github_url_format' => 'GitHub 저장소 URL 형식이어야 합니다. (예: https://github.com/owner/repo)',
'file_required' => '설치할 파일을 선택해 주세요.',
'file_invalid' => '유효한 파일이 아닙니다.',
'file_must_be_zip' => 'ZIP 파일만 업로드할 수 있습니다.',
'file_max_size' => '파일 크기는 :sizeMB를 초과할 수 없습니다.',
],
// Artisan 커맨드 메시지
'commands' => [
'list' => [
@@ -249,8 +238,18 @@ return [
'updated' => '플러그인 설정이 성공적으로 업데이트되었습니다.',
],
// 검증 메시지
// 검증 메시지 (FormRequest)
'validation' => [
// GitHub / 파일 업로드 설치
'github_url_required' => 'GitHub URL은 필수입니다.',
'github_url_invalid' => '유효한 URL 형식이 아닙니다.',
'github_url_format' => 'GitHub 저장소 URL 형식이어야 합니다. (예: https://github.com/owner/repo)',
'file_required' => '설치할 파일을 선택해 주세요.',
'file_invalid' => '유효한 파일이 아닙니다.',
'file_must_be_zip' => 'ZIP 파일만 업로드할 수 있습니다.',
'file_max_size' => '파일 크기는 :sizeMB를 초과할 수 없습니다.',
// 플러그인 이름 / 목록 조회
'plugin_name_required' => '플러그인 이름은 필수입니다.',
'plugin_name_string' => '플러그인 이름은 문자열이어야 합니다.',
'plugin_name_max' => '플러그인 이름은 최대 :max자까지 입력할 수 있습니다.',
+32 -15
View File
@@ -565,6 +565,12 @@ return [
'data_source_id_must_be_string' => 'data_sources[:index].id는 문자열이어야 합니다.',
],
// 알림 채널 검증 메시지
'notification_channel' => [
'invalid' => '알림 채널 식별자가 올바르지 않습니다.',
'unavailable' => "사용할 수 없는 알림 채널입니다: ':value'",
],
// 다국어 필드 검증 메시지
'translatable' => [
'must_be_array' => '다국어 필드는 배열이어야 합니다.',
@@ -577,24 +583,14 @@ return [
],
// 템플릿 검증 메시지
'template' => [
'type' => [
'in' => 'type 파라미터는 user 또는 admin만 가능합니다.',
],
'description' => [
'string' => '템플릿 설명은 문자열이어야 합니다.',
'max' => '템플릿 설명은 :max자를 초과할 수 없습니다.',
],
'metadata' => [
'array' => 'metadata는 배열이어야 합니다.',
],
'status' => [
'in' => 'status는 active 또는 inactive여야 합니다.',
],
],
// 메뉴 검증 메시지
'menu' => [
'roles' => [
'array' => '역할 목록은 배열이어야 합니다.',
'integer' => '역할 ID는 숫자여야 합니다.',
'exists' => '선택한 역할을 찾을 수 없습니다.',
],
'name' => [
'required' => '메뉴 이름을 입력해주세요.',
],
@@ -734,8 +730,20 @@ return [
'file_type_not_allowed' => '허용되지 않은 파일 타입입니다. 확장자: :extension (허용: :allowed)',
],
// 확장 식별자 검증 메시지 (ValidExtensionIdentifier Rule)
'extension_identifier' => [
'max' => '확장 식별자는 최대 255자까지 입력 가능합니다.',
'must_be_string' => '확장 식별자는 문자열이어야 합니다.',
'min_parts' => '확장 식별자는 vendor-name 형식이어야 합니다 (예: sirsoft-board).',
'empty_part' => '확장 식별자에 빈 부분이 있습니다. 하이픈이 연속되거나 양끝에 올 수 없습니다.',
'invalid_characters' => '확장 식별자는 영문 소문자, 숫자, 언더스코어(_)만 사용할 수 있습니다.',
'empty_word' => '확장 식별자에서 언더스코어가 연속되거나 양끝에 올 수 없습니다.',
'word_starts_with_digit' => '확장 식별자의 각 단어는 숫자로 시작할 수 없습니다.',
],
// 모듈 경로 검증 메시지
'module_path' => [
'file_type_not_allowed' => '허용되지 않은 파일 타입입니다. 확장자: :extension (허용: :allowed)',
'must_be_string' => '경로는 문자열이어야 합니다.',
'traversal_detected' => '경로 트래버설이 감지되었습니다: :pattern',
'absolute_path_not_allowed' => '절대 경로는 허용되지 않습니다.',
@@ -745,6 +753,7 @@ return [
// 플러그인 경로 검증 메시지
'plugin_path' => [
'file_type_not_allowed' => '허용되지 않은 파일 타입입니다. 확장자: :extension (허용: :allowed)',
'must_be_string' => '경로는 문자열이어야 합니다.',
'traversal_detected' => '경로 트래버설이 감지되었습니다: :pattern',
'absolute_path_not_allowed' => '절대 경로는 허용되지 않습니다.',
@@ -1168,5 +1177,13 @@ return [
'websocket_host' => '웹소켓 호스트',
'websocket_port' => '웹소켓 포트',
'websocket_scheme' => '웹소켓 프로토콜',
'layout' => '레이아웃',
'module' => '모듈',
'token' => '토큰',
'mailgun_domain' => 'Mailgun 도메인',
'mailgun_secret' => 'Mailgun 시크릿',
'ses_key' => 'SES 액세스 키',
'ses_secret' => 'SES 시크릿 키',
'ses_region' => 'SES 리전',
],
];