Files
gtsit/docs/qa-list.md
2026-08-18 10:53:58 +09:00

307 lines
27 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QA 체크리스트
최종 수정일: 2026-08-10
기능 구현 시 해당 섹션을 복사하거나 항목을 추가해 계속 확장합니다. 민감정보가 포함된 화면 캡처와 로그는 저장소에 넣지 않습니다.
## 실행 기록 템플릿
| 항목 | 기록 |
| --- | --- |
| 실행일 | YYYY-MM-DD |
| 담당자 | |
| 환경 | 로컬 / Cafe24 기본 도메인 / 운영 도메인 |
| URL | |
| 브라우저·기기 | |
| 배포 버전 | |
| 결과 | 통과 / 조건부 통과 / 실패 |
| 증빙 | 안전한 스크린샷 또는 이슈 링크 |
## 1. 임시 페이지
- [x] 로컬에서 HTML 정상 표시
- [x] 외부 CSS, 폰트, 이미지 의존성 없음
- [x] 390px 모바일에서 가로 스크롤 없음
- [x] 전화 링크의 번호와 표시 문구 확인
- [x] 검색엔진 `noindex, nofollow` 적용
- [x] Cafe24 기본 도메인에서 HTTPS 200 응답
- [x] 운영 도메인에서 로컬 원본과 동일한 콘텐츠 표시
- [x] Cafe24 기본 도메인 HTTPS에서 보안 경고 없음
- [x] 로고와 저작권에 `(주)지티에스정보통신` 표시
- [ ] 모바일 실기기에서 전화 링크 동작
## 2. 배포 및 서버
- [x] 현재 등록된 SSH 인증키를 다시 내려받아 로컬 키 지문 비교
- [x] 서버에 등록된 키로 SSH 로그인 성공
- [x] 실제 웹 루트와 업로드 경로 확인
- [x] 기존 파일 백업 후 배포
- [ ] 디렉터리 목록 노출 차단
- [ ] 불필요한 설정, 백업, 로그 파일의 웹 접근 차단
- [ ] 404 및 500 오류 응답 확인
- [x] 임시 `index.html` 파일 권한 `640` 적용
- [x] 웹 루트에 `Options -Indexes` 적용
- [ ] 배포 후 오류 로그에 신규 치명 오류 없음
테스트 배포 기록: 2026-08-04 `https://gtsit.co.kr/site-preview-7c2a91f4/`에 본 사이트를 별도 라우팅했습니다. 홈·블로그·문의·개인정보·문의 조회·관리자 로그인은 200, 비로그인 관리자 경로는 테스트 경로의 로그인으로 302, 없는 경로는 404를 반환했습니다. CSS·JavaScript 에셋 4종은 모두 200이며 기존 운영 루트 임시 페이지도 200과 기존 문구를 유지합니다.
운영 오픈 기록: 2026-08-10 `https://gtsit.co.kr` 운영 루트를 본 사이트로 전환했습니다. 홈·블로그·문의·개인정보와 공개 게시글 6건은 GET 200, 없는 경로는 404, 비로그인 관리자는 `/admin/login`으로 이동했습니다. 공개 canonical에서 테스트 경로가 제거되고 공개 화면에는 robots 차단이 없으며 관리자 화면은 `noindex,nofollow,noarchive`를 유지합니다. 홈 1280px에서 메인 이미지 4장·서비스 아이콘 4개·최신 글 3개와 가로 넘침 없음을 확인했고, 문의 지도는 `ready`·프레임 300px·지도 298px·타일 27개·전체화면 버튼 표시 상태입니다. 운영 업로드 경로의 임시 PHP 파일 요청은 403으로 차단됐고 검사 파일은 즉시 삭제했습니다.
관리자 글 미리보기 기록: 2026-08-10 글 관리 목록의 14개 글에 관리자 전용 미리보기 링크를 추가했습니다. 초안 1건과 공개 글 1건을 실제 공개 페이지 레이아웃으로 확인했으며, 상태별 미리보기 안내·수정 링크·대표 이미지·초안 수정일 대체 표시·공개 URL canonical·`noindex,nofollow,noarchive`·가로 넘침 없음을 검증했습니다. 비로그인 요청은 관리자 로그인으로 이동합니다.
회사 정보 반영 기록: 2026-08-04 대표 이메일과 주소를 `site_settings` 및 애플리케이션 기본값에 반영했습니다. 테스트 문의 페이지에서 새 주소, 푸터에서 새 이메일·주소가 표시되고 이전 값이 남아 있지 않은 것을 확인했습니다.
회사명 통일 기록: 2026-08-04 공개 헤더·푸터·메타데이터, 관리자 콘솔, 게시글 작성자 기본값과 기존 초안 9건, 운영 루트 임시 페이지를 `(주)지티에스정보통신`으로 통일했습니다. 실제 응답 3개 화면에서 이전 표기 0건, 새 표기 16건을 확인했고 360·390·1440px에서 가로 넘침이 없었습니다.
푸터·플로팅 버튼 기록: 2026-08-04 푸터의 전화번호를 일반 텍스트로 변경해 `tel:` 링크 0건을 확인했습니다. 플로팅 전화상담 버튼은 전화기 SVG 아이콘, 대표번호 `tel:` 링크와 접근성 이름을 유지하며 실제 Chrome 렌더링을 확인했습니다.
브랜드 로고 적용 기록: 2026-08-04 도식형 심볼을 `GTS` 글자 기반 워드마크로 교체해 `public/assets/images/company-logo-v3.png`로 적용했습니다. 공개 헤더·푸터, 관리자 헤더·로그인·초기 설정, 운영 임시 페이지에서 512×237 투명 PNG 로드를 확인했습니다. 테스트 경로 1280px와 390px에서 헤더 로고를 64×29.6px로 표시했으며 회사명·메뉴 겹침과 가로 넘침이 없었습니다.
메인 이미지 적용 기록: 2026-08-05 HTML 템플릿 자산 `design/assets/hero-network.png`를 1200×675, 151KB JPEG로 최적화해 메인 비주얼에 적용했습니다. CSS 캐시 갱신 버전을 추가했고 테스트 사이트에서 1280px·390px 모두 이미지 로드, `cover` 크롭, 가로 넘침 없음을 확인했습니다. 원본은 템플릿 제공 이미지이므로 실제 회사 시공 사진이 확보되면 동일 영역에서 교체합니다.
메인 슬라이드·콘텐츠 이관 기록: 2026-08-05 기존 사이트 백업의 실제 시공 사진 4장을 1200×900 JPEG로 최적화해 5초 자동 슬라이드로 교체했습니다. 1280px에서 첫 번째에서 두 번째 사진으로 자동 전환되고, 390px에서 컨트롤 한 줄 표시와 가로 넘침 없음을 확인했습니다. LAN·옥외 무선·키폰·CCTV·통신 랙 관리 게시글 5건을 공개해 기존 공개 글을 포함한 카드 6건, 대표 이미지, 상세 본문 4개 문단과 페이지 메타데이터를 확인했습니다.
네이버 지도 연동 기록: 2026-08-05 `https://gtsit.co.kr/site-preview-7c2a91f4/contact`에서 Client ID와 허용 URL 인증, 지도 `ready` 상태, `(주)지티에스정보통신` 마커, 네이버 지도 검색 링크를 확인했습니다. 주소 변환 API는 활성화하지 않고 확인된 고정 좌표로 `Dynamic Map`만 사용합니다. Client Secret은 전달받거나 저장하지 않았으며, SDK 실패 상태에서도 주소와 외부 지도 링크가 유지됩니다.
지도 표시·전체화면 수정 기록: 2026-08-05 NAVER SDK가 지도 요소의 위치 속성을 덮어써 내부 높이가 0px이 된 원인을 수정했습니다. 일반 상태에서 프레임 300px·지도 298px·타일 이미지 27개·마커 1개를 확인했습니다. 사용자 정의 전체화면 아이콘으로 720px 확장 후 298px 복귀와 마커 유지를 검증했고, 390px에서도 지도 298px와 가로 넘침 없음을 확인했습니다. 정상 상태의 외부 텍스트 링크는 숨기고 실패 시 fallback으로 유지합니다.
지도·전화상담 스태킹 기록: 2026-08-10 네이버 지도 내부 컨트롤이 최대 `z-index: 10000`을 사용해 `z-index: 80`인 전화상담 버튼보다 위에 표시되는 현상을 확인했습니다. 지도 프레임에 독립 스태킹 컨텍스트를 적용하고 전화상담 버튼을 공통 헤더보다 높은 `z-index: 200`으로 조정했습니다. 운영 문의 화면의 실제 겹침 지점에서 최상위 요소가 전화상담 링크이고 지도는 `ready` 상태를 유지하며 가로 넘침이 없음을 확인했습니다.
지도 이동 잠금 기록: 2026-08-10 네이버 지도 옵션에서 마우스·터치 드래그와 키보드 이동을 차단하고 휠·핀치·확대축소 컨트롤은 유지했습니다. 확대 이벤트마다 회사 마커 좌표를 중심으로 재고정합니다. 운영 화면에서 확대 버튼을 눌렀을 때 지도 타일이 27개에서 39개로 갱신되고 마커의 지도 중심 오차가 확대 전후 `1px, -16px`로 동일하며 `ready` 상태가 유지됨을 확인했습니다.
지도 제스처 줌 차단 기록: 2026-08-10 핀치·휠·더블클릭·더블탭·두 손가락 탭 확대축소를 비활성화했습니다. 네이버 기본 줌 컨트롤도 축소 시 세로 중심이 이동하는 것을 확인해 제거하고, 회사 주소 좌표를 중심으로 애니메이션 없이 줌 단계만 변경하는 자체 `+ / ` 컨트롤로 교체했습니다. 운영 화면에서 기본 줌 컨트롤 0개·자체 버튼 2개를 확인했고, 자체 축소 전후 마커 중심 오차가 모두 `1px, -16px`로 동일하며 지도 `ready` 상태가 유지됐습니다.
블로그 임시 썸네일 기록: 2026-08-05 공개 글 6건 중 실제 대표 이미지 5건은 기존 사진을 유지하고, 이미지가 없는 1건에는 `GTS` 브랜드 플레이스홀더가 표시되는 것을 확인했습니다. 1280px에서 카드 행 높이 정렬과 가로 넘침 없음, 390px에서 카드 358px·플레이스홀더 356×199px 및 가로 넘침 없음을 확인했습니다.
문의 입력 편의 기록: 2026-08-05 이메일 아이디 `11111``naver.com` 선택 시 전송용 값 `11111@naver.com`, `직접입력` 선택 시 전체 주소 `hello@company.co.kr`이 유지되는 것을 확인했습니다. 연락처 숫자 `01011111111``010-1111-1111`로 자동 변환됐습니다. 실제 문의는 생성하지 않았으며 390px에서 이메일 필드 312px와 가로 넘침 없음을 확인했습니다.
문의 입력 시각 보정 기록: 2026-08-05 연락처 자동 하이픈 안내 문구와 연결된 `aria-describedby`를 제거했습니다. 연락처 placeholder는 `14px`·`rgb(161, 161, 170)`, 이메일 아이디 placeholder는 `13px`·`rgb(176, 179, 186)`로 확인했습니다. 이메일 도메인·문의 유형 드롭다운은 우측 여백 `14px`, 내부 우측 여백 `42px`로 조정했으며 390px 화면에서 이메일 아이디 `155px`, 도메인 `132px`, 가로 넘침 없음을 확인했습니다.
연락처·조회 PIN 기록: 2026-08-05 단일 연락처 필드에서 `010-1234-5678`, `02-123-4567`, `02-1234-5678`, `031-123-4567`, `031-1234-5678`, `1588-1234`, `070-1234-5678`, `0507-1234-5678` 자동 형식을 확인했습니다. 문자와 기호가 섞인 조회 PIN 입력은 숫자 4자리만 남았으며, 실제 QA 문의를 생성해 올바른 PIN 조회 성공과 잘못된 PIN 5회 후 15분 잠금을 확인한 뒤 테스트 문의를 완전 삭제했습니다.
개인정보처리방침 기록: 2026-08-05 개인정보보호위원회 「개인정보 처리방침 작성지침(2026.4.)」과 개인정보 포털의 수집·이용 동의 양식을 기준으로 처리 목적·항목·법적 근거·보유기간·제3자 제공·Cafe24 위탁·파기·권리 행사·안전조치·세션 쿠키·담당부서·권익침해 구제·시행일을 반영했습니다. 문의 폼에도 목적·필수/선택 항목·보유기간·동의 거부 불이익을 직접 표시했습니다.
서비스 카드 아이콘 기록: 2026-08-10 네트워크·키폰·CCTV·유지보수 카드에 항목별 인라인 SVG 아이콘을 고정 UI 자산으로 배포했습니다. 테스트 경로에서 아이콘 4개와 각 SVG 존재, 48×48px 컨테이너와 26×26px 아이콘, 항목별 배경·선 색상, 중앙 정렬, CSS 버전 `20260805-11`, 1280px 화면의 가로 넘침 없음을 확인했습니다. 운영 루트 임시 페이지는 기존 상태로 HTTP 200 응답을 유지합니다.
파기 명령 기록: 2026-08-05 `bin/purge-inquiries.php`를 Cafe24 PHP 8.4와 MariaDB에서 실행해 만료 대상 0건으로 정상 종료했습니다. 현재 뉴아우토반 일반형은 Cafe24 공식 안내상 cron 미지원 상품이고 서버에도 `crontab` 명령이 없어, 정기 실행 등록은 외부 스케줄러 또는 호스팅 상품 변경 시 진행합니다.
진행 기록: 2026-08-04 새 키로 SSH 로그인 성공. 웹 루트 `/home/hosting_users/gts0201/www`, 기존 안내 파일 백업, 임시 페이지 배포 완료. `https://gts0201.mycafe24.com` HTTPS 200, 운영·로컬 파일 SHA-256 일치, 브라우저 1280px에서 가로 넘침 없음 확인.
## 3. 도메인 및 DNS
- [x] 연결 도메인 `gtsit.co.kr` 철자와 소유 계정 확인
- [x] 루트 도메인의 A 레코드가 호스팅 서버 `112.175.85.162`를 가리킴
- [x] `www` 도메인이 루트 도메인을 거쳐 같은 서버를 가리킴
- [x] 로컬 및 Google Public DNS에서 `SERVFAIL` 해소
- [ ] 여러 공개 DNS에서 결과 일치
- [x] Cafe24 대표 도메인이 `gtsit.co.kr`로 표시됨
- [x] HTTP와 `www``https://gtsit.co.kr`로 301 리디렉션
- [ ] `HEAD` 요청이 공개 GET 경로와 같은 상태 코드 반환
- [ ] 기존 메일 사용 시 MX 및 TXT 레코드 보존 확인
진단 참고: 2026-08-04 Cafe24 자가진단은 서버 연결 및 SSL 오류를 표시했으나, 외부 HTTP/HTTPS 요청과 인증서 검증은 정상입니다. Cafe24 진단 결과만 근거로 장애 처리하지 않고 실제 응답을 함께 확인합니다.
## 4. HTTPS
- [x] SSL Basic 신청 가능 도메인과 최초 1회 설치비 11,000원 확인
- [x] 루트와 `www` 인증서의 도메인 일치
- [x] 인증서 유효기간 2026-08-04~2026-11-02 확인
- [x] HTTP 요청이 HTTPS로 한 번만 리디렉션
- [x] `www` 요청이 대표 루트 주소로 한 번만 리디렉션
- [x] 임시 페이지 혼합 콘텐츠 없음
- [x] 루트와 `www`에서 인증서 경고 없이 HTTPS 200 응답
- [ ] 세션 쿠키에 `Secure`, `HttpOnly`, 적절한 `SameSite` 적용
## 5. 데이터베이스
- [x] MariaDB 10.6.5 클라이언트와 `localhost:3306` 접속정보 확인
- [x] PHP PDO MySQL 및 mysqli 확장 확인
- [x] PHP UTF-8 및 `Asia/Seoul` 기본값 확인
- [x] 비밀번호 없는 DB 접근 차단 확인
- [x] 비밀번호 인증 DB 연결 확인
- [x] DB 기본 문자셋 `utf8mb4``utf8mb4_unicode_ci` 적용
- [x] DB 설정 파일의 웹 루트 외부 배치와 권한 `600` 확인
- [x] 임시 DB 진단 및 설정 파일 제거 확인
- [ ] `utf8mb4` 한글 및 이모지 저장·조회
- [ ] 서버 시간과 화면 표시 시간 일치
- [ ] 모든 쿼리에 파라미터 바인딩 적용
- [ ] DB 오류에 접속정보 또는 SQL 원문 미노출
- [ ] 외부 MySQL 접속 차단 유지
- [ ] 백업 생성 및 복원 테스트
- [ ] 삭제 또는 익명화 정책 동작 확인
진행 기록: 2026-08-04 `admins`, `posts`, `post_images`, `inquiries`, `site_settings` 테이블 생성 및 전체 테이블 `utf8mb4_unicode_ci` 적용 확인.
## 6. 디자인 구현 필수 QA
- [x] 비로그인 상태에서 관리자 및 글 관리 URL이 로그인 화면으로 302 이동
- [x] 관리자 비밀번호 및 인증 판정 로직이 HTML·JavaScript에 노출되지 않음
- [x] 문의와 게시글이 브라우저 저장소가 아닌 MariaDB에 저장됨
- [x] 360px 이상 공개 화면에서 가로 스크롤 없음
- [ ] 모바일 관리자 목록이 카드 또는 접근 가능한 표 형태로 표시됨
- [x] 문의 필수값, 형식, 글자 수, 동의 여부의 서버 검증
- [x] 개인정보 수집 항목·목적·보유기간·거부 안내 표시
- [ ] 블로그 카드와 주요 탐색 요소를 키보드로 이용 가능
- [x] 페이지별 title, description, canonical, Open Graph 적용
- [x] 업로드 이미지 형식·용량·크기 검증 및 대체 텍스트 제공
## 7. 공통 UI 및 접근성
- [x] 360px, 390px, 768px, 1024px, 1440px 레이아웃 확인
- [x] 가로 스크롤과 콘텐츠 잘림 없음
- [ ] 키보드만으로 모든 조작 가능
- [ ] 포커스 표시가 명확함
- [x] 제목 구조가 논리적이고 페이지당 `h1`이 명확함
- [x] 입력 요소에 연결된 레이블 존재
- [ ] 오류 메시지를 색상 외의 방법으로 전달
- [ ] 이미지 대체 텍스트 적절성 확인
- [ ] 모달 사용 시 포커스 이동과 복귀 확인
- [ ] 확대 200%에서도 주요 기능 사용 가능
## 8. 공개 페이지
- [x] 홈의 주요 링크와 CTA 동작
- [x] 홈 서비스 카드 4종의 항목별 고정 아이콘 표시
- [x] 대표 이미지 없는 게시글 카드에 브랜드형 임시 썸네일 표시
- [x] 문의 이메일 도메인 선택·직접입력 전환 동작
- [x] 문의 연락처의 휴대전화·지역번호·대표번호별 자동 형식 적용
- [x] 문의 입력 placeholder 대비와 드롭다운 꺾쇠 여백
- [ ] 게시글 목록의 정렬과 페이지네이션 동작
- [ ] 게시글 상세의 줄바꿈, 이미지, 이전·다음 글 동작
- [x] 존재하지 않는 게시글에 404 응답
- [x] 문의 필수값과 형식 검증
- [x] 중복 제출 방지
- [ ] 문의 조회번호 발급과 안내
- [ ] 올바른 조회정보로 문의 확인
- [ ] 틀린 조회정보로 개인정보 노출 없음
- [ ] 성공, 오류, 빈 상태 문구 확인
## 9. 관리자
- [x] 로그인 전 관리자 URL 접근 차단
- [ ] 올바른 계정 로그인과 로그아웃 동작
- [x] 관리자 초기 등록 URL의 토큰 없는 접근 404, 유효 토큰 교환 302, 등록 폼 200
- [x] 관리자 초기 등록의 약한 비밀번호 422 거부
- [ ] 반복 로그인 실패 제한
- [ ] 세션 만료 후 재인증 요구
- [ ] 게시글 작성, 수정, 삭제, 공개 상태 동작
- [x] 관리자 글 목록에서 초안·공개 글 미리보기와 비로그인 접근 차단
- [x] 신규·기존 게시글의 `post-{id}` 자동 URL과 종전 주소 301 이동
- [x] 테스트 초안에서 대표 이미지 3장 슬라이드 렌더링과 5초 자동 전환
- [x] 테스트 초안 본문의 `[[image:번호]]` 위치에 이미지 2장 렌더링
- [x] 관리자에서 내부 이미지 토큰 미노출 및 문단·이미지 블록 변환
- [x] 이미지 블록 위·아래 이동 후 저장과 공개 형식 미리보기 순서 일치
- [x] 블록 저장 후 기존 텍스트 이스케이프·이미지 매핑 구조 유지
- [x] 작성 화면 미리보기에 저장 전 제목·본문 변경 즉시 반영
- [x] 작성 화면 미리보기에서 대표 이미지 개수·썸네일·본문 이미지 렌더링 확인
- [x] 대표 이미지 썸네일 선택 시 미리보기의 큰 이미지 전환
- [x] 테스트 관리자 블록 편집기의 등록 본문 이미지 경로와 실제 이미지 응답 확인
- [x] 대표 슬라이드 이전·다음·직접 선택·일시정지 조작 제공
- [x] 다중·본문 이미지가 있는 글의 공개 저장 차단
- [ ] 이미지 파일 선택 후 대체 텍스트·본문 삽입 버튼 실제 업로드 회귀 테스트
- [ ] 관리자 목록의 검색, 필터, 페이지네이션 동작
- [ ] 문의 목록, 상세, 처리 상태 변경 동작
- [ ] 모바일 표와 조작 버튼의 잘림 없음
- [x] 관리자 변경 작업에 CSRF 방어 적용
- [x] 일반 사용자가 관리자 경로를 호출할 수 없음
- [x] 관리자 대시보드 GA4 집계 카드·기간 차트·인기 페이지·유입경로의 데스크톱 표시
- [ ] 관리자 대시보드 GA4 지표의 모바일 표시와 가로 넘침 없음
- [x] 관리자 대시보드에 최근 접속자·전체 방문자·30일 방문자·처음 온 방문자·페이지 열람 수·사이트 방문 횟수가 쉬운 설명과 함께 표시됨
- [ ] GA4 API 장애 시 대시보드의 안전한 대체 안내와 기존 관리자 기능 유지
진행 기록: 2026-08-04 공식 PHP 8.4 컨테이너와 Cafe24 PHP 8.4에서 전체 PHP 문법 통과. 로컬 주요 경로 `/`, `/blog`, `/contact`, `/privacy`, `/inquiry/lookup`, `/admin/login` 200, 비로그인 `/admin`, `/admin/posts` 302, 없는 경로 404 확인. 문의 CSRF 누락 403 및 빈 필수값 제출 422 확인. Cafe24가 비표준 419를 500으로 변환하는 것을 확인해 표준 403으로 조정했습니다.
추가 기록: 2026-08-04 시스템 Chrome으로 공개 주요 6개 경로를 360·390·768·1024·1440px에서 재검수했습니다. 모든 조합에서 HTTP 200, 가로 넘침 없음, 페이지당 `h1` 1개, 누락된 폼 레이블 0개를 확인했습니다. 모바일 문의 화면에서 고정 전화 버튼이 입력 영역을 가리던 문제는 640px 이하에서 버튼을 숨기도록 수정 후 재검수를 통과했습니다.
## 10. 파일 업로드
- [x] 허용 확장자와 MIME만 업로드 가능
- [x] 최대 용량 초과 차단 및 안내
- [x] 실행 가능한 파일 업로드 차단
- [x] 서버에서 안전한 파일명으로 변경
- [x] 동일 이름 파일 충돌 없음
- [ ] 이미지 메타데이터와 방향 처리 확인
- [ ] 삭제된 게시글의 파일 정리 정책 확인
- [x] 업로드 경로에서 PHP 실행 불가 확인
진행 기록: 2026-08-04 Cafe24 테스트 경로의 업로드 폴더에 무해한 PHP 검사 파일을 잠시 배치해 HTTP 403과 미실행을 확인한 뒤 즉시 삭제했습니다.
게시글 미디어 기록: 2026-08-10 `https://gtsit.co.kr/site-preview-7c2a91f4/admin/posts/15/preview`에서 대표 이미지 3장, 본문 이미지 2장, 관리자 대체 텍스트 필드와 본문 삽입 토큰을 확인했습니다. 자동재생 후 활성 슬라이드가 변경되고 다음 버튼 조작이 반영되는 것을 확인했습니다. 테스트 자산은 이전 사이트의 메인 이미지와 EXIF 위치정보가 없는 600×450 시공 썸네일만 사용했습니다.
블록 편집기 기록: 2026-08-10 테스트 관리자 글 15번에서 텍스트 3개·이미지 2개 블록 변환, 내부 토큰 미노출, 이동 버튼 상태, 이미지 블록 순서 변경 저장과 미리보기 반영을 확인한 뒤 원래 순서로 복원했습니다. JavaScript와 뷰에서 `innerHTML`, `contenteditable`, 임의 HTML 삽입 API를 사용하지 않으며 모든 편집 요소를 DOM API와 일반 textarea로 생성합니다. 자동 브라우저의 파일 선택 API 제한으로 신규 파일을 통한 전체 업로드 회귀 항목은 수동 확인 대상으로 유지합니다.
작성 화면 미리보기 기록: 2026-08-10 테스트 관리자 글 15번 수정 화면에서 저장하지 않은 제목과 첫 문단이 미리보기 모달에 반영되는 것을 확인했습니다. 대표 이미지 3장과 본문 이미지 2장이 렌더링되고 두 번째 대표 이미지 썸네일 선택 시 큰 이미지가 바뀌는 것을 확인한 뒤, 입력 폼은 원래 값으로 되돌리고 저장하지 않았습니다.
게시글 URL 자동화 기록: 2026-08-10 공유 DB의 기존 게시글 15건을 `post-1`~`post-15`로 변경하고 관리자 목록에서 15건 모두 번호형 주소로 표시되는 것을 확인했습니다. 운영의 종전 공개 주소는 `/blog/post-1`로 301 이동하고 새 주소는 200, 테스트 경로에서도 base path를 포함한 301 이동과 새 주소 200을 확인했습니다. 공개 글 6건의 사이트맵도 번호형 주소로 갱신했습니다.
본문 이미지 경로 기록: 2026-08-10 숨겨진 `data-path`는 공통 HTML의 `src` 경로 보정 대상이 아니어서 테스트 base path가 빠진 `/uploads/...`를 참조하던 문제를 수정했습니다. 관리자 글 15번에서 기존 본문 이미지 2개가 `/site-preview-7c2a91f4/uploads/media-preview/` 경로를 사용하고 각각 600×450px로 정상 로드되는 것을 확인했습니다.
## 11. 보안 및 개인정보
- [ ] HTML과 스크립트 입력의 XSS 방어
- [ ] SQL 삽입 입력 방어
- [x] 관리자 비밀번호와 문의 조회 PIN 해시 저장
- [x] HTML, JavaScript, 로그에 비밀번호 없음
- [x] 오류 화면에 서버 경로와 스택 정보 없음
- [x] 개인정보 동의 내용과 수집 항목 일치
- [x] 개인정보 보관기간·종료일 기록·완전 삭제 명령 구현
- [ ] 만료 문의 완전 삭제 명령의 정기 실행 등록
- [ ] 보안 헤더 적용 여부 확인
- [x] 통계 쿠키 동의 전 Google 태그 미로딩
- [ ] 통계 쿠키 거부·철회 후 선택과 측정 차단 유지
- [x] 운영 공개 경로만 GA4 측정, 관리자·테스트 경로 제외
- [x] 문의 개인정보·접수번호와 관리자 정보가 GA4 이벤트로 전송되지 않음
- [ ] ModSecurity와 UploadGuard 오탐 없음
GA4 수집 기록: 2026-08-12 무료 표준 속성 `549573245`, 운영 웹 스트림 `15422491033`, 측정 ID `G-92XBR314YD`를 생성했습니다. 테스트 경로는 허용 전후 Google 태그 0개, 운영 루트는 최초 동의 전 0개·허용 후 1개를 확인했습니다. GA4 홈의 지난 30분 활성 사용자가 1명으로 표시되어 실제 수집을 확인했으며 광고 저장·Google 신호·광고 개인화는 비활성화했습니다. 사용자·이벤트 데이터는 신규 속성 기본값인 2개월을 사용합니다.
GA4 관리자 연동 기록: 2026-08-13 전용 서비스 계정에 GA4 속성 `뷰어` 권한만 부여했고 Cloud 프로젝트 역할은 추가하지 않았습니다. JSON 키와 15분 집계 캐시는 Git·웹 루트 밖에서 권한 `600`으로 보관합니다. Analytics Data API 실제 요청에서 최근 30일 사용자·신규 사용자·페이지뷰·세션, 14일 추이, 인기 페이지, 유입경로 응답을 확인했습니다.
GA4 대시보드 표시 기록: 2026-08-13 테스트 관리자 화면에서 전체 방문자 1명과 최근 30일 방문자·첫 방문자·페이지 열람·사이트 방문 횟수 각 1회를 확인했습니다. 전체 방문자는 GA4 측정 시작일 `2026-08-12` 이후의 `totalUsers`이며 카드 설명에 측정 시작일을 함께 표시합니다.
운영 배포 기록: 2026-08-13 운영 PHP 파일 전체 문법 통과, GA4 Data API 응답 `available=true`와 전체 방문자 1명 확인, 키·캐시 권한 600 확인. `/`, `/blog`, `/contact`, `/privacy`, 사이트맵과 CSS·JavaScript는 200, 비로그인 `/admin`은 302, `/blog/post-10``/blog/post-14`는 200, 종전 게시글 주소는 번호형 주소로 301 응답했습니다. 브라우저에서 운영 홈의 콘텐츠·슬라이드·서비스·글 목록과 문의 폼·네이버 지도·전체화면 및 확대축소 컨트롤을 확인했습니다.
## 12. 검색, 성능 및 운영
- [x] 임시 페이지 종료 후 공개 화면 `noindex` 제거 확인
- [x] 테스트 경로 `X-Robots-Tag`와 robots 메타 색인 차단
- [x] 페이지별 고유 제목과 설명 적용
- [x] canonical과 대표 도메인 일치
- [x] `robots.txt`와 사이트맵 정책 확인
- [ ] 이미지 크기와 지연 로딩 적절성 확인
- [ ] 모바일 저속 환경에서 주요 콘텐츠 표시
- [ ] 용량 및 트래픽 알림 동작 확인
- [ ] 일일 백업과 외부 백업 성공 확인
- [ ] 장애 시 임시 페이지로 되돌리는 절차 확인
## 13. 네이버 지도
- [x] Dynamic Map Client ID 및 허용 웹 서비스 URL 일치
- [x] 회사 주소 좌표와 마커 위치 일치
- [x] 지도 SDK 적용 후 실제 지도 요소 높이와 타일 표시
- [x] 사용자 정의 전체화면 아이콘 열기·종료 및 지도 크기 복구
- [x] 지도 드래그·키보드 이동 차단 및 마커 중심 확대·축소 유지
- [x] 핀치·휠·더블클릭/탭 확대·축소 차단 및 지도 컨트롤만 허용
- [ ] 데스크톱·모바일 지도 확대·축소 및 페이지 스크롤 충돌 없음
- [x] 지도 API 로드 실패 시 주소와 네이버 지도 링크 유지
- [x] Client Secret이 HTML·JavaScript·저장소에 포함되지 않음
- [ ] API 이용 한도와 임계치 알림 설정
## 이슈 기록 템플릿
```md
### QA-000 제목
- 환경:
- URL:
- 재현 절차:
1.
2.
- 기대 결과:
- 실제 결과:
- 심각도: Blocker / Critical / Major / Minor
- 증빙:
- 상태: Open / Fixed / Retest / Closed
```