# 수습용 실전 티켓 풀 34 · AWESOMEDEV

티켓 고르는 기준

## 수습용 티켓의 4가지 조건

- 1
  망가뜨려도 복구 쉬운 것. 롤백 가능하고, 스테이징에서 검증 가능하고, 결제·인증·개인정보 같은 민감 영역이 아닐 것.
- 2
  범위가 한 문장으로 설명되는 것. "이 화면의 이 부분을 이렇게" — 파일 3~4개 이내로 끝나는 크기. 아키텍처를 이해해야만 하는 건 아직 아님.
- 3
  완료 조건(DoD)을 명확히 쓸 수 있는 것. "되면 이렇게 보인다/동작한다"를 미리 적을 수 없으면 수습용이 아님.
- 4
  실제로 가치 있는 것. 연습용 가짜 일이 아니라, 머지되면 정말 제품이 나아지는 일. (이게 동기부여의 핵심이에요)

주지 말 것: 운영 DB 마이그레이션 · 인증/권한 로직 · 결제 · 배포 설정 · 고객사 SLA가 걸린 긴급 건 · "리팩터링 알아서" 같은 범위 무한 티켓.

🖥️

## 프론트엔드 (React) — 7개

화면에서 보이는 것부터. 결과가 눈에 보여서 첫 실전에 가장 좋아요.
FE-01

### 빈 상태(Empty State) 화면 추가

★0.5~1일
무엇을데이터가 없을 때 휑하게 비는 목록/테이블에 "아직 항목이 없어요 + 안내 문구/버튼"을 보여주기.
찾는 법각 화면에서 데이터 0건으로 조회해 보기. `.map()` 돌리는 목록 중 length가 0일 때 분기가 없는 곳이 후보.
완료 조건0건일 때 지정된 문구·아이콘 노출, 1건 이상이면 기존과 동일, 스크린샷 첨부된 PR.
멘토 준비대상 화면 지정, 문구 확정(디자이너 수습생과 협업시키면 좋음).
🎯 우리 건코딩 문제 필터 결과 0건 빈 상태 — FE-04(필터)와 짝 티켓. 코딩 문제 목록 `frontend/src/pages/CodingPage.jsx`에 FE-04로 언어·난이도 필터가 생기면 "조건에 맞는 문제 0건"이라는 새 상태가 태어난다. 0건일 때 "조건에 맞는 문제가 없어요" 안내 + [필터 초기화] 버튼을 보여줄 것. FE-04 담당자와 둘이 짝으로 진행 — 남의 코드 위에 얹는 연습.
FE-02

### 로딩 표시(스피너/스켈레톤) 추가

★0.5~1일
무엇을API 응답을 기다리는 동안 아무것도 안 보이는 화면에 로딩 상태 표시 넣기.
찾는 법네트워크를 느리게(개발자도구 throttling) 하고 화면 이동 — 흰 화면이나 깜빡임이 보이는 곳이 후보.
완료 조건로딩 중 표시 노출, 로드 완료 시 자연스럽게 교체, 에러 시 로딩이 무한히 남지 않음.
멘토 준비기존 공용 로딩 컴포넌트가 있으면 알려주기(새로 만들지 재사용할지).
🎯 우리 건공용 로딩 컴포넌트(스켈레톤) 도입 — "불러오는 중…" 텍스트가 9곳에 하드코딩되어 있다(`grep -rn "불러오는 중" frontend/src`로 직접 세어 보기). `components/Loading.jsx`를 만들어 카드 모양 스켈레톤으로 통일하고, 우선 대시보드(`DashboardPage.jsx`)와 학습 문서(`DocsPage.jsx`) 2곳만 교체. 나머지는 후속 티켓.
FE-03

### 폼 입력 유효성 검사 보강

★1일
무엇을빈 값·형식 오류를 제출 후에야 알려주는 폼에, 입력 시점 안내 메시지 추가(예: 이메일 형식, 필수값).
찾는 법각 폼에 일부러 빈 값/이상한 값 넣고 제출해 보기 — 서버 에러로만 알게 되는 폼이 후보.
완료 조건정의된 규칙별 에러 문구 노출, 통과 시 정상 제출, 에러 문구는 한국어로 친절하게.
멘토 준비검사 규칙 목록 확정(무엇을 필수로, 어떤 형식으로).
🎯 우리 건비밀번호 변경: 새 비번 = 현재 비번 차단 — `frontend/src/pages/ChangePasswordPage.jsx` — 지금은 새 비밀번호를 현재 것과 똑같이 넣어도 통과된다(바꾼 게 아닌데 바꿨다고 안내됨). 프론트 validate에 "현재와 다른 비밀번호를 써 주세요" 추가 + 백엔드 `AuthService.changePassword`에도 같은 검사(프론트는 우회 가능 — 서버가 최종 방어선이라는 걸 몸으로 익히는 티켓).
FE-04

### 목록 정렬/필터 옵션 추가

★★2일
무엇을있는 목록 화면에 정렬(최신순/이름순) 또는 필터(상태별) 드롭다운 1개 추가.
찾는 법운영/관리 화면 중 항목이 20개 이상 쌓이는 목록에서 사용자가 스크롤로만 찾는 곳.
완료 조건옵션 변경 시 목록 갱신, 새로고침해도 기본값 정상, 기존 기능 회귀 없음.
멘토 준비정렬/필터 기준 확정, 서버 쿼리 지원 여부 확인(클라이언트 정렬로 충분한지).
🎯 우리 건코딩 문제 목록에 언어·난이도 필터 — `frontend/src/pages/CodingPage.jsx` — 문제 25개(JS 12·SQL 5·Java 8)가 한 줄로 길게만 나온다. 언어(전체/JS/SQL/Java)와 난이도(쉬움/보통/어려움) 필터 칩을 추가. `useState` 2개와 `.filter()`면 충분 — 새 API 불필요. 퀴즈 페이지의 탭 UI(`tabs` 클래스)를 참고. 완료되면 FE-01(0건 빈 상태)로 이어진다.
FE-05

### 에러 화면/토스트 메시지 개선

★0.5~1일
무엇을"Error" 또는 영문 원문이 그대로 뜨는 실패 메시지를, 사용자가 이해할 한국어 안내로 교체.
찾는 법서버 꺼두고/네트워크 끊고 주요 동작 실행 — 알 수 없는 문구가 뜨는 곳 수집.
완료 조건실패 상황별 지정 문구 노출, 콘솔 에러는 유지(디버깅용), 문구 목록 문서화.
멘토 준비상황별 문구 톤 가이드 한 줄(사과·원인·해결 순).
🎯 우리 건세션 만료 안내 메시지 — `frontend/src/api/client.js`의 401 인터셉터가 `/login`으로 보낼 때 아무 설명이 없다 — 학생 입장에선 "쓰다가 갑자기 로그인 화면"이다. 인터셉터에서 `/login?expired=1`로 보내고, `LoginPage.jsx`가 쿼리스트링(`useSearchParams`)을 읽어 "세션이 만료됐어요. 다시 로그인해 주세요"를 폼 위에 표시.
FE-06

### 모바일 화면 깨짐 수정

★★1~2일
무엇을좁은 화면에서 넘치거나 겹치는 요소(테이블·버튼 줄바꿈 등) 1~2군데 반응형 수정.
찾는 법개발자도구 모바일 뷰(375px)로 주요 화면 전부 훑기 — 가로 스크롤 생기는 곳이 후보.
완료 조건375px·768px·데스크톱 3구간 스크린샷 첨부, 기존 데스크톱 레이아웃 변화 없음.
멘토 준비깨지는 화면 목록 미리 수집(학생이 찾는 것부터 시키면 반나절 추가).
🎯 우리 건상단 메뉴 가로 스크롤 힌트 — 모바일에서 상단 메뉴(`global.css`의 `.topnav-menu`)가 "코딩 문…"처럼 잘리는데, 스크롤바까지 숨겨져 있어(`::-webkit-scrollbar`) 더 있다는 표시가 전혀 없다. 오른쪽 가장자리 그라데이션 페이드(`mask-image` 또는 `::after`)로 "더 있음"을 암시할 것. CSS만으로 해결 — JS 불필요.
FE-07

### 공통 컴포넌트로 중복 UI 정리

★★2~3일
무엇을거의 똑같은 버튼/카드/모달이 여러 파일에 복붙돼 있는 것을 컴포넌트 1개로 추출해 교체.
찾는 법비슷한 JSX 덩어리를 검색(클래스명·문구로 grep) — 3곳 이상 반복되는 블록이 후보.
완료 조건추출한 컴포넌트 1개 + 기존 사용처 전부 교체, 화면 픽셀 변화 없음(전후 스크린샷).
멘토 준비대상 지정 필수(범위 폭주 방지). props 설계는 착수 계획서에서 함께 리뷰.
🎯 우리 건페이지 히어로 공통 컴포넌트 추출 — `hero compact` 블록(eyebrow + 제목 + 설명)이 7개 페이지에 복붙되어 있다. `components/PageHero.jsx`로 추출(`eyebrow·title·children` props 설계)하고 2~3개 페이지부터 적용. "언제 컴포넌트로 뽑는가(3번 반복되면)"와 props 설계를 연습하는 티켓.
⚙️

## 백엔드 (Spring Boot) — 6개

서버 쪽 안전 지대. 응답·검증·로그처럼 되돌리기 쉬운 것 위주.
BE-01

### API 응답에 필드 1개 추가

★1일
무엇을화면에서 필요해진 값(예: 등록일, 개수, 상태명)을 기존 조회 API 응답에 추가하고 프론트 반영까지.
찾는 법프론트에서 두 번 요청해서 조합하거나, 하드코딩으로 때운 값이 있는 화면의 API가 후보.
완료 조건응답 DTO에 필드 추가, 기존 호출부 회귀 없음, 화면에 값 표시, API 문서/주석 갱신.
멘토 준비추가할 필드와 출처(어느 테이블/계산) 지정.
🎯 우리 건코딩 문제 목록에 시도 횟수(attempts) 내려주기 — `CodingController`의 `ProblemSummary` record에는 `attempts`가 없다(상세 `ProblemDetail`에는 있음). 목록 응답에 추가하고, 프론트 `CodingPage.jsx` 목록에 "3번째 도전 중" 배지 표시. record 필드 추가 → 서비스 → 화면까지 세로로 관통하는 첫 티켓으로 적당.
BE-02

### 요청 검증(Validation) 보강

★1일
무엇을이상한 값(음수, 빈 문자열, 초과 길이)이 들어와도 500으로 터지는 API에 검증 어노테이션과 400 응답 추가.
찾는 법등록/수정 API에 일부러 이상한 값 보내 보기 — 500이 뜨는 곳이 후보.
완료 조건정의된 규칙 위반 시 400 + 명확한 메시지, 정상 값은 기존대로, 테스트 1개 추가.
멘토 준비검증 규칙 표(필드·규칙·에러 메시지) 초안.
🎯 우리 건코딩 제출 코드 길이 제한 — `CodingController.SubmitRequest`의 `code` 필드에 길이 제한이 없다 — 수 MB를 보내도 DB가 그대로 받는다. `@Size(max = 20000)`(약 500줄) + 컨트롤러 `@Valid` 확인 + 프론트 초과 시 안내. "받을 수 있는 것"과 "받아도 되는 것"은 다르다는 검증 원칙 티켓.
BE-03

### 에러 로그 메시지 개선

★0.5~1일
무엇을"error occurred" 수준의 로그에 무엇이/어떤 값으로/왜 실패했는지 문맥 추가 (단, 개인정보는 제외).
찾는 법최근 장애/문의 때 로그 보고도 원인을 몰랐던 지점을 선임에게 물어 수집.
완료 조건지정 지점 로그에 식별자·원인 포함, 개인정보(전화번호 등) 마스킹 확인.
멘토 준비개인정보 로깅 금지 규칙 브리핑(이 티켓이 보안 교육 기회).
🎯 우리 건검증 실패(400) 응답 메시지 한국어 통일 — `@Valid` 실패 시 응답 message가 "Validation failed for object='loginRequest'…" 영어 원문이다(기본기 감사에서 발견). `@RestControllerAdvice` + `MethodArgumentNotValidException` 핸들러를 만들어 첫 번째 필드 에러의 한국어 메시지(DTO에 이미 다 적어 둠)를 `{"message": "..."}`로 내려주기. 전역 예외 처리 입문 티켓.
BE-04

### 조회 API 신규 작성 (단순 CRUD의 R)

★★2~3일
무엇을기존 테이블에서 조건으로 조회하는 GET API 1개를 컨트롤러→서비스→리포지토리 계층대로 신규 작성.
찾는 법관리/통계 화면에서 "이 목록도 보고 싶다"고 미뤄둔 요구가 후보 (신규 화면과 세트로 주면 FE 수습생과 협업 티켓이 됨).
완료 조건API 동작(페이징 포함 여부 명시), 계층 구조 준수, 테스트 1개, API 명세 공유.
멘토 준비대상 테이블·조건·응답 형태 스펙 한 장. 참고할 기존 유사 API 지정.
🎯 우리 건학생 한 명의 과제 제출 모아보기 API — 멘토 화면(`MentorController`)에는 전체 제출 최신순(`GET /api/mentor/submissions`)만 있고 학생별로 모아보기가 없다. `GET /api/mentor/students/{userId}/submissions` 신규 작성(단순 R) + `MentorPage.jsx`에서 학생 이름 클릭 시 필터. `hasRole("MENTOR")` 권한이 어떻게 걸리는지(SecurityConfig) 함께 확인.
BE-05

### 매직 넘버/하드코딩 값 설정으로 추출

★1일
무엇을코드에 박힌 숫자·문자열(페이지 크기, 제한 횟수, 안내 문구)을 상수/설정 파일로 추출.
찾는 법서비스 코드에서 의미를 알 수 없는 숫자 리터럴 grep — 선임이 "이건 바뀔 수 있는 값"이라고 확인해준 것만.
완료 조건동작 변화 없음(값 동일), 상수 이름이 의미를 설명, 어디서 왜 쓰는지 주석.
멘토 준비추출 대상 목록 지정(전체 수색은 범위 폭주).
🎯 우리 건로그인 잠금 정책을 설정값으로 추출 — `LoginAttemptService`의 5회/5분이 `static final` 상수로 박혀 있다. `security.login-lock.max-failures`·`lock-minutes`를 `application.yml`에 `${ENV:기본값}` 패턴으로 추출(`@Value` 주입) — 컨테이너 재빌드 없이 정책을 조정할 수 있게. 기존 테스트(`LoginAttemptServiceTest`)가 깨지지 않게 유지하는 것까지가 완료 조건.
BE-06

### 느린 조회 1건 개선 (N+1 / 불필요 조회 제거)

★★2~3일
무엇을목록 조회 시 항목마다 추가 쿼리가 나가는 지점 1개를 한 번에 가져오도록 개선.
찾는 법쿼리 로그 켜고 목록 화면 열기 — 같은 모양 쿼리가 수십 번 반복되는 곳이 후보.
완료 조건쿼리 수 전/후 비교 기록(예: 51→2), 결과 데이터 동일함 검증, 개선 설명 PR에 작성.
멘토 준비대상 지점 확정 필수. JPA 페치 전략을 함께 리뷰(혼자 두면 위험한 티켓).
🎯 우리 건N+1 지점 측정하고 개선하기 — `MentorController`·`CodingService` 주석에 "학생 4~5명이라 괜찮다(N+1)"고 적어 둔 지점이 있다(`grep -rn "N+1" backend/src`). SQL 로그를 켜고(`logging.level...SQL: DEBUG`) 멘토 화면을 열어 쿼리가 몇 번 나가는지 직접 센 뒤, 학생 100명 가정으로 IN 절/JOIN FETCH로 줄이기. 측정→개선→재측정 수치를 PR에 첨부.
🧪

## 품질 · 테스트 · 문서 — 4개

티가 덜 나지만 팀이 정말 고마워하는 일. 코드 이해 훈련으로도 최고예요.
QA-01

### 버그 재현 → 수정 → 회귀 테스트

★★2~3일
무엇을알려진 경미한 버그 1개를 재현 절차 문서화 → 원인 찾아 수정 → 재발 방지 테스트 추가.
찾는 법이슈 트래커/메모에 쌓인 "급하지 않은 버그" 목록에서 데이터 파손 위험 없는 것.
완료 조건재현 절차 문서, 수정 PR, 실패했다가 통과하는 테스트 1개.
멘토 준비버그 후보 2~3개 골라두기(1개는 막힐 경우의 교체용).
🎯 우리 건잠재 버그: 문서 뷰어 notFound 상태 미리셋 — `frontend/src/pages/DocViewerPage.jsx` — `notFound`가 한 번 true가 되면 되돌리는 코드가 없다. 지금은 문서 간 직행 링크가 없어 안 터질 뿐(전수 감사에서 "결함 실재, 현재 도달 불가"로 판정된 건). 재현 경로를 직접 구성(없는 slug 접속 → 정상 문서로 이동)해 버그를 드러내고, slug 변경 시 상태 리셋으로 수정. "도달 불가한 결함은 언제 고치는가"를 토론해 보는 티켓.
QA-02

### 핵심 함수에 단위 테스트 추가

★1~2일
무엇을테스트가 없는 계산/변환 함수(금액 포맷, 날짜 계산, 상태 판정 등)에 정상·경계·예외 케이스 테스트 작성.
찾는 법if 분기가 3개 이상인데 테스트 0개인 함수를 서비스 코드에서 찾기.
완료 조건케이스 5개 이상(경계값 포함), 전부 통과, 테스트 이름만 봐도 뭘 검증하는지 알 것.
멘토 준비대상 함수 지정 + 기존 테스트 파일 1개를 본보기로 알려주기.
🎯 우리 건SubmissionService·CourseProgressService 단위 테스트 — 이 두 서비스만 테스트가 0개다(`backend/src/test/.../service/` 목록과 대조). `ProgressServiceTest` 패턴(Mockito + 한국어 `@DisplayName`) 그대로 — 재제출 시 상태가 SUBMITTED로 돌아오는지, 없는 과제 404, 빈 내용 400 등 분기마다 1개. 전체 테스트가 25개+로 늘어나는 걸 확인.
QA-03

### README / 로컬 실행 가이드 현행화

★1일
무엇을본인이 1주차에 환경 세팅하며 막혔던 지점을 살려, 실행 가이드를 "처음 온 사람도 따라 하면 되는" 상태로 갱신.
찾는 법본인의 1주차 세팅 메모가 그대로 재료. (이 티켓은 사실상 준비돼 있음)
완료 조건문서만 보고 다른 수습생이 클린 세팅 성공(상호 검증), 시크릿 값은 문서에 안 씀.
멘토 준비문서 위치 지정, 시크릿 기재 금지 재강조.
🎯 우리 건README 현행화 — 따라 하면 실행되게 — `README.md`에 텔레그램 알림·로그인 잠금·내 정보·주소찾기 등 최근 기능이 하나도 없다(grep 0건). README만 보고 처음부터 로컬 실행을 따라 해 보고, 막히는 지점(환경변수·포트·시드 계정)을 전부 고쳐 쓰기. "문서는 새 팀원이 검증한다" — 여러분이 그 새 팀원이다.
QA-04

### 미사용 코드/주석 정리 (지정 범위)

★0.5~1일
무엇을멘토가 지정한 폴더 안에서 주석 처리된 죽은 코드, 안 쓰는 import, 미사용 함수 제거.
찾는 법에디터/린트의 unused 경고 + 주석 블록 검색. 삭제 전 "정말 안 쓰나" 확인 방법을 배우는 게 포인트.
완료 조건빌드·테스트 통과, 삭제 목록을 PR 설명에 정리, 확신 없는 건 삭제 대신 질문.
멘토 준비범위 폴더 지정(전체 수색 금지), 리뷰 꼼꼼히.
🎯 우리 건미사용 import·변수 정리 (frontend/src/pages 한정) — `npm run lint` 결과를 기준으로 `frontend/src/pages` 디렉터리의 미사용 import·변수만 정리. 범위를 벗어난 "김에 수정"은 금지 — 정리 PR은 작아야 리뷰가 된다는 걸 배우는 티켓. lint 경고 개수 before/after를 PR 설명에 기록.
🎨

## 디자이너 티켓 — 3개

디자인 수습생용. 개발 수습생의 FE 티켓과 짝지으면 협업 훈련이 됩니다.
DZ-01

### 빈 상태·에러 상태 디자인 세트

★1~2일
무엇을FE-01·FE-05와 짝: 빈 상태/에러 상태의 일러스트·문구·레이아웃을 디자인하고 개발자에게 핸드오프.
완료 조건시안 + 문구 + 간격/색 명세, 개발 구현 결과가 시안과 일치하는지 확인까지.
멘토 준비기존 디자인 톤 참고 자료 전달.
🎯 우리 건빈 상태·오류 화면 디자인 세트 — FE-01·FE-05와 짝. 플랫폼 공통 상태 3종(데이터 없음 / 검색 결과 없음 / 오류) 일러스트+문구 톤을 피그마로 설계. 현재 화면들은 회색 텍스트 한 줄뿐이다. 개발 수습생과 협업해 1종은 실제 반영까지 — 디자인이 코드가 되는 전 과정을 경험.
DZ-02

### 화면 1개 UX 개선 제안 → 반영

★★2~3일
무엇을2주차 UI 인벤토리에서 찾은 불편 지점 1개를 개선 시안으로 만들고, 팀 리뷰 통과분을 개발 티켓으로 넘기기.
완료 조건현행 문제 정의 → 개선 시안(2안) → 선택안 핸드오프 문서 → 구현 확인.
멘토 준비개선 후보 화면 2~3개 승인해 두기(고객사 승인 필요 화면 제외).
🎯 우리 건퀴즈 결과 화면 UX 관찰·개선 제안 — 퀴즈 결과 화면(`QuizPage.jsx` 채점 후) — 틀린 문제를 다시 보는 흐름을 동료 2명이 쓰는 걸 관찰하고(어디서 머뭇거리나), 개선안 1장(before/after 스케치)을 멘토에게 제안 → 승인되면 개발 티켓으로 전환. "관찰 → 제안 → 반영"의 UX 사이클 한 바퀴.
DZ-03

### UI 컴포넌트 정리표 (미니 디자인 시스템)

★★2~3일
무엇을서비스에서 쓰이는 버튼·입력·카드·색·글자 크기를 한 장으로 정리한 "컴포넌트 정리표" 제작 — FE-07(공통 컴포넌트화)의 근거 자료가 됨.
완료 조건컴포넌트별 변형 수 집계, 통일 제안 포함, 팀 공유 발표 10분.
멘토 준비범위(화면 몇 개까지) 지정.
🎯 우리 건미니 디자인 시스템 정리표 — `global.css`의 버튼(btn·btn-primary·btn-ghost)·배지(badge-*)·칩·카드 변형을 화면 캡처로 전수 수집해 피그마 정리표로. 색·간격·글자 크기 토큰까지 뽑으면 이 플랫폼의 미니 디자인 시스템 v0.1이 된다. DZ-01·FE-07과 자연스럽게 연결.
🔬

## 고도화 점검에서 나온 추가 티켓 (14건)

2026-07-17 다중 에이전트 점검으로 발굴 · 운영·보안·테스트·UX·교육 전반. 위 20개와 같은 방식으로 배정하세요.
OP-01

### 컨테이너 헬스체크 + 의존성 조건

★1일
무엇을backend·caddy 컨테이너에 HEALTHCHECK를 넣어 "죽지는 않았지만 응답을 멈춘(hang)" 상태를 감지한다. caddy의 `depends_on`을 `condition: service_healthy`로 올린다.
찾는 법docker-compose.prod.yml에 postgres만 healthcheck가 있음. backend엔 무인증 200 GET이 없으니 actuator 대신 wget/nc로 8080 응답 존재만 확인하는 가벼운 형태로.
완료 조건backend·caddy에 healthcheck 추가, `docker ps`에 (healthy) 표시, 일부러 hang 상황을 만들어 재기동되는지 확인.
멘토 준비이미 있는 헬스체크 알림(deploy/healthcheck.sh)과 역할이 다름을 설명 — 이건 컨테이너 자동복구, 그건 사람 알림.
OP-02

### push 시 자동 테스트 게이트 (Gitea Actions) ✅ 구현됨

★★확장
무엇을기본 CI는 이미 구축돼 있다(`.gitea/workflows/ci.yml` — push마다 백엔드 `mvn test` + 프론트 `npm run build`, deploy/CI.md 참고). 이 티켓은 그 위에 얹는 확장이다.
찾는 법Gitea 웹 → 저장소 → Actions 탭에서 초록/빨강 체크를 직접 본다. `deploy/CI.md`로 러너 구조를 이해한다.
완료 조건아래 중 하나: (1) 일부러 실패하는 테스트를 push해 빨간 X를 확인하고 되돌리기, (2) QA-05의 프론트 테스트를 CI에 `npm test` 단계로 추가, (3) Maven·npm 캐시로 실행 시간 단축, (4) main 브랜치 보호(체크 통과해야 merge).
멘토 준비deploy/CI.md의 '함정 메모'(Maven archive·clone add-host·checkout node)를 함께 읽어 "CI가 왜 이렇게 생겼나"를 설명.
SEC-01

### 보안·권한 계약 통합테스트 (@WebMvcTest)

★★2~3일
무엇을SecurityConfig의 URL→권한 규칙을 검증하는 통합테스트를 작성한다: (1) 비로그인 `/api/mentor/students`→401, (2) STUDENT 세션→403, (3) MENTOR→통과, (4) `/api/auth/login·signup`→permitAll 도달.
찾는 법backend/src/test는 전부 서비스 단위테스트라 컨트롤러/보안 계약 테스트가 0건. 권한은 SecurityConfig 한 곳에만 있고 검증이 없다.
완료 조건`@WebMvcTest` + `spring-security-test`로 위 5가지 단언, 전부 초록.
멘토 준비spring-security-test 의존성 추가, @MockBean으로 서비스 대체하는 패턴 안내.
SEC-02

### 민감 PII 작업 감사로그 ✅ 구현됨

★1일
무엇을전체 인적사항 CSV 다운로드·멘토 비번 재설정·명단 조회에 "행위자(멘토)+대상 학생 id+시각"을 `log.info`로 남긴다. 세션 Authentication에서 행위자를 얻는다.
찾는 법백엔드 log.* 호출은 LoginAttemptService·TelegramNotifier뿐. mentor/auth/profile 경로엔 감사로그가 전무 — 누가 전체 명단을 받았는지 추적 불가.
완료 조건위 세 경로에 감사로그 추가, 실제 호출 후 로그에 행위자·대상·시각이 남는지 확인.
멘토 준비미성년 PII라 추적이 왜 중요한지 설명. TelegramNotifier로 "CSV 전체 다운로드됨" 알림을 함께 보내도 좋음.
SEC-03

### 공개 쓰기 엔드포인트 레이트리밋 ✅ 구현됨

★★2일
무엇을이미 있는 LoginAttemptService 패턴(IP+창시간)을 재사용해 `POST /api/auth/signup`과 `PUT /api/profile/me`에 분당 상한을 건다.
찾는 법signup은 무인증으로 DB에 계정을 쓰고 성공마다 텔레그램 알림까지 쏜다 — 남용 시 가짜계정·알림 폭주 표면.
완료 조건짧은 시간에 반복 요청 시 429가 나는지 확인, 정상 사용은 영향 없음.
멘토 준비로그인 잠금(LoginAttemptService) 코드를 먼저 읽게 하고, 재사용/일반화하는 방향으로 안내.
SEC-04

### 개인정보 열람·내보내기 접근 로그 ✅ 구현됨 (SEC-02에 통합)

★0.5일
무엇을`/api/mentor/students`(전체 인적사항)와 `/export.csv`에 접근 한 줄(사용자·행위·시각) 로그를 남긴다. SEC-02와 짝.
찾는 법두 경로 모두 누가·언제 접근했는지 기록이 0. 유출 시 추적 근거가 없다.
완료 조건두 경로 접근 시 로그 한 줄이 남는지 확인.
멘토 준비"접근 감사" 개념 설명. 소규모라 법적 강제성은 낮지만 습관으로 배우는 주제.
SEC-05

### 의존성 취약점 손으로 점검해 보기

★0.5일
무엇을backend는 `mvn versions:display-dependency-updates`(또는 OWASP dependency-check) 1회, frontend는 `npm audit`를 돌려 결과를 읽고 STUDY.md에 정리한다.
찾는 법지금 버전은 대체로 최신이라 급한 건 없다 — "취약점이 어떻게 딸려 오는지"와 audit 읽는 법을 배우는 게 목적.
완료 조건audit 결과 요약 + "무엇을 언제 올려야 하나" 판단 한 단락을 STUDY.md에 추가.
멘토 준비CI 자동화가 아니라 "손으로 한 번 돌려 읽기"로 범위 한정.
QA-05

### 프론트 첫 테스트 — 채점 함수 gradeSql 검증

★1일
무엇을Vitest를 devDependency로 추가하고 test 스크립트 1줄 + 최소 설정 후, `frontend/src/lib/runSql.js`의 순수함수 `gradeSql` 단위테스트를 작성한다.
찾는 법frontend에 테스트 러너가 아예 없다. gradeSql은 SQL 통과/실패를 결정하는데, 서버는 그 판정을 그대로 믿고 저장한다 — 조용히 깨지면 진도가 잘못 기록된다.
완료 조건행 개수 불일치→false, orderMatters=false 순서무시 동등, true일 때 순서 다르면 오답, 값만 비교 — 4케이스 초록.
멘토 준비runJs/runSql은 Worker·WASM 의존이라 이번 범위 밖(후속 티켓)임을 명시.
QA-06

### 죽은 퀴즈 사본 정리 (seed/quiz 71개)

★0.5일
무엇을`seed/quiz/` 폴더(코스별 71개 파일)를 제거하거나, 최소한 "실사용은 quizzes.json"이라는 안내를 남겨 단일 출처로 정리한다.
찾는 법실제 적재는 `SeedDataLoader`가 `seed/quizzes.json`(단일 355문항)만 읽는다. quiz/ 폴더는 어디서도 참조 안 됨(grep 0건) — 고쳐도 앱에 반영 안 되는 함정.
완료 조건quiz/ 삭제(또는 명확한 주석/README), quizzes.json이 단일 출처임을 확인.
멘토 준비"편집하기 좋아 보이는 죽은 파일"이 왜 위험한지 — 교재로서 가장 나쁜 함정임을 설명.
FE-08

### 학습센터 진도율 로딩 가드 (0% 깜빡임)

★0.5일
무엇을`LearnHubPage`에 loading 가드를 추가해, fetch 도착 전 순간적으로 "0% · 모든 코스 미완료"가 보였다 갱신되는 깜빡임을 없앤다.
찾는 법completedSlugs를 빈 Set으로 두고 즉시 렌더. 대시보드 위젯·CourseShell은 로딩 처리가 있는데 여기만 빠짐(감사에서 지적된 일관성의 남은 사례).
완료 조건느린 네트워크(throttling)에서 0% 깜빡임 없이 로딩→실제 진도로 자연스럽게 전환.
멘토 준비대시보드 위젯의 로딩 처리를 참고 예시로 알려주기.
FE-09

### 멘토 '리뷰 대기' 한눈에 보기

★1일
무엇을멘토 화면 상단에 '리뷰 대기 N건' 카운트와 '미검토(SUBMITTED) 우선' 정렬/필터 토글을 추가한다.
찾는 법/mentor/submissions·/mentor/coding-submissions가 최신순 평면 목록이라, 미검토 건을 상태 배지로 눈으로 스캔해야 함.
완료 조건미검토 건수 표시, 토글 시 미검토가 위로 정렬, 8주 누적돼도 놓치지 않음.
멘토 준비개별 타임라인/일괄 피드백은 4명 규모엔 과잉 — 카운트·정렬만으로 충분함을 안내.
FE-10

### '개발 환경 설치 가이드' 진입점 만들기

★0.5일
무엇을대시보드에 '처음이라면: 개발 환경 설치 가이드부터' 배너나 nav의 눈에 띄는 링크 하나를 추가한다.
찾는 법설치 가이드가 학습센터 마지막 카테고리 "부록·도구"의 첫 항목으로만 있고 nav·대시보드에 링크가 없다. 개발 3명이 첫날 스스로 못 찾으면 멘토가 병목.
완료 조건첫 로그인 학생이 대시보드/nav에서 설치 가이드로 한 번에 도달.
멘토 준비온보딩 첫 관문임을 강조. 링크 하나로 해결되는 저비용 개선.
EDU-01

### '웹 보안·인증 기초' 코스 신설

★★2~3일
무엇을학습센터에 웹/애플리케이션 보안(비밀번호 해싱·세션/쿠키·무차별대입·인가) 코스 1개를 신설한다. 이 앱에 이미 있는 구현(BCrypt·changeSessionId·로그인 잠금·쿠키 플래그·서버측 정답 보관)을 읽고 개념화한다.
찾는 법71개 코스에 네트워크 보안(wifi-security·firewall)은 있으나 웹 보안이 없다. 마침 이 저장소가 그 주제의 살아있는 예제다.
완료 조건courseCatalog에 코스 등록 + 코스 페이지(courses/) 작성 + 확인 퀴즈, 실제 코드 참조 포함.
멘토 준비새 이론이 아니라 "있는 코드를 개념으로 잇기"임을 강조. 후반부 실습 티켓감.
EDU-02

### 코딩 문제·캡스톤 문서를 주차별 교육안에 연결

★0.5일
무엇을주차별 문서에 교차참조 추가: (1) 관련 주차(3~4주 자립코딩, 5~6주 티켓)에 '학습센터→코딩 문제로 손 풀기' 링크, (2) week7·8 강의안에서 capstone-demoday 문서 링크.
찾는 법코딩 문제 25개와 capstone-demoday 문서가 주차별 교육안·수습 가이드 어디에도 언급 없음 — 좋은 자료가 사장될 위험.
완료 조건해당 주차 문서에 링크·안내 문장 추가, 1~4주와 5~8주를 잇는 동선이 문서상 연결됨.
멘토 준비멘토가 "언제 무엇을 시킬지" 안내가 목적임을 설명.
구체화 양식

## 티켓 작성 양식 — 이 틀로 실제 티켓을 만드세요

위 패턴에서 찾은 실제 건을 이 양식으로 옮기면 수습생에게 바로 줄 수 있는 티켓이 됩니다. 이슈 트래커에 그대로 복붙해도 돼요.

수습 티켓 양식 (복사해서 사용)

    [제목] (패턴ID) 화면/기능 — 한 줄 요약
           예: (FE-01) 알림 목록 — 빈 상태 화면 추가

    [배경] 왜 필요한가 (1~2문장)
    [할 일] 무엇을 어떻게 (구체적으로)
    [범위] 건드릴 파일/영역 · 건드리지 말 것
    [완료 조건]
      - [ ] 조건 1 (눈으로 확인 가능하게)
      - [ ] 조건 2
      - [ ] PR에 전/후 스크린샷 또는 테스트
    [참고] 비슷한 기존 코드 위치, 참고 문서
    [난이도/예상] ★ or ★★ / 예상 소요
    [멘토] 담당 멘토 이름

배정 트래커

## 티켓 풀 현황판

✅ 2026-07-17 구체화 완료 — 20건 모두 이 학습 플랫폼(mirim-app) 실코드 기준으로 검증했습니다. 이제 5~6주차에 배정만 하면 됩니다. 학생 1명당 5~6주 동안 2~4건이 적당해요.

패턴 | 실제 티켓 제목 | 구체화 | 배정 대상 | 배정일 | 상태
--- | --- | --- | --- | --- | ---
FE-01 | 코딩 문제 필터 결과 0건 빈 상태 | ☑ |  |  |
FE-02 | 공용 로딩 컴포넌트(스켈레톤) 도입 | ☑ |  |  |
FE-03 | 비밀번호 변경: 새 비번 = 현재 비번 차단 | ☑ |  |  |
FE-04 | 코딩 문제 목록에 언어·난이도 필터 | ☑ |  |  |
FE-05 | 세션 만료 안내 메시지 | ☑ |  |  |
FE-06 | 상단 메뉴 가로 스크롤 힌트 | ☑ |  |  |
FE-07 | 페이지 히어로 공통 컴포넌트 추출 | ☑ |  |  |
BE-01 | 코딩 문제 목록에 시도 횟수(attempts) 내려주기 | ☑ |  |  |
BE-02 | 코딩 제출 코드 길이 제한 | ☑ |  |  |
BE-03 | 검증 실패(400) 응답 메시지 한국어 통일 | ☑ |  |  |
BE-04 | 학생 한 명의 과제 제출 모아보기 API | ☑ |  |  |
BE-05 | 로그인 잠금 정책을 설정값으로 추출 | ☑ |  |  |
BE-06 | N+1 지점 측정하고 개선하기 | ☑ |  |  |
QA-01 | 잠재 버그: 문서 뷰어 notFound 상태 미리셋 | ☑ |  |  |
QA-02 | SubmissionService·CourseProgressService 단위 테스트 | ☑ |  |  |
QA-03 | README 현행화 — 따라 하면 실행되게 | ☑ |  |  |
QA-04 | 미사용 import·변수 정리 (frontend/src/pages 한정) | ☑ |  |  |
DZ-01 | 빈 상태·오류 화면 디자인 세트 | ☑ |  |  |
DZ-02 | 퀴즈 결과 화면 UX 관찰·개선 제안 | ☑ |  |  |
DZ-03 | 미니 디자인 시스템 정리표 | ☑ |  |  |
OP-01 | 컨테이너 헬스체크 + 의존성 조건 | ☐ |  |  |
OP-02 | push 시 자동 테스트 게이트 (Gitea Actions) | ☐ |  |  |
SEC-01 | 보안·권한 계약 통합테스트 (@WebMvcTest) | ☐ |  |  |
SEC-02 | 민감 PII 작업 감사로그 | ☐ |  |  |
SEC-03 | 공개 쓰기 엔드포인트 레이트리밋 | ☐ |  |  |
SEC-04 | 개인정보 열람·내보내기 접근 로그 | ☐ |  |  |
SEC-05 | 의존성 취약점 손으로 점검해 보기 | ☐ |  |  |
QA-05 | 프론트 첫 테스트 — 채점 함수 gradeSql 검증 | ☐ |  |  |
QA-06 | 죽은 퀴즈 사본 정리 (seed/quiz 71개) | ☐ |  |  |
FE-08 | 학습센터 진도율 로딩 가드 (0% 깜빡임) | ☐ |  |  |
FE-09 | 멘토 '리뷰 대기' 한눈에 보기 | ☐ |  |  |
FE-10 | '개발 환경 설치 가이드' 진입점 만들기 | ☐ |  |  |
EDU-01 | '웹 보안·인증 기초' 코스 신설 | ☐ |  |  |
EDU-02 | 코딩 문제·캡스톤 문서를 주차별 교육안에 연결 | ☐ |  |  |

배정 팁 — 첫 티켓(5주차)은 ★로 시작해 성공 경험을 만들고, 6주차에 ★★로 올리세요. FE-01+DZ-01, FE-07+DZ-03, BE-04+FE(신규 화면)처럼 짝 티켓으로 주면 협업 평가 재료가 생깁니다. 고객사 코드 반영이 어려운 경우, 사내 도구·내부 프로젝트에서 같은 패턴을 찾아도 좋아요.