Files
Gnuboard7/lang/ko/activity_log.php
T
HeuJung d17ea28da5 fix(core,board,ecommerce,page,kginicis): 정책값 하드코딩·계약 분리 결함 일괄 수정
관리자 환경설정이 값을 저장은 하지만 실제 동작에는 닿지 않던 결함군을 정리했다.
설정 화면(min/max)·저장 검증(FormRequest)·런타임 적용(Service) 세 계층이 각자
리터럴을 들고 있어 서로 조용히 갈라지던 것이 공통 원인이다.

경계값 SSoT 도입:
- config/core.php `settings_limits` 를 단일 출처로 두고, FormRequest 는 이 값으로
 규칙을 만들고 화면은 설정 응답의 `_meta.limits` 로 같은 값을 받아 바인딩한다.
- 게시판·이커머스도 각 모듈 config 의 limits 를 동일 구조로 노출한다.

적용되지 않던 정책을 실제로 적용:
- 비밀번호 최소 길이·특수문자 필수(신규 지정 7개 경로. 로그인은 제외 — 정책을
 올렸을 때 기존 회원이 자기 계정에 접근조차 못 하는 데드락을 막기 위함)
- 계정 잠금 시간 0 = 무한대(전용 컬럼 분리. timestamp 상한과 NULL 규약 때문에
 기존 컬럼 재사용이 불가능하다) + 관리자 수동 해제 경로
- 업로드 최대 크기·허용 확장자, 게시판 첨부 개수·댓글 깊이, 페이지 첨부 정책,
 장바구니 수량·구매 한도, 마일리지 사용 한도, 주문 부가세

파생 결함:
- 큐 Job(sync 드라이버)이 진행 중인 요청의 Request 바인딩을 덮어써, 뒤이어 실행되는
 훅 리스너가 헤더를 잃고 조용히 건너뛰었다. Job 이 원 바인딩을 복원하도록 고치고,
 전송 헤더가 필요한 리스너는 동기 실행으로 선언한다.
- 확장 업데이트 실패 시 상태만 되돌리고 상태 캐시를 비우지 않아, 그 확장의 관리자
 화면만 캐시 TTL(기본 하루) 동안 404 로 남았다. 실패 경로에도 무효화를 대칭으로
 두고, 빈 목록 자체를 캐시하지 않는다.
- 글 작성 시 첨부 파일이 Service 로 전달되지 않아 검증·권한은 통과하고 첨부만 사라졌다.
- 환경설정 저장 실패 안내가 내부 설정 키를 그대로 노출했다(105개 항목에 라벨 부여).

재발 방지:
- audit 룰 3종(레이아웃 경계 리터럴 / FormRequest 경계 불일치 / Service 재클램프)
- 테스트 실행 범위 강제 훅(check-test-scope)
- 트러블슈팅 사례 2건(큐 Job 요청 오염 / 확장 상태 캐시 고착)

공개 이슈: gnuboard/g7
2026-07-30 07:52:24 +09:00

301 lines
14 KiB
PHP

<?php
return [
// 활동 로그 관련 메시지
'fetch_success' => '활동 로그 정보를 성공적으로 가져왔습니다.',
'fetch_failed' => '활동 로그 정보를 가져오는데 실패했습니다.',
'delete_success' => '활동 로그가 삭제되었습니다.',
'bulk_delete_success' => '선택한 활동 로그가 삭제되었습니다.',
'delete_failed' => '활동 로그 삭제에 실패했습니다.',
// 유효성 검증 메시지
'validation' => [
'ids_required' => '삭제할 활동 로그를 선택해주세요.',
'ids_min' => '삭제할 활동 로그를 하나 이상 선택해주세요.',
'id_not_found' => '선택한 활동 로그를 찾을 수 없습니다.',
'log_type_invalid' => '선택한 로그 유형이 올바르지 않습니다.',
'date_range_invalid' => '종료일은 시작일과 같거나 이후여야 합니다.',
'per_page_min' => '페이지당 표시 개수는 1개 이상이어야 합니다.',
'per_page_max' => '페이지당 표시 개수는 100개를 초과할 수 없습니다.',
],
// 로그 유형 라벨
'type' => [
'admin' => '관리자',
'user' => '사용자',
'system' => '시스템',
],
// 액션 라벨 (마지막 세그먼트 기준)
'action' => [
'created' => '생성',
'create' => '생성',
'updated' => '수정',
'update' => '수정',
'deleted' => '삭제',
'delete' => '삭제',
'login' => '로그인',
'logout' => '로그아웃',
'login_failed' => '로그인 실패',
'account_locked' => '계정 잠금',
'account_unlocked' => '계정 잠금 해제',
'request' => '요청',
'expired' => '만료',
'verify' => '본인인증',
'verify_failed' => '본인인증 실패',
'export' => '내보내기',
'import' => '가져오기',
'index' => '목록 조회',
'show' => '상세 조회',
'search' => '검색',
'install' => '설치',
'activate' => '활성화',
'deactivate' => '비활성화',
'uninstall' => '제거',
'save' => '저장',
'run' => '실행',
'duplicate' => '복제',
'upload' => '업로드',
'toggle_status' => '상태 전환',
'bulk_update' => '일괄 수정',
'bulk_delete' => '일괄 삭제',
'bulk_update_status' => '일괄 상태 변경',
'refund' => '환불',
'publish' => '발행',
'register' => '회원가입',
'reset_password' => '비밀번호 재설정',
'forgot_password' => '비밀번호 찾기',
'record_consents' => '동의 기록',
'check' => '확인',
'sync_permissions' => '권한 동기화',
'sync_roles' => '역할 동기화',
'reply' => '답변',
'toggle' => '토글',
// 추가 액션
'withdraw' => '탈퇴',
'update_order' => '순서 변경',
'refresh_layouts' => '레이아웃 갱신',
'version_update' => '버전 업데이트',
'version_restore' => '버전 복원',
'reset' => '초기화',
// 이커머스/게시판 공용
],
// 설명 템플릿 (description_key로 사용)
'description' => [
// 사용자 관리
'user_index' => '사용자 목록 조회',
'user_create' => '사용자 생성 (ID: :user_id)',
'user_show' => '사용자 상세 조회 (ID: :user_id)',
'user_update' => '사용자 수정 (ID: :user_id)',
'user_delete' => '사용자 삭제 (ID: :user_id)',
'user_withdraw' => '사용자 탈퇴 (ID: :user_id)',
'user_statistics' => '사용자 통계 조회',
'user_recent' => '최근 사용자 조회',
'user_search' => '사용자 검색',
'user_check_email' => '이메일 중복 확인',
'user_update_language' => '사용자 언어 설정 변경',
'user_bulk_update_status' => '사용자 일괄 상태 변경 (:count건)',
// 역할 관리
'role_index' => '역할 목록 조회',
'role_active' => '활성 역할 목록 조회',
'role_show' => '역할 상세 조회 (ID: :role_id)',
'role_create' => '역할 생성 (ID: :role_id)',
'role_update' => '역할 수정 (ID: :role_id)',
'role_delete' => '역할 삭제 (ID: :role_id)',
'role_toggle_status' => '역할 상태 전환 (ID: :role_id)',
'role_sync_permissions' => '역할 권한 동기화 (ID: :role_id)',
// 권한 관리
'permission_index' => '권한 목록 조회',
// 메뉴 관리
'menu_index' => '메뉴 목록 조회',
'menu_hierarchy' => '메뉴 계층 조회',
'menu_active' => '활성 메뉴 목록 조회',
'menu_show' => '메뉴 상세 조회 (ID: :menu_id)',
'menu_create' => '메뉴 생성 (ID: :menu_id)',
'menu_update' => '메뉴 수정 (ID: :menu_id)',
'menu_delete' => '메뉴 삭제 (ID: :menu_id)',
'menu_update_order' => '메뉴 순서 변경',
'menu_toggle_status' => '메뉴 상태 전환 (ID: :menu_id)',
'menu_sync_roles' => '메뉴 역할 동기화 (ID: :menu_id)',
'menu_get_by_extension' => '확장별 메뉴 조회 (:extension_type: :extension_identifier)',
// 설정 관리
'settings_index' => '설정 목록 조회',
'settings_save' => '설정 저장',
'settings_show' => '설정 조회',
'settings_update' => '설정 수정',
'settings_system_info' => '시스템 정보 조회',
'settings_clear_cache' => '캐시 초기화',
'settings_optimize_system' => '시스템 최적화',
'settings_backup_database' => '데이터베이스 백업',
'settings_get_app_key' => '앱 키 조회',
'settings_app_key_regenerated' => '앱 키 재생성',
'settings_backup' => '백업 생성',
'settings_restore' => '백업 복원',
'settings_test_mail' => '메일 전송 테스트',
'settings_test_driver_connection' => '드라이버 연결 테스트',
// 인증
'auth_login' => '관리자 로그인',
'auth_logout' => '관리자 로그아웃',
'auth_register' => '회원가입',
'auth_forgot_password' => '비밀번호 찾기 요청',
'auth_reset_password' => '비밀번호 재설정',
'auth_record_consents' => '이용약관 동의 기록',
'auth_login_failed' => '로그인 실패 (:email)',
'auth_account_locked' => '계정 잠금 (:attempts회 실패, :minutes분 차단)',
'auth_account_locked_permanently' => '계정 영구 잠금 (:attempts회 실패, 관리자 해제 필요)',
'auth_account_unlocked' => '계정 잠금 해제 (:email)',
// 스케줄 관리
'schedule_index' => '스케줄 목록 조회',
'schedule_show' => '스케줄 상세 조회 (ID: :schedule_id)',
'schedule_create' => '스케줄 생성 (ID: :schedule_id)',
'schedule_update' => '스케줄 수정 (ID: :schedule_id)',
'schedule_delete' => '스케줄 삭제 (ID: :schedule_id)',
'schedule_run' => '스케줄 수동 실행 (ID: :schedule_id)',
'schedule_duplicate' => '스케줄 복제',
'schedule_bulk_update_status' => '스케줄 일괄 상태 변경 (:count건)',
'schedule_bulk_delete' => '스케줄 일괄 삭제 (:count건)',
'schedule_statistics' => '스케줄 통계 조회',
'schedule_history' => '스케줄 실행 이력 조회 (ID: :schedule_id)',
'schedule_delete_history' => '스케줄 이력 삭제',
// 대시보드
'dashboard_stats' => '대시보드 통계 조회',
'dashboard_resources' => '대시보드 리소스 조회',
'dashboard_activities' => '대시보드 활동 조회',
'dashboard_alerts' => '대시보드 알림 조회',
// 첨부파일 관리
'attachment_upload' => '파일 업로드',
'attachment_upload_batch' => '파일 일괄 업로드',
'attachment_delete' => '파일 삭제',
'attachment_bulk_delete' => '파일 일괄 삭제',
'attachment_reorder' => '파일 순서 변경',
// 레이아웃 관리
'layout_index' => '레이아웃 목록 조회',
'layout_show' => '레이아웃 상세 조회 (:layout_path)',
'layout_update' => '레이아웃 수정 (:layout_path)',
'layout_versions_index' => '레이아웃 버전 목록 조회 (:layout_path)',
'layout_version_show' => '레이아웃 버전 상세 조회 (:layout_path)',
'layout_version_restore' => '레이아웃 버전 복원 (:layout_path)',
// 메일 템플릿 관리
'mail_template_update' => '메일 템플릿 수정 (:template_name)',
'mail_template_toggle_active' => '메일 템플릿 활성 상태 변경 (:template_name)',
// 모듈 관리
'module_index' => '모듈 목록 조회',
'module_installed' => '설치된 모듈 목록 조회',
'module_uninstalled' => '미설치 모듈 목록 조회',
'module_show' => '모듈 상세 조회 (:module_name)',
'module_install' => '모듈 설치 (:module_name)',
'module_activate' => '모듈 활성화 (:module_name)',
'module_deactivate' => '모듈 비활성화 (:module_name)',
'module_uninstall' => '모듈 제거 (:module_name)',
'module_uninstall_info' => '모듈 삭제 정보 조회 (모듈: :module_name)',
'module_check_updates' => '모듈 업데이트 확인',
'module_update' => '모듈 업데이트 (:module_name)',
'module_refresh_layouts' => '모듈 레이아웃 갱신 (:module_name)',
'module_dependent_templates' => '모듈 종속 템플릿 조회',
'module_install_from_file' => '파일에서 모듈 설치',
'module_install_from_github' => 'GitHub에서 모듈 설치',
// 모듈 설정
'module_settings_save' => '모듈 설정 저장 (:module_name)',
'module_settings_reset' => '모듈 설정 초기화 (:module_name)',
// 플러그인 관리
'plugin_index' => '플러그인 목록 조회',
'plugin_installed' => '설치된 플러그인 목록 조회',
'plugin_show' => '플러그인 상세 조회 (:plugin_name)',
'plugin_install' => '플러그인 설치 (:plugin_name)',
'plugin_activate' => '플러그인 활성화 (:plugin_name)',
'plugin_deactivate' => '플러그인 비활성화 (:plugin_name)',
'plugin_uninstall' => '플러그인 제거 (:plugin_name)',
'plugin_uninstall_info' => '플러그인 삭제 정보 조회 (플러그인: :plugin_name)',
'plugin_check_updates' => '플러그인 업데이트 확인',
'plugin_update' => '플러그인 업데이트 (:plugin_name)',
'plugin_refresh_layouts' => '플러그인 레이아웃 갱신 (:plugin_name)',
'plugin_dependent_templates' => '플러그인 종속 템플릿 조회',
// 플러그인 설정
'plugin_settings_save' => '플러그인 설정 저장 (:plugin_name)',
'plugin_settings_reset' => '플러그인 설정 초기화 (:plugin_name)',
// 템플릿 관리
'template_index' => '템플릿 목록 조회',
'template_show' => '템플릿 상세 조회 (:template_name)',
'template_install' => '템플릿 설치 (:template_name)',
'template_activate' => '템플릿 활성화 (:template_name)',
'template_deactivate' => '템플릿 비활성화 (:template_name)',
'template_uninstall' => '템플릿 제거 (:template_name)',
'template_check_updates' => '템플릿 업데이트 확인',
'template_check_modified_layouts' => '템플릿 수정된 레이아웃 확인 (:template_name)',
'template_update' => '템플릿 업데이트 (:template_name)',
'template_version_update' => '템플릿 버전 업데이트 (:template_name)',
'template_install_from_file' => '파일에서 템플릿 설치',
'template_install_from_github' => 'GitHub에서 템플릿 설치',
'template_refresh_layouts' => '템플릿 레이아웃 갱신 (:template_name)',
// 코어 업데이트
'core_update_check' => '코어 업데이트 확인',
'core_update_update' => '코어 업데이트 실행',
// 활동 로그
'activity_log_index' => '활동 로그 목록 조회',
'activity_log_delete' => '활동 로그 삭제 (ID: :log_id)',
'activity_log_bulk_delete' => '활동 로그 일괄 삭제 (:count건)',
],
// ChangeDetector 필드 라벨
'fields' => [
// User
'name' => '이름',
'nickname' => '닉네임',
'email' => '이메일',
'language' => '언어',
'timezone' => '시간대',
'country' => '국가',
'status' => '상태',
'is_super' => '최고관리자',
'homepage' => '홈페이지',
'mobile' => '휴대폰',
'phone' => '전화번호',
'zipcode' => '우편번호',
'address' => '주소',
'address_detail' => '상세주소',
'bio' => '소개',
'admin_memo' => '관리자 메모',
// Role
'identifier' => '식별자',
'is_active' => '활성 여부',
// Menu
'url' => 'URL',
'icon' => '아이콘',
'parent_id' => '상위 항목',
'order' => '순서',
// Schedule
'command' => '명령어',
'expression' => '실행 주기',
'without_overlapping' => '중복 실행 방지',
'run_in_maintenance' => '점검 모드 실행',
'timeout' => '타임아웃',
// MailTemplate
'subject' => '제목',
'body' => '본문',
'is_default' => '기본값',
],
];