# SkyPine Study — PhpStorm 개발 지시서

**문서 상태:** 1차 개발 기준서 (실행 가능한 개발 지시)
**작성 기준일:** 2026-11-13
**사업 도메인(계획):** `skypinestudy.com` (실제 도메인 등록·DNS·서버 구성은 별도 확인)
**개발 환경:** PhpStorm / PHP / CodeIgniter 4 / MySQL
**최초 완성 과목:** **Statistics**
**제품 정의:** 텍스트 중심 디지털 교과서 + 학습별 Quiz + 단원별 Test + 종합 Final Test + 유료 이용권

---

## 0. 개발자에게 주는 최상위 지시

> **공통 학습 엔진은 단 한 번 완성한다. 첫 번째 Statistics 과목을 실제 판매 가능한 수준으로 완성하면서 엔진의 모든 범용 기능을 구축한다. 그 후 Biology, Geometry 등의 신규 과목은 독립 콘텐츠 패키지만 추가하여 작동시킨다. 일반적인 과목 추가를 위해 PHP·JS·DB 스키마나 프런트엔드 코드를 고쳐서는 안 된다.**

- 지금 개발하는 것은 **Statistics 전용 웹사이트**가 아니라 **범용 학습 엔진 + 첫 Statistics 콘텐츠 패키지**다.
- 최초에는 **Statistics 한 과목만 실제로 완성**한다. 다른 과목의 실제 교재·문제 제작은 첫 엔진과 과목이 검증된 **후**에 진행한다.
- 매 단계마다 **Codex/개발 도구의 구현·자동 테스트 → 실제 사용자의 추가 검증 → 수정 → 전체 회귀 테스트**를 반복한다.
- 미완성 기능을 완료로 보고하지 않는다. 테스트하지 않은 기능은 반드시 `미검증`으로 기록한다.
- 설계가 정해지지 않은 부분은 임의로 제품 정책을 만들어 확정하지 않는다. 기본값을 정해야 한다면 문서화하고 승인 대기 사항으로 분리한다.

## 1. 비즈니스 목표와 제품 성격

### 1.1 목표

1. 미국 학생이 익숙한 **일반 교과목명**으로 과목을 제공한다. 예: Statistics, Geometry, Biology, Chemistry, Algebra I.
2. 사용자는 책을 읽듯 **한 페이지씩 넘겨 학습**한다. 텍스트가 중심이며 필요한 그림·도표·표·공식은 해당 위치에 넣는다.
3. 일정 학습 구간마다 **Quiz**, 각 단원 뒤 **Unit Test**, 과목 전체 뒤 **Final Test**를 제공한다.
4. 회원은 로그인하면 읽던 위치, 성적, 오답, 북마크를 다시 이용할 수 있다.
5. 기간별 유료 이용권으로 특정 과목 또는 전체 과목에 접근한다.
6. 공통 엔진과 과목 콘텐츠를 철저히 분리한다.

### 1.2 제외 범위

- 기본 학습 방식에 동영상 강의는 넣지 않는다. 영상 업로드·스트리밍 인프라는 최초 개발 범위 밖이다.
- 특정 시험명, 시험 운영 기관명, 공식 인증·제휴를 암시하는 문구는 **사이트 제목·상품명·설명·광고에 사용하지 않는다.**
- 제3자의 시험문항·공식 문제지·유료 교재·이미지를 무단 복제하거나 AI에 입력해 변형하는 방식으로 콘텐츠를 만들지 않는다.
- 최초 단계에서 다과목 실제 콘텐츠를 동시에 제작하지 않는다.
- AI가 생성한 장문 서술형 답안을 사실처럼 자동 채점하는 기능은 첫 버전에 넣지 않는다.

## 2. 확정 상품·가격 정책

| 상품 | 기간 | 가격(USD) | 초기 노출 조건 |
|---|---|---:|---|
| Single Subject | 6개월 | **$29.99** | Statistics 출시 시 사용 가능 |
| Single Subject | 12개월 | **$59.99** | Statistics 출시 시 사용 가능 |
| Two Subjects | 12개월 | **$79.99** | 실제 판매 과목 2개 이상일 때 활성화 |
| All-Subject Access | 12개월 | **$99.99** | 실제 판매 과목 3개 이상일 때 활성화 |

- **현재 가격은 초기 출시가격**이며, 과목이 충분히 증가하면 향후 인상할 수 있어야 한다. 가격·상품은 코드가 아니라 관리자 설정/가격표 데이터로 관리한다.
- `All-Subject Access`는 **구매 시점뿐 아니라 이용 기간 내 새로 출시되는 과목까지** 이용 가능하다. 최초의 `$99.99`는 영구 가격 동결 약속이 아니다.
- 2과목 이상 **6개월 상품은 아직 정해지지 않았으므로 만들지 않는다.**
- 기본 상품은 **자동갱신 없는 기간제 선불 이용권**이다. 만료일과 갱신 조건을 명시한다.
- 이미 결제한 이용자의 계약 기간·결제가격은 나중에 가격을 변경하더라도 유지한다.
- 구매 시점의 상품 버전과 결제액·이용 시작/종료 시각·선택 과목을 불변 주문 기록으로 저장한다.
- 기존 이용권의 상위 상품 전환/차액 정산 정책은 **추후 별도 결정**한다. 구현할 경우 사용자에게 금액·기간을 보여준 다음 서버에서 재계산한다. 초기 제품에는 해당 UI를 임의 도입하지 않는다.
- 구입한 과목의 **첫 단원 일부와 일부 Quiz를 무료 체험**할 수 있게 한다. 무료/유료 범위는 콘텐츠 메타데이터로 지정한다.

## 3. 기술 스택 및 개발 방식

| 분야 | 권장 기술 | 지시 |
|---|---|---|
| IDE | PhpStorm | Git, Composer, PHPUnit, 코드 검사 설정 |
| 서버 | PHP 8.4 또는 배포 환경과 호환되는 지원 PHP | 서버 호환성 확인 후 고정 |
| 프레임워크 | **CodeIgniter 4** 안정 릴리스 | 설치 시점 공식 요구사항 확인; 환경별 설정 분리 |
| DB | MySQL 8 계열 / InnoDB | UTF8MB4, 외래키, 인덱스, 트랜잭션 |
| 화면 | 서버 렌더링 + HTML/CSS/JavaScript | 무거운 SPA 프레임워크 사용 강제 금지 |
| 수식 | KaTeX 등 검증된 렌더러 | LaTeX 표현식 자체는 콘텐츠로 저장 |
| 그래프 | SVG/Canvas 또는 필요한 범위의 라이브러리 | 접근성 대체 설명 필요 |
| 결제 | Stripe Checkout (후보) | 실제 공급자 및 계정은 최종 연결 시 확정 |
| 테스트 | PHPUnit + 브라우저 E2E 테스트 | CI 파이프라인, 스테이징, 릴리스 체크 |

**중요:** CI4의 웹서버 DocumentRoot는 반드시 `public/`으로 설정한다. `app/`, `writable/`, 패키지 원본, 비밀키, 테스트 파일을 웹 루트에 노출하지 않는다. 공식 CI4 요구사항은 최신 문서를 참조한다.

## 4. 단일 엔진 아키텍처

### 4.1 엔진이 담당하는 것

- 회원가입·로그인·계정 복구·권한 관리
- 과목 카탈로그, 무료 맛보기, 결제 및 이용권 판정
- 목차·텍스트 페이지 렌더링·이미지·표·공식 표시
- 학습 위치·북마크·진도·오답 저장
- Quiz / Unit Test / Final Test 생성, 시험 시간·답안 제출·채점
- 성적표와 약점 분석
- 관리자 과목 패키지 업로드·검증·미리보기·발행·수정 이력 관리
- 결제 기록·접근권한·감사로그·백업·복구

### 4.2 과목 패키지가 담당하는 것

- 과목 이름·설명·학습 수준·표지 이미지
- 장/절/개별 읽기 콘텐츠 및 안정적인 콘텐츠 ID
- 그림·도표·수식·표 등 참고 자산과 대체 텍스트
- 문제은행, 정답, 선택지, 오답별 해설, 평가 목표/난이도
- Quiz·Unit Test·Final Test 청사진 및 출제 범위
- 콘텐츠 버전, 편집자 검토 상태, 저작권·출처 메타데이터

**절대 금지:** PHP/JS 실행 코드, 실행 가능한 플러그인, 외부 임의 스크립트를 과목 콘텐츠 업로드에 포함하지 않는다. 서버는 선언적 데이터와 허용된 자산만 읽는다.

### 4.3 확장 원칙

`Statistics.zip` → 관리자 업로드 → 패키지 검증 → 미리보기 → 승인 → Published → 공통 엔진에서 자동 작동.

나중에 `Geometry.zip` 등도 동일한 흐름을 사용한다. 예외적으로 새로운 **문항 유형 또는 상호작용 종류**가 필요한 경우에만 공통 엔진의 기능 버전을 올린다. 단순 새 과목과 기능 확장을 혼동하지 않는다.

## 5. 디지털 교과서 화면 명세

1. 학습 화면은 한 페이지 단위로 보여주며 **Previous / Next** 버튼, 화살표 키, 터치 동작을 지원한다.
2. 왼쪽 또는 별도 패널에 목차, 현재 장·절, 진도율, 북마크를 둔다. 모바일에서는 접을 수 있도록 한다.
3. **긴 세로 스크롤을 기본 학습 방식으로 사용하지 않는다.** 단, 큰 수식·표·접근성 환경에서는 의미 손실이 없는 대체 탐색을 허용한다.
4. 본문은 텍스트 중심이며 과목에 필요한 **이미지·수식·표·도표**를 본문 흐름 속에 배치한다.
5. 각 문단, 그림, 페이지 블록에는 불변의 `content_node_id`를 부여한다.
6. PC/태블릿/휴대폰·글자 크기에 따라 실제 화면 페이지 수가 달라도 **기록한 위치는 내용 블록 ID**로 복원한다. 화면상의 `5/12`는 임시 페이지 번호로 취급한다.
7. 문장 선택/복사, 줄간격·글자 크기·주간/야간 모드, 키보드 포커스, 대체 텍스트, 읽기 위치 이동 기능을 지원한다.
8. 장을 끝낼 때 Quiz가 있는 경우 `Take Quiz`를 명확히 보여주되 학습자가 임의로 앞뒤 페이지를 복습할 수 있도록 한다.
9. 본문 화면에 광고나 과도한 팝업을 넣지 않는다.

### 5.1 레이아웃 검증

- 데스크톱의 일반적인 가로 화면에서는 **책 한 페이지를 읽는 편안한 폭**을 유지한다.
- 모바일에서는 본문을 재흐름(reflow)시키며, 고정된 종이 폭을 강제로 축소하지 않는다.
- 수식·표·이미지가 페이지 경계에서 잘리거나 사라지지 않아야 한다.
- 브라우저 확대 200%, 좁은 화면, 키보드 전용 조작과 화면읽기 지원을 검사한다.

## 6. Quiz · Test · 채점 설계

### 6.1 공통 문항 유형(최초 엔진에 포함)

- `single_choice`: 보기 4개 기본, 정확히 하나의 정답
- `multiple_choice`: 여러 정답, 부분점수 정책 명시
- `true_false`: 참/거짓
- `numeric`: 수치 답안, 허용 오차·단위·반올림 규칙 명시
- `short_text`: 정해진 객관적 문자열·동의어 집합 등 검증 가능 범위
- `written_response`: 서술형 답안 저장 및 예시 풀이·채점 기준 제공; **최초 버전에서는 자동 점수 확정 금지**

### 6.2 출제와 평가

- **Lesson Quiz:** 학습 범위 기반 5~10문항 권장; 제출 후 해설과 관련 본문으로 돌아가기.
- **Unit Test:** 여러 Quiz 학습 목표를 통합하는 20~30문항 권장; 종료 후 결과 발표.
- **Final Test:** 전체 과목 범위 60~100문항 권장; 문항 분포 청사진에 따라 구성.
- 출제 시 해당 과목·장·목표·난이도·문항상태·사용 이력을 고려하고, 같은 평가에서 동일 문항을 중복 출제하지 않는다.
- 퀴즈의 문제를 그대로 복사해 테스트만 만드는 구조를 피하고, 동일 개념을 평가하는 독립 응용 문항을 포함한다.
- 평가 시작 시 **문항 스냅샷/콘텐츠 버전**을 고정하여 후속 교재 수정이 과거 점수나 답안의 의미를 바꾸지 않도록 한다.
- 제한시간은 서버 기준으로 판정하고, 브라우저 새로고침·연결 단절·중복 제출·기간 만료 등의 예외를 처리한다.
- 점수·정답·풀이·보기의 판정은 서버 측에서 확정하고, 정답 키를 평가 전 클라이언트에 노출하지 않는다.
- 시험별 `attempt_id`와 문제별 답변, 채점 근거, 시작·종료 시각을 저장한다.
- 무제한 재도전 여부·점수표시 방식·부분점수 등은 평가 종류별 설정으로 관리한다.

### 6.3 통계 과목에 필요한 예외 처리

- 수치형 문제는 소수점, 허용 오차, 유효숫자, 단위를 명시해야 한다.
- 확률값 범위, 표본 크기, 계산식 결과를 독립 계산으로 검증한다.
- 그래프·통계표의 수치는 본문·정답·해설 사이에 일치해야 한다.
- 단답·서술형 자동 채점을 무리하게 확대하지 않는다. 객관적 채점이 불가능한 문항은 연습·모범답안 중심으로 제공한다.

## 7. 최초 과목: Statistics (완전한 교재)

### 7.1 최초 과목 범위

과목명은 **Statistics**, 언어는 미국 학생을 위한 **영어**다. 일반 고등학교 및 심화·대학 입문 수준까지 학습할 수 있도록 구성하되 특정 시험에 대한 공식 연계성을 주장하지 않는다.

**단원 초안(교육적 검토 후 확정)**

| Unit | 주제 | 주요 학습 성과 |
|---|---|---|
| 1 | Data and Statistical Thinking | 모집단·표본·변수, 통계 질문 |
| 2 | Collecting Data | 표본추출, 편향, 관찰연구·실험 |
| 3 | Exploring Categorical Data | 빈도·비율·분할표, 그래프 |
| 4 | Exploring Quantitative Data | 분포·중심·산포·이상치 |
| 5 | Probability Foundations | 사건, 조건부확률, 독립성 |
| 6 | Random Variables and Distributions | 이산·연속 확률변수, 기댓값 |
| 7 | Sampling Distributions | 표본통계량과 표집분포 |
| 8 | Estimation and Confidence Intervals | 추정, 오차한계, 신뢰구간 |
| 9 | Hypothesis Testing | 유의성, 오류, p-value 해석 |
| 10 | Comparing Groups | 비율·평균 비교, 가정과 해석 |
| 11 | Association and Regression | 산점도, 상관, 선형회귀 |
| 12 | Integrated Data Analysis | 종합 사례, 분석 보고, 최종 평가 |

### 7.2 Statistics 콘텐츠 완성 기준

- **한 과목 전체가 처음부터 끝까지 학습 가능**한 수준의 완성된 영어 교재가 있어야 한다.
- 약 **400~600쪽 상당의 텍스트 교재**와 **1,000~1,500개 독창적 연습·평가문항**을 초기 콘텐츠 기획 목표로 삼는다. 숫자를 맞추려고 중복·빈약한 내용을 채우지 않는다.
- 모든 문항에 **정답, 해설, 관련 학습 목표, 난이도, 검증 상태**를 부여한다. 서술형은 명확한 모범답안과 평가 기준을 제공한다.
- 대표 단원마다 필요한 통계 그림·그래프·표·수식을 삽입한다. 장식용 이미지는 최소화한다.
- 기본 콘텐츠는 PDF 파일을 페이지별로 화면에 붙이는 방식이 아니라 **HTML/구조화 텍스트 + 허용된 이미지·수식**으로 보관한다.
- 각 Unit에 학습 성과, 본문, Quiz, Test, 오답으로 돌아가는 링크가 존재해야 한다.
- 전 과목 Final Test를 실제 데이터로 수행할 수 있어야 한다.
- 저작권 문제 없는 **독자 제작** 텍스트·문항·그림을 사용하고, 사실·통계·계산을 별도로 검증한다.

### 7.3 작업 순서

1. Unit 1을 완성해 **엔진 인터페이스/콘텐츠 규격을 시험**한다.
2. Unit 1의 교재·Quiz·Unit Test를 실제로 사용하며 공통 엔진 문제를 수정한다.
3. 동일 규격으로 Units 2–12를 작성·검증하고 과목 전체 패키지를 완성한다.
4. Final Test·성적·진도·결제 권한 등 **전체 수명주기**를 실제로 검사한다.
5. 첫 과목의 상용 완성 기준이 통과되기 전까지 다른 정식 과목 제작을 시작하지 않는다.

## 8. 과목 콘텐츠 패키지 규격

**권장 파일:** `statistics-v1.0.0.zip` (예시)

```text
statistics/
  manifest.json                 # 패키지 형식 버전, 과목 ID, 내용 버전, 체크섬
  course.json                   # 제목, 설명, 학습 수준, 공개 미리보기 범위
  units/
    unit-01.json                # 단원 메타데이터와 lesson 참조
    ...
  lessons/
    lesson-01-01.json           # 본문 노드, 그림/공식 참조, 고정 콘텐츠 ID
    ...
  questions/
    unit-01.json                # 문항·보기·정답·해설·검증 메타데이터
    ...
  assessments/
    quizzes.json                # 출제 목표와 평가 설정
    unit-tests.json
    final-tests.json
  assets/
    ...                         # 이미지·SVG 등 허용된 자산
  attribution.json              # 저작권·출처·사용권 정보
```

### 8.1 필수 스키마 규칙

- 모든 과목은 고정된 `course_id`(예: `statistics`)를 사용하며 사람이 보는 제목은 별도 필드로 둔다.
- Unit, Lesson, Content Node, Question, Assessment에 **안정적이고 유일한 ID**를 부여한다.
- `manifest.schema_version`, `content.version`, `min_engine_version`을 구분한다.
- 본문 표현은 허용된 콘텐츠 노드 타입(heading, paragraph, figure, table, equation, example, callout 등)만 사용한다.
- 문항은 타입별 엄격한 필드/정답 규격과 검증 상태를 포함한다.
- 수식은 안전한 문자열로 렌더링하며 스크립트 실행·인라인 이벤트 핸들러를 금지한다.
- 이미지 파일 타입·크기·치수 제한, 압축폭탄 방지, 경로 이동(`../..`) 금지, 악성 SVG 정화/비허용 정책을 둔다.
- `draft → validated → reviewed → published → archived` 상태를 분리한다.
- 이미 발행된 콘텐츠는 새 버전을 만들고, 옛 버전과 수강생 평가 스냅샷을 보존한다.

### 8.2 관리자 업로드 절차

1. ZIP 업로드 → 파일 크기·MIME·확장자·압축 구조 검사.
2. `manifest.json`과 JSON Schema 검증; 콘텐츠 ID·링크·자산 참조 무결성 검사.
3. 문항 정답·선택지 중복·해설 누락·데이터 형식 등을 자동 검사.
4. 악성 콘텐츠·스크립트와 공개해선 안 되는 정답 키의 노출 위험 검사.
5. 격리된 staging 영역에 import 후 **관리자 미리보기** 제공.
6. 담당자가 내용 검토 및 출판 승인 → 트랜잭션 방식 publish.
7. 어느 단계에서 실패해도 **기존 published 버전 보존** 및 롤백 가능.
8. 작업 결과, 오류, 변경 사항, 승인자, 시각을 감사로그에 기록.

## 9. 권장 데이터베이스 개념 모델

| 구분 | 테이블 예시 | 핵심 목적 |
|---|---|---|
| 계정 | `users`, `roles`, `user_roles` | 회원·관리자 권한 |
| 과목 | `courses`, `course_versions`, `units`, `lessons`, `content_nodes` | 교재 본문과 버전 |
| 자산 | `assets`, `asset_references` | 이미지·그래프·저작권 메타데이터 |
| 문항 | `questions`, `question_versions`, `question_options`, `question_objectives` | 문항·정답·해설·학습 목표 |
| 평가 | `assessments`, `assessment_blueprints`, `assessment_items` | Quiz/Test 구성 |
| 응시 | `attempts`, `attempt_items`, `attempt_answers`, `grades` | 시험 스냅샷·답변·결과 |
| 진도 | `reading_positions`, `lesson_progress`, `bookmarks`, `review_items` | 학습 현황 |
| 상품 | `plans`, `plan_prices`, `orders`, `order_items` | 기간·가격·주문 |
| 권한 | `entitlements`, `entitlement_subjects` | 과목별 이용 가능 기간 |
| 결제 | `payment_transactions`, `webhook_events` | 결제 확정·중복 차단 |
| 운영 | `package_imports`, `audit_logs`, `system_settings` | 콘텐츠 반영·기록·설정 |

**구조 원칙:** 과목 추가를 위해 새 테이블을 만들지 않는다. 가격은 정수 센트(`2999`, `5999` 등)로 저장한다. 결제 원장과 이용권 레코드를 분리한다. 시간은 UTC 저장·표시 시 이용자 지역 시간으로 변환한다. 스키마 변경은 CI4 Migration으로만 수행한다.

## 10. 회원 · 구매 · 접근 권한

1. 무료 방문자는 과목 소개와 무료 공개 페이지 및 미리보기 Quiz에만 접근한다.
2. 로그인한 학생의 유료 접근은 매 요청마다 **서버 측 이용권 조회**로 판정한다.
3. URL 변경·API 직접 호출·캐시를 이용해 잠긴 본문·정답·시험을 볼 수 없어야 한다.
4. `Single Subject`: 선택 과목 하나만, `Two Subjects`: 지정한 두 과목만 허용한다.
5. `All-Subject Access`: 유효 기간에 published 상태인 **모든 과목**을 허용한다(향후 추가 과목 포함).
6. 만료 시 새 학습/시험 접근을 차단하며, 구매 내역과 과거 점수·학습 기록은 정책에 따라 보존한다.
7. 카드번호·CVC를 자체 DB에 저장하지 않는다. 결제 공급자에 맡긴다.
8. 외부 결제 성공 리다이렉트만으로 이용권을 발급하지 않는다. **서명 검증된 webhook**에서 결제 완료를 확인하고 한 번만 발급한다. 중복 webhook은 멱등 처리한다.
9. 취소·환불·차지백을 받은 경우 상품·권한의 상태 변경을 로깅하고 일관되게 처리한다.
10. 이용권 만료일 계산, 기간 연장, 계정 변경, 중복 구매에 대한 자동 테스트를 작성한다.

### 10.1 초기 고정 정책과 미확정 정책 분리

**확정:** 가격표, 6/12개월 기간, 3과목 이상 전체 이용, 현재 자동갱신 없음, 과목 수 증가 시 향후 가격 조정 가능.

**추후 사업 결정 필요:** 환불 기한과 예외, 정식 업그레이드 차액 계산, 신규 구매의 기존 이용권과의 합산·중복 처리, 세금 징수·납부 방식, 계정 공유 제한 수준. **미정 항목을 몰래 임의 구현하지 않는다.** 결제 오픈 전에는 반드시 최종 정책을 확정한다.

## 11. 미국 학생 대상 서비스의 개인정보·보안

- 초기에 고교생 대상 서비스로 정의하고 **13세 미만의 계정 가입·개인정보 수집은 법적 검토와 필요한 보호 장치가 준비되기 전까지 지원하지 않는 설계**를 우선 검토한다. 사이트의 실제 타깃 연령·마케팅에 따라 COPPA 적용 여부가 달라지므로 법률 검토를 거친다.
- 등록에 필요한 최소한의 정보만 요청하고, 광고 추적·불필요한 프로파일링을 하지 않는다.
- 보관 데이터: 계정 식별정보, 결제 공급자 식별자, 학습 진도·점수·이용권 정보 등 최소 범위.
- 비밀번호는 안전한 해시로만 저장; 로그인 시도 제한·세션 보호·관리자 MFA 적용을 검토한다.
- CSRF, XSS, SQL Injection, IDOR, 권한 상승, 업로드 악용, 세션 탈취, 무단 콘텐츠 접근에 대한 보안 테스트를 필수화한다.
- 관리자 변경, 가격 변경, 수동 권한 부여, 콘텐츠 발행은 변경 전/후와 행위자를 감사 기록으로 남긴다.
- 개인정보 처리방침, 이용약관, 환불 정책, 접근성/지원 문의 페이지를 판매 전 준비한다.
- 백업 암호화, 복구 훈련, 개인정보 삭제 요청 및 보유 기간 정책을 수립한다.

## 12. 관리자 기능

**콘텐츠 관리자:** 과목 등록/미리보기, 패키지 검사, 교재 버전 비교, 배포, 이전 버전 복원, 이미지 사용권 검토, 문항 검증 목록, 공개 범위 설정.

**운영 관리자:** 회원·활성 이용권 조회, 상품/가격 버전 관리, 결제 기록 조회, 환불 상태 반영, 공지, 에러 모니터링, 감사로그 확인.

- 실제 결제가 확인되지 않은 주문을 관리자 화면만으로 `paid`로 바꾸지 않는다. 시험용 수동 권한 부여는 별도 감사 추적이 있는 명시적 기능으로 제한한다.
- 운영 DB에서 직접 SQL 수정 없이 일상적인 과목 운영이 가능해야 한다.

## 13. 프로젝트 구성(권장)

```text
skypine-study/
  app/
    Config/
    Controllers/
      Web/               # 홈, 카탈로그, 학생 뷰어, 평가
      Admin/             # 과목 패키지·가격·운영
      Webhooks/          # 결제 webhook 수신
    Domain/
      Courses/           # 콘텐츠 읽기·버전·패키지 import
      Reader/            # 책 페이지 조합 및 위치 기록
      Assessments/       # 문항 선택·채점·답안·결과
      Commerce/          # 상품·주문·결제·이용권
      Accounts/          # 회원·접근 제어
    Database/
      Migrations/
      Seeds/
    Filters/
    Views/
  content-packages/       # 개발용 원본; 배포 공개 금지
    statistics/
  public/                 # 공개 웹 문서 루트(검증된 공개 자산만)
  tests/
    Unit/
    Feature/
    Integration/
  docs/
    architecture.md
    package-schema.md
    pricing-rules.md
    qa-checklist.md
    operations.md
  writable/               # 비공개 임시 저장·업로드·로그
  composer.json
  .env.example
```

구조는 예시이며 CI4 관례와 배포 환경을 존중해 실제 구현에서 합리적으로 조정할 수 있다. 중요한 것은 **도메인별 책임 분리, 콘텐츠와 코드 분리, 웹 루트 비공개 영역 보호**이다.

## 14. 개발 단계별 지시와 종료 조건

### Phase 0 — 개발 환경·설계 고정

- Git 저장소 생성, CI4 설치, .env 분리, DB 연결, PHPUnit 설정, README·운영 절차 작성.
- 데이터모델, 권한 모델, 콘텐츠 JSON Schema, UX 프로토타입을 먼저 확정.
- **완료 조건:** 새 개발 환경에서 설치·마이그레이션·테스트가 반복 가능.

### Phase 1 — 공통 교재 뷰어

- 과목/장/절/페이지 표시, Previous/Next, 목차, 반응형 페이지 구분, 본문·이미지·공식·표 지원.
- 위치 자동저장, 북마크, 글자 크기·다크 모드, 무료/잠금 콘텐츠 분리.
- **완료 조건:** Statistics Unit 1을 PC·태블릿·휴대폰에서 정확히 읽고 복원 가능.

### Phase 2 — 공통 문제·평가 엔진

- 타입별 문항 채점, Quiz, Unit Test, Final Test, 시험 스냅샷, 서버 기준 시간 처리, 답변 기록.
- 독립 채점 검증, 부정답 해설, 오답 복습과 진도·성적표.
- **완료 조건:** 정상·오류·중복·재접속 상황을 모두 자동/수동 테스트 통과.

### Phase 3 — 과목 패키지 관리

- JSON Schema, ZIP 격리, 무결성 검사, 미리보기, 승인, 발행, 롤백, 로그.
- 콘텐츠 버전 변경 시 기존 학습 위치·과거 시험 스냅샷이 유지되어야 함.
- **완료 조건:** Statistics 패키지의 수정·재발행이 엔진 코드 변경 없이 가능.

### Phase 4 — 회원·판매·이용권

- 회원가입/로그인, 무료 체험, 실제 상품 1과목 6개월/12개월, Stripe 테스트 결제, webhook.
- 미출시된 2과목/전체 이용권은 미래 상품 모델에만 정의하고 판매 화면에는 노출하지 않음.
- **완료 조건:** 정상 결제·실패·중복 webhook·환불·기간 만료·권한 우회 검증 통과.

### Phase 5 — Statistics 전체 콘텐츠 완성

- Unit 1~12의 영어 교재, 필요한 그림·도표, 1,000~1,500 문항을 **완성도 중심**으로 제작·검증.
- 모든 단원 Quiz, Unit Test, 전체 Final Test, 오답 링크, 콘텐츠 버전 검증.
- **완료 조건:** 학생이 전 범위를 학습하고 평가를 완료할 수 있으며 중대한 내용 오류가 없음.

### Phase 6 — 출판 QA · 보안 · 부하 · 운영

- 브라우저/모바일/접근성 검증, 개인정보·보안·백업/복구, 결제와 콘텐츠 접근검사.
- 외부 시험 사용자 피드백 및 결함 수정, 자동 회귀 테스트 반복.
- **완료 조건:** 15절의 출시 게이트를 모두 통과. 미해결 치명적 결함 0건.

### Phase 7 — 출시 후 확장성 확인 (새 정식 과목 제작 전)

- 시험용 최소 샘플 패키지를 별도 판매 없이 스테이징에 업로드하여 엔진의 과목 독립성 검증.
- Statistics의 최신 버전과 과거 버전, 회원 기록, 가격·이용권에 부작용이 없는지 확인.
- **완료 조건:** 다음 정식 과목 개발을 시작해도 공통 엔진을 다시 짤 필요가 없음을 입증.

## 15. 출시 승인 게이트 (필수 체크리스트)

- [ ] `Statistics`의 모든 Unit/학습/퀴즈/단원 Test/Final Test가 완성됨.
- [ ] 각 문항의 정답·오답 해설·계산식·표/그래프 일치 여부가 검증됨.
- [ ] 잘못된 선택지, 복수정답 오류, 단위·반올림 오류가 해결됨.
- [ ] 각 화면의 Previous/Next, 목차, 위치 복원, 기기별 레이아웃이 정상임.
- [ ] 로그인·관리자·콘텐츠·결제 API에서 무단 접근이 차단됨.
- [ ] 과목 패키지 업로드 실패가 운영 콘텐츠를 망가뜨리지 않음.
- [ ] 시험 중단/재접속/중복 제출에도 응시 기록과 성적이 일관됨.
- [ ] 결제 webhook 위조·중복 수신이 권한 발급으로 이어지지 않음.
- [ ] 가격 $29.99/$59.99 적용 및 미래 $79.99/$99.99 상품 규칙이 테스트됨.
- [ ] 이용권 만료, 전 과목 권한, 추후 가격 인상 시 기존 주문 보호가 테스트됨.
- [ ] 개인정보·저작권·접근성·환불 안내가 검토됨.
- [ ] 백업 복구 시험 및 배포 롤백이 실제로 성공함.
- [ ] 외부 사용자 시험 결과의 치명적·높은 우선순위 문제 해결됨.
- [ ] 설치/배포/운영 문서와 Git 태그가 정리됨.

**품질 원칙:** "오류 0"은 모든 가능한 오류가 없음을 증명한다는 뜻이 아니다. 출시 시점에서 알려진 치명적 오류 0건, 핵심 흐름 검증 완료, 잔여 위험 기록이 기준이다.

## 16. 개발자·Codex 작업 지시 프로토콜

개발자는 각 단계마다 다음 순서로 보고한다.

1. **현재 단계와 구현 범위:** 무엇을 구현할 것인지, 범위를 벗어난 작업은 무엇인지.
2. **변경 파일/DB Migration 목록:** 파일과 스키마의 변경 내용을 제시.
3. **실행 가능한 결과:** 로컬 서버에서 확인 가능한 페이지/기능.
4. **자동 테스트 결과:** 명령, 통과/실패, 남은 결함.
5. **수동 검증 항목:** 사람이 실제 브라우저에서 확인할 행동과 기대 결과.
6. **수정 후 회귀 테스트:** 수정 기능뿐 아니라 기존 합격 기능이 유지되는지 확인.
7. **릴리스 판단:** `완료 / 미완료 / 승인 대기`를 명시. 미완료를 완료로 표시 금지.

**특별 금지사항**

- 통합 전용 하드코딩: `if ($course === 'statistics') ...`로 엔진 기능을 분기하지 않는다.
- 실제로 검증하지 않고 `테스트 통과`, `판매 준비 완료`를 선언하지 않는다.
- 사용자 승인 없이 신규 유료 상품·자동갱신·가격·환불 방식을 임의 추가하지 않는다.
- 기존 데이터를 임의로 삭제하거나 과거 답안·성적을 수정하지 않는다.
- 한 오류를 수정하면서 다른 기능을 망가뜨리지 않도록 회귀 테스트를 건너뛰지 않는다.

## 17. 최초 실행 작업 — PhpStorm에서 시작할 지시

**지금 즉시 수행할 최초 작업:**

1. 빈 프로젝트 또는 지정된 Git 저장소에서 공식 CI4 App Starter를 설치한다.
2. PHP/CI4/DB 환경을 확인하고 개발·테스트·스테이징 환경을 분리한다.
3. `docs/architecture.md`, `docs/package-schema.md`, `docs/pricing-rules.md`, `docs/qa-checklist.md`를 이 문서에 근거하여 먼저 작성한다.
4. Phase 0의 데이터 모델·과목 패키지 JSON Schema·Statistics Unit 1 예시와 테스트 계획을 작성한다.
5. **Phase 1의 교재 뷰어부터 개발**한다. 초기부터 다과목 UI나 영상 처리 등을 추가하지 않는다.
6. 이후 각 Phase 종료 때 자동 테스트 결과와 수동 확인 체크리스트를 제출한다.

> **최종 성공 조건:** Statistics 한 과목이 상용 수준으로 완성되어 판매·학습·평가가 실제로 가능하고, 추후 새 과목은 정해진 패키지 파일을 검증 후 업로드하는 방식만으로 동일 엔진에서 작동한다.

---

## 참고 공식 자료 (개발 중 현행 버전 재확인)

- CodeIgniter 4 서버 요구사항: https://codeigniter.com/user_guide/intro/requirements.html
- CodeIgniter 4 개발 및 테스트 안내: https://codeigniter.com/user_guide/index.html
- Stripe Checkout 서버 측 결제 확정 안내: https://docs.stripe.com/payments/existing-customers?platform=web&ui=stripe-hosted
- FTC COPPA 안내: https://www.ftc.gov/business-guidance/resources/complying-coppa-frequently-asked-questions
- W3C WCAG 2.2 접근성 지침: https://www.w3.org/TR/wcag/

**이 문서는 제품 개발 지시서다. 실제 서비스 출시 전에는 결제·세금·개인정보·학생 대상 서비스의 적용 법률을 별도로 검토해야 한다.**
