목록 조회 성능 축(깊은 OFFSET·정렬·색인)과 그 검증 계층에서 계획서 전수검수와 3회에 걸친 감사가 지적한 항목을 처리했다. 세부 경위는 의 각 회차 문서에 있다. 검증 계층 — 컨트롤러가 base Request 를 직접 주입받던 확장 13곳을 전용 FormRequest 로 옮겼다. 옮기면서 기존 동작 계약은 그대로 두었다: 상한 초과 limit 을 거부하지 않고 상한까지 반환하던 공개 API, per_page 를 범위로 조정하던 관리자 목록, 미지원 period 를 year 로 해석하던 인기글 목록 모두 종전과 같은 응답을 낸다. 상한/폴백을 rules 로 승격시키면 200 이던 응답이 422 가 되어 기존 링크가 깨지므로, 규칙은 타입만 닫고 클램프·폴백은 접근자가 맡는다. period 는 접근자가 닫힌 집합만 반환해 캐시 키 공간도 함께 닫힌다. ckeditor5 이미지 업로드만 ResponseHelper 봉투를 쓰지 않는다. 응답을 파싱하는 주체가 CDN 으로 로드되는 상위 CKEditor5 43.3.1 의 SimpleUploadAdapter 라 규약을 바꿀 수 없어, 각 응답 지점에 사유를 명시한 면제를 부착하고 근거를 API 문서에 남겼다. 하네스 — 룰 5개의 대상 경로 패턴이 매처와 맞지 않아 번들 확장 컨트롤러가 검사 대상에서 통째로 빠져 있었다. 패턴을 고치자 확장 위반 17건이 드러나 전건 처리했다. severity 오타가 요약 집계 양쪽에 안 잡혀 "0 error" 로 보고되던 문제도 런너 사전 검증으로 막았다. 정렬 게이트 대조 하네스는 관계 정렬 변형만 쓰는 저장소를 탐지하지 못한 채 통과시키고 있었다. 탐지·제외·인자 파싱을 함께 고치고 단위 테스트를 신설했다.
74 lines
3.9 KiB
PHP
74 lines
3.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* 통합 검색 관련 다국어 메시지 (한국어)
|
|
*/
|
|
|
|
return [
|
|
'empty_keyword' => '검색어를 입력해주세요.',
|
|
'results_found' => ':count건의 검색 결과를 찾았습니다.',
|
|
'no_results' => '검색 결과가 없습니다.',
|
|
'view_more' => '더보기',
|
|
|
|
// 검증 메시지
|
|
'validation' => [
|
|
'q_min' => '검색어는 2글자 이상 입력해주세요.',
|
|
'q_max' => '검색어는 최대 200자까지 입력 가능합니다.',
|
|
'page_integer' => '페이지 번호는 숫자여야 합니다.',
|
|
'page_min' => '페이지 번호는 1 이상이어야 합니다.',
|
|
'per_page_integer' => '페이지당 항목 수는 숫자여야 합니다.',
|
|
'per_page_min' => '페이지당 항목 수는 1 이상이어야 합니다.',
|
|
'per_page_max' => '페이지당 항목 수는 최대 100개까지 가능합니다.',
|
|
],
|
|
|
|
// 검색 인덱스 점검·재생성 (search:index) — 엔진 중립
|
|
'index' => [
|
|
'status' => [
|
|
'healthy' => '정상',
|
|
'degraded' => '부분',
|
|
'stale' => '색인 누락',
|
|
'skipped' => '판정 불가',
|
|
],
|
|
|
|
'no_maintainer' => '현재 검색 엔진(:driver)은 인덱스 점검을 제공하지 않습니다. 엔진 제공자가 점검 기능을 등록하면 이 화면에서 함께 다룹니다.',
|
|
'unavailable' => '현재 검색 엔진(:driver)의 인덱스를 점검할 수 없습니다.',
|
|
'no_targets' => '검색 엔진(:driver)에 점검할 인덱스가 없습니다.',
|
|
'driver_label' => '검색 엔진: :driver',
|
|
|
|
'col' => [
|
|
'index' => '인덱스',
|
|
'status' => '판정',
|
|
'measurement' => '측정',
|
|
],
|
|
|
|
'counts' => '정상 :healthy · 부분 :degraded · 색인누락 :stale · 판정불가 :skipped (총 :total)',
|
|
'rebuild_targets' => '재생성 대상 :count개',
|
|
'rebuild_cost_warning' => '재생성 중에는 대상 인덱스가 잠기거나 재색인됩니다. 운영 중인 사이트에서는 유지보수 시간에 수행하세요.',
|
|
'rebuild_confirm' => '위 인덱스를 재생성할까요?',
|
|
'rebuild_after_bulk_confirm' => '일괄 업데이트 후 검색 인덱스를 재생성할까요? (기본: 아니오 — 운영 중이면 유지보수 시간에 별도로 수행하세요)',
|
|
'rebuild_skipped' => '재생성을 건너뜁니다.',
|
|
'stale_hint' => '색인이 누락된 인덱스가 있습니다. `php artisan search:index --repair` 로 재생성하세요.',
|
|
'stale_after_update' => '색인이 누락된 검색 인덱스 :count개가 있어 해당 검색이 결과를 돌려주지 않습니다.',
|
|
'rebuilt_item' => '재생성: :index',
|
|
'rebuild_failed_item' => '재생성 실패: :index — :error',
|
|
'still_stale_item' => '재생성 후에도 색인 누락: :index',
|
|
'degraded_hint' => '「부분」 은 엔진의 토큰 처리 특성일 수 있어 자동 재생성 대상이 아닙니다. 필요하면 개별 확인하세요.',
|
|
|
|
'report' => [
|
|
'nothing_to_do' => '점검 :count개 · 재생성 대상 없음',
|
|
'rebuilt' => '점검 :inspected개 · 재생성 :repaired개 · 실패 :failed개 · 잔존 :remaining개',
|
|
],
|
|
|
|
// mysql-fulltext 드라이버 전용 문구
|
|
'fulltext' => [
|
|
'unsupported_driver' => '현재 DB 드라이버는 FULLTEXT 를 지원하지 않습니다 (LIKE 검색으로 동작하며 점검 대상이 없습니다).',
|
|
'self_match' => ':found/:probed 행이 자기 자신을 찾음',
|
|
'skip' => [
|
|
'no_single_pk' => '단일 컬럼 기본키가 없어 행 단위 판정을 할 수 없습니다',
|
|
'no_rows' => '색인 컬럼에 내용이 있는 행이 없습니다',
|
|
'no_tokens' => '표본 행에서 검색 토큰을 만들 수 없습니다 (내용이 너무 짧음)',
|
|
],
|
|
],
|
|
],
|
|
];
|