// 이 파일이 하는 일: "코드 리뷰와 리팩터링 전략" 코스 — 고급 과정의 종착점.
// 동작을 바꾸지 않고 구조를 개선하는 규율(리팩터링)에서 출발해, 코드 냄새 목록,
// 작은 단계 기법, 우선순위 정하기, 리뷰의 진짜 목적, 좋은 리뷰 실천을 거쳐,
// 앞 11강에서 배운 설계·성능·보안·운영 관점을 하나의 리뷰 체크리스트로 통합한다.
// 프레이밍은 "혼자 잘 짜는 사람"에서 "팀이 잘 만들게 하는 사람"으로의 전환.
// 학습 포인트: API 호출이 없는 '내용 고정' 페이지다. 스타일은 styles/global.css의
// 가이드 전용 클래스(step-card, code-block, tip 등)를 재사용하고 색은 var(--*)만 쓴다(하드코딩 금지).
// 예제 코드는 JSX 중괄호/백틱 충돌을 피하려고 파일 상단의 백틱 문자열 상수로 정의한다.

import { Link } from 'react-router-dom';

// ── 예제 코드 상수들 ──
// 학습 포인트: 리뷰·리팩터링은 언어보다 '판단'이 핵심이라, 예제도 표·디프·체크리스트
// 같은 텍스트 형태를 주로 쓴다. 코드가 필요한 곳은 파이썬풍 의사코드로 적었다.

const CODE_TWO_HATS = `기능 개발 모자 🎩                리팩터링 모자 🧢
─────────────────────────────────────────────────────
새 동작을 추가한다               동작은 그대로, 구조만 바꾼다
테스트를 '새로' 쓴다             기존 테스트가 '계속' 통과해야 한다
결과: 사용자가 차이를 느낀다      결과: 사용자는 차이를 못 느낀다

규율: 한 커밋 안에서 두 모자를 동시에 쓰지 않는다.
"기능도 넣고 김에 정리도 했어요" 커밋은 —
버그가 나면 어느 쪽 때문인지 아무도 모르게 됩니다.`;

const CODE_SAFETY_NET = `리팩터링의 순서 — 안전망이 먼저다

① 바꾸려는 코드에 테스트가 있는가?
     없다  →  먼저 '현재 동작'을 고정하는 테스트를 쓴다
     있다  →  ②로
② 테스트를 돌려 전부 초록불인지 확인한다
③ 구조를 '조금' 바꾼다 (한 번에 한 기법)
④ 테스트를 다시 돌린다 — 초록불이면 커밋, 빨간불이면 즉시 되돌린다
⑤ ③~④를 반복한다

포인트: 테스트 없는 리팩터링은 리팩터링이 아니라 '수정 도박'입니다.
초록불 → 초록불 사이를 짧은 보폭으로 건너는 것이 전부예요.`;

const CODE_SMELL_MAP = `코드 냄새 → 리팩터링 기법 매핑 (자주 만나는 것부터)

냄새                  증상                          처방
──────────────────────────────────────────────────────────────
긴 함수               스크롤해야 끝이 보인다          함수 추출(Extract Function)
큰 클래스             이름에 Manager·Util·Service만   클래스 분리, 책임별로 쪼개기
중복 코드             복붙 흔적, 세 번째 복사 중       공통 함수로 추출 후 호출
기능 편애             남의 데이터만 주무르는 함수      그 데이터가 사는 곳으로 이동
매직 넘버             코드에 3, 86400, 0.1 같은 숫자   이름 있는 상수로 추출
긴 매개변수 목록       인자가 5개 이상                 객체 하나로 묶기
주석으로 때우기        "여기서 X를 함" 주석 필수        이름을 바꿔 주석을 지운다

앞 강의와의 연결:
· N+1 쿼리(성능 강의)      → '반복문 속 쿼리'라는 냄새의 DB 버전
· God Service(설계 강의)   → '큰 클래스' 냄새가 서비스 계층에서 자란 것`;

const CODE_EXTRACT = `# 함수 추출 — 가장 자주 쓰는 기본기 (의사코드)

# before: 주문 처리 함수 하나가 검증·계산·알림을 다 한다 (긴 함수 냄새)
def 주문_처리(주문):
    if 주문.수량 <= 0: raise 검증오류("수량은 1 이상")
    if not 주문.회원: raise 검증오류("로그인이 필요합니다")
    금액 = 주문.단가 * 주문.수량
    if 주문.회원.등급 == "VIP": 금액 = 금액 * 0.9
    알림서비스.보내기(주문.회원, "주문 완료: " + str(금액))

# after: 세 덩어리에 '이름'을 붙여 꺼냈다 — 동작은 완전히 동일
def 주문_처리(주문):
    주문_검증(주문)
    금액 = 결제금액_계산(주문)
    주문완료_알림(주문.회원, 금액)

# 무엇이 좋아졌나: 함수 본문이 곧 목차가 됐다.
# 리뷰어는 세 줄만 읽고 흐름을 파악하고, 의심 가는 덩어리만 파고든다.`;

const CODE_SMALL_COMMITS = `커밋을 작게 쪼개기 — 되돌리기 쉬운 역사 만들기

나쁜 예 (커밋 1개):
  fix: 정산 버그 수정 및 코드 정리        ← 300줄 변경, 뭐가 뭔지 모름

좋은 예 (커밋 4개, 순서대로):
  test: 정산 금액 계산 현재 동작 고정      ← ① 안전망 먼저
  refactor: 정산 계산 함수 추출            ← ② 구조만 변경 (동작 동일)
  refactor: 매직 넘버 0.033을 수수료율 상수로  ← ③ 역시 구조만
  fix: VIP 등급 수수료 누락 버그 수정      ← ④ 이제야 '동작' 변경 1줄

효과: ④에서 문제가 생기면 ④만 되돌리면 된다(revert).
IDE 자동 리팩터링(이름 변경·함수 추출)은 참조를 기계가 전부 따라가므로
손으로 찾아 바꾸기(Ctrl+H)보다 훨씬 안전하다 — 단, 커밋은 사람이 쪼갠다.`;

const CODE_PRIORITY = `어디부터 리팩터링할까 — 변경 빈도 × 코드 상태

                     │  코드가 깨끗함        코드가 지저분함
─────────────────────┼──────────────────────────────────────
자주 바뀌는 파일      │  그대로 두기          ★ 최우선 정리 대상
거의 안 바뀌는 파일   │  그대로 두기          급하지 않음(놔둬도 됨)

이유: 지저분해도 아무도 안 여는 코드는 이자를 물리지 않는다.
빚(기술 부채)의 이자는 '그 코드를 만질 때마다' 나가기 때문에,
자주 만지는 곳의 빚부터 갚는 게 이득이 가장 크다.

변경 빈도는 감이 아니라 기록으로 확인한다:
  git log --since="3 months ago" --name-only 로 파일별 등장 횟수 세기
  → 상위 파일 = 우리 팀의 '뜨거운 길목'`;

const CODE_PR_CONVENTION = `우리 팀 커밋·PR 매너 (한국어 컨벤션)

커밋 메시지 — 접두어 + 한국어 요약:
  feat: 관심종목 알림 조건 추가
  fix: 정산 반올림 오차 수정
  refactor: 주문 검증 로직 함수 추출
  docs: 배포 절차에 롤백 단계 보강

PR 설명에 꼭 들어갈 3가지:
  · 무엇을: 한 줄 요약 (제목만 읽어도 알게)
  · 왜: 배경 — 이슈 번호, 장애 링크, 요구 근거
  · 어떻게 확인: 리뷰어가 따라 할 수 있는 재현/검증 절차

리뷰 코멘트 — 사람이 아니라 코드를 향해 쓴다:
  ✗ "이렇게 짜시면 안 되죠"                (사람을 평가)
  ○ "이 함수가 검증과 저장을 같이 해서,     (코드를 서술)
     검증만 실패하는 케이스 테스트가 어려워 보여요.
     검증부를 추출하면 어떨까요?"           (근거 + 제안)`;

const CODE_REVIEW_CHECKLIST = `리뷰어 체크리스트 — 관점별로 한 바퀴 (블로킹/제안 표시)

[설계]
  □ 이 변경이 한 가지 일만 하는가? (PR이 크면 분리 요청 — 블로킹)
  □ 새 의존성 방향이 기존 계층 규칙을 거스르지 않는가? — 블로킹
  □ 이름만 읽고 역할을 알 수 있는가? — 제안

[성능]
  □ 반복문 안에 쿼리·외부 호출이 없는가? (N+1) — 블로킹
  □ 큰 목록에 페이징·상한이 있는가? — 블로킹
  □ 캐시를 얹을 만한 반복 조회인가? — 제안

[보안]
  □ 입력 검증이 서버 쪽에 있는가? (프론트 검증만으론 부족) — 블로킹
  □ 시크릿·토큰이 코드/로그에 남지 않는가? — 블로킹
  □ 권한 확인이 '누락된 경로'는 없는가? — 블로킹

[운영]
  □ 실패 시 로그로 원인 추적이 되는가? — 제안
  □ 롤백이 가능한 변경인가? (스키마 변경 주의) — 블로킹

블로킹 = 머지 전에 반드시 해결. 제안 = 다음에 개선해도 됨(작성자 재량).
이 구분을 코멘트에 명시하면 "다 고쳐야 하나요?" 소모전이 사라진다.`;

const CODE_FINAL_LADDER = `12강의 사다리 — 전부 리뷰 한 판에서 만난다

  설계 강의    →  "이 책임, 이 계층에 있는 게 맞나?"
  성능 강의    →  "이 쿼리, 데이터가 10배 늘면 버티나?"
  보안 강의    →  "이 입력, 악의적인 사용자가 보내면?"
  운영 강의    →  "이거 장애 나면 새벽에 로그만 보고 찾을 수 있나?"
  테스트 강의  →  "이 변경, 안전망이 같이 왔나?"
  이번 강의    →  위 질문들을 '체크리스트'로 만들어 매 PR마다 돌린다

좋은 팀의 비밀은 천재가 아니라 '반복되는 좋은 질문'입니다.
체크리스트는 그 질문을 개인의 컨디션에서 떼어내 팀의 습관으로 만들어요.`;

// ── 이 페이지 안에서만 쓰는 작은 부품들 ──
// 학습 포인트: 같은 모양이 반복되면 컴포넌트로 뽑는다. props만 바꿔 재사용.
function Section({ n, title, sub, children }) {
  return (
    <section className="step-card" id={`sec-${n}`}>
      <div className="step-head">
        <span className="step-num">{n}</span>
        <div>
          <h3>{title}</h3>
          {sub && <span className="step-sub">{sub}</span>}
        </div>
      </div>
      <div className="step-body">{children}</div>
    </section>
  );
}

function Code({ children }) {
  return <pre className="code-block"><code>{children}</code></pre>;
}

const SECTIONS = [
  { n: 1, label: '리팩터링이라는 규율' },
  { n: 2, label: '코드 냄새 목록' },
  { n: 3, label: '작은 단계 리팩터링' },
  { n: 4, label: '우선순위' },
  { n: 5, label: '리뷰의 목적' },
  { n: 6, label: '좋은 리뷰 실천' },
  { n: 7, label: '종합: 잘 만드는 팀' },
];

export default function Lv3CodeReviewRefactoringPage() {
  return (
    <div>
      {/* 히어로: 이 코스가 고급 과정 전체의 종착점임을 선언 */}
      <div className="hero">
        <div className="eyebrow">Course · 고급 과정</div>
        <h1>코드 리뷰와<br />리팩터링 전략</h1>
        <p>
          여기까지 오면서 설계·성능·보안·운영을 하나씩 배웠어요. 그런데 그 지식이 실제로
          팀의 코드 품질을 지키는 현장은 어디일까요? 바로 <strong>매일 열리는 PR 리뷰</strong>와{' '}
          <strong>일상의 리팩터링</strong>입니다. 이 과정의 종착점 — 앞 11강의 관점을{' '}
          <strong>리뷰 한 판에 녹여내는</strong> 법을 익혀 봅시다.
        </p>
        <div className="chip-row">
          <span className="chip">예상 소요 75분</span>
          <span className="chip">실습: 우리 팀 코드리뷰 체크리스트 만들기</span>
          <span className="chip">선수 지식: 고급 과정 앞 강의들</span>
        </div>
      </div>

      {/* 섹션 바로가기 — 학습 포인트: SECTIONS 배열 하나로 목차를 생성(데이터 → 화면) */}
      <nav className="chip-row" style={{ marginBottom: 18 }}>
        {SECTIONS.map((s) => (
          <a key={s.n} className="chip" href={`#sec-${s.n}`}>
            <b>{s.n}</b> {s.label}
          </a>
        ))}
      </nav>

      <Section n={1} title="리팩터링이라는 규율" sub="동작은 그대로, 구조만 좋아진다">
        <p>
          <strong>리팩터링(Refactoring)</strong>의 정의는 한 줄이에요.{' '}
          <strong>"겉으로 보이는 동작을 바꾸지 않으면서, 코드의 내부 구조를 개선하는 것."</strong>{' '}
          입력이 같으면 출력도 같아야 하고, 사용자는 아무 변화도 느끼지 못해야 합니다.
          "정리하는 김에 버그도 고쳤어요"는 리팩터링이 아니에요 — 그 순간 동작이 바뀌었으니까요.
        </p>
        <p>
          그래서 첫 번째 규율은 <strong>모자를 하나만 쓰는 것</strong>입니다. 기능을 추가할 땐
          기능 개발 모자를, 구조를 고칠 땐 리팩터링 모자를 — <strong>한 커밋 안에서 둘을 섞지
          않아요.</strong> 섞는 순간, 나중에 버그가 났을 때 "새 기능 때문인지, 정리하다 깨진
          건지" 아무도 구분할 수 없게 됩니다.
        </p>
        <Code>{CODE_TWO_HATS}</Code>
        <p>
          두 번째 규율은 <strong>안전망이 먼저</strong>라는 거예요. "동작이 안 바뀌었다"를
          사람 눈으로 보장할 수는 없습니다. 그걸 보장하는 건 <strong>테스트</strong>예요.
          바꾸려는 코드에 테스트가 없다면, 리팩터링을 시작하기 전에 <strong>현재 동작을
          고정하는 테스트부터</strong> 씁니다. 그다음 초록불 → 작은 변경 → 초록불 확인, 이
          짧은 보폭을 반복하는 게 리팩터링의 전부입니다.
        </p>
        <Code>{CODE_SAFETY_NET}</Code>
        <div className="tip">
          <b>비유</b> 리팩터링은 <strong>영업 중인 가게의 진열대 정리</strong>예요. 손님(사용자)이
          사는 물건(동작)은 그대로인데, 점원(개발자)이 물건을 찾는 속도가 빨라지죠. 진열대를
          엎고 가게를 새로 차리는 것(재작성)과는 완전히 다른 행위입니다 — 그 차이는 섹션 4에서
          다시 봐요.
        </div>
      </Section>

      <Section n={2} title="코드 냄새 목록" sub="고치기 전에 먼저 '맡을' 줄 알아야 한다">
        <p>
          <strong>코드 냄새(Code Smell)</strong>는 "당장 버그는 아니지만, 더 깊은 문제가 있을
          가능성을 풍기는 코드의 특징"이에요. 냄새라는 표현이 절묘한 게, 그 자체로 유죄는
          아니지만 <strong>코를 킁킁거리며 원인을 찾아보라는 신호</strong>거든요. 대표 냄새
          네 가지만 기억해도 리뷰의 눈이 달라집니다.
        </p>
        <p>
          <strong>① 긴 함수</strong> — 한 함수가 검증·계산·저장·알림을 다 해요. 읽는 사람이
          중간에 길을 잃죠. <strong>② 큰 클래스</strong> — 이름이{' '}
          <span className="icode">OrderManager</span>, <span className="icode">CommonUtil</span>{' '}
          같이 두루뭉술하고, 필드와 메서드가 수십 개예요. <strong>③ 중복 코드</strong> —
          같은 로직이 복붙으로 세 군데 살아요. 한 곳만 고치면 나머지 둘이 조용히 낡습니다.{' '}
          <strong>④ 기능 편애(Feature Envy)</strong> — 어떤 함수가 자기 클래스보다{' '}
          <strong>남의 클래스 데이터</strong>를 더 열심히 주물러요. 그 로직은 데이터가 사는
          곳으로 이사 가야 한다는 신호입니다.
        </p>
        <Code>{CODE_SMELL_MAP}</Code>
        <p>
          표의 아래 두 줄을 보세요. 사실 우리는 이미 냄새 훈련을 해 왔어요. 성능 강의에서 잡은{' '}
          <strong>N+1 쿼리</strong>는 "반복문 안의 외부 호출"이라는 냄새의 DB 버전이고, 설계
          강의의 <strong>God Service</strong>는 "큰 클래스" 냄새가 서비스 계층에서 자란
          모습입니다. 냄새 목록은 새 지식이 아니라, <strong>흩어져 있던 감각에 이름을 붙여
          목록으로 만든 것</strong>이에요. 이름이 붙어야 리뷰 코멘트로 쓸 수 있습니다.
        </p>
        <div className="tip">
          <b>냄새 ≠ 즉시 수리</b> 냄새를 발견했다고 그 자리에서 다 고치는 게 아니에요.
          기록해 두고(이슈, TODO 주석보다는 이슈가 좋아요) <strong>섹션 4의 우선순위</strong>로
          갚을 순서를 정합니다. 냄새 감지와 수리 결정은 별개의 판단이에요.
        </div>
      </Section>

      <Section n={3} title="작은 단계 리팩터링" sub="추출·이름 변경·인라인, 그리고 잘게 쪼갠 커밋">
        <p>
          리팩터링 기법은 책 한 권 분량이지만, 실무 체감 8할은 세 가지 기본기예요.{' '}
          <strong>① 추출(Extract)</strong> — 긴 함수에서 덩어리를 꺼내 이름을 붙입니다.{' '}
          <strong>② 이름 변경(Rename)</strong> — <span className="icode">data2</span>,{' '}
          <span className="icode">temp</span>를 역할이 보이는 이름으로 바꿉니다. 이름이 좋아지면
          주석이 필요 없어져요. <strong>③ 인라인(Inline)</strong> — 반대로, 한 줄짜리 의미 없는
          함수·변수는 다시 안으로 밀어 넣어 단계를 줄입니다. 추출의 되감기 버튼이죠.
        </p>
        <Code>{CODE_EXTRACT}</Code>
        <p>
          이 기본기들은 <strong>IDE의 자동 리팩터링</strong>으로 하는 게 원칙이에요. IntelliJ나
          VS Code에서 함수 추출·이름 변경을 실행하면, <strong>프로젝트 전체의 참조를 기계가
          전부 따라가며</strong> 바꿔 줍니다. 손으로 찾아 바꾸기(Ctrl+H)는 문자열이 우연히 같은
          엉뚱한 곳까지 바꿔 버릴 수 있어요. 기계가 잘하는 일은 기계에게 맡기고, 사람은{' '}
          <strong>무엇을 추출하고 뭐라고 이름 붙일지</strong>라는 판단에 집중합니다.
        </p>
        <p>
          그리고 판단의 마지막 조각 — <strong>커밋을 작게 쪼개기</strong>. 리팩터링 커밋과 동작
          변경 커밋을 분리하면, 문제가 생겼을 때 <strong>해당 커밋 하나만 되돌리면(revert)</strong>{' '}
          됩니다. 섞인 300줄 커밋은 되돌리는 순간 멀쩡한 변경까지 같이 날아가요.
        </p>
        <Code>{CODE_SMALL_COMMITS}</Code>
        <div className="tip">
          <b>직접 확인해 보기</b> 에디터에서 아무 함수나 블록을 선택하고 리팩터링 메뉴(IntelliJ는{' '}
          <span className="icode">Ctrl+Alt+M</span>, VS Code는 전구 아이콘)를 눌러 보세요.
          함수 추출이 참조까지 한 번에 정리되는 걸 눈으로 보면, 다시는 손으로 안 하게 됩니다.
        </div>
      </Section>

      <Section n={4} title="리팩터링 우선순위" sub="빚은 이자가 나가는 곳부터 갚는다">
        <p>
          냄새 목록을 만들면 항상 같은 고민이 옵니다. "이걸 언제 다 고치지?" — 답은{' '}
          <strong>다 고치지 않는 것</strong>이에요. 기술 부채의 이자는{' '}
          <strong>그 코드를 만질 때마다</strong> 나갑니다. 아무도 안 여는 낡은 코드는 지저분해도
          이자가 0원이에요. 그러니 <strong>자주 바뀌는 곳부터</strong>(변경 빈도 × 코드 상태)
          정리하는 게 투자 대비 효과가 가장 큽니다.
        </p>
        <Code>{CODE_PRIORITY}</Code>
        <p>
          일상에서는 <strong>보이스카웃 규칙</strong>이 이 우선순위를 자동으로 실행해 줘요.
          "캠핑장을 떠날 때는 왔을 때보다 조금 더 깨끗하게" — 코드에 적용하면,{' '}
          <strong>어떤 파일을 고치러 들어갔다면 나올 때 아주 조금만 더 깨끗하게 하고
          나온다</strong>는 규칙입니다. 이름 하나 고치기, 매직 넘버 하나 상수로 빼기 정도요.
          어차피 자주 만지는 파일에 자주 들어가게 되니, 뜨거운 길목일수록 저절로 자주
          정리됩니다.
        </p>
        <p>
          마지막으로 <strong>전면 재작성의 유혹</strong>을 경계해야 해요. 지저분한 코드를 보면
          "이건 갈아엎는 게 빠르겠다"는 생각이 들죠. 하지만 낡은 코드에는{' '}
          <strong>수년치 버그 수정과 엣지 케이스 처리</strong>가 배어 있고, 재작성은 그걸 전부
          다시 발견해야 합니다. 재작성하는 몇 달 동안 기능 개발은 멈추고, 새 코드는 새 버그를
          데려와요. 정말 재작성이 답인 경우도 있지만(플랫폼 수명 종료 등), 대부분은{' '}
          <strong>돌아가는 시스템을 작은 단계로 고쳐 가는 쪽</strong>이 이깁니다.
        </p>
        <div className="tip">
          <b>비유</b> 재작성은 <strong>살면서 집을 허물고 새로 짓기</strong>예요. 그동안 어디서
          살죠? 리팩터링은 <strong>살면서 방 하나씩 고치기</strong>고요. 불편해도 집은 계속
          집이어야 합니다 — 서비스는 재작성 중에도 계속 돌아가야 하니까요.
        </div>
      </Section>

      <Section n={5} title="리뷰의 목적" sub="결함 발견은 절반, 나머지 절반은 지식 공유">
        <p>
          코드 리뷰를 "버그 잡는 관문"으로만 알고 있다면 절반만 아는 거예요. 리뷰의 효용은
          크게 셋입니다. <strong>① 결함 발견</strong> — 물론 중요하죠. 그런데{' '}
          <strong>② 지식 공유</strong>가 못지않게 커요. 리뷰를 거친 코드는{' '}
          <strong>최소 두 사람</strong>이 이해하는 코드가 됩니다. 담당자가 휴가를 가도, 퇴사해도
          팀이 멈추지 않는 이유죠. <strong>③ 표준 정착</strong> — 네이밍, 계층 규칙, 에러 처리
          방식 같은 팀의 합의가 리뷰 코멘트를 통해 매일 조금씩 전파되고 단단해집니다.
        </p>
        <p>
          그리고 리뷰 문화의 제1원칙 — <strong>사람이 아니라 코드를 리뷰한다.</strong>{' '}
          "당신이 틀렸다"가 아니라 "이 코드가 이런 상황에서 이렇게 동작할 것 같다"로 말해요.
          작성자도 마찬가지로, 코멘트를 <strong>내 실력에 대한 판정이 아니라 코드에 대한
          정보</strong>로 받습니다. 이 분리가 무너지면 리뷰는 방어전이 되고, 방어전이 된 팀에선
          아무도 솔직한 코멘트를 달지 않아요 — 그때부터 리뷰는 요식 행위가 됩니다.
        </p>
        <Code>{CODE_PR_CONVENTION}</Code>
        <p>
          우리 팀은 커밋 메시지·PR 설명·리뷰 코멘트를 <strong>한국어</strong>로 쓰고, 커밋
          접두어(<span className="icode">feat:</span> <span className="icode">fix:</span>{' '}
          <span className="icode">refactor:</span> <span className="icode">docs:</span>)로 변경의
          성격을 먼저 밝힙니다. 접두어 덕에 <span className="icode">git log</span>만 훑어도
          "동작이 바뀐 커밋"과 "구조만 바뀐 커밋"이 구분돼요 — 섹션 1의 두 모자 규율이 기록에도
          남는 거죠.
        </p>
        <div className="tip">
          <b>리뷰는 저자에게도 이득</b> 신기하게도, "누가 읽는다"는 사실만으로 코드가 좋아져요.
          PR을 올리기 전에 스스로 한 번 훑으며 설명을 쓰다 보면 본인이 먼저 문제를 발견하는
          일이 흔합니다. 이걸 <strong>셀프 리뷰</strong>라고 하고, 리뷰어의 시간을 아껴 주는
          기본 매너이기도 해요.
        </div>
      </Section>

      <Section n={6} title="좋은 리뷰 실천" sub="작은 PR, 재현 가능한 근거, 블로킹과 제안의 구분">
        <p>
          좋은 리뷰의 첫째 조건은 리뷰어가 아니라 <strong>작성자</strong>가 만듭니다 — 바로{' '}
          <strong>작은 PR</strong>이에요. 변경 1,000줄짜리 PR은 아무리 성실한 리뷰어도 대충 훑고
          "LGTM"을 누르게 됩니다(다 읽을 수 없으니까요). 통계적으로도 리뷰 품질은 변경량이
          커질수록 급격히 떨어져요. 대략 <strong>200~400줄 이내</strong>, "한 가지 일"만 하는
          PR이 리뷰가 가장 정확합니다. 커밋을 쪼갰듯 PR도 쪼개는 거예요.
        </p>
        <p>
          둘째는 <strong>재현 가능한 근거</strong>입니다. "느려질 것 같아요"보다{' '}
          <strong>"이 쿼리를 1만 건 데이터로 돌려 보니 3.2초 걸렸어요, 실행계획은 이렇습니다"</strong>가
          강해요. 리뷰 코멘트도, PR 설명도 <strong>따라 해 볼 수 있는 절차와 숫자</strong>가
          붙으면 논쟁이 짧아집니다. 취향의 문제는 취향이라고 인정하고, 사실의 문제는 사실로
          판정하는 거죠.
        </p>
        <p>
          셋째, 리뷰어는 <strong>관점 체크리스트</strong>를 돌립니다. 즉흥적으로 눈에 띄는
          것만 보면 그날 컨디션에 따라 품질이 출렁여요. 설계 → 성능 → 보안 → 운영, 관점별로
          한 바퀴 도는 습관이 누락을 막습니다.
        </p>
        <Code>{CODE_REVIEW_CHECKLIST}</Code>
        <p>
          체크리스트 끝의 구분을 눈여겨보세요. <strong>블로킹(blocking)</strong>은 "이건 머지
          전에 반드시 해결돼야 한다"(보안 구멍, N+1, 롤백 불가), <strong>제안(non-blocking)</strong>은
          "나는 이렇게 하겠지만 당신 판단에 맡긴다"(네이밍 취향, 사소한 개선)예요. 모든 코멘트가
          블로킹처럼 읽히면 작성자는 지치고 PR은 며칠씩 묶입니다. <strong>코멘트마다 어느 쪽인지
          명시</strong>하는 것만으로 리뷰 속도와 분위기가 눈에 띄게 좋아져요.
        </p>
        <div className="tip">
          <b>승인의 의미</b> "Approve"는 "완벽하다"가 아니라 <strong>"내가 이 코드에 같이 책임을
          진다"</strong>는 뜻이에요. 그래서 대충 누르는 LGTM이 위험한 겁니다. 반대로, 제안 코멘트만
          남았다면 승인과 함께 맡기는 게 좋아요 — 완벽주의로 PR을 붙들면 팀 전체가 느려집니다.
        </div>
      </Section>

      <Section n={7} title="종합: 잘 만드는 팀" sub="12강의 관점을 하나의 체크리스트로">
        <p>
          이제 사다리 꼭대기에서 지나온 계단을 내려다볼 차례예요. 설계 강의는 "책임이 제자리에
          있는가"를, 성능 강의는 "데이터가 늘어도 버티는가"를, 보안 강의는 "악의적인 입력에도
          안전한가"를, 운영 강의는 "장애가 나면 추적할 수 있는가"를 물었죠. 그 질문들이 각각
          따로 노는 게 아니라 — <strong>매 PR의 리뷰에서 한꺼번에 던져질 때</strong>, 비로소
          팀의 품질이 됩니다.
        </p>
        <Code>{CODE_FINAL_LADDER}</Code>
        <p>
          그래서 이 강의의 실습이 <strong>체크리스트 만들기</strong>인 거예요. 섹션 6의 예시를
          출발점 삼아, 앞 강의들에서 <strong>여러분이 실제로 데인 것들</strong>(우리 코드에서
          만난 N+1, 우리가 놓쳤던 검증 누락)을 항목으로 옮기세요. 남의 체크리스트를 복사하면
          장식이 되고, <strong>우리 팀의 사고가 담기면 도구</strong>가 됩니다. 그리고 실제 PR
          하나에 적용해 보세요 — 항목이 너무 많으면 줄이고, 매번 걸리는 게 있으면 자동화(린터·
          CI)로 내리는 겁니다.
        </p>
        <p>
          마지막으로, 체크리스트는 <strong>완성품이 아니라 살아 있는 문서</strong>예요. 장애를
          겪으면 항목이 하나 늘고, 린터가 대신 잡게 되면 항목이 하나 줄어요. 이렇게{' '}
          <strong>회고 → 반영 → 자동화</strong>의 고리를 도는 것이 지속적 개선 문화고, "잘 만드는
          팀"의 실체입니다. 천재 한 명이 아니라, <strong>반복되는 좋은 질문</strong>이 품질을
          만들어요.
        </p>
        <div className="tip">
          <b>실습 과제</b> ① 섹션 6 체크리스트를 바탕으로 <strong>우리 팀용 10~15개 항목</strong>을
          추려 문서로 만드세요(블로킹/제안 표시 포함). ② 최근 머지된 실제 PR 하나를 골라 그
          체크리스트로 <strong>다시 리뷰</strong>해 보세요. ③ 원 리뷰가 놓친 항목이 있었다면,
          왜 놓쳤는지(항목이 없어서? 급해서?)를 한 줄로 기록하세요 — 그 한 줄이 체크리스트
          버전 2의 재료입니다.
        </div>
      </Section>

      {/* 마무리 카드: 고급 과정 전체의 마무리 — 학습 센터로 안내 */}
      <div className="step-card">
        <div className="step-body">
          <h3 style={{ marginBottom: 6 }}>🧭 여기까지 왔다면</h3>
          <p className="muted">
            고급 과정의 사다리를 전부 올랐습니다. 서비스를 <strong>만드는</strong> 사람에서,
            설계·성능·보안·운영을 저울에 올려 <strong>잘 만드는</strong> 사람으로 — 그리고 그
            감각을 리뷰와 체크리스트로 <strong>팀에 전파하는</strong> 사람으로 한 계단씩
            올라왔어요. 이제 남은 건 반복입니다. 오늘 만든 체크리스트로 내일의 PR을 리뷰하고,
            데일 때마다 항목을 고치세요. 다른 과정의 지도가 궁금하다면{' '}
            <Link to="/learn"><strong>학습 센터</strong></Link>로 돌아가 다음 여정을 골라 봅시다.
          </p>
        </div>
      </div>
    </div>
  );
}
