리얼북 한 장으로 즉흥 연주까지.
체르니 100 정도의 손은 있는데 C-7 앞에서 멈추는 사람을 위한, 재즈피아노 연주 전공
학부 커리큘럼 기반 웹 학습 서비스. 이론을 늘리는 게 아니라 음표 없는 악보 앞에서
손이 움직이기까지의 시간을 줄이는 것이 목표다.
백엔드 없음. React 19 + TypeScript + Vite. 오디오는 전부 Web Audio 합성.
npm install
npm run dev # http://localhost:5173품질 게이트:
npm run typecheck # TypeScript strict
npm run test # 이론 엔진 단위 테스트 + 콘텐츠 정합성
npm run validate:content # 콘텐츠 정합성만
npm run build # 타입체크 + 프로덕션 번들
npm run smoke # 빌드 결과를 실제 크로미움으로 열어 전 라우트 확인
npm run verify:media # 유튜브 링크 생존 확인 (아래 참조)정적 호스팅 서브패스로 배포할 때:
JAZZYTORY_BASE=/Jazzytory/ npm run build.github/workflows/deploy.yml 이 푸시마다 타입체크 → 테스트 → 빌드 → 배포를 수행한다.
게이트를 통과하지 못하면 배포하지 않는다.
최초 1회만 저장소 소유자가 켜야 한다:
Settings → Pages → Build and deployment → Source: GitHub Actions
워크플로의 GITHUB_TOKEN 으로는 Pages 를 켤 수 없다
(Resource not accessible by integration 으로 실패한다).
그리고 github-pages 환경은 기본적으로 기본 브랜치에서만 배포를 허용한다.
기능 브랜치에서 실행하면 build 는 통과하지만 deploy 잡이 스텝 하나도 실행하지
못한 채 즉시 실패한다. 기본 브랜치에 머지하거나,
Settings → Environments → github-pages → Deployment branches 에 해당 브랜치를
추가해야 한다.
프로젝트 페이지 경로(/Jazzytory/)는 configure-pages 의 base_path 를
Vite 가 요구하는 끝 슬래시 형태로 정규화해 처리한다.
npm run build:artifact # artifact-dist/ 에 CSS 인라인 + 상대경로 번들 생성CSS 를 인라인하고 자산을 상대 경로로 참조하는 번들을 만든다.
<html>/<head>/<body> 없이 본문만 출력하므로 페이지를 스켈레톤으로 감싸는
호스팅(Claude Artifact 등)에 그대로 올릴 수 있다. 라우팅은 HashRouter 라
서버 리라이트가 필요 없다.
| 영역 | 내용 |
|---|---|
| 강의실 | 9개 강좌 · 51차시. 강의계획서 + 주차별 목차, 차시 하나에 그 단원의 전부 |
| 교수법 | 공개 출판물로 검증되는 재즈 교수법 18가지를 51개 모듈 전체에 84건으로 이식 |
| 이론 엔진 | 코드 심볼 파서, 철자 보존 이조, 기능 기반 코드 스케일 판정, 로마숫자 분석, ii‑V 감지 |
| 보이싱 엔진 | 셸 / 가이드톤 / 루트리스 A·B / 드롭2 / 쿼탈 / 어퍼스트럭처 / 블록 / 스프레드 — 음역 제약과 성부 진행 최소화 포함 |
| 오디오 | Web Audio 합성 피아노·더블베이스·드럼, 룩어헤드 스케줄러, 워킹베이스·컴핑 자동 생성 |
| 연습 랩 | 보이싱 랩(12키 자동 순환) · 진행 분석 + 반주 · 코드 탐색기 · 청음 훈련 · 연습 설계 · 메트로놈(2·4박) |
| 레퍼토리 | 스탠다드 코드 차트 + Jazzytory 오리지널 연습곡. 이조·반주·마디별 분석·난구간 해법 |
| 청음 | 필청 명반 + 트랙 단위 청취 지시문 (목록이 아니라 듣는 법) |
| 진도 | 8축 숙련도, 간격 반복 복습, 인터리빙 세션 생성, 연습 로그 |
| 연습 설계 | 매개변수를 하나만 고정해 연습하는 랩(밀도·음역·여백 등 8종) |
이 저장소가 감추지 않는 세 가지.
원 기획은 "버클리음대 등 유수 교수의 검수"를 포함했다. 실제로 구현한 것은:
- 8항목 루브릭 기반 검수 파이프라인 자체를 제품 기능으로 만들었다
- 콘텐츠를 버클리 프레스 등 실존 공개 교재의 개념 체계에 정렬하고 출처를 달았다
- 검수 패널은 교수법 계보를 대표하는 가상의 심사 기준이다. 실존 인물이 아니다
- 외부 검수 슬롯은 비워 두었다 (
faculty-pending→faculty-approved상태 머신 구현됨)
src/data/content.test.ts 가 이 정직성 규칙을 빌드 게이트에서 강제한다 —
검수자를 실존 인물로 표기하거나 실제 대학 소속으로 적으면 테스트가 실패한다.
교수법 페이지에 인용된 배리 해리스·트리스타노·갤퍼 등은 공개 출판물의 저자일 뿐
이 서비스를 승인하지 않았다. TeachingMethod.endorsedJazzytory 가 타입상 false 로
고정되어 있어 반대로 표기할 수 없다.
자세한 내용: docs/04-REVIEW-PROTOCOL.md ·
docs/09-PEDAGOGY.md
스탠다드는 코드 진행(화성 골격)만 수록한다. Tune.melodyIncluded 는 타입상
false 로 고정되어 있고 테스트가 검사한다. 리얼북 스캔·PDF·가사·채보된 솔로는 없다.
음원도 호스팅하지 않는다 — 청음은 앨범 메타데이터 + 청취 지시문으로 제공한다.
일부 스탠다드는 판본에 따라 화성이 다르다. 확신이 낮은 곡은 널리 가르쳐지는 교육용
버전을 싣고 그 사실을 곡의 approach 에 한국어로 명시했다.
개발 환경의 네트워크 정책이 유튜브를 차단해 영상 ID 의 생존을 확인할 수 없었다.
깨진 임베드는 없는 것보다 나쁘므로, 추측한 ID 를 하나도 싣지 않았다.
현재 모든 영상은 videoId: null 이고 채널명 + 정밀 검색어 딥링크로 렌더링된다.
임베드를 살리려면 두 단계가 필요하다. 검색어를 영상 ID 로 해석하고(resolve), 그 ID 가 살아 있는지 확인한다(verify).
# 1단계 + 2단계 한 번에. 키는 인자로 넘기면 OS 를 가리지 않는다
npm run verify:media -- --resolve --write --key=발급받은_키
# 이미 ID 가 채워져 있다면 생존 확인만 (키 불필요)
npm run verify:media -- --write환경변수로 주고 싶다면:
| 셸 | 명령 |
|---|---|
| Windows CMD | set YOUTUBE_API_KEY=키 |
| Windows PowerShell | $env:YOUTUBE_API_KEY="키" |
| macOS / Linux / Git Bash | export YOUTUBE_API_KEY=키 |
VAR=value 명령 한 줄 형태는 Windows CMD 에서 동작하지 않는다.
키를 --key= 인자로 넘기면 npm 배너와 셸 히스토리에 남는다. 유튜브 읽기 전용
키라 위험은 낮지만, 신경 쓰인다면 환경변수를 쓰거나 npm run --silent 로 배너를
없애고 실행 후 히스토리를 지운다.
API 키는 Google Cloud Console 에서
YouTube Data API v3 를 사용 설정하고 발급한다. 무료 할당량 10,000 units/일,
search.list 1회당 100 units 이므로 58개 항목이면 5,800 units — 하루치 안에 든다.
검색 1등 결과를 무조건 받아들이지 않는다. 항목에 선언된 channel 과 실제 결과의
채널명이 일치할 때만 채택하고, 불일치하면 그 항목은 검색 폴백으로 남긴다 —
엉뚱한 영상을 임베드하는 것이 링크 없는 것보다 나쁘기 때문이다.
유튜브에 닿지 않는 환경에서는 아무것도 승격하지 않고 정상 종료한다 — 검증 실패와 네트워크 차단을 구분하기 위해서다.
승격 후에는 반드시 npm test 와 npm run smoke 를 다시 돌린다.
src/
├─ data/ 콘텐츠 (순수 데이터). types.ts 가 단일 타입 계약
├─ lib/ 도메인 엔진 (React 를 모른다)
├─ components/ 렌더링만
└─ routes/ 화면 (라우트 단위 코드 분할)
docs/ 기획·커리큘럼·검수·아키텍처 문서
.claude/agents/ 개발 프로세스별 에이전트 정의 17종
scripts/ 미디어 검증
lib/ 는 components/ 를 import 하지 않는다. components/ 는 계산하지 않는다.
화면은 대학 LMS 구조를 따른다 — 강의실 → 강좌(강의계획서 + 주차별 목차) → 차시. 메뉴는 네 개뿐이다(강의실 · 연습 랩 · 자료실 · 내 진도). 차시 하나에 학습목표·개념· 교수법·드릴·곡·필청·영상·평가·검수가 번호 순서로 들어가므로 학습 중에 메뉴를 돌아다닐 일이 없다.
자세한 설계 결정: docs/05-ARCHITECTURE.md
| 문서 | 내용 |
|---|---|
docs/00-MASTER-PROMPT.md |
마스터 스펙 — 모든 에이전트의 공통 브리프 |
docs/01-PRD.md |
제품 요구사항 · 페르소나 · 지표 |
docs/02-CURRICULUM.md |
9레벨 계열화 원리와 주리 기준 |
docs/03-IA-UX.md |
정보구조 · 핵심 루프 · UX 라이팅 · 접근성 |
docs/04-REVIEW-PROTOCOL.md |
검수 프로토콜 · 루브릭 · 정직성 규칙 |
docs/05-ARCHITECTURE.md |
아키텍처와 핵심 설계 결정 |
docs/06-SOURCES.md |
참고 문헌 · 인용 정책 · 저작권 |
docs/07-ROADMAP.md |
로드맵 (v2 = MIDI 입력 채점) |
docs/08-DESIGN-SYSTEM.md |
디자인 시스템 — 토큰·타이포·표면·모션·접근성 |
docs/09-PEDAGOGY.md |
교수법 레이어 — 18가지 방법과 모듈 이식 규칙 |
.claude/agents/ 에 웹 서비스 개발 프로세스의 각 기능을 담당하는 에이전트 17종이 정의되어 있다.
기획 product-strategist · 학습설계 learning-scientist · 교육과정 jazz-curriculum-architect ·
집필 jazz-theory-author · 레퍼토리 repertoire-curator · 청음 listening-curator ·
미디어 media-curator · 검수 faculty-reviewer · UX ux-architect ·
디자인 design-system-engineer · 프론트엔드 frontend-engineer ·
음악엔진 music-engine-engineer · 오디오 audio-engineer · QA qa-engineer ·
접근성 a11y-i18n-engineer · 배포 release-engineer · 문서 tech-writer
각 정의는 그 역할이 무엇을 반려하는가까지 명시한다. 예를 들어 repertoire-curator 는
멜로디를 포함한 산출물을 폐기하고, faculty-reviewer 는 실존 인물 사칭을 금지한다.
학습용 도구다. 교재의 개념 체계를 참조했을 뿐 어떤 기관의 승인·인증·제휴도 받지 않았다. 상업적 재배포 전에 레퍼토리 화성 데이터의 저작권 지위를 각 관할에서 별도로 검토할 것.