AI 단계별 작업 문서 04 — 운영, 검증, 롤백 및 부록
완료 후 사용법, 주의사항, 체크리스트, 롤백 절차와 원본 부록을 보존했습니다.
6. 운영자·방문자 사용법 (완성 후)
6-1. 관리자가 설정하는 순서
- 관리자 → 게시판 관리 → 해당 게시판의 여분 필드 아이콘 → 필드 추가/수정
- 목록에 보일 필드는 "목록 노출" 체크
- 필터로 쓸 필드는 "검색 필터" 체크
- 저장 → 해당 게시판 목록 화면에서 즉시 반영 (스킨에 2·3단계가 적용되어 있을 때)
- 칸 순서는 정렬 순서(
sort_order) 숫자로 조절 (작을수록 앞)
6-2. 타입별 권장 설정
| 타입 | 목록 노출 | 검색 필터 | 비고 |
|---|---|---|---|
| select / radio | 권장 | 권장 | 가장 쓰기 좋은 필터 (드롭다운) |
| checkbox | 선택 | 권장 | 선택 항목을 모두 포함하는 글만 표시 (AND). 옵션에 쉼표(,) 금지 |
| number | 권장 | 권장 | 최소~최대 범위. 숫자만 입력하도록 안내 (쉼표 금지, 부록 B 참고) |
| date / datetime | 선택 | 권장 | 기간 범위 |
| text / tel / url | 선택 | 선택 | 필터는 부분 일치. url 은 목록에서 "링크"로 표시 |
| textarea | 비권장 | 비권장 | 길이가 길어 목록·검색에 부적합 |
6-3. 방문자(사용자) 사용법
- 목록 위 필터 폼에서 조건을 고르고 "필터 적용" 을 누른다. 여러 조건은 모두 만족하는 글만 나온다(AND).
- 적용된 조건은 칩으로 표시되고, "초기화" 를 누르면 필터가 해제된다.
- 필터 결과 주소(URL)를 그대로 복사해 공유·북마크할 수 있다.
- 카테고리와 키워드 검색도 함께 사용할 수 있다.
7. 한계와 주의사항 (테스트로 확인된 것 포함)
| # | 내용 | 대응 |
|---|---|---|
| 1 | number 값에 쉼표가 있으면(12,000) 범위 필터에서 12 로 계산됨 (실제 테스트에서 재현) |
필드 안내문에 "숫자만 입력" 표기. 기존 데이터는 UPDATE dx_post_meta SET value=REPLACE(value, ',', '') WHERE field_key='price' 로 정리 (실행 전 SELECT 로 대상 확인·백업) |
| 2 | number 값이 비어 있는 글은 범위 필터에서 제외됨 (의도된 동작) | — |
| 3 | 정확 일치·체크박스 비교는 대소문자를 구분하지 않음 (utf8mb4_unicode_ci) |
— |
| 4 | 체크박스 필터는 AND. OR 가 필요하면 dx_bf_build_filter 의 checkbox 분기에서 FIND_IN_SET 조건들을 OR 로 묶도록 수정 |
요구가 있을 때만 |
| 5 | 필터를 쓰는 요청은 목록 캐시를 우회한다 | 필터 사용 빈도가 높고 트래픽이 크면 부하 증가 가능 |
| 6 | 값 컬럼은 TEXT 라 값에 인덱스가 없다. 글마다 필드당 EXISTS 1회 (post_id + field_key 유니크 인덱스를 사용) |
글 수 수만 건, 동시 필터 3~4개 이하 권장. 그 이상이면 별도 정규화 컬럼/검색 테이블을 검토 |
| 7 | 옵션 이름을 바꾸면 기존 글의 저장값과 불일치 → 필터에 안 걸림 | 옵션 변경 시 dx_post_meta 값도 함께 UPDATE |
| 8 | 필드를 비활성/삭제하면 필터 대상에서 제외 | — |
| 9 | 글 상세 하단 목록, list-live.js 실시간 삽입 행에는 적용되지 않음 |
사실 #7, #8 |
| 10 | handler.php 업데이트 시 패치 소실 |
grep -n BF-PATCH boards/handler.php 로 점검 |
| 11 | 여분 필드는 글 작성 시점에 저장되는 값만 검색 대상. API/별도 저장 경로로 만든 글은 meta가 없을 수 있음 | dx_save_post_meta() 로 보완 |
8. 검증 체크리스트 (AI가 작업 후 반드시 수행)
목록 노출
- 관리자에서 필드의 "목록 노출" 체크 → 목록 화면에 칸/라벨이 나온다
- 값이 있는 글/없는 글 모두 오류 없이 표시된다 (빈 칸)
- 체크박스 값이 칩으로, url 이 "링크"로, number 가 천 단위 구분으로 표시된다
- "목록 노출"을 해제하면 칸이 사라진다 (스킨 재수정 불필요)
- 비로그인 상태(캐시 경로)에서도 칸이 보인다
- 목록 쿼리 수가 글 수에 비례해 늘지 않는다 (meta 조회는 페이지당 1회)
검색 필터
-
php -l boards/handler.php통과,BF-PATCH마커 확인 - 필터 폼이 나타나고, 선택한 값이 적용 후에도 유지된다
-
?bf_{key}=값결과가 정확하고, 총 개수/페이지 수가 맞다 - 2페이지로 이동해도 필터가 유지된다 (페이지네이션 연결)
- 비로그인 상태에서도 필터가 적용된다 (캐시 우회 확인)
-
is_search=0인 필드, 정의되지 않은 key 를 URL 에 넣어도 무시된다 - 카테고리·키워드 검색과 함께 써도 정상이다
- 이상한 값(
' OR '1'='1, 배열 등)을 넣어도 오류 없이 빈 결과/무시 처리된다 - 필터 초기화 링크가
cat/검색어를 유지하면서bf_*만 지운다
SQL 직접 확인 (대조용)
-- 게시판 3, 지역=서울 인 글 수 (화면의 총 개수와 같아야 함)
SELECT COUNT(*) FROM dx_posts p
WHERE p.board_id=3 AND p.status=1 AND p.is_notice=0
AND EXISTS (SELECT 1 FROM dx_post_meta pm
WHERE pm.post_id=p.id AND pm.field_key='region' AND pm.value='서울');
9. 롤백
extend/top/60_board_fields_helpers.php삭제boards/handler.php를 백업본으로 복원 (또는BF-PATCH3곳 제거)- 스킨 수정분 복원 (복사본 스킨을 썼다면 게시판의 스킨을 원래대로 선택)
DB 구조·데이터는 이 작업이 전혀 건드리지 않으므로 롤백 시 데이터 손실이 없다.
10. AI 작업 요약 (한눈에)
| 사용자 요청 | 할 일 |
|---|---|
| "목록에 {필드}가 보이게" | 1단계 + 2단계 + 관리자에서 해당 필드 "목록 노출" 체크 |
| "{필드}로 필터/검색" | 1단계 + 3단계(패치 3곳 + 폼 + 페이지네이션) + 관리자에서 "검색 필터" 체크 |
| "필터가 2페이지에서 풀려요" | 5-3 (3) 페이지네이션 연결 누락 |
| "비로그인에서만 필터가 안 먹어요" | 패치 2(캐시 조건) 누락 |
| "필터 결과 개수가 이상해요" | 패치 3 위치($where 조립 이후, COUNT 이전)·$params 순서 확인 |
| "가격 범위가 이상해요" | 값에 쉼표/문자가 섞여 있는지 확인 (7장 #1) |
| "글 상세 아래 목록에는 안 나와요" | 정상 (사실 #8). 필요 시 _list_rows.php 에 2단계 코드 추가 |
부록 A. 실행 검증 결과
환경: MariaDB 10.11 / PHP 8.3, 샘플 글 5건(게시판 3) + 타 게시판 1건, 위 헬퍼 코드를 그대로 실행. 각 케이스에서 ? 개수 = 바인딩 값 개수임을 확인했다.
| 케이스 | 결과 (글 ID) | 판정 |
|---|---|---|
| 필터 없음 | 1001~1005 (5건) | 정상 |
bf_region=서울 |
1001, 1003, 1005 | 정상 (타 게시판 글 2001 제외) |
| 서울 + 주차 | 1001 | 정상 |
| 체크박스 주차+에어컨 (AND) | 1001, 1002 | 정상 |
| 체크박스 엘리베이터 | 1002, 1005 | 정상 |
bfmin_price=1000 |
1001, 1002 | 정상 (빈 값 1003 제외) |
bfmax_price=1000 |
1001, 1004, 1005 | 1004 는 값이 12,000 → 쉼표 문제(7장 #1) |
bfmin 500 ~ bfmax 6000 |
1001, 1002 | 정상 |
bfmin_price=abc |
조건 무시 (5건) | 정상 |
bfq_memo=100%_ |
1001 | 정상 (%, _ 이스케이프) |
bfq_memo=1_0 |
0건 | 정상 (_ 가 와일드카드로 동작하지 않음) |
bfq_memo=조용 |
1002 | 정상 (한글) |
date bfmin_open_date=2026-10-15 / bfmax=2026-10-01 |
1002 / 1001 | 정상 |
datetime bfmax_start_at=2026-10-17 |
1001 | 정상 (그날 23:59 까지 포함) |
datetime bfmin_start_at=2026-10-18 |
1005 | 정상 |
is_search=0 필드 / 미정의 key |
조건 무시 | 정상 |
bf_region=서울' OR '1'='1 |
0건 | 정상 (바인딩으로 인젝션 무효) |
| 배열/이상값 | 조건 무시 | 정상 |
| 필터 폼 | 선택값 유지, hidden 유지, 검색 비대상 필드 미노출 | 정상 |
dx_bf_display |
url 은 http(s):// 만 링크, blocked: 는 텍스트, HTML 이스케이프 |
정상 |
패치된 handler.php |
php -l 문법 통과 |
정상 |
실제 DXCMS 전체를 구동한 통합 테스트는 아니다. 헬퍼 SQL/폼/표시 함수는 실제 MariaDB 로,
handler.php패치는 문법 검사로 검증했다. 최종 확인은 8장 체크리스트를 실제 사이트에서 수행해야 한다.
부록 B. 관련 파일
extend/top/50_board_fields.php ← 여분 필드 로더 (기존)
extend/top/60_board_fields_helpers.php ← 이 문서 3장 (신규)
boards/handler.php ← 5-2 패치 3곳 (case 'list' / 'search')
boards/skins/{스킨}/list.php ← 4장 목록 칸, 5-3 필터 폼·페이지네이션
boards/skins/gallery/_list_rows.php ← 카드 행 partial (view 하단 목록과 공유)
core/BoardFields.php ← getFields / getMeta (수정 불필요)