mirim-app/frontend/public/docs/week7-detailed.html
AWESOMEDEV 84144a1608 fix(security+a11y): 종합 감사(PMD+5관점, 29에이전트) 확정 12건 수정
[HIGH]
- 로그인 잠금 XFF 스푸핑 우회: X-Forwarded-For leftmost(위조 가능) → rightmost(Caddy가 붙인 실제 IP) 사용
- 멘토 기본 비밀번호 하드코딩 제거: env 미설정 시 SecureRandom 생성 후 로그 1회 출력.
  compose에 MENTOR_INITIAL_PASSWORD 추가
- 클릭 카드 키보드 접근 불가(학습문서 전체): Card에 role=button·tabIndex·Enter/Space·aria-label

[MEDIUM]
- CSV 수식 인젝션: =+-@ 로 시작하는 학생 자유입력 앞에 ' 붙여 엑셀 수식화 차단 (+회귀 테스트)
- 학습문서 17개 <html lang=ko> 골격 주입 (스크린리더 한국어 발음)
- 과제 제출 폼 label htmlFor/id 연결
- 상단 아이콘 링크(👤·🔑) aria-label + 이모지 aria-hidden
- 멘토 제출물 표 행 키보드 접근(role/tabIndex/Enter·Space)
- 배지 amber/teal 글자 대비 4.5:1 확보(테마별 --amber-text/--teal-text)

[LOW]
- 코드에디터 포커스 표시(:focus-within), 문제번호 색 대비(--muted), 카드 :focus-visible
- 폼 오류 메시지 role=alert (스크린리더 즉시 안내)

검증: 테스트 26개 통과, 운영에서 XFF 우회 차단(6회째 429)·카드 role/aria·문서 lang=ko 확인.
PMD 29건은 전부 저심각 스멜로 실질 결함 없음. 각 수정에 원리 학습 주석.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 13:38:30 +09:00

971 lines
60 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>7주차 상세 강의안 — 종합 프로젝트 기획·설계 (멘토용)</title>
<style>
:root {
--paper: #FAFBFD; --card: #FFFFFF; --ink: #101A28; --ink-soft: #46536A;
--ink-faint: #7B8798; --line: #E4E8F0; --line-soft: #EFF2F7;
--primary: #2159C5; --primary-soft: #E5EDFB; --primary-deep: #163F8F;
--amber: #B9772A; --amber-soft: #F6EBDA; --amber-line: #E4C79A;
--teal: #0E8C86; --teal-soft: #E0F1EF;
--rose: #B4463C; --rose-soft: #F7E7E4;
--code-bg: #F1F4F9;
--shadow: 0 1px 2px rgba(16,26,40,.05), 0 8px 24px -12px rgba(16,26,40,.16);
--radius: 14px;
}
@media (prefers-color-scheme: dark) {
:root {
--paper: #0B1017; --card: #131A24; --ink: #E8EDF4; --ink-soft: #A4B0C0;
--ink-faint: #74808F; --line: #263140; --line-soft: #1C242F;
--primary: #6AA0F0; --primary-soft: #172A44; --primary-deep: #AECBF8;
--amber: #DBA25C; --amber-soft: #2C2318; --amber-line: #4A3B23;
--teal: #4FC7BE; --teal-soft: #14302E; --rose: #E08A80; --rose-soft: #331E1B;
--code-bg: #161E28;
--shadow: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.65);
}
}
:root[data-theme="light"] {
--paper: #FAFBFD; --card: #FFFFFF; --ink: #101A28; --ink-soft: #46536A;
--ink-faint: #7B8798; --line: #E4E8F0; --line-soft: #EFF2F7;
--primary: #2159C5; --primary-soft: #E5EDFB; --primary-deep: #163F8F;
--amber: #B9772A; --amber-soft: #F6EBDA; --amber-line: #E4C79A;
--teal: #0E8C86; --teal-soft: #E0F1EF; --rose: #B4463C; --rose-soft: #F7E7E4;
--code-bg: #F1F4F9;
--shadow: 0 1px 2px rgba(16,26,40,.05), 0 8px 24px -12px rgba(16,26,40,.16);
}
:root[data-theme="dark"] {
--paper: #0B1017; --card: #131A24; --ink: #E8EDF4; --ink-soft: #A4B0C0;
--ink-faint: #74808F; --line: #263140; --line-soft: #1C242F;
--primary: #6AA0F0; --primary-soft: #172A44; --primary-deep: #AECBF8;
--amber: #DBA25C; --amber-soft: #2C2318; --amber-line: #4A3B23;
--teal: #4FC7BE; --teal-soft: #14302E; --rose: #E08A80; --rose-soft: #331E1B;
--code-bg: #161E28;
--shadow: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.65);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; background: var(--paper); color: var(--ink);
font-family: "Pretendard","Apple SD Gothic Neo","Malgun Gothic","Noto Sans KR",system-ui,sans-serif;
line-height: 1.7; -webkit-font-smoothing: antialiased; letter-spacing: -0.01em; }
.wrap { max-width: 860px; margin: 0 auto; padding: clamp(20px,4vw,48px); }
.eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--primary); display: flex; align-items: center; gap: 10px; }
.eyebrow::before { content:""; width: 22px; height: 2px; background: currentColor; border-radius: 2px; }
header.mast { border: 1px solid var(--line); border-radius: var(--radius);
background: radial-gradient(120% 140% at 100% 0%, var(--primary-soft) 0%, transparent 55%), var(--card);
box-shadow: var(--shadow); padding: clamp(26px,4vw,42px); }
.wordmark { font-size: 13px; font-weight: 800; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-soft); }
.wordmark b { color: var(--primary); }
header.mast h1 { font-size: clamp(27px,5.4vw,40px); line-height: 1.15; margin: 16px 0 0; font-weight: 800; letter-spacing: -0.03em; text-wrap: balance; }
header.mast .lede { margin: 16px 0 0; font-size: clamp(15px,2.4vw,17px); color: var(--ink-soft); max-width: 58ch; }
.mast-meta { margin-top: 22px; display: flex; flex-wrap: wrap; gap: 10px; }
.chip { font-size: 13px; font-weight: 600; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line); padding: 6px 12px; border-radius: 999px; display: inline-flex; align-items: center; gap: 7px; }
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
nav.toc { margin-top: 22px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); padding: 18px 22px; box-shadow: var(--shadow); }
nav.toc .t { font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
nav.toc ol { margin: 12px 0 0; padding: 0; list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; }
nav.toc a { display: flex; gap: 10px; text-decoration: none; color: var(--ink-soft); font-size: 14px; padding: 3px 0; }
nav.toc a b { color: var(--primary); font-weight: 800; min-width: 40px; }
nav.toc a:hover { color: var(--primary); }
@media (max-width:560px){ nav.toc ol { grid-template-columns: 1fr; } }
section { margin-top: clamp(30px,5vw,46px); scroll-margin-top: 20px; }
section > h2 { font-size: clamp(20px,3.4vw,25px); font-weight: 800; letter-spacing: -0.025em; margin: 12px 0 0; text-wrap: balance; }
section > .sub { color: var(--ink-soft); margin: 9px 0 0; font-size: 15px; max-width: 64ch; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(18px,3vw,26px); }
.mt { margin-top: 16px; }
p { margin: 0; } strong { font-weight: 700; }
.day-div { margin-top: clamp(38px,6vw,56px); display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; }
.day-badge { width: 58px; height: 58px; border-radius: 14px; background: var(--primary); color: #fff; display: grid; place-items: center; text-align: center; line-height: 1.05; box-shadow: var(--shadow); }
@media (prefers-color-scheme: dark){ .day-badge { color:#0B1017; } }
:root[data-theme="dark"] .day-badge { color:#0B1017; }
.day-badge .w { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; opacity: .85; }
.day-badge .n { font-size: 22px; font-weight: 800; }
.day-div h2 { margin: 0; font-size: clamp(21px,3.6vw,27px); font-weight: 800; letter-spacing: -0.025em; }
.day-div .dm { margin-top: 3px; color: var(--ink-soft); font-size: 14px; }
.session { margin-top: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.s-head { padding: 16px 20px; border-bottom: 1px solid var(--line-soft); background: var(--primary-soft); }
.s-head .tag { font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--primary); font-variant-numeric: tabular-nums; }
.s-head h3 { margin: 5px 0 0; font-size: 18px; font-weight: 800; letter-spacing: -0.015em; }
.s-head .dur { margin-top: 5px; font-size: 12.5px; color: var(--ink-soft); font-weight: 600; }
.s-body { padding: 18px 20px; display: grid; gap: 16px; }
.block > .bt { font-size: 12px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 8px; display: flex; align-items: center; gap: 7px; }
.block .bt .ic { width: 20px; height: 20px; border-radius: 6px; display: grid; place-items: center; font-size: 12px; }
.bt .ic.obj { background: var(--primary-soft); } .bt .ic.run { background: var(--line-soft); }
.bt .ic.script { background: var(--primary-soft); } .bt .ic.act { background: var(--teal-soft); }
.bt .ic.check { background: var(--amber-soft); } .bt .ic.pit { background: var(--rose-soft); }
.obj-list { margin: 0; padding: 0; display: grid; gap: 6px; }
.obj-list li { list-style: none; padding-left: 24px; position: relative; font-size: 14.5px; color: var(--ink); }
.obj-list li::before { content: "✓"; position: absolute; left: 2px; color: var(--primary); font-weight: 800; }
.prep { font-size: 13.5px; color: var(--ink-soft); background: var(--code-bg); border-radius: 9px; padding: 10px 14px; }
.run { display: grid; gap: 0; }
.run .r { display: grid; grid-template-columns: 66px 1fr; gap: 14px; padding: 9px 0; border-top: 1px solid var(--line-soft); align-items: baseline; }
.run .r:first-child { border-top: 0; }
.run .r .tm { font-size: 12.5px; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.run .r .ac { font-size: 14px; color: var(--ink-soft); } .run .r .ac b { color: var(--ink); font-weight: 600; }
.script { border: 1px solid var(--primary-soft); border-left: 3px solid var(--primary); border-radius: 9px; background: color-mix(in srgb, var(--primary-soft) 40%, transparent); padding: 12px 15px; }
.script .who { font-size: 12px; font-weight: 800; color: var(--primary); margin-bottom: 5px; }
.script p { font-size: 14px; color: var(--ink); line-height: 1.6; }
.script p + p { margin-top: 8px; }
.script em { color: var(--ink-soft); font-style: normal; font-size: 13px; }
.tpl { border: 1px solid var(--amber-line); background: var(--code-bg); border-radius: 10px; overflow: hidden; }
.tpl .cap { font-size: 11.5px; font-weight: 800; letter-spacing: 0.04em; color: var(--amber); background: var(--amber-soft); padding: 7px 15px; border-bottom: 1px solid var(--amber-line); text-transform: uppercase; }
.tpl pre { margin: 0; padding: 14px 16px; font-family: "SF Mono","Cascadia Code","Consolas",ui-monospace,monospace; font-size: 13px; line-height: 1.65; color: var(--ink); white-space: pre-wrap; word-break: break-word; letter-spacing: 0; }
.tpl .hl { color: var(--primary); font-weight: 600; }
.act-box { border: 1px solid color-mix(in srgb,var(--teal) 30%,transparent); background: var(--teal-soft); border-radius: 10px; padding: 13px 16px; }
.act-box p { font-size: 14px; color: var(--ink); } .act-box p b { font-weight: 700; }
.act-box ol, .act-box ul { margin: 8px 0 0; padding-left: 20px; font-size: 14px; color: var(--ink-soft); display: grid; gap: 5px; }
.check-box { border: 1px solid var(--amber-line); background: var(--amber-soft); border-radius: 10px; padding: 13px 16px; }
.check-box p { font-size: 13.5px; color: var(--ink-soft); } .check-box b { color: var(--ink); }
.check-box ul { margin: 8px 0 0; padding-left: 20px; display: grid; gap: 5px; font-size: 13.5px; color: var(--ink); }
.pit-box { border: 1px solid color-mix(in srgb,var(--rose) 30%,transparent); background: var(--rose-soft); border-radius: 10px; padding: 13px 16px; }
.pit-box .row { font-size: 13.5px; color: var(--ink-soft); } .pit-box .row + .row { margin-top: 8px; }
.pit-box b { color: var(--rose); }
code { font-family: "SF Mono","Cascadia Code","Consolas",ui-monospace,monospace; font-size: 0.9em; background: var(--code-bg); padding: 1px 6px; border-radius: 5px; }
footer { margin-top: 46px; padding-top: 22px; border-top: 1px solid var(--line); color: var(--ink-faint); font-size: 13px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.next { margin-top: 22px; border: 1px dashed var(--primary); border-radius: var(--radius); padding: 18px 22px; background: var(--primary-soft); }
.next b { color: var(--primary-deep); }
@media (max-width:560px){ .run .r { grid-template-columns: 58px 1fr; gap: 10px; } }
@media print { body{background:#fff;} .card,header.mast,.session,nav.toc,.day-badge{box-shadow:none;} .session{break-inside:avoid;} nav.toc{display:none;} }
</style>
</head>
<body>
<div class="wrap">
<header class="mast">
<div class="wordmark"><b>AWESOMEDEV</b> · 수습 상세 강의안 · 7 / 8</div>
<h1>7주차 상세 강의안<br>종합 프로젝트 — 기획 · 설계</h1>
<p class="lede">이번 주는 수습생 4명이 처음으로 한 팀이 되어, 실제 제품에 붙일 수 있는 <strong>작지만 끝까지 가는 기능 하나</strong>를 함께 기획하고 설계합니다. 개인 강의를 잠시 접고, 주제 브레인스토밍·역할 분담·설계 리뷰로 이어지는 팀 워크숍 형태로 한 주를 굴립니다. 목요일부터는 실제로 손을 대기 시작하고, 금요일에 계획 대비 어디까지 왔는지 함께 점검합니다.</p>
<div class="mast-meta">
<span class="chip"><span class="dot"></span>미림마이스터고 3학년 · 수습생 4명(개발 3 · 디자인 1)</span>
<span class="chip"><span class="dot"></span>핵심 = 팀 협업 · 소통 · 주도성</span>
<span class="chip"><span class="dot"></span>산출물: 기획서 · 화면 설계 · 태스크 보드 · 초기 구현</span>
</div>
<nav class="toc">
<div class="t">이번 주 일정</div>
<ol>
<li><a href="#d1"><b></b> 주제 확정 · 역할 분담</a></li>
<li><a href="#d2"><b></b> 기획서 · 화면 설계</a></li>
<li><a href="#d3"><b></b> API 설계 · 태스크 보드</a></li>
<li><a href="#d4"><b></b> 개발 착수</a></li>
<li><a href="#d5"><b></b> 중간 점검 · 진행률 리뷰</a></li>
</ol>
</nav>
</header>
<section>
<div class="card">
<p><strong>6블록 틀</strong>(학습목표 · 진행표 · 멘토 스크립트 · 실습 · 이해 확인 · 흔한 실수)은 1주차 강의안과 동일합니다. 이번 주는 세션 대부분이 개인 실습이 아니라 <strong>팀 워크숍</strong>이라는 점만 기억하세요 — 멘토는 강사보다 퍼실리테이터(진행자)에 가깝게 움직입니다.</p>
</div>
</section>
<!-- ============ 월요일 ============ -->
<div class="day-div" id="d1">
<div class="day-badge"><div class="w">MON</div><div class="n"></div></div>
<div>
<h2>주제 확정 · 역할 분담</h2>
<div class="dm">목표 — 4명이 만들 "작은 기능 하나"를 정하고, PM 포함 역할을 나눈다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 1 · 세션 1 · 오전</div>
<h3>아침 스탠드업 — 프로젝트 모드로 전환</h3>
<div class="dur">30분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>이번 주부터 아침이 "기본기 강의"가 아니라 "팀 프로젝트 시간"임을 이해한다.</li>
<li>매일 아침 스탠드업으로 진행 상황을 서로에게 공유하는 습관을 만든다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 안내</div>
<div class="act-box">
<p><b>스탠드업 규칙</b> — 이번 주부터 CS 기본기 4주 커리큘럼은 잠시 멈추고, 아침 시간을 팀 작업으로 씁니다. 매일 아침 각자 30초씩 세 가지만 말해요.</p>
<ul>
<li>어제 한 것</li>
<li>오늘 할 것</li>
<li>막힌 것 / 도움이 필요한 것</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"자, 오늘부터 한 주 동안은 여러분 넷이 한 팀이에요. 지금까지는 각자 배웠지만, 이번 주는 <strong>같이</strong> 하나를 만들어 봅니다. 회사에서 실제로 일하는 방식이 딱 이래요."</p>
<p>"아침마다 '스탠드업'이라는 걸 할 거예요. 서서 짧게 하는 회의라 이름이 그래요. 어제 뭐 했고, 오늘 뭐 할 거고, 막힌 게 있으면 말하는 거예요. 잘 못했다고 혼나는 자리 절대 아니고요, 서로 어디쯤 있는지 아는 자리예요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 스탠드업이 30초를 넘겨 5분짜리 잡담이 된다.</div>
<div class="row"><b>대처</b> — 멘토가 타이머를 잡고, 길어지면 "그건 끝나고 따로 얘기해요"로 끊어 준다.</div>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 1 · 세션 2 · 오전</div>
<h3>주제 브레인스토밍 워크숍</h3>
<div class="dur">90분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>"작지만 실제 제품에 붙일 수 있는 기능"이 어떤 크기인지 감을 잡는다.</li>
<li>아이디어를 자유롭게 내고, 팀이 함께 후보를 3개로 좁힌다.</li>
<li>좋은 아이디어와 나쁜 아이디어가 아니라, "1주에 끝나는가"로 판단한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">010분</div><div class="ac"><b>범위 감 잡기</b> — 멘토가 "작은 기능" 예시 3~4개를 보여준다.</div></div>
<div class="r"><div class="tm">1035분</div><div class="ac"><b>개인 아이디어</b> — 각자 포스트잇/메모에 아이디어 3개씩 조용히 적는다.</div></div>
<div class="r"><div class="tm">3560분</div><div class="ac"><b>공유</b> — 한 명씩 벽에 붙이며 30초 설명. 질문·평가 없이 듣기만.</div></div>
<div class="r"><div class="tm">6080분</div><div class="ac"><b>묶고 좁히기</b> — 비슷한 것끼리 모으고, 스티커 투표로 상위 3개.</div></div>
<div class="r"><div class="tm">8090분</div><div class="ac"><b>정리</b> — 후보 3개를 화이트보드에 크게 적어 남긴다.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"우리가 만들 건 '앱 전체'가 아니에요. 이미 있는 제품에 <strong>쏙 붙는 작은 기능 하나</strong>예요. 예를 들면 '할 일에 마감일 추가하기', '게시글에 좋아요 버튼', '내가 쓴 글만 모아보기' 정도요. 이 정도면 한 주에 기획하고 설계하고 조금 만들어 볼 수 있어요."</p>
<p>"지금은 좋은 아이디어를 뽑는 시간이 아니에요. <strong>많이 내는</strong> 시간이에요. 이상해 보여도 일단 적어요. 서로 아이디어에 '에이 그건 안 돼' 하는 말은 잠깐 참아 주세요."</p>
<p><em>디자이너 학생에게: "화면이 그려지는 아이디어가 있으면 그쪽으로 더 밀어봐도 좋아요. 이번 주 화면 설계를 ○○님이 이끌 거니까요."</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>아이디어를 이 문장 틀에 맞춰</b> 적으면 크기를 가늠하기 쉬워요. 각자 최소 2개는 이 틀로 채워 봅니다.</p>
</div>
<div class="tpl mt">
<div class="cap">아이디어 한 줄 정의 워크시트</div>
<pre><span class="hl">누가</span>: (예: 앱을 쓰는 일반 사용자 / 관리자)
<span class="hl">무엇을 하고 싶다</span>: (예: 할 일에 마감일을 정하고 싶다)
<span class="hl">그래서 어떤 화면·버튼이 생긴다</span>: (예: 날짜 선택 버튼과 마감일 뱃지)
<span class="hl">한 주에 끝날까? (O/△/X)</span>:
<span class="hl">우리 스택으로 되나? (웹=React, 서버=Spring Boot)</span>: </pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — "인스타그램 같은 거요" 처럼 서비스 전체를 만들자고 한다.</div>
<div class="row"><b>대처</b> — "그중에 딱 하나 화면만 고른다면?"이라고 되물어 범위를 잘라 준다.</div>
<div class="row"><b>실수</b> — 목소리 큰 한 명 아이디어로 순식간에 결론난다.</div>
<div class="row"><b>대처</b> — 개인 메모 → 투표 순서를 지켜, 조용한 학생 아이디어도 벽에 올린다.</div>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 1 · 세션 3 · 오후</div>
<h3>주제 확정 · 역할 분담 회의</h3>
<div class="dur">120분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>후보 3개 중 하나를 팀 합의로 최종 결정한다.</li>
<li>PM · 디자인(기획·화면) · 프론트 · 백엔드 역할을 서로 납득하게 나눈다.</li>
<li>역할이 "칸막이"가 아니라 "책임을 맡는 사람"이라는 걸 이해한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">030분</div><div class="ac"><b>후보 비교</b> — 3개를 "재미·유용·난이도" 3칸으로 같이 평가.</div></div>
<div class="r"><div class="tm">3045분</div><div class="ac"><b>주제 확정</b> — 손들기로 하나 결정. 멘토는 표결만 돕고 강요하지 않는다.</div></div>
<div class="r"><div class="tm">4590분</div><div class="ac"><b>역할 분담</b> — 아래 역할 카드로 누가 무엇을 맡을지 배정.</div></div>
<div class="r"><div class="tm">90110분</div><div class="ac"><b>팀 헌장 작성</b> — 팀 이름·규칙·소통 방법을 한 장으로 정리.</div></div>
<div class="r"><div class="tm">110120분</div><div class="ac"><b>마무리</b> — PM이 내일 할 일을 한 문장으로 선언.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"이제 셋 중 하나를 골라요. 정답은 없어요. 대신 한번 고르면 이번 주는 그걸로 끝까지 가는 거예요. 마음이 흔들려도요."</p>
<p>"역할을 나눌 건데, PM이 제일 궁금하죠? PM은 대장이 아니에요. <strong>팀이 길을 잃지 않게 챙기는 사람</strong>이에요. 오늘 뭐 하기로 했는지, 누가 막혔는지 기억하는 사람. 디자인 맡은 ○○님이 이번 주 화면과 기획을 이끌고, 개발 셋은 프론트·백엔드로 나눠서 붙어요. 근데 벽 쌓지 말고, 서로 넘나들어도 돼요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>역할 카드</b>를 채워 벽에 붙입니다. 이름을 적는 순간 "내 일"이 생겨요.</p>
</div>
<div class="tpl mt">
<div class="cap">팀 헌장 · 역할 배정 워크시트</div>
<pre>팀 이름: ____________________
우리가 만들 기능(한 줄): ____________________
<span class="hl">PM</span> : ______ (역할: 일정·할 일 챙기기, 스탠드업 진행)
<span class="hl">기획·디자인</span> : ______ (역할: 기획서·화면 설계 주도, 스펙 전달)
<span class="hl">프론트엔드</span> : ______ (역할: React 화면 구현)
<span class="hl">백엔드</span> : ______ (역할: Spring Boot API 구현)
우리 팀 규칙 3가지:
1. ____________________
2. ____________________
3. ____________________
소통 방법(예: 채팅방 / 보드): ____________________</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인</div>
<div class="check-box">
<p>퇴근 전 각자 <b>한 문장</b>으로 답하게 하세요.</p>
<ul>
<li>우리가 이번 주에 만들 기능을 한 줄로 말해 볼까요?</li>
<li>내 역할은 무엇이고, 내일 아침 내가 첫 번째로 할 일은?</li>
<li>PM이 하는 일은 "명령"인가요, "챙김"인가요?</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 개발 3명이 다 백엔드를 하겠다고 몰린다.</div>
<div class="row"><b>대처</b> — "화면 없으면 사용자가 못 써요"로 프론트의 가치를 세워 균형을 맞춘다.</div>
<div class="row"><b>실수</b> — 디자이너가 "저는 코드 몰라서요" 하고 뒤로 빠진다.</div>
<div class="row"><b>대처</b> — 이번 주 화면·기획의 <b>주인</b>이 디자이너임을 분명히 하고, 개발자에게 스펙을 넘기는 역할을 강조한다.</div>
</div>
</div>
</div>
</div>
<!-- ============ 화요일 ============ -->
<div class="day-div" id="d2">
<div class="day-badge"><div class="w">TUE</div><div class="n"></div></div>
<div>
<h2>기획서 · 화면 설계</h2>
<div class="dm">목표 — "무엇을 왜 만드는지"를 기획서로, "어떻게 보이는지"를 화면 설계로 남긴다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 2 · 세션 1 · 오전</div>
<h3>아침 스탠드업</h3>
<div class="dur">15분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>어제 확정한 주제·역할을 다시 확인하고 오늘 목표를 공유한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 안내</div>
<div class="act-box">
<p><b>스탠드업 (PM 진행)</b> — 각자 어제 한 것 / 오늘 할 것 / 막힌 것을 30초씩. 오늘은 기획서·화면 설계가 목표라는 걸 PM이 선언합니다. (아침 기본기 강의는 이번 주 없음 — 프로젝트 작업으로 대체)</p>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 2 · 세션 2 · 오전</div>
<h3>기획서 함께 쓰기</h3>
<div class="dur">120분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>기획서가 "왜 · 누가 · 무엇을 · 성공 기준"을 담는 문서임을 안다.</li>
<li>디자이너가 초안을 이끌고, 팀 전원이 한 문단씩 채운다.</li>
<li>"다 안 만들어도 되는 것(이번 주 범위 밖)"을 분명히 적는다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">015분</div><div class="ac"><b>좋은 기획서 예시</b> — 멘토가 한 장짜리 예시 하나를 같이 읽는다.</div></div>
<div class="r"><div class="tm">1540분</div><div class="ac"><b>배경·목표</b> — "왜 이걸 만드나"를 팀이 대화하며 채운다(디자이너 주도).</div></div>
<div class="r"><div class="tm">4075분</div><div class="ac"><b>사용자 시나리오</b> — 사용자가 이 기능을 쓰는 흐름을 문장으로.</div></div>
<div class="r"><div class="tm">75100분</div><div class="ac"><b>범위 · 비범위</b> — 이번 주에 할 것 / 안 할 것을 나눈다.</div></div>
<div class="r"><div class="tm">100120분</div><div class="ac"><b>성공 기준</b> — "이렇게 되면 성공"을 2~3개 적는다.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"기획서는 어렵게 쓰는 게 아니에요. <strong>나중에 우리끼리 딴소리 안 하려고</strong> 미리 정해 두는 메모예요. '어? 이거 만들기로 했었나?' 이걸 막아줘요."</p>
<p>"제일 중요한 칸은 <strong>안 만들 것</strong> 칸이에요. 욕심내면 한 주에 절대 못 끝내요. '이번 주엔 여기까지만' 하고 선을 긋는 것도 실력이에요. 우리 회사 슬로건이 '고객과 함께 더 나은 세상을 만들어 나가는 기업'인데, 그 시작이 이렇게 작은 기능 하나를 제대로 끝내는 거예요."</p>
<p><em>디자이너에게: "○○님이 이 문서 주인이에요. 개발자들이 헷갈리면 ○○님한테 물어보게 될 거예요."</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>기획서 한 장</b>을 이 틀로 완성합니다. 문서 도구(노션·구글 문서 등) 하나에 함께 씁니다.</p>
</div>
<div class="tpl mt">
<div class="cap">기획서 원페이저 템플릿</div>
<pre>기능 이름: ____________________
<span class="hl">1. 배경 / 왜 만드나</span>
____________________
<span class="hl">2. 누가 쓰나 (대상 사용자)</span>
____________________
<span class="hl">3. 사용자 시나리오 (쓰는 흐름)</span>
① 사용자가 ____ 한다
② 그러면 화면에 ____ 이 보인다
③ 사용자가 ____ 하면 ____ 된다
<span class="hl">4. 이번 주에 만들 것 (범위)</span>
- ____________________
<span class="hl">5. 이번 주에 안 만들 것 (비범위)</span>
- ____________________
<span class="hl">6. 성공 기준</span>
- ____________________</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 기획서를 화면 얘기(버튼 색·위치)로 가득 채운다.</div>
<div class="row"><b>대처</b> — "그건 다음 화면 설계 시간에요. 여기선 왜·무엇만"이라고 나눠 준다.</div>
<div class="row"><b>실수</b> — 성공 기준이 "잘 되면 성공"처럼 뭉뚱그려진다.</div>
<div class="row"><b>대처</b> — "무엇을 보면 알 수 있죠?"로 구체적 문장(예: 마감일이 화면에 뜬다)으로 바꾼다.</div>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 2 · 세션 3 · 오후</div>
<h3>화면 설계 (와이어프레임) — 디자이너 주도</h3>
<div class="dur">150분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>기획서의 시나리오를 실제 화면 그림(와이어프레임)으로 옮긴다.</li>
<li>화면에 어떤 요소·버튼이 있고, 무엇을 누르면 어디로 가는지 정한다.</li>
<li>디자이너가 화면을 이끌고, 개발자가 "이건 어떻게 동작해요?"를 질문한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">020분</div><div class="ac"><b>화면 목록 뽑기</b> — 이 기능에 필요한 화면이 몇 개인지 센다(보통 1~3개).</div></div>
<div class="r"><div class="tm">2090분</div><div class="ac"><b>손그림 와이어프레임</b> — 종이/피그마로 화면마다 요소 배치.</div></div>
<div class="r"><div class="tm">90120분</div><div class="ac"><b>흐름 연결</b> — 화살표로 "이 버튼 → 이 화면" 연결.</div></div>
<div class="r"><div class="tm">120150분</div><div class="ac"><b>개발자 질문 타임</b> — 각 요소가 데이터로 뭘 필요로 하는지 메모.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"화면 설계는 처음부터 예쁘게 그릴 필요 없어요. <strong>네모랑 글씨</strong>면 충분해요. '여기 목록이 있고, 위에 추가 버튼, 각 줄에 마감일 뱃지' 이렇게요."</p>
<p>"개발자 셋은 그림 보면서 계속 질문해요. '이 버튼 누르면 저장돼요? 어디에 저장돼요?' 이 질문이 내일 API 설계로 바로 이어져요. 디자이너랑 개발자가 지금 대화를 많이 할수록 나중에 덜 헤매요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>화면 카드</b>를 화면 수만큼 만듭니다. 개발자가 붙는 "데이터 메모" 칸이 핵심이에요.</p>
</div>
<div class="tpl mt">
<div class="cap">화면 설계 카드 (화면 1개당 1장)</div>
<pre>화면 이름: ____________________ (예: 할 일 목록 화면)
<span class="hl">이 화면에 보이는 것</span>:
- ____________________ (예: 할 일 목록)
- ____________________ (예: [+ 추가] 버튼)
- ____________________ (예: 각 항목의 마감일 뱃지)
<span class="hl">누르면 일어나는 일</span>:
- [____] 버튼 → ____________________
<span class="hl">개발자 데이터 메모</span> (이 화면이 서버에서 받아야 할 것):
- ____________________ (예: 할 일 제목, 마감일)</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인</div>
<div class="check-box">
<p>오후 마무리로 팀에게 물어보세요.</p>
<ul>
<li>우리 기능은 화면이 몇 개예요? 각 화면에서 사용자가 뭘 하죠?</li>
<li>가장 중요한 버튼 하나를 누르면 무슨 일이 나요?</li>
<li>이 화면들을 그리면서 새로 생긴 질문이 있나요?</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 색·폰트·간격을 다듬느라 시간을 다 쓴다.</div>
<div class="row"><b>대처</b> — "지금은 '무엇이 어디 있나'만. 예쁘게는 나중에"라고 방향을 잡아 준다.</div>
<div class="row"><b>실수</b> — 개발자들이 그림만 구경하고 질문을 안 한다.</div>
<div class="row"><b>대처</b> — 멘토가 "이 버튼 누르면 데이터 어디서 와요?"를 먼저 시범 질문한다.</div>
</div>
</div>
</div>
</div>
<!-- ============ 수요일 ============ -->
<div class="day-div" id="d3">
<div class="day-badge"><div class="w">WED</div><div class="n"></div></div>
<div>
<h2>API 설계 · 태스크 보드</h2>
<div class="dm">목표 — 화면과 서버가 주고받을 데이터를 API로 정하고, 할 일을 보드에 쪼갠다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 3 · 세션 1 · 오전</div>
<h3>아침 스탠드업</h3>
<div class="dur">15분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>화면 설계까지 온 상태를 확인하고, 오늘 API·보드 목표를 공유한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 안내</div>
<div class="act-box">
<p><b>스탠드업 (PM 진행)</b> — 30초씩 3가지. 어제 화면 설계에서 남은 질문이 있으면 오늘 API 설계로 넘겨 해결한다고 정리합니다.</p>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 3 · 세션 2 · 오전</div>
<h3>API 설계 워크숍 — 화면과 서버 잇기</h3>
<div class="dur">150분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>API가 "화면(React)과 서버(Spring Boot)가 데이터를 주고받는 약속"임을 이해한다.</li>
<li>화면 카드의 "데이터 메모"를 실제 요청·응답 모양으로 옮긴다.</li>
<li>어떤 주소(URL)로, 어떤 방식(GET/POST)으로 주고받을지 팀이 합의한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">020분</div><div class="ac"><b>API 개념</b> — 멘토가 "식당 주문서" 비유로 요청/응답을 설명.</div></div>
<div class="r"><div class="tm">2050분</div><div class="ac"><b>필요한 동작 나열</b> — 화면에서 필요한 동작(목록 보기·추가·삭제)을 적는다.</div></div>
<div class="r"><div class="tm">50110분</div><div class="ac"><b>API 표 채우기</b> — 동작마다 주소·방식·주고받는 데이터를 정한다.</div></div>
<div class="r"><div class="tm">110140분</div><div class="ac"><b>응답 예시(JSON)</b> — 서버가 돌려줄 데이터 모양을 손으로 적어 본다.</div></div>
<div class="r"><div class="tm">140150분</div><div class="ac"><b>합의</b> — 프론트·백엔드가 이 표대로 만들기로 악수.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"API가 어려운 말 같죠? 쉽게 생각해요. 식당에서 <strong>주문서</strong><strong>나온 음식</strong>이에요. 화면이 '할 일 목록 주세요' 하고 주문서(요청)를 보내면, 서버가 목록(응답)을 내주는 거예요."</p>
<p>"이 표를 지금 같이 정해 두면, 프론트 맡은 사람이랑 백엔드 맡은 사람이 <strong>따로 앉아서도 같은 걸</strong> 만들 수 있어요. '나는 이 주소로 보낼게' '나는 이 주소로 받을 준비할게' 이렇게 약속이 되니까요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>API 명세 표</b>를 동작마다 한 줄씩 채웁니다. 우리 스택은 웹=React, 서버=Spring Boot(Java)라는 걸 기억하세요.</p>
</div>
<div class="tpl mt">
<div class="cap">API 명세 워크시트</div>
<pre>동작 방식 주소(URL) 보내는 것 받는 것
-------- ---- ---------------- ----------- -----------------
목록 보기 <span class="hl">GET</span> /api/todos (없음) 할 일 배열
할 일 추가 <span class="hl">POST</span> /api/todos 제목, 마감일 추가된 할 일
할 일 삭제 <span class="hl">DELETE</span> /api/todos/{id} (없음) 성공 여부
응답 예시(JSON) — 목록 보기:
[
{ "id": 1, "title": "청소하기", "dueDate": "2026-07-20" },
{ "id": 2, "title": "숙제하기", "dueDate": "2026-07-18" }
]</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인</div>
<div class="check-box">
<p>표를 다 채운 뒤 확인하세요.</p>
<ul>
<li>"목록 보기"는 왜 <b>GET</b>이고 "추가"는 왜 <b>POST</b>일까요?</li>
<li>프론트 담당자: 이 주소로 무엇을 보내고 무엇을 받죠?</li>
<li>백엔드 담당자: 이 응답 JSON을 만들려면 서버가 뭘 저장해야 하죠?</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 프론트와 백엔드가 서로 다른 주소·데이터 이름을 상상한 채 넘어간다.</div>
<div class="row"><b>대처</b> — 표를 <b>한 장에</b> 같이 적어 "이 이름 그대로 쓴다"를 못 박는다.</div>
<div class="row"><b>실수</b> — API를 실제 제품 수준으로 완벽히 설계하려 든다.</div>
<div class="row"><b>대처</b> — "이번 기능에 필요한 동작만"으로 3~4줄이면 충분하다고 안심시킨다.</div>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 3 · 세션 3 · 오후</div>
<h3>태스크 보드 만들기 + 멘토 설계 리뷰</h3>
<div class="dur">120분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>기획·화면·API를 "작은 할 일 카드"로 쪼개 보드에 올린다.</li>
<li>각 카드에 담당자와 순서를 붙여, 목요일에 바로 손댈 수 있게 한다.</li>
<li>멘토 리뷰를 통해 설계에 큰 구멍이 없는지 점검받는다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">015분</div><div class="ac"><b>보드 소개</b> — 할 일 / 하는 중 / 끝 3칸 칸반을 만든다.</div></div>
<div class="r"><div class="tm">1555분</div><div class="ac"><b>카드 쪼개기</b> — 기능을 하루 안에 끝날 크기의 카드로 나눈다.</div></div>
<div class="r"><div class="tm">5575분</div><div class="ac"><b>담당·순서</b> — 카드마다 이름 붙이고, 먼저 할 것을 위로.</div></div>
<div class="r"><div class="tm">75115분</div><div class="ac"><b>멘토 설계 리뷰</b> — 팀이 기획~보드를 5분 발표, 멘토가 질문·보완.</div></div>
<div class="r"><div class="tm">115120분</div><div class="ac"><b>정리</b> — PM이 "목요일 아침 첫 카드"를 지목.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"이제 큰 덩어리를 <strong>손에 잡히는 작은 카드</strong>로 쪼갤 거예요. '할 일 기능 만들기'는 너무 커요. '목록 화면 뼈대 만들기', '추가 버튼 붙이기', '서버에 저장 API 만들기'처럼 하루 안에 끝날 크기로 잘라요."</p>
<p><em>설계 리뷰에서 (격려 톤): "지금부터 제가 몇 가지 물어볼 텐데, 틀렸다고 지적하는 게 아니에요. 여러분이 놓친 게 있으면 지금 찾는 게 훨씬 이득이라서 그래요. 잘 만들었어요, 여기서 한 걸음만 더 봐요."</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>칸반 보드</b>를 벽이나 노션/트렐로 같은 도구에 만들고, 카드를 채웁니다.</p>
</div>
<div class="tpl mt">
<div class="cap">태스크 보드 · 카드 템플릿</div>
<pre>[ 할 일 ] [ 하는 중 ] [ 끝 ]
---------- ---------- ----------
카드 한 장 형식:
제목 : ____________________ (예: 목록 화면 뼈대 만들기)
담당 : ______
크기 : 반나절 / 하루
메모 : ____________________ (예: 화면 카드 1번 참고)</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인 · 멘토 리뷰 체크</div>
<div class="check-box">
<p>멘토가 리뷰 때 <b>이 질문들</b>로 설계 구멍을 확인합니다.</p>
<ul>
<li>기획서의 "성공 기준"을 보드 카드들이 다 커버하나요?</li>
<li>화면에 있는 버튼마다, 그걸 처리할 API 카드가 있나요?</li>
<li>목요일 아침에 누가 어떤 카드부터 잡을지 정해졌나요?</li>
<li>혹시 한 사람에게만 카드가 몰려 있지 않나요?</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 카드가 "기능 완성"처럼 너무 커서 며칠이 걸린다.</div>
<div class="row"><b>대처</b> — "이걸 반나절짜리 두세 개로 자르면?"으로 함께 쪼갠다.</div>
<div class="row"><b>실수</b> — 리뷰에서 지적받자 학생이 위축된다.</div>
<div class="row"><b>대처</b> — "설계 단계에서 찾은 문제는 100% 이득"이라고 프레임을 바꿔 준다.</div>
</div>
</div>
</div>
</div>
<!-- ============ 목요일 ============ -->
<div class="day-div" id="d4">
<div class="day-badge"><div class="w">THU</div><div class="n"></div></div>
<div>
<h2>개발 착수</h2>
<div class="dm">목표 — 보드의 첫 카드들을 실제 코드로 옮기기 시작한다(React · Spring Boot).</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 4 · 세션 1 · 오전</div>
<h3>아침 스탠드업 — 개발 첫날</h3>
<div class="dur">15분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>각자 오늘 잡을 첫 카드를 말로 선언하고 시작한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 안내</div>
<div class="act-box">
<p><b>스탠드업 (PM 진행)</b> — 오늘부터는 "오늘 할 것"을 <b>보드 카드 이름</b>으로 말합니다. 예: "저는 '목록 화면 뼈대' 카드 잡을게요." 카드를 '하는 중'으로 옮기며 시작해요.</p>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 4 · 세션 2 · 오전~오후</div>
<h3>구현 착수 — 페어로 손대기</h3>
<div class="dur">240분 (중간 휴식 포함)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>설계 문서(기획·화면·API)를 보며 첫 코드를 작성한다.</li>
<li>프론트는 React로 화면 뼈대, 백엔드는 Spring Boot로 API 뼈대를 만든다.</li>
<li>막히면 혼자 오래 붙들지 않고 팀·멘토에게 빨리 묻는다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">020분</div><div class="ac"><b>환경 확인</b> — 각자 프로젝트가 실행되는지(React <code>npm run dev</code>, 서버 기동) 먼저 확인.</div></div>
<div class="r"><div class="tm">20120분</div><div class="ac"><b>첫 카드 구현</b> — 프론트=화면 뼈대, 백엔드=API 뼈대(빈 응답이라도).</div></div>
<div class="r"><div class="tm">120130분</div><div class="ac"><b>중간 싱크</b> — 5분 서서 "어디까지 됐나" 짧게 공유.</div></div>
<div class="r"><div class="tm">130220분</div><div class="ac"><b>이어서 구현</b> — 프론트-백엔드가 API 주소로 실제 연결 시도.</div></div>
<div class="r"><div class="tm">220240분</div><div class="ac"><b>카드 정리</b> — 끝난 카드는 '끝'으로, 못 끝낸 건 메모 남기기.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"드디어 코드예요! 근데 오늘 목표는 '완성'이 아니라 '시작해서 굴러가게'예요. 화면에 목록이 딱 하나라도 뜨면 대성공이에요."</p>
<p>"막히는 건 당연해요. 규칙 하나만 지켜요 — <strong>15분 넘게 혼자 못 풀면 손 드세요.</strong> 오래 붙들고 있는 게 멋진 게 아니라, 빨리 물어보고 앞으로 가는 게 프로예요. 옆 사람이랑 화면 같이 보면서 해도 좋아요."</p>
<p><em>디자이너에게: "○○님은 화면이 설계대로 나오는지 봐 주고, 개발자가 스펙을 헷갈려 하면 짚어 주세요. 여유가 되면 간단한 스타일도 손대 보고요."</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 안내</div>
<div class="act-box">
<p><b>오늘의 최소 목표(각 역할)</b> — 완벽하지 않아도 됩니다. "한 조각이라도 화면/서버에서 돌아간다"가 기준입니다.</p>
<ul>
<li>프론트: React로 첫 화면이 열리고, 목록 자리(빈 목록이라도)가 보인다.</li>
<li>백엔드: Spring Boot에서 <code>GET /api/todos</code>가 200으로 응답한다(내용은 가짜여도 OK).</li>
<li>디자이너: 화면 설계와 실제 화면을 나란히 비교해 다른 점 3개를 메모한다.</li>
<li>PM: 오늘 끝난 카드와 남은 카드를 세어 내일 아침에 공유할 준비.</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 처음부터 예쁜 UI·완벽한 코드에 매달려 아무것도 안 굴러간다.</div>
<div class="row"><b>대처</b> — "일단 못생겨도 돌아가게, 다듬기는 나중에"를 반복해 준다.</div>
<div class="row"><b>실수</b> — 프론트·백엔드가 서로 안 맞춰서 연결이 안 된다.</div>
<div class="row"><b>대처</b> — 수요일 API 표를 다시 펴서 주소·데이터 이름이 같은지 대조하게 한다.</div>
</div>
</div>
</div>
</div>
<!-- ============ 금요일 ============ -->
<div class="day-div" id="d5">
<div class="day-badge"><div class="w">FRI</div><div class="n"></div></div>
<div>
<h2>중간 점검 · 진행률 리뷰</h2>
<div class="dm">목표 — 계획 대비 어디까지 왔는지 함께 확인하고, 다음 주 할 일을 정한다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 5 · 세션 1 · 오전</div>
<h3>아침 스탠드업 + 오늘 마무리 계획</h3>
<div class="dur">20분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>어제까지 진행을 확인하고, 오늘 "점검·발표"가 목표임을 공유한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 안내</div>
<div class="act-box">
<p><b>스탠드업 (PM 진행)</b> — 30초씩 3가지에 더해, PM이 보드를 보며 "지금 끝난 카드 / 남은 카드 개수"를 숫자로 알려 줍니다. 오전은 남은 카드를 조금 더 밀고, 오후는 점검·발표라고 안내합니다.</p>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 5 · 세션 2 · 오전</div>
<h3>마무리 스프린트 + 진행률 집계</h3>
<div class="dur">120분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>오늘 오전에 끝낼 수 있는 카드를 골라 마무리한다.</li>
<li>계획(월~수 보드) 대비 실제 진행률을 숫자로 정리한다.</li>
<li>못 끝낸 것을 "실패"가 아니라 "다음 주 할 일"로 옮긴다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">070분</div><div class="ac"><b>마무리 구현</b> — 거의 다 된 카드를 우선 끝낸다(새 카드 시작 금지).</div></div>
<div class="r"><div class="tm">7095분</div><div class="ac"><b>진행률 집계</b> — 전체 카드 중 몇 개 끝났는지 세어 % 계산.</div></div>
<div class="r"><div class="tm">95120분</div><div class="ac"><b>데모 준비</b> — 오후 발표용으로 "지금 되는 것"을 정리.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>진행률 카드</b>를 채워 오후 발표에 씁니다. "계획 대비 실행"이 이번 주 평가 포인트 중 하나예요.</p>
</div>
<div class="tpl mt">
<div class="cap">주간 진행률 워크시트</div>
<pre>전체 카드 수 : ______ 개
끝낸 카드 수 : ______ 개
진행률 : ______ % (끝낸 ÷ 전체 × 100)
<span class="hl">지금 실제로 되는 것</span> (데모 가능):
- ____________________
<span class="hl">아직 안 되는 것</span> (다음 주로):
- ____________________
<span class="hl">계획과 달라진 점 / 배운 것</span>:
- ____________________</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 발표 직전에 새 기능을 욕심내다 되던 것까지 망가뜨린다.</div>
<div class="row"><b>대처</b> — "지금부터 새 카드 금지, 되는 걸 지키자"로 잠금한다.</div>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 5 · 세션 3 · 오후</div>
<h3>진행률 리뷰 · 팀 회고</h3>
<div class="dur">120분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>팀이 만든 것을 서로에게 데모하고, 한 주를 회고한다.</li>
<li>협업·소통·주도성·계획 대비 실행을 스스로/서로 돌아본다.</li>
<li>다음 주에 이어서 할 일을 보드에 명확히 남긴다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">025분</div><div class="ac"><b>데모</b> — "지금 되는 것"을 화면으로 시연(작아도 OK).</div></div>
<div class="r"><div class="tm">2570분</div><div class="ac"><b>회고 (KPT)</b> — 좋았던 것 / 아쉬운 것 / 다음에 해볼 것.</div></div>
<div class="r"><div class="tm">7095분</div><div class="ac"><b>서로 칭찬</b> — 팀원별로 "이 사람 덕분에 좋았던 점" 한마디씩.</div></div>
<div class="r"><div class="tm">95120분</div><div class="ac"><b>다음 주 준비</b> — 남은 카드 정리, 멘토 마무리 코멘트.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"일주일 동안 정말 많은 걸 했어요. 아이디어에서 시작해서 기획서, 화면, API, 보드, 그리고 실제로 돌아가는 코드까지요. 아직 다 안 됐어도 괜찮아요. <strong>진짜 개발은 원래 다음 주로 이어져요.</strong>"</p>
<p>"회고는 잘잘못 따지는 자리가 아니에요. '이건 좋았으니 계속하자, 이건 아쉬웠으니 바꿔보자'를 찾는 자리예요. 특히 서로한테 고마웠던 점을 꼭 말해 주세요. 같이 일하는 힘이 거기서 나와요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 워크시트</div>
<div class="act-box">
<p><b>KPT 회고</b>를 각자 적고 벽에 붙인 뒤, 팀이 함께 읽습니다.</p>
</div>
<div class="tpl mt">
<div class="cap">KPT 회고 워크시트</div>
<pre><span class="hl">Keep (좋았던 것, 계속할 것)</span>
- ____________________
<span class="hl">Problem (아쉬웠던 것, 힘들었던 것)</span>
- ____________________
<span class="hl">Try (다음 주에 새로 해볼 것)</span>
- ____________________
이번 주 나의 한마디:
- 내가 팀에 기여한 것: ____________________
- 팀원 ○○ 덕분에 좋았던 것: ____________________</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인 · 평가 체크포인트</div>
<div class="check-box">
<p>멘토는 회고를 들으며 <b>이번 주 평가 포인트</b>를 관찰·기록합니다.</p>
<ul>
<li><b>협업·소통</b> — 스탠드업·리뷰에서 서로 묻고 도왔는가?</li>
<li><b>주도성</b> — 시키기 전에 카드를 잡고 스스로 움직였는가?</li>
<li><b>계획 대비 실행</b> — 보드 계획과 실제 결과의 차이를 스스로 설명하는가?</li>
<li>디자이너는 화면·기획을 주도하고 개발자에게 스펙을 넘겼는가?</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> — 회고가 "누구 때문에 안 됐다"는 탓하기로 흐른다.</div>
<div class="row"><b>대처</b> — "사람이 아니라 방법을 말해요"로 방향을 돌리고, 칭찬 라운드로 마무리한다.</div>
<div class="row"><b>실수</b> — 다 못 끝냈다고 팀 전체가 풀이 죽는다.</div>
<div class="row"><b>대처</b> — "한 주에 여기까지 온 게 대단한 것"이라고 성취를 구체적으로 짚어 준다.</div>
</div>
</div>
</div>
</div>
<section>
<div class="next">
<p><b>다음 주 예고 — 8주차 · 프로젝트 완성 & 최종 발표.</b> 이번 주에 만든 기능을 끝까지 다듬어 완성하고, 데모와 함께 최종 발표로 8주 수습 과정을 마무리합니다.</p>
</div>
</section>
<footer>
<span>AWESOMEDEV · 7주차 상세 강의안 (멘토용) · 8부작 중 7</span>
<span>2026 · 수습 가이드·CS 커리큘럼·평가 루브릭과 함께 사용</span>
</footer>
</div>
</body>
</html>