A+ Tracker PRD v0.2 (P0 Scope, Open Q 4건 해소)

v0.2 변경 요약

  • §2 데이터 모델 갱신Questionvariant_type, ai_check_passed, human_reviewed, beta_metrics 추가 / Unit 71행 시드 데이터 명시
  • §3.5 신규 — 콘텐츠 풀 운영 — AI 변형 파이프라인·외주 검수 4단계 통합
  • §4.4 신규 — 결제 사용자 데이터 모델 분리 (Open Q 학부모 결제 vs 원장 결제 사전 대응)
  • §7 외부 의존성 갱신 — 카카오 알림톡 템플릿 5종 ID 명시

Open Question 4건 해소

mathflat-clone-service-plan §11에 잔존하던 Open Question 4건 중 본 PRD에서 해소:

  • 외주 강사 수학 정확성 검수 프로세스 → §3.5
  • AI 변형 1제→3제 품질 검증 방법 → §3.5 (AI variant pipeline 인용)
  • 학부모 결제 vs 원장 결제 데이터 모델 사전 분리 → §4.4
  • 단원 트리 마스터 데이터 시드 → §2 + seed-units.json

1. v0.1 대비 보존 사항 (변경 없음)

다음은 v0.1 그대로 유지. 본 v0.2에서 미언급 = 변경 없음으로 간주:

  • §1 핵심 사용자 시나리오 (3종)
  • §4 화면 흐름 5종 와이어프레임
  • §5 비기능 요건
  • §6 의도적 미구현 (P0)
  • §8 다음 단계 (PRD v0.3 → v1.0)

2. 데이터 모델 (변경분만)

2.1 Question 테이블 — 4필드 추가

Question (문항 마스터)
  id, unit_id → Unit
  type: enum(multiple_choice, short_answer, descriptive)
  difficulty: enum(low, mid, high)
  body_md: text
  choices: jsonb
  answer: text
  source: enum(self_made, ai_variant, public_link)
  source_question_id?: int
  public_link_url?: text
  created_by: text
  reviewed_by: text?
  reviewed_at: timestamp?
+ variant_type?: enum(V1, V2, V3)         -- AI 변형의 종류 (수치/맥락/표현)
+ ai_check_passed: boolean default false   -- AI 변형 파이프라인 Step 4 통과
+ human_reviewed: boolean default false    -- AI 변형 파이프라인 Step 7 통과
+ beta_metrics: jsonb?                     -- 정답률·풀이시간·신고 누적 (Step 8)
+ status: enum(draft, active, archived)    -- archived = 폐기됨
+ code: text unique                        -- 부록 B §10 정규식 예: "E5-1-2-MID-MC-007"

검증 룰 (DB CHECK 제약):

ALTER TABLE Question ADD CHECK (
  code ~ '^E[1-6]-[12]-[1-6]-(LOW|MID|HIGH)-(MC|SA|DE)-[0-9]{3}(-V[1-3])?$'
);
ALTER TABLE Question ADD CHECK (
  (source = 'ai_variant' AND variant_type IS NOT NULL AND source_question_id IS NOT NULL)
  OR (source != 'ai_variant')
);

2.2 Unit 테이블 — Seed 데이터

71행 (E1~E6 전 학년·학기·단원). seed-units.json 직접 사용.

-- 시드 적용 예시 (Supabase migration)
INSERT INTO Unit (id, grade, semester, "order", name, abbr, domain, level, parent_unit_id)
VALUES
  ('E1-1-1', 'E1', 1, 1, '9까지의 수', 'NUM9', 'NUM', 2, NULL),
  ('E1-1-2', 'E1', 1, 2, '여러 가지 모양', 'SHAPE1', 'GMM', 2, NULL),
  -- ... 71행 ...
  ('E6-2-6', 'E6', 2, 6, '원기둥, 원뿔, 구', 'CYLCONE', 'GMM', 2, NULL);

2.3 Account 테이블 — role 필드 추가 (학부모 결제 사전 분리)

Account
  id, email, phone, password_hash, created_at
  status: enum(active, suspended)
+ role: enum(owner, parent, admin) default 'owner'  -- P1 학부모 결제 사전 분리용
+ linked_student_id?: int → Student                  -- role=parent일 때만 사용

role enum의 의미:

  • owner: 학원 원장 (P0의 기본 계정)
  • parent: 학부모 (P1+ 학부모 직접 결제 시 가입)
  • admin: 발주처 운영자 (서비스 관리)

P0에서는 role 모두 owner 또는 admin. P1에서 parent 활성화. 데이터 모델 사전 분리로 마이그레이션 비용 차단.

2.4 Subscription 테이블 — 신규 (P1 진입 대비)

CREATE TABLE Subscription (
  id SERIAL PRIMARY KEY,
  account_id INT REFERENCES Account(id),  -- 결제 주체 (owner 또는 parent)
  academy_id INT REFERENCES Academy(id),
  scope: enum('whole_academy', 'single_student'),  -- 학원 전체 결제 (원장) vs 단일 학생 (학부모)
  student_id INT? REFERENCES Student(id),  -- scope='single_student'일 때만 사용
  plan: enum('free', 'starter', 'pro'),
  amount: numeric,
  billing_cycle: enum('monthly', 'annual'),
  status: enum('active', 'paused', 'cancelled'),
  next_billing_at: timestamp,
  created_at: timestamp default now(),
  payment_method_id: text  -- 토스페이먼츠 결제수단 ID
);

왜 P0에 미리 만드는가:

  • P0은 베타 무료라 Subscription 행 없음
  • 그러나 데이터 모델은 P1 학부모 결제 흐름을 사전 가정 → 마이그레이션 1회로 끝
  • P0 운영 중 학부모 결제 의향 데이터 수집 가능

3. 핵심 API 윤곽 (변경분만)

3.5 콘텐츠 풀 운영 (신규 섹션)

본 절은 v0.1에 없던 영역. 외주 강사 납품·AI 변형·검수·운영을 모두 포함.

POST   /api/internal/questions                       강사 납품분 일괄 임포트 (YAML 업로드)
POST   /api/internal/questions/:id/variants/generate AI 변형 3건 생성 (Step 2 트리거)
POST   /api/internal/questions/:id/variants/verify   AI 변형 셀프 검증 (Step 4)
GET    /api/internal/questions/review-queue          인간 검수 큐 조회 (Step 7)
PATCH  /api/internal/questions/:id/review            검수 결과 입력 (PASS/FAIL/EDIT)
POST   /api/internal/questions/seed-units            seed-units.json 적용 (71행)
GET    /api/internal/metrics/content-pool             풀 통계 (생성·통과·폐기·검수 대기)

/api/internal/* 는 발주처 운영자(role='admin') 전용. 일반 원장에게는 노출 X.

3.6 학부모 직접 결제 (P1 사전 정의)

POST   /api/parents/signup                            학부모 가입 (역할 자동 'parent')
POST   /api/parents/link-student                      학부모 ↔ 학생 연결 (학습 코드 입력)
POST   /api/subscriptions                             구독 생성 (원장 또는 학부모 모두)
GET    /api/subscriptions/me                          내 구독 내역
POST   /api/subscriptions/:id/cancel                  구독 해지

4. 결제·구독 흐름 (신규)

4.1 P0 (베타 무료)

  • Academy.plan = 'free'
  • Subscription 행 없음
  • 학생당 비용은 발주처가 부담 (단위 경제 §7)

4.2 P1 시점 (학원 결제, 매쓰플랫 동일 모델)

  • 원장(Account.role = 'owner') 결제
  • Subscription.scope = 'whole_academy'
  • 학원 단위로 학생 무제한 (플랜 한도 내)

4.3 P2 시점 (학부모 직접 결제, 신규 가능성)

  • 학부모(Account.role = 'parent') 결제
  • Subscription.scope = 'single_student'
  • 학부모가 학원과 별개로 학생 1명에 대해 구독
  • 사용 시나리오: 학원 비활성 사용자가 본인 자녀만 도구 사용

4.4 결제 데이터 모델의 사전 분리 효과

항목P0P1 (학원 결제)P2 (학부모 결제)
Account.roleowner onlyownerowner + parent
Subscription.scopen/awhole_academy+ single_student
데이터 마이그레이션0건0건 (사전 정의)
결제수단n/a토스페이먼츠토스페이먼츠
알림톡 발신자n/aowner 명의 (= 미경)parent 명의? — TBD

P2 학부모 결제 시 알림톡 발신 주체

학부모가 결제 주체일 때 우리 발신프로필(“A+ Tracker by 미경”)이 학원 명의로 발송하는 것이 적절할지 추가 검토 필요. 학원 발신 vs 운영처 발신 구분의 카카오 정책 갱신 시 재확인.


5. 외주 콘텐츠 검수 4단계 (PRD에 직접 통합)

content-rfp §5의 4단계를 PRD에 명시:

1단계 — 강사 자체 검수 (강사 본인)
  · 부록 E 50항목 모두 점검
  · 자체 점검 시트 (PDF) 첨부 후 납품

2단계 — 강사 2인 교차 검수
  · 부록 E 영역 2 (수학 5) + 영역 3 (분류 10) = 15항목 점검
  · 처리 시간 1제 당 평균 60초 목표

3단계 — 발주처 무작위 5% 샘플 검수
  · 50항목 전체
  · 미경 또는 위탁 (강사 1인에게 시급 30,000원 외주)
  · 5% 표본에서 오류율 5% 초과 시 → 강사 전수 재검수 트리거 (RFP §5)

4단계 — 베타 학생 시범 풀이
  · 정답률 < 20% 또는 > 95% → 변형 폐기 / 난이도 재분류
  · 풀이시간 ±100% 이탈 → estimated 갱신
  · 학생 신고 ≥ 3건 → 인간 재검수 큐

DB 컬럼:

  • Question.reviewed_by — 1단계 강사 식별자
  • Question.cross_reviewed_by — 2단계 (신규 컬럼)
  • Question.sample_reviewed — 3단계 boolean (신규)
  • Question.beta_metrics — 4단계 누적 (§2.1 추가됨)

6. AI 변형 파이프라인 통합 (참조)

본 PRD v0.2에서 AI 변형 파이프라인은 별도 문서 ai-variant-pipeline 참조.

데이터 모델 영향 (§2.1에 이미 반영):

  • variant_type, ai_check_passed, human_reviewed, beta_metrics, status

API 영향 (§3.5에 이미 반영):

  • /api/internal/questions/:id/variants/generate
  • /api/internal/questions/review-queue

7. 외부 의존성 (변경분)

서비스v0.1v0.2
Anthropic Claude APISonnet (리포트), Haiku (보조)+ Haiku (변형 생성), Sonnet (변형 셀프 검증) — pipeline §3
카카오 비즈메시지미정 템플릿5종 사전 작성monthly-report-v1, worksheet-assigned-v1, attendance-checked-v1 (P1), notice-v1, welcome-v1
토스페이먼츠(P1) 학원 결제(P1) 학원 결제 + (P2) 학부모 결제
SupabaseDB + Auth+ 시드 데이터 (seed-units.json 71행)

8. 마이그레이션 계획 (v0.1 → v0.2)

본 PRD는 코드 미작성 상태이므로 마이그레이션 = 데이터 모델 정의 갱신.

-- v0.2 schema (Supabase migration 1번)
-- Account
ALTER TABLE Account ADD COLUMN role TEXT DEFAULT 'owner' CHECK (role IN ('owner', 'parent', 'admin'));
ALTER TABLE Account ADD COLUMN linked_student_id INT REFERENCES Student(id);
 
-- Question
ALTER TABLE Question ADD COLUMN variant_type TEXT CHECK (variant_type IN ('V1', 'V2', 'V3'));
ALTER TABLE Question ADD COLUMN ai_check_passed BOOLEAN DEFAULT false;
ALTER TABLE Question ADD COLUMN human_reviewed BOOLEAN DEFAULT false;
ALTER TABLE Question ADD COLUMN beta_metrics JSONB;
ALTER TABLE Question ADD COLUMN cross_reviewed_by TEXT;
ALTER TABLE Question ADD COLUMN sample_reviewed BOOLEAN DEFAULT false;
ALTER TABLE Question ALTER COLUMN status TYPE TEXT CHECK (status IN ('draft', 'active', 'archived'));
ALTER TABLE Question ADD COLUMN code TEXT UNIQUE CHECK (code ~ '^E[1-6]-[12]-[1-6]-(LOW|MID|HIGH)-(MC|SA|DE)-[0-9]{3}(-V[1-3])?$');
 
-- Subscription (신규 테이블)
CREATE TABLE Subscription (...);  -- §2.4 참고
 
-- Unit seed
\copy Unit FROM 'seed-units.json';  -- 또는 application-level seed

9. v0.2의 잔존 Open Questions

mathflat-clone-service-plan §11 5건 중 본 PRD에서 미해소:

  • 외주 수학 강사 모집 — 채널·계약서 (B4·B1 산출물 작성됨, 미경 본인 처리 영역)
  • 공공자료(EBS·KOFAC) 외부 링크 약관 — 한국저작권위 상담 결과 갱신 (체크리스트 §4 진행)

미경 본인 처리 영역이라 PRD에서는 미언급, mathflat-clone-service-plan §11 Still Open 절에서 추적.


10. v0.2 → v1.0 갈 때 추가 필요

  • 화면 와이어프레임 → 디자인 (Figma)
  • API 상세 명세 (OpenAPI 3.0 spec)
  • 인증·권한 흐름 상세 (RLS in Supabase)
  • 모바일 앱 화면 흐름 (학생·학부모)
  • 단위 테스트·통합 테스트 시나리오
  • 배포·롤백 프로세스