feat: GTSIT 사이트 구축
This commit is contained in:
35
docs/README.md
Normal file
35
docs/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# GTSIT 사이트 문서
|
||||
|
||||
사이트 구축, Cafe24 배포, 도메인 연결, 데이터베이스 설정 과정을 한곳에서 관리합니다.
|
||||
|
||||
- [디자인 구현 전 검토](./design-review.md): 페이지별 구현 우려점, 수정 우선순위, 확정 필요 항목
|
||||
|
||||
## 문서 목록
|
||||
|
||||
- [사이트 설계안](./architecture.md): 페이지 구조, 기술 구성, 데이터 모델, 배포 및 보안 원칙
|
||||
- [구현 TODO](./implementation-todo.md): 단계별 작업 순서와 담당자 체크리스트
|
||||
- [QA 체크리스트](./qa-list.md): 임시 페이지부터 운영 사이트까지 이어서 사용할 검증 항목
|
||||
|
||||
## 현재 목표
|
||||
|
||||
1. 임시 안내 페이지를 Cafe24 기본 도메인에 배포
|
||||
2. 실제 보유 도메인을 호스팅에 연결하고 DNS 정상화
|
||||
3. HTTPS 인증서 적용
|
||||
4. MariaDB 접속 및 기본 스키마 준비
|
||||
5. `design/` 시안을 기준으로 본 사이트 구현
|
||||
|
||||
## 상태 표기
|
||||
|
||||
- `[x]`: 완료 및 확인됨
|
||||
- `[ ]`: 미진행 또는 재확인 필요
|
||||
- `[사용자]`: 사용자가 직접 수행하거나 결정해야 하는 항목
|
||||
- `[Codex]`: 사용자 확인 후 Codex가 수행할 수 있는 항목
|
||||
- `[공동]`: 화면 확인이나 의사결정이 함께 필요한 항목
|
||||
|
||||
## 문서 관리 원칙
|
||||
|
||||
- 프로젝트 작업자는 루트 `AGENTS.md`의 문서 동기화 규칙을 따른다.
|
||||
- 작업 완료 즉시 `implementation-todo.md`의 체크박스와 날짜 갱신
|
||||
- QA 수행 시 `qa-list.md` 실행 기록에 URL, 환경, 결과, 증빙 기록
|
||||
- 호스팅 비밀번호, DB 비밀번호, SSH 개인키, 인증번호는 문서와 Git에 기록하지 않음
|
||||
- 호스팅 또는 도메인 설정을 실제로 변경하기 전 대상과 영향 범위를 재확인
|
||||
197
docs/architecture.md
Normal file
197
docs/architecture.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# GTSIT 사이트 설계안
|
||||
|
||||
최종 수정일: 2026-08-10
|
||||
|
||||
## 1. 구축 목표
|
||||
|
||||
- 회사와 서비스를 명확히 소개하는 반응형 웹사이트 구축
|
||||
- 게시글과 문의를 운영자가 관리할 수 있는 관리자 기능 제공
|
||||
- Cafe24 웹호스팅의 PHP 및 MariaDB 환경에 맞춘 단순하고 유지보수 가능한 구성
|
||||
- 비밀번호와 문의 내용 등 민감정보를 브라우저 저장소가 아닌 서버에서 안전하게 처리
|
||||
|
||||
## 2. 확인된 운영 환경
|
||||
|
||||
| 항목 | 확인 내용 | 후속 작업 |
|
||||
| --- | --- | --- |
|
||||
| 호스팅 계정 | `gts0201` | 인증 정보는 문서에 저장하지 않음 |
|
||||
| 상품 | 뉴아우토반호스팅 일반형 | 현재 용량으로 초기 운영 가능 |
|
||||
| 웹 환경 | PHP 8.4 | 배포 전 필수 PHP 확장 확인 |
|
||||
| DB 환경 | MariaDB 10.6.17, `localhost:3306`, 계정 `gts0201` | `utf8mb4_unicode_ci`, 스키마 생성 대기 |
|
||||
| 서버 IP | `112.175.85.162` | DNS 생성 후 실제 응답과 대조 |
|
||||
| 기본 도메인 | `gts0201.mycafe24.com` | 연결 도메인으로 유지, 운영 노출 정책 결정 대기 |
|
||||
| 대표 도메인 | `gtsit.co.kr` | 2026-08-04 Cafe24 대표 도메인 변경 완료 |
|
||||
| 대표 이메일 | `gts0201@naver.com` | 공개 화면 및 문의 안내에 사용 |
|
||||
| 회사 주소 | `서울시 송파구 정의로7길 13, B동 오피스 1020호` | 공개 화면 사업자 정보에 사용 |
|
||||
| 네임서버 | Cafe24 네임서버 위임 확인 | 호스팅 연결 후 DNS 레코드 생성 확인 |
|
||||
| 현재 DNS | 루트·`www`가 `112.175.85.162`로 연결, 공개 DNS 전파 중 | Cloudflare DNS 전파 재확인 |
|
||||
| SSL | Let’s Encrypt 적용, 루트·`www` 포함 | 자동 갱신 상태 지속 확인 |
|
||||
| 웹 방화벽 | ModSecurity 사용 | 적용 후 기능 오탐 점검 |
|
||||
| UploadGuard | 사용 | 파일 업로드 기능과 호환성 점검 |
|
||||
| SSH/SFTP | RSA 4096 인증키, 만료일 2026-09-03 | 새 다운로드 키로 접속 성공 |
|
||||
| 서버 홈·웹 루트 | `/home/hosting_users/gts0201`, `www` | 임시 페이지 배포 완료 |
|
||||
| PHP 안티웹쉘 | 미사용 | 본 사이트 배포 전 활성화 검토 |
|
||||
| 외부 MySQL 접속 | 차단 | 서버 내부 PHP에서만 DB 사용 권장 |
|
||||
|
||||
## 3. 페이지 구조
|
||||
|
||||
### 공개 페이지
|
||||
|
||||
| 경로 | 역할 | 주요 구성 |
|
||||
| --- | --- | --- |
|
||||
| `/` | 홈 | 회사 소개, 핵심 서비스, 최신 게시글, 문의 유도 |
|
||||
| `/blog` | 게시글 목록 | 검색 또는 분류, 목록, 페이지네이션 |
|
||||
| `/blog/{slug}` | 게시글 상세 | 제목, 본문, 이미지, 작성일, 이전·다음 글 |
|
||||
| `/contact` | 문의 접수 | 작성자 정보, 문의 내용, 개인정보 동의 |
|
||||
| `/inquiry/lookup` | 문의 확인 | 접수번호와 숫자 4자리 조회 PIN을 통한 본인 확인 |
|
||||
|
||||
### 관리자 페이지
|
||||
|
||||
| 경로 | 역할 | 주요 구성 |
|
||||
| --- | --- | --- |
|
||||
| `/admin/login` | 관리자 인증 | 서버 세션 기반 로그인 |
|
||||
| `/admin` | 대시보드 | 게시글 및 문의 요약 |
|
||||
| `/admin/posts` | 게시글 관리 | 목록, 상태 변경, 수정, 삭제 |
|
||||
| `/admin/posts/new` | 게시글 작성 | 제목, 본문, 대표 이미지, 공개 상태 |
|
||||
| `/admin/posts/{id}/edit` | 게시글 수정 | 기존 데이터 편집 |
|
||||
| `/admin/inquiries` | 문의 관리 | 목록, 검색, 처리 상태 |
|
||||
| `/admin/inquiries/{id}` | 문의 상세 | 내용 확인, 답변 메모, 상태 변경 |
|
||||
| `/admin/company` | 회사 정보 | 연락처와 사이트 공통 정보 관리 |
|
||||
|
||||
## 4. 권장 기술 구성
|
||||
|
||||
- 서버: PHP 8.4
|
||||
- 데이터베이스: MariaDB 10.6.17, PDO MySQL과 prepared statement 사용
|
||||
- 화면: 서버 렌더링 HTML, CSS, 필요한 범위의 경량 JavaScript
|
||||
- 인증: PHP 세션, `password_hash()`와 `password_verify()` 사용
|
||||
- URL: Apache rewrite 사용 가능 여부 확인 후 의미 있는 경로 적용
|
||||
- 설정: DB 접속값을 공개 디렉터리 밖의 환경별 설정 파일로 분리
|
||||
|
||||
확인된 웹 PHP 환경은 PHP 8.4.21p1, UTF-8, `Asia/Seoul`, PDO MySQL, mysqli, mbstring, OpenSSL, fileinfo, 업로드 최대 100MB, 메모리 256MB입니다. DB 접속 설정은 서버 웹 루트 밖의 `.gtsit-db.env`에 권한 600으로 저장합니다.
|
||||
|
||||
Cafe24의 실제 웹 루트는 `/home/hosting_users/gts0201/www`로 확인했습니다. PHP 확장은 본 사이트 개발 단계에서 확정합니다. 아래 구조는 공유호스팅 권한 범위에 맞춰 조정합니다.
|
||||
|
||||
```text
|
||||
app/
|
||||
Controllers/
|
||||
Repositories/
|
||||
Views/
|
||||
config/
|
||||
database/
|
||||
schema.sql
|
||||
docs/
|
||||
public/
|
||||
assets/
|
||||
uploads/
|
||||
index.php
|
||||
storage/
|
||||
logs/
|
||||
```
|
||||
|
||||
초기 임시 배포는 현재의 `public/index.html` 단일 파일을 유지합니다. 본 사이트는 `public/index.php` 프런트 컨트롤러와 공통 PHP 뷰로 구현하며, 운영 전환 시 Apache가 `index.php`를 우선 사용합니다.
|
||||
|
||||
## 5. 데이터 모델 초안
|
||||
|
||||
| 테이블 | 목적 | 핵심 데이터 |
|
||||
| --- | --- | --- |
|
||||
| `admins` | 관리자 계정 | 로그인 ID, 비밀번호 해시, 상태, 마지막 로그인 |
|
||||
| `posts` | 게시글 | 제목, slug, 본문, 공개 상태, 작성·수정일 |
|
||||
| `post_images` | 게시글 이미지 | 게시글 ID, 파일 경로, 대체 텍스트, 정렬값 |
|
||||
| `inquiries` | 고객 문의 | 접수번호, 작성자, 연락처, 내용, 조회 PIN 해시, 처리 상태, 조회 실패·잠금, 종료일 |
|
||||
| `site_settings` | 회사 및 공통 설정 | 설정 키, 값, 수정일 |
|
||||
|
||||
2026-08-04 초기 스키마를 MariaDB에 적용했습니다. `admins`, `posts`, `post_images`, `inquiries`, `site_settings` 5개 테이블은 모두 `utf8mb4_unicode_ci`를 사용합니다. 문의는 접수번호와 숫자 4자리 조회 PIN의 해시로 공개 답변을 조회합니다. 2026-08-05 접수번호별 조회 실패 횟수와 잠금 시각, 처리 종료일을 추가했으며 5회 실패 시 15분 동안 해당 접수번호의 조회를 제한합니다.
|
||||
|
||||
## 5-1. 현재 구현 구조
|
||||
|
||||
```text
|
||||
app/
|
||||
Auth/AdminAuth.php
|
||||
Repositories/
|
||||
Support/helpers.php
|
||||
Views/
|
||||
bin/create-admin.php
|
||||
config/
|
||||
database/schema.sql
|
||||
public/
|
||||
assets/css/
|
||||
assets/images/company-logo-v3.png
|
||||
assets/js/
|
||||
index.html
|
||||
index.php
|
||||
```
|
||||
|
||||
- 공개 페이지: 서버 렌더링, 페이지별 title·description·canonical·Open Graph 적용
|
||||
- 브랜드 로고: 투명 배경 `GTS` 워드마크 PNG를 이미지로 사용하고, 법인명은 정확한 표기와 접근성을 위해 HTML 텍스트로 분리
|
||||
- 서비스 아이콘: 네트워크·키폰·CCTV·유지보수 항목에 대응하는 인라인 SVG를 고정 UI 자산으로 관리하며 관리자 입력 대상에서 제외
|
||||
- 메인 비주얼: 기존 사이트 백업의 실제 시공 이미지 4장을 `public/assets/images/field/`에 1200×900 JPEG로 최적화해 5초 간격 자동 슬라이드로 표시
|
||||
- 슬라이드 접근성: 이전·다음·직접 선택·일시정지 제공, 포인터·키보드 조작 중 자동 전환 정지, `prefers-reduced-motion` 환경 자동재생 중지
|
||||
- 이전 콘텐츠 이관: LAN·옥외 무선·키폰·CCTV·통신 랙 관리 5개 주제를 현재 표현으로 재구성하고 `database/seed-legacy-content.sql`로 멱등 반영
|
||||
- 문의: 이메일은 아이디와 주요 도메인을 조합하고 `직접입력`에서만 전체 주소 작성, 연락처는 단일 필드에서 휴대전화·서울·기타 지역번호·대표번호·인터넷전화·안심번호 형식으로 자동 변환
|
||||
- 문의 보안: 서버 필수값 검증, CSRF, 20초 중복 방지, 숫자 4자리 조회 PIN 해시, 세션 및 접수번호별 조회 실패 제한
|
||||
- 개인정보: 2026 개인정보보호위원회 작성지침을 기준으로 처리 목적·항목·법적 근거·보유기간·제3자 제공·위탁·파기·권리 행사·안전조치·세션 쿠키·담당부서·시행일을 공개
|
||||
- 개인정보 파기: 문의가 `closed`로 전환된 시각을 기록하고 1년이 지난 문의를 `bin/purge-inquiries.php`로 데이터베이스에서 완전 삭제
|
||||
- 파기 실행 환경: 현재 뉴아우토반 공유 웹호스팅은 cron을 지원하지 않아 정리 명령을 수동 실행할 수 있도록 배포했으며, 외부 스케줄러 또는 지원 상품 전환 시 정기 실행 등록 필요
|
||||
- 관리자: 서버 세션, 비밀번호 해시, 계정별 잠금, 세션 단위 시도 제한, 모든 하위 경로 인증 선행
|
||||
- 초기 관리자: 24시간 유효한 토큰을 세션으로 교환한 뒤 비밀번호를 직접 설정하며, 생성 즉시 토큰 파일 삭제
|
||||
- 게시글: slug, 분류, 초안·공개 상태, 소프트 삭제 기반
|
||||
- 대표 이미지: JPG·PNG·WebP, 8MB, 6000px 제한, MIME 재검증, 임의 파일명, 대체 텍스트 적용
|
||||
- 이미지 없는 게시글 카드: 글을 숨기지 않고 `GTS` 로고와 카테고리 색상을 사용한 16:9 브랜드 플레이스홀더 표시, 대표 이미지 등록 시 실제 이미지 우선
|
||||
- 회사 정보: 관리자 화면에서 연락처·주소·사업자 정보를 DB 설정값으로 관리
|
||||
- 오시는 길: NAVER Cloud Dynamic Map으로 주소 기반 지도와 회사 마커 표시, API 오류 시 네이버 지도 검색 링크 제공
|
||||
- 운영 임시 페이지: 본 사이트 배포 전까지 `public/index.html` 유지
|
||||
- 운영 테스트 경로: `/site-preview-7c2a91f4`, 애플리케이션은 웹 루트 밖에 두고 공개 에셋과 프런트 컨트롤러만 노출
|
||||
|
||||
## 6. 디자인 구현 전 수정 원칙
|
||||
|
||||
- 19개 HTML 시안의 공통 헤더, 푸터, 내비게이션을 공통 뷰로 통합
|
||||
- 게시글 상세 페이지를 개별 정적 파일이 아닌 하나의 동적 템플릿으로 통합
|
||||
- 공개 화면의 모바일 헤더 가로 넘침 수정
|
||||
- 관리자 게시글 목록의 모바일 조작 영역 잘림 수정
|
||||
- `localStorage` 기반 게시글과 문의 데이터를 MariaDB로 이전
|
||||
- 클라이언트 코드에 포함된 관리자 인증값 제거
|
||||
- 문의 등록 시 접수번호와 조회 PIN 해시를 서버에 저장하고 접수번호별 시도 제한을 적용한 조회 절차 구현
|
||||
- 업로드 파일의 확장자, MIME, 용량, 저장 파일명을 서버에서 검증
|
||||
|
||||
## 7. 보안 원칙
|
||||
|
||||
- 모든 운영 페이지 HTTPS 강제
|
||||
- 관리자 로그인 시도 제한과 세션 쿠키 보안 옵션 적용
|
||||
- CSRF 토큰, 출력 이스케이프, SQL 파라미터 바인딩 적용
|
||||
- 비밀번호와 개인키를 저장소, 로그, HTML, JavaScript에 포함하지 않음
|
||||
- 업로드 디렉터리에서 PHP 실행 차단
|
||||
- 관리자 경로에 검색엔진 차단 및 필요 시 추가 접근 제한 적용
|
||||
- Cafe24 일일 백업과 별도의 외부 백업 병행
|
||||
|
||||
## 8. 배포 순서
|
||||
|
||||
1. SSH/SFTP 개인키 준비 및 서버 접속 확인
|
||||
2. 기존 웹 루트 파일 확인 및 백업
|
||||
3. 임시 `index.html` 업로드
|
||||
4. `gts0201.mycafe24.com`에서 응답 및 모바일 화면 확인
|
||||
5. 확정한 사용자 도메인을 호스팅에 연결
|
||||
6. 루트 도메인과 `www` DNS 응답 확인
|
||||
7. 무료 SSL 신청, 발급, HTTPS 리디렉션 확인
|
||||
8. MariaDB 접속 확인 및 최소 권한 구성
|
||||
9. 본 사이트 스키마와 애플리케이션 배포
|
||||
10. 보안, 백업, 알림, 최종 회귀 QA
|
||||
|
||||
정식 전환 전에는 운영 루트를 임시 안내 페이지로 유지하고 `https://gtsit.co.kr/site-preview-7c2a91f4/`에서 테스트합니다. 경로 접두사는 링크, 폼, 리디렉션, 업로드, 세션 쿠키에 일관되게 적용하며 검색엔진 색인을 차단합니다.
|
||||
|
||||
## 9. 미확정 의사결정
|
||||
|
||||
현재 대표 주소는 `https://gtsit.co.kr`입니다. Cafe24 대표 도메인도 `gtsit.co.kr`로 변경했으며, HTTP와 `www` 요청은 `public/.htaccess`에서 대표 주소로 301 리디렉션합니다. 2026-08-04 확인한 Let’s Encrypt 인증서는 루트와 `www`를 포함하며 2026-11-02까지 유효합니다.
|
||||
- 회사 대표 메일을 Cafe24 메일로 사용할지 외부 메일 서비스를 사용할지 결정
|
||||
- 관리자 계정 수와 권한 구분 필요 여부 확정
|
||||
- 게시글 분류, 검색, 임시저장, 예약발행 필요 여부 확정
|
||||
|
||||
## 10. 네이버 지도 연동
|
||||
|
||||
- NAVER Cloud Platform의 Maps Application에서 `Dynamic Map` 선택
|
||||
- Web 서비스 URL은 공식 형식에 맞춰 `http://gtsit.co.kr` 등록(HTTP·HTTPS 구분 없음, `www` 제외)
|
||||
- 브라우저 지도 로더에는 Client ID를 `ncpKeyId`로 사용
|
||||
- Client Secret은 프런트엔드, 저장소, HTML에 포함하지 않음
|
||||
- 고정 회사 위치는 확인된 위도 `37.48524`, 경도 `127.11478`을 사용해 `Dynamic Map`만 호출하고, 별도 Geocoding 상품과 일일 주소 변환 호출은 사용하지 않음
|
||||
- 주소 표시는 `서울시 송파구 정의로7길 13, B동 오피스 1020호`, 네이버 지도 검색은 건물 주소를 기준으로 연결
|
||||
- 지도 SDK가 컨테이너 위치 속성을 덮어써도 높이가 유지되도록 지도 요소에 `height: 100%` 적용
|
||||
- NAVER 기본 컨트롤에 전체화면이 없으므로 Fullscreen API 기반 사용자 정의 아이콘을 지도 안에 제공하고, 미지원 환경에서는 네이버 지도 새 창 열기로 대체
|
||||
- 정상 지도 상태에서는 별도 텍스트 링크를 숨기고, API 로드 실패 또는 JavaScript 비활성 환경에서만 주소가 지정된 네이버 지도 링크 제공
|
||||
117
docs/design-review.md
Normal file
117
docs/design-review.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# 디자인 구현 전 검토
|
||||
|
||||
검토일: 2026-08-04
|
||||
대상: `design/`의 공개 페이지 12개, 관리자 페이지 7개, 공통 에셋
|
||||
|
||||
## 결론
|
||||
|
||||
현재 디자인의 색상, 타이포그래피, 카드 구성, 홈의 정보 흐름은 구현 기준으로 사용할 수 있습니다. 다만 `design/*.html`은 화면 확인용 프로토타입이므로 운영 코드로 복사하거나 그대로 배포하면 안 됩니다. 공개 화면은 공통 PHP 템플릿과 시맨틱 HTML로 다시 구성하고, 관리자 인증·문의·게시글·회사 정보는 서버와 MariaDB를 통해 처리해야 합니다.
|
||||
|
||||
구현 착수 전 아래 P0 항목을 설계에 반영합니다.
|
||||
|
||||
1. 관리자 인증 및 모든 관리자 URL의 서버 측 접근 통제
|
||||
2. 문의 접수·답변 확인 방식 확정과 개인정보 동의 문구 보완
|
||||
3. 모바일 헤더·관리자 목록의 별도 레이아웃 추가
|
||||
4. 회사 정보, 연락처, 실적 수치, 이미지 원본 확정
|
||||
5. 페이지별 중복 프로토타입을 공통 템플릿 구조로 전환
|
||||
|
||||
## P0: 구현 전에 반드시 수정
|
||||
|
||||
### 관리자 인증
|
||||
|
||||
- 모든 관리자 상세 HTML에 `adminAuthed: true`가 설정되어 있어 URL 직접 접근만으로 관리 화면이 노출됩니다.
|
||||
- 시안용 관리자 비밀번호가 모든 HTML과 `design/README.md`에 평문으로 포함되어 있습니다.
|
||||
- 인증 판단이 브라우저 JavaScript에서 이루어져 비밀번호를 바꾸더라도 우회할 수 있습니다.
|
||||
- 운영 구현에서는 비밀번호 해시, 서버 세션, 로그인 시도 제한, 로그아웃, CSRF 방어를 적용합니다.
|
||||
- `/admin` 및 하위 URL은 검색엔진 제외와 서버 측 인증 검사를 모두 적용합니다. 공개 푸터의 관리자 진입 버튼은 제거합니다.
|
||||
|
||||
### 데이터 저장
|
||||
|
||||
- 게시글, 문의, 회사 정보가 `localStorage`에만 저장되어 다른 브라우저·기기·관리자에게 공유되지 않습니다.
|
||||
- 문의자가 접수해도 관리자가 다른 브라우저에서 볼 수 없고, 브라우저 데이터 삭제 시 내용이 사라집니다.
|
||||
- 운영 구현에서는 MariaDB를 단일 원본으로 사용하고 게시글 이미지 파일만 웹 루트 밖 또는 보호된 업로드 경로에 저장합니다.
|
||||
- 디자인에 포함된 샘플 문의에는 이름, 연락처, 이메일 등 실제 개인정보처럼 보이는 값이 있으므로 운영 데이터에 포함하지 않습니다.
|
||||
|
||||
### 문의와 개인정보 흐름
|
||||
|
||||
- 화면은 문의 비밀번호로 답변을 확인할 수 있다고 안내하지만 비밀번호는 필수가 아니며 저장도 되지 않고, 공개 답변 조회 화면도 없습니다.
|
||||
- 문의 내용은 필수로 표시되지만 현재 제출 검증에서는 누락되어 빈 내용도 접수됩니다.
|
||||
- 이름·연락처 형식, 본문 길이, 스팸 요청, 반복 제출에 대한 검증이 없습니다.
|
||||
- 개인정보 동의 문구에 수집 항목, 이용 목적, 보유 기간, 동의 거부권과 불이익, 개인정보처리방침 연결을 명확히 표시해야 합니다.
|
||||
- 초기 출시 권장안은 전화·이메일 회신 방식으로 단순화하고 공개 답변 조회 비밀번호를 제거하는 것입니다. 웹 답변 조회가 필요하면 별도의 `접수번호 + 비밀번호` 조회 페이지와 비밀번호 해시 저장, 시도 제한을 설계합니다.
|
||||
|
||||
### 반응형 구조
|
||||
|
||||
- 공개 헤더가 로고, 3개 메뉴, 전화번호, 상담 버튼을 한 줄 고정 배치해 모바일 너비에서 넘칩니다. 햄버거 메뉴 또는 2단 모바일 헤더가 필요합니다.
|
||||
- 홈 히어로의 `minmax(340px, 1fr)`는 320px급 화면에서 가로 넘침 가능성이 있습니다.
|
||||
- 관리자 글 목록은 `1fr 120px 110px 156px` 고정 4열이라 태블릿·모바일에서 사용할 수 없습니다. 작은 화면에서는 카드 목록으로 전환합니다.
|
||||
- 우측 하단 전화상담 고정 버튼은 모바일에서 콘텐츠·푸터를 가릴 수 있으므로 크기와 안전 여백을 조정합니다.
|
||||
|
||||
## P1: 첫 배포 전에 보완
|
||||
|
||||
### 홈
|
||||
|
||||
- 히어로, 블로그 카드가 이미지 자리표시자 상태입니다. 실제 시공 이미지와 사용 권한, 대체 텍스트를 확보합니다.
|
||||
- `20년`, `1,200+`, `24시간 내 견적 회신`, `정기 사후관리`는 대외 표시 가능한 근거와 정확한 서비스 조건을 확인합니다.
|
||||
- 서비스 카드가 설명만 있고 상세 이동이 없습니다. 최소한 문의 유형이 미리 선택된 상담 화면으로 연결하거나 서비스 상세 섹션 앵커를 제공합니다.
|
||||
- 모든 회사명 표기를 `(주)지티에스정보통신`으로 통일합니다.
|
||||
|
||||
### 블로그 목록·상세
|
||||
|
||||
- 카드 전체가 `onclick`만 사용되어 키보드 접근과 새 탭 열기가 불가능합니다. 실제 `<a>` 링크로 변경합니다.
|
||||
- 숫자 파일명 대신 의미 있는 slug URL을 사용합니다. 예: `/blog/office-network-checklist`.
|
||||
- 제목 외에 페이지별 description, canonical, Open Graph, 구조화 데이터, 대표 이미지 메타데이터가 필요합니다.
|
||||
- 업로드 이미지마다 대체 텍스트, 캡션, 대표 이미지 선택 기능을 제공합니다.
|
||||
- 관리자 글 편집에 초안/공개 상태가 없어 저장 즉시 노출됩니다. 초안과 공개 상태를 분리합니다.
|
||||
|
||||
### 문의
|
||||
|
||||
- 지도는 자리표시자이며 실제 지도 사용 여부와 개인정보·외부 스크립트 정책을 정해야 합니다. 초기에는 지도 링크 버튼과 주소 텍스트만 제공하는 편이 가볍습니다.
|
||||
- 성공 화면에는 접수번호, 접수 일시, 회신 방법, 예상 응답 시간을 표시합니다.
|
||||
- 오류는 `alert`가 아니라 필드별 메시지와 요약 메시지로 제공하고 `aria-live`를 적용합니다.
|
||||
- 전화번호 자동 형식화, 이메일 형식, 글자 수 제한, 서버 검증, CSRF, 허니팟 또는 속도 제한을 적용합니다.
|
||||
|
||||
### 관리자
|
||||
|
||||
- 게시글 목록과 문의 목록은 시맨틱 테이블 또는 모바일 카드 구조로 구현합니다.
|
||||
- 삭제는 즉시 영구 삭제보다 확인 단계와 복구 가능한 소프트 삭제를 권장합니다.
|
||||
- 이미지 업로드는 확장자·MIME·용량·픽셀 크기 검증, 안전한 파일명, EXIF 제거, WebP 변환을 적용합니다.
|
||||
- 답변이 고객에게 이메일로 전송되는지, 사이트에서 조회되는지, 단순 내부 기록인지 명확히 구분합니다.
|
||||
- 회사 정보 변경은 입력 형식 검증과 변경 이력을 적용하고 관리자 비밀번호 변경 메뉴는 별도로 둡니다.
|
||||
|
||||
## P2: 품질 및 운영 개선
|
||||
|
||||
- 19개 HTML 각각에 약 152KB의 동일한 스타일·데이터·로직이 반복됩니다. 공통 레이아웃, 컴포넌트, 데이터 접근 계층으로 분리합니다.
|
||||
- 약 2MB인 동일 폰트 파일이 두 이름으로 중복되어 있습니다. 하나만 사용하고 필요한 경우 서브셋 또는 시스템 폰트 폴백을 검토합니다.
|
||||
- 현재 화면은 전용 JavaScript 런타임에 의존합니다. 공개 콘텐츠는 서버 렌더링해 JavaScript 실패 시에도 제목·본문·연락처가 보여야 합니다.
|
||||
- `design/assets/styles.css`와 `hero-network.png`는 현재 렌더링되는 프로토타입에서 사용되지 않습니다. 구현 시 사용 자산만 선별합니다.
|
||||
- 접근성 QA에 키보드 이동, 포커스 표시, 200% 확대, 색상 대비, 이미지 대체 텍스트, 오류 안내를 포함합니다.
|
||||
- 성능 QA에 모바일 LCP, 폰트 로딩, 이미지 지연 로딩, 캐시 헤더, 압축을 포함합니다.
|
||||
|
||||
## 페이지별 구현 방향
|
||||
|
||||
| 화면 | 유지할 구성 | 수정할 구성 |
|
||||
| --- | --- | --- |
|
||||
| 홈 | 히어로 → 실적 → 서비스 → 강점 → 프로세스 → 블로그 → CTA 흐름 | 실제 이미지, 수치 검증, 서비스 이동 링크, 모바일 헤더 |
|
||||
| 블로그 목록 | 카테고리와 카드 그리드 | 링크 시맨틱, 실제 썸네일, 빈 결과, 서버 페이지네이션 |
|
||||
| 블로그 상세 | 제목·작성 정보·본문·문의 CTA | slug, SEO 메타, 이미지 alt/캡션, 이전·다음 글 |
|
||||
| 1:1 문의 | 좌측 폼·우측 연락처 구조 | 개인정보 고지, 검증, 스팸 방어, 회신 방식 확정, 지도 대체 |
|
||||
| 관리자 로그인 | 단일 로그인 화면 | 서버 인증, 시도 제한, 세션 만료, 비밀번호 재설정 |
|
||||
| 글 관리 | 목록·작성·수정 흐름 | 공개 상태, slug, 대표 이미지, alt, 소프트 삭제 |
|
||||
| 문의 관리 | 상태·상세·답변 흐름 | DB 저장, 답변 전달 방식, 개인정보 접근 기록·보관기간 |
|
||||
| 회사 정보 | 한 화면 설정 | 검증, 변경 이력, 권한 분리 여부 |
|
||||
|
||||
## 구현 기준 정보 구조
|
||||
|
||||
- 공개: `/`, `/blog`, `/blog/{slug}`, `/contact`, `/privacy`
|
||||
- 관리자: `/admin/login`, `/admin/posts`, `/admin/inquiries`, `/admin/company`
|
||||
- 관리자 URL은 디자인 파일명과 무관하게 모든 요청에서 서버 인증을 선행합니다.
|
||||
- 공개 페이지는 PHP 서버 렌더링을 기본으로 하고 JavaScript는 메뉴, 필터, 폼 편의 기능에만 점진적으로 사용합니다.
|
||||
|
||||
## 구현 전 사용자 확인 항목
|
||||
|
||||
- 문의 답변 방식: 전화·이메일 회신만 제공할지, 웹 답변 조회까지 제공할지
|
||||
- 표시할 대표번호, 지점번호, 이메일, 주소, 대표자, 사업자등록번호의 최종 값
|
||||
- `20년`, `1,200+`, `24시간`, A/S 문구의 대외 사용 가능 여부
|
||||
- 실제 시공 사진과 로고 원본의 사용 가능 여부
|
||||
- 블로그 9개 샘플 글을 초기 운영 콘텐츠로 사용할지 여부
|
||||
174
docs/implementation-todo.md
Normal file
174
docs/implementation-todo.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# 구현 TODO
|
||||
|
||||
최종 수정일: 2026-08-10
|
||||
|
||||
완료한 작업은 체크하고, 설정값이나 URL이 바뀌면 관련 문서도 함께 갱신합니다.
|
||||
|
||||
## 0. 사전 조사
|
||||
|
||||
- [x] [Codex] 프로젝트 문서 상시 동기화 규칙을 `AGENTS.md`에 추가
|
||||
- [x] [Codex] 로컬 저장소 및 작업 대상 확인
|
||||
- [x] [Codex] `design/` 페이지 구성과 반복 구조 검토
|
||||
- [x] [Codex] 공개 화면과 관리자 화면의 모바일 문제 확인
|
||||
- [x] [Codex] 브라우저 저장소 및 클라이언트 인증 문제 확인
|
||||
- [x] [Codex] Cafe24 호스팅 상품, PHP, MariaDB, 보안 설정 확인
|
||||
- [x] [Codex] 도메인 이전 상태, 네임서버 위임, DNS 장애 상태 확인
|
||||
- [x] [사용자] 연결할 도메인을 `gtsit.co.kr`로 최종 확인
|
||||
|
||||
## 1. 임시 페이지 배포
|
||||
|
||||
- [x] [Codex] 외부 리소스 없는 `public/index.html` 제작
|
||||
- [x] [Codex] 데스크톱 화면 확인
|
||||
- [x] [Codex] 390px 모바일 화면 및 가로 넘침 확인
|
||||
- [x] [Codex] 로컬 검증 서버 종료
|
||||
- [x] [사용자] Cafe24 SSH 인증키 다운로드
|
||||
- [x] [Codex] 인증키를 `.secrets/`로 이동, 파일 권한 제한, Git 제외
|
||||
- [x] [사용자] Cafe24 `FTP/Shell 접속설정`에서 SSH key 로그인 재적용
|
||||
- [x] [사용자] `인증키 재발급` 없이 현재 등록된 SSH 인증키 다시 다운로드
|
||||
- [x] [Codex] 새 키 지문 확인, 권한 제한, `.secrets/` 보관
|
||||
- [x] [Codex] SSH/SFTP 접속 및 실제 웹 루트 확인
|
||||
- [x] [Codex] 서버 기존 파일 목록 확인
|
||||
- [x] [Codex] 기존 Cafe24 안내 파일 백업
|
||||
- [x] [Codex] 임시 페이지 업로드
|
||||
- [x] [Codex] `gts0201.mycafe24.com` HTTPS 200 및 파일 일치 확인
|
||||
- [x] [Codex] 실제 브라우저에서 임시 페이지와 가로 넘침 확인
|
||||
- [x] [Codex] 임시 페이지 상단 로고와 하단 저작권을 `(주)지티에스정보통신`으로 변경 및 재배포
|
||||
- [ ] [사용자] 다운로드 폴더의 인증키 복사본 정리 여부 결정
|
||||
|
||||
진행 메모: 2026-08-04 새로 다운로드한 키의 지문이 기존 키와 다른 것을 확인했고 새 키로 SSH 접속에 성공했습니다. 실제 홈은 `/home/hosting_users/gts0201`, 웹 루트는 `www`입니다. 기존 `hosting_index.html`은 `hosting_index.html.backup-20260804`로 보존했고, `public/index.html`을 `www/index.html`로 배포했습니다. 기본 도메인 HTTPS 200, 로컬·운영 파일 SHA-256 일치, 브라우저 렌더링 및 1280px 가로 넘침 없음까지 확인했습니다.
|
||||
|
||||
## 2. 사용자 도메인 연결
|
||||
|
||||
- [x] [공동] Cafe24의 연결 대상 호스팅 `gts0201`과 도메인 `gtsit.co.kr` 재확인
|
||||
- [x] [Codex] 사용자 승인 후 호스팅에 도메인 연결
|
||||
- [x] [Codex] 루트 도메인 A 레코드 `112.175.85.162` 응답 확인
|
||||
- [x] [Codex] `www`가 루트 도메인을 거쳐 같은 서버로 연결되는지 확인
|
||||
- [x] [Codex] 로컬 및 Google Public DNS에서 기존 `SERVFAIL` 해소 확인
|
||||
- [ ] [Codex] Cloudflare DNS를 포함한 전체 전파 완료 확인
|
||||
- [x] [공동] 대표 주소를 `https://gtsit.co.kr`로 결정
|
||||
- [x] [Codex] Cafe24 대표 도메인을 `gtsit.co.kr`로 변경
|
||||
- [x] [Codex] HTTP 및 `www`를 대표 HTTPS 주소로 영구 리디렉션
|
||||
- [ ] [Codex] 기본 Cafe24 도메인의 운영 노출 정책 결정 및 적용
|
||||
|
||||
진행 메모: 2026-08-04 Cafe24 대표 도메인을 `gtsit.co.kr`로 변경했습니다. 변경 직후 외부 요청에서 `http://gtsit.co.kr`과 `https://www.gtsit.co.kr`은 `https://gtsit.co.kr`로 301 응답하고, 대표 HTTPS 주소는 200 응답하는 것을 재확인했습니다. Cafe24 자가진단은 같은 시각 서버 연결 및 SSL 오류를 표시했지만 실제 공개 접속과 TLS 검증은 정상이라 진단 표시 불일치로 기록합니다.
|
||||
|
||||
## 3. HTTPS 설정
|
||||
|
||||
- [ ] [Codex] 도메인 DNS 전체 전파 확인
|
||||
- [x] [Codex] 도메인 연결 직후 HTTP 응답 및 배포 파일 일치 확인
|
||||
- [x] [Codex] Cafe24 SSL Basic 신청 가능 상태와 비용 확인
|
||||
- [x] [사용자] SSL 발급 및 설치 완료
|
||||
- [x] [Codex] 루트 및 `www` 인증서 적용 확인
|
||||
- [x] [Codex] HTTP에서 HTTPS로 301 리디렉션
|
||||
- [x] [Codex] `www`에서 루트 HTTPS 주소로 301 리디렉션
|
||||
- [x] [Codex] 혼합 콘텐츠와 인증서 체인 QA
|
||||
|
||||
진행 메모: 2026-08-04 Let’s Encrypt 인증서가 루트와 `www`에 적용됐습니다. 인증서 유효기간은 2026-08-04~2026-11-02이며, HTTP와 `www`는 `https://gtsit.co.kr`로 301 리디렉션됩니다.
|
||||
|
||||
## 4. MariaDB 설정
|
||||
|
||||
- [x] [Codex] DB 주소 `localhost`, 계정 `gts0201`, 포트 `3306`, MariaDB `10.6.5` 확인
|
||||
- [x] [Codex] PHP 8.4의 PDO MySQL 및 mysqli 확장 사용 가능 여부 확인
|
||||
- [x] [Codex] PHP 기본 문자셋 UTF-8 및 시간대 `Asia/Seoul` 확인
|
||||
- [x] [사용자] 기존 DB 비밀번호를 로컬 비밀 설정에 입력
|
||||
- [x] [사용자] DB 비밀번호를 `.secrets/db.env`에 직접 저장
|
||||
- [x] [Codex] DB 접속 설정을 서버 웹 루트 밖에 배치하고 권한 `600` 적용
|
||||
|
||||
- [x] [Codex] DB 비밀번호와 설정 파일의 Git 제외 확인
|
||||
- [x] [Codex] 비밀번호 인증 연결 테스트 및 임시 진단 파일 제거
|
||||
- [x] [Codex] 빈 DB 기본값을 `utf8mb4`와 `utf8mb4_unicode_ci`로 변경
|
||||
- [x] [Codex] `database/schema.sql` 초안 작성
|
||||
- [x] [Codex] 관리자, 게시글, 이미지, 문의, 사이트 설정 테이블 생성
|
||||
- [x] [Codex] 초기 관리자 계정의 안전한 생성 절차 마련
|
||||
- [x] [사용자] 초기 관리자 아이디 `gts0201` 확정
|
||||
- [ ] [사용자] 1회용 등록 URL에서 관리자 비밀번호 직접 설정
|
||||
- [ ] [Codex] 백업 및 복구 절차 검증
|
||||
|
||||
진행 메모: 2026-08-04 웹 진단으로 PHP 8.4.21p1, PDO 드라이버 `mysql`, `mysqli`, `mbstring`, `openssl`, `fileinfo`, 업로드 100MB, 메모리 256MB를 확인했습니다. MariaDB 10.6.17 비밀번호 인증에 성공했고, 테이블 0개인 빈 DB의 기본값을 `utf8mb4`와 `utf8mb4_unicode_ci`로 변경했습니다. 서버 접속 설정은 웹 루트 밖의 `.gtsit-db.env`에 권한 600으로 저장했으며 모든 임시 웹 파일은 삭제했습니다.
|
||||
|
||||
관리자 등록 메모: 초기 아이디는 `gts0201`입니다. 비밀번호는 채팅이나 저장소에 남기지 않고 24시간 유효한 1회용 URL에서 사용자가 직접 입력합니다. 계정 생성 후 서버의 등록 토큰 파일은 자동 삭제됩니다.
|
||||
|
||||
## 5. 디자인 구현 전 확정
|
||||
|
||||
- [x] [Codex] 공개·관리자 전체 디자인 구조 검토
|
||||
- [x] [Codex] 접수번호와 비밀번호를 사용한 웹 답변 조회 흐름 구현
|
||||
- [ ] [사용자] 회사 정보와 대외 표시 실적 수치 최종 확인
|
||||
- [x] [사용자] 대표 이메일 `gts0201@naver.com` 확인
|
||||
- [x] [사용자] 주소 `서울시 송파구 정의로7길 13, B동 오피스 1020호` 확인
|
||||
- [x] [사용자] 공개·관리자 전체 회사명을 `(주)지티에스정보통신`으로 통일
|
||||
- [x] [Codex] `GTS` 글자 기반 워드마크 로고 이미지 생성 및 공개·관리자·임시 페이지 적용
|
||||
- [x] [Codex] HTML 템플릿의 네트워크 시공 이미지를 최적화해 메인 비주얼에 적용
|
||||
- [x] [Codex] 기존 사이트 백업의 실제 시공 이미지 4장으로 메인 자동 슬라이드 구현
|
||||
- [x] [Codex] 기존 사이트의 LAN·무선·키폰·CCTV 글을 재구성한 공개 게시글 5건 등록
|
||||
- [x] [사용자] 푸터 전화번호 연결 제거 및 플로팅 전화상담 아이콘 적용
|
||||
- [x] [Codex] 네이버 지도 API 연동 방식 및 공식 등록 요건 확인
|
||||
- [x] [사용자] NAVER Cloud Maps Application 생성, Dynamic Map 선택, 웹 URL `http://gtsit.co.kr` 등록
|
||||
- [x] [사용자] Maps Client ID 전달·등록, Client Secret은 전달하지 않음
|
||||
- [x] [Codex] 오시는 길 지도·회사 마커·네이버 지도 열기 fallback 구현
|
||||
- [x] [Codex] 지도 SDK 요소 높이 안정화 및 사용자 정의 전체화면 컨트롤 적용
|
||||
- [x] [사용자] 기존 사이트 백업의 실제 시공 이미지 원본 전달
|
||||
- [ ] [사용자] 최신 시공 이미지 추가 전달
|
||||
- [x] [Codex] 관리자 인증·세션·접근 통제 방식 확정
|
||||
- [x] [Codex] 모바일 헤더와 관리자 모바일 목록 구조 설계
|
||||
- [x] [Codex] 2026 개인정보보호위원회 작성지침 기반 개인정보 수집·이용 고지 및 개인정보처리방침 확정
|
||||
- [x] [Codex] 공통 PHP 템플릿과 MariaDB 기반 구현 구조 확정
|
||||
|
||||
## 6. 공통 마크업 및 기반 구축
|
||||
|
||||
- [x] [Codex] 디자인 토큰과 공통 CSS 정리
|
||||
- [x] [Codex] 공통 헤더, 내비게이션, 푸터 템플릿화
|
||||
- [x] [Codex] 모바일 공개 헤더 구조 구현
|
||||
- [x] [Codex] 관리자 목록 모바일 카드 구조 구현
|
||||
- [x] [Codex] 공통 버튼, 입력 필드, 표, 상태 UI 정리
|
||||
- [x] [Codex] 접근 가능한 포커스, 오류, 빈 상태 정의
|
||||
- [x] [Codex] PHP 라우팅 및 오류 페이지 구성
|
||||
|
||||
## 7. 공개 페이지 구현
|
||||
|
||||
- [x] [Codex] 홈 구현
|
||||
- [x] [Codex] 게시글 목록 및 페이지네이션 구현
|
||||
- [x] [Codex] 게시글 상세 동적 템플릿 구현
|
||||
- [x] [Codex] 주제별 공개 게시글과 대표 이미지 데이터 반영
|
||||
- [x] [Codex] 대표 이미지 없는 게시글의 브랜드형 임시 썸네일 적용
|
||||
- [x] [Codex] 메인 서비스 카드의 네트워크·키폰·CCTV·유지보수 고정 아이콘 구현
|
||||
- [x] [Codex] 메인 서비스 카드 아이콘 테스트 경로 배포 및 시각 QA
|
||||
- [x] [Codex] 문의 작성 및 서버 검증 구현
|
||||
- [x] [Codex] 문의 이메일 도메인 선택·직접입력 전환 적용
|
||||
- [x] [Codex] 단일 연락처 필드의 휴대전화·지역번호·대표번호 자동 형식 적용
|
||||
- [x] [Codex] 문의 입력 안내 제거·placeholder 대비·드롭다운 꺾쇠 여백 조정
|
||||
- [x] [Codex] 문의 조회 및 본인 확인 구현
|
||||
- [x] [Codex] 숫자 4자리 조회 PIN과 접수번호별 5회 실패·15분 잠금 적용
|
||||
- [x] [Codex] 개인정보 수집·이용 요약 고지와 최종 개인정보처리방침 적용
|
||||
- [x] [Codex] 공개 페이지 반응형 QA
|
||||
|
||||
## 8. 관리자 구현
|
||||
|
||||
- [x] [Codex] 서버 세션 기반 관리자 로그인 구현
|
||||
- [x] [Codex] 클라이언트 코드의 기존 관리자 인증값 제거
|
||||
- [x] [Codex] 대시보드 구현
|
||||
- [x] [Codex] 게시글 목록, 작성, 수정, 소프트 삭제 구현
|
||||
- [x] [Codex] 이미지 업로드 검증 구현
|
||||
- [x] [Codex] 문의 목록, 상세, 처리 상태 및 공개 답변 구현
|
||||
- [x] [Codex] 회사 및 사이트 설정 구현
|
||||
- [x] [Codex] CSRF, 세션 만료, 로그인 시도 제한, 권한 검증 적용
|
||||
|
||||
## 9. 운영 설정 및 출시
|
||||
|
||||
- [x] [Codex] 운영 루트를 유지한 채 `/site-preview-7c2a91f4` 테스트 라우팅 배포
|
||||
- [x] [Codex] 테스트 경로 검색엔진 차단 및 세션 쿠키 경로 격리
|
||||
- [ ] [Codex] 만료 문의 파기 명령의 정기 실행 일정 등록
|
||||
- [ ] [공동] ModSecurity와 실제 기능 호환성 QA
|
||||
- [ ] [공동] PHP 안티웹쉘 활성화 여부 결정 및 QA
|
||||
- [x] [Codex] 업로드 디렉터리 PHP 실행 차단 설정 작성
|
||||
- [ ] [사용자] 하드 용량 및 트래픽 알림 수신처 결정
|
||||
- [ ] [공동] 용량 및 트래픽 알림 활성화
|
||||
- [ ] [공동] 검색 봇 차단 정책과 공개 시점 결정
|
||||
- [ ] [사용자] 대표 메일 서비스 결정
|
||||
- [ ] [공동] Cafe24 백업 외 별도 외부 백업 위치 결정
|
||||
- [ ] [Codex] 운영 QA 전체 실행
|
||||
- [ ] [공동] 임시 페이지를 본 사이트로 전환
|
||||
- [ ] [Codex] 출시 후 DNS, HTTPS, 오류 로그, 문의 흐름 재확인
|
||||
|
||||
진행 메모: 2026-08-04 기존 임시 안내 페이지는 `https://gtsit.co.kr/`에 유지하고 본 사이트 테스트 빌드를 `https://gtsit.co.kr/site-preview-7c2a91f4/`에 배포했습니다. 테스트 경로는 `X-Robots-Tag`와 HTML robots 메타로 색인을 차단하며, 세션 쿠키 경로도 테스트 경로로 제한합니다.
|
||||
|
||||
지도 연동 메모: 2026-08-05 Client ID `0xuekem2qn`을 `ncpKeyId`로 등록했습니다. 고정된 회사 위치는 주소 변환 API를 매번 호출하지 않고 확인된 위·경도로 표시하며, `Dynamic Map`만으로 회사 마커를 렌더링합니다. 지도 SDK 로드·인증 실패 시에도 주소와 네이버 지도 검색 링크를 유지합니다.
|
||||
41
docs/legacy-content-migration.md
Normal file
41
docs/legacy-content-migration.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# 기존 사이트 콘텐츠 이관 기록
|
||||
|
||||
최종 수정일: 2026-08-05
|
||||
|
||||
## 1. 원본 범위
|
||||
|
||||
- 원본 폴더: `/Users/feel_home_m5/workspace/MY/html/`
|
||||
- 형태: GnuBoard 기반 기존 사이트 백업
|
||||
- 주요 텍스트: `network1.html`, `network2.html`, `network3.html`, `keyphone1.html`, `cctv.html`
|
||||
- 주요 사진: `data/file/case/`의 원본 JPG
|
||||
- 제외 대상: 관리자 UI 이미지, 제품 썸네일, CAPTCHA·캐시·테마 이미지, 개인정보 가능성이 있는 로그·문의 데이터
|
||||
|
||||
## 2. 메인 슬라이드 이미지
|
||||
|
||||
| 적용 파일 | 내용 | 원본 |
|
||||
| --- | --- | --- |
|
||||
| `field/keyphone-network-rack.jpg` | 키폰·네트워크 통합 장비 랙 | `1868270649_exLJIMtX_...JPG` |
|
||||
| `field/lan-cabling-rack.jpg` | 패치패널·스위치 배선 정리 | `1868270649_9aEG5TN2_...JPG` |
|
||||
| `field/cctv-control-rack.jpg` | CCTV 녹화장치·관제 랙 | `1868270649_0caniNb8_...JPG` |
|
||||
| `field/outdoor-wireless-link.jpg` | 옥외 무선 통신 장비 | `1868270649_Z5yW9YJ8_...JPG` |
|
||||
|
||||
모든 이미지는 EXIF 방향을 반영한 1200×900 JPEG로 최적화했습니다. 특정 고객명이나 장소를 식별할 수 있는 설명은 사용하지 않습니다.
|
||||
|
||||
## 3. 공개 게시글
|
||||
|
||||
| 분류 | 제목 | slug |
|
||||
| --- | --- | --- |
|
||||
| 네트워크 | 사무실 LAN 구축, 구조와 배선 설계부터 확인하세요 | `office-lan-structure-cabling-guide` |
|
||||
| 네트워크 | 옥외 무선 통신 구간 설치 시 확인할 사항 | `outdoor-wireless-link-installation-guide` |
|
||||
| 키폰시스템 | 키폰시스템 주장치 선택, 증설 용량이 중요합니다 | `keyphone-system-capacity-selection` |
|
||||
| CCTV | CCTV 녹화장치 구성 시 꼭 확인할 기능 | `cctv-recorder-essential-features` |
|
||||
| 시공사례 | 통신실 랙 배선 정리가 유지보수를 좌우하는 이유 | `network-rack-cabling-maintenance-case` |
|
||||
|
||||
원문의 핵심 개념만 사용하고 Windows Server 2003, WEP, FDD·CD-RW 같은 오래된 제품·기술 표현은 현재 고객 안내에 맞게 제외하거나 일반화했습니다. 사진만으로 확인할 수 없는 고객, 현장 규모, 공사 결과는 추정하지 않았습니다.
|
||||
|
||||
## 4. 반영 방식
|
||||
|
||||
- 데이터 파일: `database/seed-legacy-content.sql`
|
||||
- slug 중복 시 내용 갱신, 삭제 상태 복구, 대표 이미지 재연결
|
||||
- 기존 게시글과 관리자 초안 유지
|
||||
- 공개 이미지 경로: `/assets/images/field/`
|
||||
253
docs/qa-list.md
Normal file
253
docs/qa-list.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# 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-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-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 리디렉션
|
||||
- [ ] 기존 메일 사용 시 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] 관리자 변경 작업에 CSRF 방어 적용
|
||||
- [x] 일반 사용자가 관리자 경로를 호출할 수 없음
|
||||
|
||||
진행 기록: 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과 미실행을 확인한 뒤 즉시 삭제했습니다.
|
||||
|
||||
## 11. 보안 및 개인정보
|
||||
|
||||
- [ ] HTML과 스크립트 입력의 XSS 방어
|
||||
- [ ] SQL 삽입 입력 방어
|
||||
- [x] 관리자 비밀번호와 문의 조회 PIN 해시 저장
|
||||
- [x] HTML, JavaScript, 로그에 비밀번호 없음
|
||||
- [x] 오류 화면에 서버 경로와 스택 정보 없음
|
||||
- [x] 개인정보 동의 내용과 수집 항목 일치
|
||||
- [x] 개인정보 보관기간·종료일 기록·완전 삭제 명령 구현
|
||||
- [ ] 만료 문의 완전 삭제 명령의 정기 실행 등록
|
||||
- [ ] 보안 헤더 적용 여부 확인
|
||||
- [ ] ModSecurity와 UploadGuard 오탐 없음
|
||||
|
||||
## 12. 검색, 성능 및 운영
|
||||
|
||||
- [ ] 임시 페이지 종료 후 `noindex` 제거 여부 확인
|
||||
- [x] 테스트 경로 `X-Robots-Tag`와 robots 메타 색인 차단
|
||||
- [ ] 페이지별 고유 제목과 설명 적용
|
||||
- [ ] canonical과 대표 도메인 일치
|
||||
- [ ] `robots.txt`와 사이트맵 정책 확인
|
||||
- [ ] 이미지 크기와 지연 로딩 적절성 확인
|
||||
- [ ] 모바일 저속 환경에서 주요 콘텐츠 표시
|
||||
- [ ] 용량 및 트래픽 알림 동작 확인
|
||||
- [ ] 일일 백업과 외부 백업 성공 확인
|
||||
- [ ] 장애 시 임시 페이지로 되돌리는 절차 확인
|
||||
|
||||
## 13. 네이버 지도
|
||||
|
||||
- [x] Dynamic Map Client ID 및 허용 웹 서비스 URL 일치
|
||||
- [x] 회사 주소 좌표와 마커 위치 일치
|
||||
- [x] 지도 SDK 적용 후 실제 지도 요소 높이와 타일 표시
|
||||
- [x] 사용자 정의 전체화면 아이콘 열기·종료 및 지도 크기 복구
|
||||
- [ ] 데스크톱·모바일 지도 확대·축소 및 스크롤 충돌 없음
|
||||
- [x] 지도 API 로드 실패 시 주소와 네이버 지도 링크 유지
|
||||
- [x] Client Secret이 HTML·JavaScript·저장소에 포함되지 않음
|
||||
- [ ] API 이용 한도와 임계치 알림 설정
|
||||
|
||||
## 이슈 기록 템플릿
|
||||
|
||||
```md
|
||||
### QA-000 제목
|
||||
|
||||
- 환경:
|
||||
- URL:
|
||||
- 재현 절차:
|
||||
1.
|
||||
2.
|
||||
- 기대 결과:
|
||||
- 실제 결과:
|
||||
- 심각도: Blocker / Critical / Major / Minor
|
||||
- 증빙:
|
||||
- 상태: Open / Fixed / Retest / Closed
|
||||
```
|
||||
Reference in New Issue
Block a user