CS 퀴즈 문항 풀 대폭 확장 + 신규 5분야 + 'ALL'(전체 랜덤) 필터

요약CS 퀴즈(/quiz) 문항을 150→350(5분야×30 → 10분야×30+확장)으로 대폭 확장하고 분야 'ALL'(전체 랜덤) 필터를 추가했다. Wave A(인프라): QuizCategory enum 신규 5종 + Palette가 globals.css에 신규 5분야 CSS 변수(WCAG AA 직접 검증) 추가 + category-meta 아이콘/var 매핑. Wave B+C(콘텐츠): 신규 5분야 각 20문항 + 기존 5분야 각 30→50문항(HARD 불균형 보강), 전역 id 유니크 350, 병렬 Curator 10에이전트 산출. Wave D('ALL' 필터): getQuestionsByFilter/getRandomQuestions가 category: 'ALL' 수용, QuizStart PillRadioGroup 'ALL' prepend(신규 토큰 0). Wave E(테스트): +22 tests, 전역 1555 PASS. 교훈: 파일당 1에이전트 병렬화, 작은따옴표 내 영문 아포스트로피 구문 에러, within() 스코프 조회, 메타 필터 옵션 토큰 0 패턴. 프론트 전용, merge≠라이브.

날짜
영향도높음

목표

  • CS 퀴즈(/quiz) 문항을 150 → 350개로 대폭 확장한다 (5분야 × 30 → 10분야, 기존 5분야도 각 30→50문항 보강).
  • 신규 5분야(컴퓨터 구조·디자인 패턴·웹·보안·AI)를 추가하고 각 분야 CSS 토큰·아이콘을 WCAG AA 기준으로 정립한다.
  • 분야 선택에 'ALL'(전체 랜덤) 필터를 추가해 사용자가 모든 분야를 섞어 퀴즈를 풀 수 있게 한다.
  • 프론트 전용, 순수 데이터/UI 확장 — merge ≠ 라이브(재배포 후 라이브 검증은 quiz-ui-verification 런북 이월에 합류).

배경

Sprint 215부터 구축된 CS 퀴즈는 Sprint 221~224에서 UI·접근성·UX가 정석화되었으나, 문항 풀은 여전히 5분야 × 30문항 = 150개로 제한적이었다. 사용자가 한 분야를 반복하면 금방 소진되고, 분야를 고정하지 않고 전체를 섞어 연습하는 시나리오도 불가했다.

Sprint 227은 이 두 갭을 동시에 해소한다:

  1. 분야 확장: 기존 네트워크·운영체제·데이터베이스·알고리즘·자료구조 5분야에 컴퓨터 구조·디자인 패턴·웹·보안·AI 5분야를 추가.
  2. 'ALL' 필터: 분야 선택 PillRadioGroup에 'ALL'(전체 랜덤) 옵션을 추가해 전 분야 350문항 풀에서 무작위 출제.

결정

D1. 신규 5분야 enum·CSS 토큰·아이콘 (Wave A)

QuizCategory enum에 5종 추가:

  • COMPUTER_ARCHITECTURE / DESIGN_PATTERN / WEB / SECURITY / AI

Paletteglobals.css에 신규 5분야 --quiz-cat-*-color / --quiz-cat-*-bg CSS 변수 20줄(라이트+다크)을 추가했다. WCAG AA 4.5:1+ 대비비를 직접 검증:

분야라이트(전경)대비비다크(전경)기존 5 hue와 구분
arch#B453094.81#FBBF24앰버 톤
dp#BE185D5.78#F472B6핑크 톤
web#4338CA7.56#818CF8인디고 톤
sec#B91C1C6.19#F87171레드 톤
ai#4D7C0F4.78#A3E635라임 톤

category-meta.ts에 신규 5분야 lucide 아이콘(CircuitBoard / Shapes / Globe / ShieldCheck / BrainCircuit)과 var 슬러그 매핑 추가.

i18n categories 객체에 신규 5키(ko+en) + categories.ALL 키 추가.

D2. 대규모 콘텐츠 병렬 생성 (Wave B+C)

Curator 10에이전트를 병렬 구동해 파일당 1에이전트 방식으로 문항을 생성했다:

  • 신규 5분야 각 20문항 (7E/7M/6H): computer-architecture.ts / design-pattern.ts / web.ts / security.ts / ai.ts
  • 기존 5분야 각 30→50문항 (+20): 특히 HARD 불균형 보강(network HARD 4→17, os 5→17, database 7→17, 각 16E/17M/17H 목표)

index.ts ALL_QUESTIONS에 5분야 합산 → QUIZ_CATEGORIES 10분야, 전역 id 유니크 350개 달성.

통합 시 발견·수정: database.ts·os.ts 영문 텍스트에서 작은따옴표 문자열 내 미이스케이프 아포스트로피(Brewer's, process's) 2건 → 쌍따옴표로 전환해 구문 에러 해소.

D3. 'ALL' 필터 추가 (Wave D)

index.ts getQuestionsByFilter / getRandomQuestionscategory: QuizCategory | 'ALL'을 수용한다:

  • 'ALL': ALL_QUESTIONS 전체 풀에서 출제 (기존 난이도 'ALL' 패턴 미러링)
  • 기존 분야별 필터링 로직 무변경

QuizStart 분야 PillRadioGroup'ALL' 옵션을 prepend:

  • Shuffle 아이콘 + primary 톤
  • 신규 디자인 토큰 0getOptionStyle'ALL'undefined 반환(기존 분야 카테고리 메타에 없는 옵션이므로 가드 처리)
  • 기본 선택값 'ALL'로 변경

page.tsx Session.category / start 파라미터에 'ALL' 전파. 저장 키는 ALL::difficulty 자동 생성. stats 집계는 'ALL' 키 무시(QUIZ_CATEGORY_META own-key 검증, 메타 모드).

D4. 테스트 전면 갱신 (Wave E)

테스트 파일변경 내용
QuizStart.test전면 갱신 — 분야·난이도 두 '전체' 라벨 중복 → within() radiogroup 스코프 조회, 기본 분야 'ALL' 반영, ALL 분야 신규 4테스트
index.test+5 — ALL 필터 동작 검증
data-integrity.test신규 +12 — 350문항 유니크 id·카테고리·bilingual 무결성
category-meta.test신규 5분야 var 슬러그 검증
page.test키 갱신(ALL 기본 선택 반영)

전역: 1533 → 1555 tests (+22).

구현

총 atomic commit (start 66820e0):

커밋에이전트내용
229da66Palette + HeraldWave A — QuizCategory +5, globals.css 20줄, category-meta 아이콘/var, i18n 신규 5키+ALL
f8660d1Curator×10 + HeraldWave B+C — 신규 5분야 각 20문항, 기존 5분야 각 +20(HARD 보강), index.ts ALL_QUESTIONS 통합, 아포스트로피 2건 수정
09dc639HeraldWave D — getQuestionsByFilter/getRandomQuestions 'ALL' 수용, QuizStart 'ALL' prepend, page.tsx 전파, stats 'ALL' 무시
2912955Herald + LibrarianWave E — 테스트 전면 갱신 +22, data-integrity.test 신규, ADR sprint-227 KR+EN, README 164→165

검증

  • tsc: 오류 0 (아포스트로피 수정 포함)
  • next lint (rtk proxy 실측): 0 errors / 487 warnings (전부 기존 인라인 토큰 var() 경고, 신규 0)
  • jest: 152 suites / 1555 PASS (+22, 전 실패 0)
  • 글로벌 커버리지: lines 88.03% / branches 79.37% (게이트 83/71 통과)
  • quiz 컴포넌트·데이터: lines 100% / branches 98.59% (data-integrity /* istanbul ignore */ 분기 제외)
  • next build: ✓ /[locale]/quiz 84.8kB (Sprint 224 40.2kB → 증가: 350문항 bilingual 데이터가 클라이언트 번들에 포함되는 기존 아키텍처 특성, 하단 교훈 ⑤ 참조)
  • ADR 게이트: index count (sprint 165) / adr-en coverage (KR/EN 1:1) / adr-links 0 broken / doc-refs no broken

Critic 교차 리뷰

  • 도구: Codex codex-cli 0.130.0, codex review --base 66820e0 -c model=gpt-5.5
  • 라운드: 2

R1 — [P2] 1건: 프론트 기본 분야 'ALL' + 신규 5분야가 백엔드 quiz-record DTO allowlist(기존 5분야)에서 거부 → 로그인 사용자 finish()saveResult(best-effort, 에러 swallow)가 조용히 실패해 best 기록 미저장·merge-up 누락. "these sessions appear to complete normally but their best records are never saved or merged up."fcb1800에서 identity entity enum +5 / identity·gateway DTO allowlist = 10분야 + 'ALL' / 회귀 spec(gateway+12·identity+13)로 해소. DB 컬럼 varchar(30)이라 마이그레이션 불필요.

R2 — CLEAN (P-finding 0): "The changes type-check across the frontend, gateway, and identity service, and the updated category/ALL flow appears consistently propagated through data, UI, and persistence DTOs. I did not find a discrete introduced bug that would warrant an inline finding." (Codex가 frontend·gateway·identity tsc를 직접 실행해 확인.)

종합 판정: ✅ 머지 가능 — R1 P2(백엔드 allowlist 누락) 수정 후 R2 CLEAN. 전역 1555 PASS + 백엔드 회귀 spec, 커버리지·ADR 게이트 전 통과.