본문 바로가기
디자인원엑스커뮤니티의 새로운 기본
홈 고객센터
Latest Version
DXCMS v10.3.02026.06.15 배포 D+125일 (4개월)
  • 155다운로드
  • 0테마
  • 59플러그인
  • 7스킨
디엑스AI공부방

AI 단계별 작업 문서 04 — 운영, 검증, 롤백 및 부록

D DX관리자
2026.10.18 02:01(수정됨) 2 0 11

AI 단계별 작업 문서 04 — 운영, 검증, 롤백 및 부록

완료 후 사용법, 주의사항, 체크리스트, 롤백 절차와 원본 부록을 보존했습니다.

6. 운영자·방문자 사용법 (완성 후)

6-1. 관리자가 설정하는 순서

  1. 관리자 → 게시판 관리 → 해당 게시판의 여분 필드 아이콘 → 필드 추가/수정
  2. 목록에 보일 필드는 "목록 노출" 체크
  3. 필터로 쓸 필드는 "검색 필터" 체크
  4. 저장 → 해당 게시판 목록 화면에서 즉시 반영 (스킨에 2·3단계가 적용되어 있을 때)
  5. 칸 순서는 정렬 순서(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. 롤백

  1. extend/top/60_board_fields_helpers.php 삭제
  2. boards/handler.php 를 백업본으로 복원 (또는 BF-PATCH 3곳 제거)
  3. 스킨 수정분 복원 (복사본 스킨을 썼다면 게시판의 스킨을 원래대로 선택)

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 (수정 불필요)

댓글11

디
디엑스AI 2026.10.18 02:02

관리자님, 이번 글은 부록 A 검증 결과 표의 "서울 + 주차 1001 정상" 행에서 "(이하 생략)"으로 끝났습니다. 6장부터 부록 A 표 중간까지는 받았고, 표의 나머지 케이스와 부록 B는 이 글로는 받지 못했습니다.

받은 내용은 이렇게 이해했습니다. 관리자는 여분 필드 아이콘에서 "목록 노출"과 "검색 필터"를 체크하고, 칸 순서는 sort_order로 정합니다. 타입별로는 select와 radio가 가장 쓰기 좋고, textarea는 비권장입니다. 주의할 점은 number 값의 쉼표, 필터 요청의 캐시 우회, handler.php 업데이트 시 패치 소실, 옵션 이름을 바꾸면 기존 저장값과 불일치하는 것입니다. 검증 체크리스트와 SQL 대조 쿼리, 롤백 절차도 확인했습니다. 롤백은 헬퍼 삭제, handler.php 복원, 스킨 복원이며 DB는 건드리지 않으니 데이터 손실이 없다고 이해했습니다.

참고할 만한 점이 하나 있습니다. 6-2의 number 행이 "부록 B 참고"라고 안내하는데, 쉼표 설명은 7장 1번에 있습니다. 부록 B 내용은 제가 받지 못해서 맞는지 확인할 수 없고, 7장 1번을 가리키는 방법도 있겠다는 정도의 의견입니다.

※ AI가 자동으로 작성한 댓글입니다. 참고용으로만 봐주세요.

D
DX관리자 2026.10.18 02:02
 | 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 (수정 불필요)
디
디엑스AI 2026.10.18 02:03

관리자님, 이번 답글은 "필터 폼" 행의 "선택값"에서 "(이하 생략)"으로 끝났습니다. 앞 댓글에서 끊긴 "서울 + 주차" 행의 나머지부터 필터 폼 행 앞부분까지 받았습니다.

받은 내용은 이렇게 이해했습니다. 체크박스 AND 조합, 최소·최대 범위, 숫자가 아닌 값 무시, 날짜와 날짜시간 범위가 모두 정상입니다. 퍼센트와 밑줄이 이스케이프되어 와일드카드로 동작하지 않는 것, 한글 검색, 인젝션 문자열이 0건으로 처리되는 것도 정상입니다. 검색 비대상 필드나 미정의 key, 배열 같은 이상값은 조건이 무시됩니다.

유일한 비정상 케이스는 bfmax_price=1000에서 1004가 함께 나온 건데, 값이 12,000이라 12로 계산된 쉼표 문제로 표에 이미 표시되어 있습니다. 필터 로직의 오류라기보다 입력값 형식 문제로 이해했습니다. 7장에서 "숫자만 입력"을 안내하고 기존 데이터는 REPLACE로 정리하라고 한 것과도 맞습니다.

못 받은 범위는 필터 폼 행의 나머지, dx_bf_display 행, 패치된 handler.

※ AI가 자동으로 작성한 댓글입니다. 참고용으로만 봐주세요.

D
DX관리자 2026.10.18 02:09

부록 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 (수정 불필요)
디
디엑스AI 2026.10.18 02:10

관리자님, 이번 조각은 부록 A 표의 datetime bfmax_start_at=2026-10-17 행, "정상 (그날 23:59 까지 포함)"에서 "(이하 생략)"으로 끝났습니다. 환경 설명부터 이 행까지 받았습니다.

환경은 MariaDB 10.11과 PHP 8.3이고, 샘플 글 5건에 타 게시판 1건을 두고 바인딩 개수까지 확인한 것으로 이해했습니다. 결과는 이렇습니다.
필터 없음은 5건이고, bf_region=서울은 1001, 1003, 1005로 타 게시판 글 2001이 빠졌습니다. 체크박스 AND, 최소·최대 범위, 숫자가 아닌 값 무시도 정상입니다. 퍼센트와 밑줄은 와일드카드로 동작하지 않고, 한글 검색도 정상입니다. 날짜 범위는 최소 10-15에서 1002, 최대 10-01에서 1001로 각각 나온 것으로 읽었습니다. datetime 최대값에 날짜만 넣으면 그날 23:59까지 포함됩니다.
유일한 비정상은 bfmax_price=1000에서 1004가 섞인 것인데, 값이 12,000이라 쉼표 때문에 12로 계산된 입력 형식 문제로 표시돼 있습니다.

※ AI가 자동으로 작성한 댓글입니다. 참고용으로만 봐주세요.

D
DX관리자 2026.10.18 02:11
이하는 사실 알 필요 없습니다.
다만, 기능은 정확히 알아야 합니다.
간단 소스 구현을 해주세요. 끊어지면 이어서 진행하겠습니다.
디
디엑스AI 2026.10.18 02:12

관리자님, 알겠습니다. 기능 핵심만 최소 구현으로 드립니다. 제가 받은 범위의 원리를 줄인 것이고, 코어 함수 시그니처는 확인하지 못해 DB 호출은 PDO 형태의 예시입니다. 적용 전에 실제 소스와 대조해 주세요.

1. 목록 노출: 현재 페이지 글 ID를 모아 한 번에 읽습니다.
$ids = array_column($posts, 'id');
$in = implode(',', array_fill(0, count($ids), '?'));
SELECT post_id, field_key, value FROM dx_post_meta WHERE post_id IN ($in)
결과를 $map[post_id][field_key]로 담고, 글 루프에서 $map[$p['id']]['price']처럼 출력합니다. 값은 htmlspecialchars로 감쌉니다.

2. 검색 필터: 필드마다 조건을 $where에 붙입니다.
$where .= ' AND EXISTS (SELECT 1 FROM dx_post_meta pm WHERE pm.post_id=p.

※ AI가 자동으로 작성한 댓글입니다. 참고용으로만 봐주세요.

D
DX관리자 2026.10.18 02:12
@디엑스 이어서
디
디엑스AI 2026.10.18 02:13

관리자님, 앞 댓글이 2번 검색 필터에서 끊겼으니 거기서부터 이어갑니다. 이것도 제가 받은 원리를 줄인 예시라서 변수명은 실제 소스와 대조해 주세요.

2. 검색 필터(이어서): 조건 한 줄은 이런 모양입니다.
$where .

※ AI가 자동으로 작성한 댓글입니다. 참고용으로만 봐주세요.

D
DX관리자 2026.10.18 02:13
너무 짧게 답이 오는데요. @디엑스
디
디엑스AI 2026.10.18 02:14

관리자님, 제 답변이 600자 안팎으로 쓰도록 정해져 있어서 짧게 나옵니다. 지난 댓글이 "$where ."에서 멈춘 것도 이 길이 안에서 끝내려다 코드가 잘린 것으로 보이지만, 정확한 원인은 제 자료로 확인되지 않습니다. 이 길이 설정을 바꿀 수 있는지도 제 자료에는 없어서 관리자 설정에서 확인해 보셔야 합니다.

그래서 한 번에 한 가지씩 나눠 답하겠습니다. 끊긴 2번 검색 필터의 핵심만 먼저 드립니다. 변수명은 실제 소스와 대조해 주세요.

foreach ($fields as $f) { $k = $f['field_key']; if (!isset($_GET['bf_'.$k]) || $_GET['bf_'.$k] === '') continue; $where .= ' AND EXISTS (SELECT 1 FROM dx_post_meta pm WHERE pm.post_id=p.id AND pm.field_key=? AND pm.value=?)'; $params[] = $k; $params[] = $_GET['bf_'.$k]; }

이렇게 값은 ?로 바인딩해서 인젝션을 막고, 필드마다 조건을 AND로 붙입니다. $fields는 is_search가 1인 필드만 담아야 합니다. 범위 검색과 체크박스 처리가 필요하시면 말씀해 주세요.

※ AI가 자동으로 작성한 댓글입니다. 참고용으로만 봐주세요.

로그인 후 댓글을 작성할 수 있습니다.
NO TITLE AUTHOR DATE VIEW
공지
D DX관리자
05.22 295
54
DX관리자
10.18 1
DX관리자 · 1
53
DX관리자
10.18 1
DX관리자 · 1
47
D DX러브맨
10.16 8
D DX러브맨 · 8
46
DX관리자
10.16 7
DX관리자 · 7
44
DX관리자
10.16 6
DX관리자 · 6
내 플레이리스트
플레이리스트가 비어있습니다
스튜디오 게시판에서
플레이리스트에 담기 버튼을
눌러보세요
목록 로그인
TODAY 가입0 게시글8 댓글56 방문18
TOTAL 회원56 게시글1,633 댓글3,532 방문56,039
현재 접속1
목록