mirim-app/frontend/public/docs/intern-guide.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

591 lines
37 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>AWESOMEDEV 수습 가이드</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;
--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;
--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;
--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;
--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.72; -webkit-font-smoothing: antialiased; letter-spacing: -0.01em;
}
.wrap { max-width: 820px; 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: var(--primary); border-radius: 2px; }
.eyebrow.amber { color: var(--amber); } .eyebrow.amber::before { background: var(--amber); }
/* Masthead */
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); position: relative; overflow: hidden;
}
.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(29px, 6vw, 44px); line-height: 1.14; 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: 54ch; }
.mast-meta { margin-top: 24px; 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); }
.chip.amber .dot { background: var(--amber); }
/* TOC */
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; counter-reset: toc; }
nav.toc a { counter-increment: toc; display: flex; gap: 10px; text-decoration: none; color: var(--ink-soft); font-size: 14.5px; padding: 3px 0; border-radius: 6px; }
nav.toc a::before { content: counter(toc, decimal-leading-zero); color: var(--primary); font-weight: 700; font-variant-numeric: tabular-nums; }
nav.toc a:hover { color: var(--primary); }
@media (max-width: 560px){ nav.toc ol { grid-template-columns: 1fr; } }
/* Sections */
section { margin-top: clamp(34px, 6vw, 56px); scroll-margin-top: 20px; }
section > h2 { font-size: clamp(21px, 3.6vw, 27px); font-weight: 800; letter-spacing: -0.025em; margin: 14px 0 0; text-wrap: balance; }
section > .sub { color: var(--ink-soft); margin: 9px 0 0; font-size: 15.5px; max-width: 60ch; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(20px, 3vw, 28px); }
.mt { margin-top: 18px; } .mt-s { margin-top: 12px; }
p { margin: 0; } strong { font-weight: 700; }
.note p { margin-top: 14px; color: var(--ink-soft); font-size: 15.5px; }
.note p:first-child { margin-top: 0; }
.note .sign { margin-top: 20px; color: var(--ink); font-weight: 600; font-size: 15px; }
.intro p { color: var(--ink-soft); font-size: 15.5px; margin-top: 14px; }
.intro p:first-child { margin-top: 0; }
.intro .motto { font-size: clamp(17px, 2.6vw, 20px); font-weight: 800; color: var(--primary); letter-spacing: -0.02em; line-height: 1.4; }
.intro .motto span { display: block; margin-top: 8px; font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); }
.intro .facts { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-soft); display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; }
.intro .facts .fk { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--primary); }
.intro .facts .fv { margin-top: 5px; font-size: 15px; font-weight: 600; color: var(--ink); }
/* Layer overview */
.layers { display: grid; gap: 12px; }
.layer { display: grid; grid-template-columns: 46px 1fr; gap: 18px; align-items: start; padding: 18px 20px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); }
.layer .lab { width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center; font-weight: 800; font-size: 17px; color: #fff; background: var(--primary); }
.layer.b .lab { background: var(--amber); } .layer.c .lab { background: var(--ink-soft); }
@media (prefers-color-scheme: dark){ .layer .lab { color: #0E1512; } }
:root[data-theme="dark"] .layer .lab { color: #0E1512; }
.layer h3 { margin: 2px 0 4px; font-size: 16.5px; font-weight: 800; letter-spacing: -0.01em; }
.layer h3 span { font-weight: 600; color: var(--ink-faint); font-size: 13px; margin-left: 8px; }
.layer p { color: var(--ink-soft); font-size: 14.5px; }
/* Detailed sub-blocks inside etiquette */
.subhead { display: flex; align-items: baseline; gap: 12px; margin: 0 0 12px; }
.subhead .num { font-weight: 800; font-size: 14px; color: var(--primary); background: var(--primary-soft); border-radius: 7px; padding: 3px 9px; font-variant-numeric: tabular-nums; }
.subhead h3 { margin: 0; font-size: 18px; font-weight: 800; letter-spacing: -0.015em; }
.why { color: var(--ink-soft); font-size: 14.5px; margin: 0 0 14px; padding-left: 14px; border-left: 3px solid var(--line); }
.why b { color: var(--ink); }
.steps { margin: 0; padding: 0; display: grid; gap: 9px; }
.steps li { list-style: none; padding-left: 26px; position: relative; font-size: 15px; color: var(--ink); }
.steps li::before { content: ""; position: absolute; left: 4px; top: 10px; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
.steps li b { font-weight: 700; }
.steps li small { display: block; color: var(--ink-faint); font-size: 13px; }
.stack { display: grid; gap: 22px; }
.divide { height: 1px; background: var(--line-soft); margin: 4px 0; }
/* O / X */
.dodont { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 4px; }
.dd { border-radius: 11px; padding: 15px 16px; border: 1px solid var(--line); }
.dd.o { background: var(--primary-soft); border-color: color-mix(in srgb, var(--primary) 30%, transparent); }
.dd.x { background: var(--rose-soft); border-color: color-mix(in srgb, var(--rose) 30%, transparent); }
.dd .h { font-weight: 800; font-size: 13px; letter-spacing: 0.03em; display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.dd.o .h { color: var(--primary); } .dd.x .h { color: var(--rose); }
.dd .mk { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 800; color: #fff; }
.dd.o .mk { background: var(--primary); } .dd.x .mk { background: var(--rose); }
@media (prefers-color-scheme: dark){ .dd .mk { color: #0E1512; } }
:root[data-theme="dark"] .dd .mk { color: #0E1512; }
.dd ul { margin: 0; padding: 0; display: grid; gap: 7px; }
.dd li { list-style: none; font-size: 14px; color: var(--ink); line-height: 1.5; }
/* Template / example box */
.tpl { margin-top: 4px; border: 1px solid var(--amber-line); background: var(--code-bg); border-radius: 11px; overflow: hidden; }
.tpl .cap { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; color: var(--amber); background: var(--amber-soft); padding: 8px 16px; border-bottom: 1px solid var(--amber-line); text-transform: uppercase; }
.tpl pre { margin: 0; padding: 16px 18px; font-family: "SF Mono", "Cascadia Code", "Consolas", ui-monospace, monospace; font-size: 13.5px; line-height: 1.7; color: var(--ink); white-space: pre-wrap; word-break: break-word; letter-spacing: 0; }
.tpl .hl { color: var(--primary); font-weight: 600; }
/* Callout */
.callout { border: 1px solid var(--amber-line); border-radius: var(--radius); background: var(--amber-soft); padding: clamp(20px, 3vw, 26px); display: grid; grid-template-columns: auto 1fr; gap: 20px; align-items: start; }
.callout .big { font-weight: 800; font-size: 34px; color: var(--amber); line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.callout h3 { margin: 0 0 6px; font-size: 17px; font-weight: 800; }
.callout p { color: var(--ink-soft); font-size: 15px; }
.callout .steps { margin-top: 12px; }
.callout .steps li::before { background: var(--amber); }
/* Compare (질문) */
.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.compare .col { padding: 18px; border-radius: 12px; border: 1px solid var(--line); }
.compare .bad { background: var(--rose-soft); } .compare .good { background: var(--primary-soft); }
.compare .tag { font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
.compare .bad .tag { color: var(--rose); } .compare .good .tag { color: var(--primary); }
.compare .q { margin: 10px 0 0; font-size: 14.5px; color: var(--ink); line-height: 1.55; }
/* CS fundamentals */
.cs { display: grid; gap: 14px; }
.cs .item { border: 1px solid var(--line); border-radius: 12px; padding: 18px 20px; background: var(--card); }
.cs .item h3 { margin: 0 0 4px; font-size: 16.5px; font-weight: 800; letter-spacing: -0.01em; }
.cs .item h3 em { font-style: normal; color: var(--ink-faint); font-weight: 600; font-size: 13px; }
.cs .item .body { color: var(--ink-soft); font-size: 14.5px; margin-top: 8px; }
.cs .link { margin-top: 12px; font-size: 13.5px; color: var(--primary); background: var(--primary-soft); border-radius: 8px; padding: 9px 12px; display: flex; gap: 8px; }
.cs .link b { color: var(--primary-deep); font-weight: 700; }
/* Weekly table */
.tblwrap { overflow-x: auto; margin-top: 18px; border: 1px solid var(--line); border-radius: 12px; }
table.week { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 520px; }
table.week th, table.week td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--line-soft); }
table.week thead th { font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); background: var(--paper); }
table.week tbody tr:last-child td { border-bottom: 0; }
table.week .wk { font-weight: 800; color: var(--primary); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.week td b { font-weight: 600; }
/* Eval */
.eval .row { display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: center; padding: 14px 0; border-top: 1px solid var(--line-soft); }
.eval .row:first-child { border-top: 0; }
.eval .k { font-weight: 600; font-size: 15px; }
.eval .k span { display: block; color: var(--ink-faint); font-size: 13px; font-weight: 400; margin-top: 2px; }
.eval-flex { display: flex; align-items: center; gap: 12px; }
.eval .bar { width: 120px; height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
.eval .bar i { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.eval .pct { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--primary); width: 40px; text-align: right; font-size: 14px; }
/* Checklist */
.check { display: grid; gap: 10px; }
.check li { list-style: none; display: grid; grid-template-columns: 22px 1fr; gap: 12px; align-items: start; font-size: 15px; color: var(--ink-soft); }
.check .box { width: 18px; height: 18px; border-radius: 5px; border: 2px solid var(--primary); margin-top: 4px; }
.check b { color: var(--ink); font-weight: 600; }
/* Contacts */
.contacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.contact { border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; background: var(--card); }
.contact .role { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--primary); }
.contact .name { font-weight: 700; margin-top: 8px; font-size: 16px; color: var(--ink-faint); }
.contact .fill { color: var(--ink-faint); font-size: 13.5px; margin-top: 4px; }
footer { margin-top: 48px; 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; }
@media (max-width: 560px) {
.compare, .dodont { grid-template-columns: 1fr; }
.callout { grid-template-columns: 1fr; }
.layer { grid-template-columns: 40px 1fr; gap: 14px; }
}
@media print {
body { background: #fff; }
header.mast, .card, .layer, .contact, .compare .col, .cs .item, nav.toc { box-shadow: none; }
section { break-inside: avoid; }
nav.toc { display: none; }
}
</style>
</head>
<body>
<div class="wrap">
<header class="mast">
<div class="wordmark"><b>AWESOMEDEV</b></div>
<h1>반가워요.<br>사회인이 되는 첫걸음, 함께 갈게요.</h1>
<p class="lede">이 가이드는 첫 출근날 받는 안내서예요. 개발부터 시키지 않아요. 먼저 <strong>회사에서 어떻게 지내는지</strong>, 그리고 <strong>컴퓨터가 어떻게 돌아가는지</strong>라는 두 개의 바닥부터 차근차근 배웁니다. 하나하나 다 알려줄 테니 몰라도 괜찮아요.</p>
<div class="mast-meta">
<span class="chip"><span class="dot"></span>수습 · 9월 1일 10월 31일 (8주)</span>
<span class="chip amber"><span class="dot"></span>개발 3 · 디자인 1</span>
</div>
</header>
<nav class="toc">
<div class="t">이 가이드에 담긴 것</div>
<ol>
<li><a href="#about">우리 회사, 어썸데브</a></li>
<li><a href="#welcome">대표가 먼저, 한마디</a></li>
<li><a href="#bigpic">두 달을 어떻게 배우나</a></li>
<li><a href="#etiquette">회사 생활·기본 예절</a></li>
<li><a href="#cs">컴퓨터 기본기</a></li>
<li><a href="#practice">실무는 이렇게 이어져요</a></li>
<li><a href="#stuck">막혔을 때 30분 룰</a></li>
<li><a href="#eval">평가는 이렇게</a></li>
<li><a href="#week1">첫 주 체크리스트</a></li>
</ol>
</nav>
<!-- Company intro -->
<section id="about">
<div class="eyebrow">About us</div>
<h2>우리 회사, 어썸데브</h2>
<div class="card mt intro">
<p class="motto">“고객과 함께 더 나은 세상을 만들어 나가는 기업”<span>혁신과 도전 · Innovation &amp; Challenge</span></p>
<p><strong>㈜어썸데브(AWESOMEDEV)</strong>는 2023년 1월에 시작한 소프트웨어 개발 회사예요. 아직 젊은 회사이고, 그래서 여러분처럼 새로 합류하는 사람의 손길이 그대로 회사의 색이 됩니다.</p>
<p>우리는 <strong>KT엠모바일 · KT알파 · 핀업</strong> 같은 기업의 서비스를 함께 만들고, 안정적으로 돌아가도록 유지·발전시켜요. 통신과 금융처럼 <strong>수많은 사람이 매일 쓰는 시스템</strong>을 다루는 일이라, 작은 코드 한 줄에도 책임이 따르고 그만큼 배우는 것도 많아요. 여러분이 짤 코드와 만들 화면이 실제 사용자에게 가닿습니다.</p>
<div class="facts">
<div class="f"><div class="fk">설립</div><div class="fv">2023년 1월</div></div>
<div class="f"><div class="fk">하는 일</div><div class="fv">SI/SM · 빅데이터 · 통합관리 솔루션</div></div>
<div class="f"><div class="fk">함께하는 곳</div><div class="fv">KT엠모바일 · KT알파 · 핀업</div></div>
<div class="f"><div class="fk">위치</div><div class="fv">서울 강남구 테헤란로78길 14-6, 4층</div></div>
</div>
</div>
</section>
<!-- Welcome from CEO -->
<section id="welcome">
<div class="eyebrow">대표 인사</div>
<h2>대표가 먼저, 한마디</h2>
<div class="card note mt">
<p>반가워요. 어썸데브 대표 <strong>장익준</strong>입니다.</p>
<p>저도 스무 살 무렵부터 개발을 시작해, <strong>20년 넘게 코드를 짜고 시스템을 만들어</strong> 왔어요. 그래서 여러분이 지금 느끼는 설렘도, 두려움도 잘 압니다. 처음엔 누구나 서툴러요 — 저도 그랬고요.</p>
<p>여러분이 아직 학생이라는 걸 알고 뽑았어요. 지금 실력이 완성돼 있길 기대하지 않아요. 제가 정말 보는 건 <strong>얼마나 빨리 배우는지</strong>, 그리고 <strong>함께 일하기 좋은 사람인지</strong>예요.</p>
<p>회사 생활은 학교와 달라서, 처음엔 인사 한 번, 이메일 한 줄도 어색할 수 있어요. 그건 부족해서가 아니라 <strong>아직 안 배웠기 때문</strong>이에요. 이 가이드가, 그리고 여러분의 멘토가 하나하나 알려줄 거예요.</p>
<p>실수해도 괜찮아요. 대신 딱 하나만 — <strong>모르면 혼자 끙끙대지 말고 물어보기.</strong> 그게 이곳에서 가장 환영받는 태도예요. 두 달 뒤 훌쩍 성장해 있을 여러분을 기대할게요. 잘 부탁해요.</p>
<p class="sign">— 어썸데브 대표 장익준 드림</p>
</div>
</section>
<!-- Big picture -->
<section id="bigpic">
<div class="eyebrow">The plan</div>
<h2>두 달을, 이 순서로 배워요</h2>
<p class="sub">개발 실무는 맨 마지막이에요. 그 전에 두 개의 바닥을 먼저 깔아요. 바닥이 튼튼해야 그 위에 뭘 쌓아도 무너지지 않으니까요.</p>
<div class="layers mt">
<div class="layer a">
<div class="lab">A</div>
<div>
<h3>회사 생활 · 기본 예절 <span>첫 주 집중 + 8주 내내</span></h3>
<p>인사하는 법, 보고하는 법, 이메일·전화·메신저 쓰는 법. 실력보다 먼저 갖춰야 할 '사회인의 태도'예요. 제일 먼저, 제일 오래 봅니다.</p>
</div>
</div>
<div class="layer b">
<div class="lab">B</div>
<div>
<h3>컴퓨터 기본기 <span>1~4주차 매일 아침</span></h3>
<p>컴퓨터 구조 · 자료구조 · 프로그램의 변화. 도구 사용법은 검색하면 나오지만, 이 뼈대는 지금 잡아야 평생 안 흔들려요.</p>
</div>
</div>
<div class="layer c">
<div class="lab">C</div>
<div>
<h3>실무 <span>3주차부터 조금씩</span></h3>
<p>작은 과제 → 실전 티켓 → 팀 프로젝트. 기본기를 배운 위에서 하니까 '왜 이렇게 하는지'를 이해하며 할 수 있어요.</p>
</div>
</div>
</div>
</section>
<!-- LAYER A: Etiquette (the detailed one) -->
<section id="etiquette">
<div class="eyebrow">Layer A · 제일 중요</div>
<h2>회사 생활 · 기본 예절</h2>
<p class="sub">여기 나온 건 '잘하는 법'이 아니라 '기본으로 하는 것'들이에요. 하나씩 몸에 익히면 됩니다.</p>
<div class="card mt stack">
<!-- A1 -->
<div>
<div class="subhead"><span class="num">A1</span><h3>하루의 기본</h3></div>
<p class="why"><b>왜?</b> 회사의 신뢰는 대단한 성과가 아니라 매일의 작은 기본에서 쌓여요.</p>
<ul class="steps">
<li><b>출근은 시작 시간 10분 전까지.</b> 자리에 앉아 준비를 마친 상태가 정시예요.<small>늦을 것 같으면 늦기 전에 멘토에게 먼저 연락 — "몇 분 늦습니다, 죄송합니다."</small></li>
<li><b>출근하면 먼저 인사.</b> "안녕하세요!" 밝게 한마디. 퇴근할 땐 "먼저 들어가겠습니다. 수고하셨습니다."</li>
<li><b>호칭은 이름 + 직급/님.</b> "김선임님", "박대리님". 잘 모르면 "○○님"으로. 반말·별명 금지.</li>
<li><b>복장은 깔끔하고 단정하게.</b> 첫 주엔 무난하게 입고, 팀 분위기를 보고 맞춰가요.</li>
<li><b>자리와 공용 공간은 깨끗하게.</b> 회의실·탕비실은 쓴 그대로 두지 않기.</li>
</ul>
</div>
<div class="divide"></div>
<!-- A2 호렌소 -->
<div>
<div class="subhead"><span class="num">A2</span><h3>보고·연락·상담 — 혼자 판단하지 않기</h3></div>
<p class="why"><b>왜?</b> 수습생이 가장 많이 하는 실수는 '혼자 끌어안다가 늦게 터뜨리는 것'이에요. 일이 잘돼도, 안 돼도 <b>중간에 공유</b>하는 게 핵심이에요.</p>
<ul class="steps">
<li><b>보고</b> — 일을 마치면 바로 결과를 알려요. 끝났는데 말 안 하면 안 한 것과 같아요.</li>
<li><b>연락</b> — 진행 중에도 상황을 공유해요. 특히 <b>문제가 생기면 즉시.</b> 숨기면 더 커져요.</li>
<li><b>상담</b> — 판단이 안 서면 혼자 정하지 말고 먼저 물어봐요. "이렇게 해도 될까요?"</li>
</ul>
<div class="tpl mt">
<div class="cap">중간 보고, 이렇게 한마디면 충분해요</div>
<pre>"<span class="hl">김선임님, 배정해주신 로그인 버그 건 중간 공유드려요.</span>
원인은 찾았고 지금 수정 중입니다.
오늘 오후까지 PR 올릴 수 있을 것 같습니다.
혹시 더 급한 게 있으면 말씀해 주세요."</pre>
</div>
</div>
<div class="divide"></div>
<!-- A3 email -->
<div>
<div class="subhead"><span class="num">A3</span><h3>이메일 쓰는 법</h3></div>
<p class="why"><b>왜?</b> 이메일은 회사의 공식 기록이에요. 순서만 지키면 누구나 깔끔하게 쓸 수 있어요.</p>
<div class="tpl">
<div class="cap">기본 형식 — 그대로 따라 쓰세요</div>
<pre><span class="hl">제목:</span> [수습] 9월 1주차 진행 상황 공유 — 홍길동
<span class="hl">안녕하세요, 김선임님.</span> ← 인사 + 받는 사람
개발팀 수습 홍길동입니다. ← 내 소개
배정해주신 로그인 버그 수정 건, ← 용건(무엇을)
원인을 찾아 수정 후 PR 올렸습니다.
확인 부탁드립니다. ← 상대가 할 일
- PR 링크: (주소)
- 남은 작업: 테스트 1개 추가 (내일 오전 완료 예정)
<span class="hl">감사합니다.</span> ← 맺음
홍길동 드림 ← 서명</pre>
</div>
<div class="dodont mt">
<div class="dd o"><div class="h"><span class="mk">O</span>이렇게</div><ul>
<li>제목만 봐도 내용을 알 수 있게</li>
<li>용건은 짧게, 결론부터</li>
<li>보내기 전에 오타·받는 사람 한 번 확인</li>
</ul></div>
<div class="dd x"><div class="h"><span class="mk">X</span>이건 피하기</div><ul>
<li>제목 없이 보내기</li>
<li>"저기요", "ㅇㅋ" 같은 말투</li>
<li>인사·소개 없이 용건만 툭</li>
</ul></div>
</div>
</div>
<div class="divide"></div>
<!-- A4 messenger -->
<div>
<div class="subhead"><span class="num">A4</span><h3>메신저(슬랙·사내 채팅) 예절</h3></div>
<p class="why"><b>왜?</b> 빠르고 편하지만, 편한 만큼 실수도 쉬워요. 상대의 시간을 존중하는 게 핵심이에요.</p>
<div class="dodont">
<div class="dd o"><div class="h"><span class="mk">O</span>이렇게</div><ul>
<li>용건을 한 번에 정리해서 보내기</li>
<li>질문엔 배경도 같이 (아래 A5·30분 룰 참고)</li>
<li>읽었으면 이모지·"확인했습니다"로 반응</li>
<li>급하지 않으면 업무시간 안에</li>
</ul></div>
<div class="dd x"><div class="h"><span class="mk">X</span>이건 피하기</div><ul>
<li>"안녕하세요" 만 보내고 기다리게 하기</li>
<li>한 문장을 여러 번 끊어 보내 알림 폭탄</li>
<li>답 없다고 재촉하기 (5분 만에 "?")</li>
<li>밤·주말에 급하지 않은 연락</li>
</ul></div>
</div>
</div>
<div class="divide"></div>
<!-- A5 phone -->
<div>
<div class="subhead"><span class="num">A5</span><h3>전화 응대</h3></div>
<p class="why"><b>왜?</b> 전화는 순간이라 당황하기 쉬워요. 첫 마디와 메모할 것만 정해두면 떨 필요 없어요.</p>
<div class="tpl">
<div class="cap">받을 때 — 첫 마디는 정해져 있어요</div>
<pre><span class="hl">"네, AWESOMEDEV 개발팀 홍길동입니다."</span>
── 들으면서 메모할 3가지 ──
· 누가 (회사·이름)
· 무엇을 (용건)
· 언제까지 (기한)
잘 모르는 내용이면:
<span class="hl">"확인 후에 다시 연락드리겠습니다.
성함과 연락처 남겨주시겠어요?"</span>
→ 그리고 담당자/멘토에게 바로 전달</pre>
</div>
</div>
<div class="divide"></div>
<!-- A6 meeting & feedback -->
<div>
<div class="subhead"><span class="num">A6</span><h3>회의 태도 &amp; 피드백 받는 자세</h3></div>
<p class="why"><b>왜?</b> 회의와 피드백은 혼나는 자리가 아니라 배우는 자리예요.</p>
<ul class="steps">
<li><b>회의엔 노트를 들고.</b> 정해진 것·내가 할 일을 적어요. 나중에 "뭐였죠?" 안 하려고.</li>
<li><b>모르면 그 자리에서 질문.</b> 모르는 채 끄덕이는 게 제일 위험해요.</li>
<li><b>피드백은 선물로.</b> 코드리뷰·지적은 여러분을 키우려는 거예요. 변명보다 "왜 그런지"를 먼저 이해해요.</li>
<li><b>지적받은 건 메모하고, 같은 걸 두 번 듣지 않기.</b> 이게 성장의 증거예요.</li>
</ul>
</div>
<div class="divide"></div>
<!-- A7 security -->
<div>
<div class="subhead"><span class="num">A7</span><h3>정보 · 보안</h3></div>
<p class="why"><b>왜?</b> 우리는 통신·금융처럼 수많은 사람의 개인정보가 오가는 서비스를 다뤄요. 여기서만큼은 작은 실수도 크게 번질 수 있어요.</p>
<ul class="steps">
<li><b>회사 코드·자료·고객 정보를 밖으로 가져가지 않기.</b> 개인 계정·개인 PC로 복사 금지.</li>
<li><b>비밀번호·접근 토큰을 채팅이나 문서에 붙여넣지 않기.</b></li>
<li><b>헷갈리면 공유하기 전에 먼저 물어보기.</b> "이거 밖에 공유해도 되나요?"</li>
</ul>
</div>
</div>
</section>
<!-- LAYER B: CS fundamentals -->
<section id="cs">
<div class="eyebrow amber">Layer B</div>
<h2>컴퓨터 기본기</h2>
<p class="sub">1~4주차 매일 아침 1시간, 배우고 → 손으로 확인해요. 모든 주제 끝엔 "그래서 우리 회사에선?"으로 연결해서, 죽은 지식이 안 되게 합니다. (디자이너는 이 시간에 디자인 기본기 + 개발자와 협업하는 법을 배워요.)</p>
<div class="cs mt">
<div class="item">
<h3>① 컴퓨터 구조 <em>— 컴퓨터는 결국 뭘 하는 기계인가</em></h3>
<div class="body">2진수·비트·바이트로 데이터가 0과 1로 저장되는 원리 / CPU·메모리(RAM)·저장장치·입출력의 역할과 차이 / 프로그램이 실행되면 벌어지는 일(메모리에 올라가 CPU가 처리).</div>
<div class="link"><span>🔗</span><span>우리 연결: <b>우리 서버(AWS EC2)도 결국 이 구조</b> — 왜 메모리가 부족하면 느려지는가로 이어져요.</span></div>
</div>
<div class="item">
<h3>② 자료구조 <em>— 데이터를 어떻게 담는가</em></h3>
<div class="body">배열·리스트·스택·큐·해시(맵)·트리 / "왜 상황마다 다른 구조를 쓰나" = 무엇이 빠르고 무엇이 순서를 지키는가(시간복잡도 감각). 파이썬으로 스택·큐를 직접 만들어봐요.</div>
<div class="link"><span>🔗</span><span>우리 연결: <b>캐시로 쓰는 Valkey가 왜 그렇게 빠른가 = 해시</b> 구조 덕분이에요.</span></div>
</div>
<div class="item">
<h3>③ 프로그램의 변화 <em>— 지금 우리가 쓰는 것이 어디서 왔나</em></h3>
<div class="body">기계어 → 어셈블리 → 고급 언어(왜 점점 사람 말에 가까워졌나) / 절차지향 → 객체지향 → 함수형 / 혼자 도는 프로그램 → 웹 → 마이크로서비스 → 클라우드 → AI 시대.</div>
<div class="link"><span>🔗</span><span>우리 연결: <b>우리 제품이 마이크로서비스 6개로 나뉜 이유</b>가 바로 이 흐름의 결과예요.</span></div>
</div>
</div>
</section>
<!-- LAYER C: practice -->
<section id="practice">
<div class="eyebrow">Layer C</div>
<h2>실무는 이렇게 이어져요</h2>
<p class="sub">기본기를 배운 위에서, 작은 것부터 진짜 일에 가까워집니다.</p>
<div class="tblwrap">
<table class="week">
<thead><tr><th>주차</th><th>A · 예절</th><th>B · 기본기</th><th>C · 실무</th></tr></thead>
<tbody>
<tr><td class="wk">1주차</td><td><b>집중 교육</b></td><td>컴퓨터 구조</td><td>환경 세팅</td></tr>
<tr><td class="wk">2주차</td><td>상시 관찰</td><td>자료구조</td><td>코드·화면 읽기</td></tr>
<tr><td class="wk">3주차</td><td>상시</td><td>프로그램의 변화</td><td><b>첫 소과제</b></td></tr>
<tr><td class="wk">4주차</td><td>상시</td><td>복습 · 미니 발표</td><td>소과제</td></tr>
<tr><td class="wk">56주차</td><td>상시</td><td>실무에 녹임</td><td>실전 티켓</td></tr>
<tr><td class="wk">78주차</td><td>상시</td><td></td><td><b>종합 프로젝트 · 발표</b></td></tr>
</tbody>
</table>
</div>
</section>
<!-- Stuck / 30min -->
<section id="stuck">
<div class="eyebrow amber">If you're stuck</div>
<h2>막혔을 때: 30분 룰</h2>
<div class="callout mt">
<div class="big">30<span style="font-size:15px;font-weight:700;"></span></div>
<div>
<h3>혼자 30분, 그다음엔 손을 드세요</h3>
<p>스스로 부딪혀 보는 30분은 성장에 꼭 필요해요. 하지만 그 이상 혼자 헤매는 건 손해예요. 물어보기 전에 이 3가지만 정리해 오면 완벽해요.</p>
<ul class="steps">
<li><b>하려던 것</b> — 무엇을 하려고 했는지</li>
<li><b>시도한 것</b> — 어떻게 해봤는지</li>
<li><b>일어난 일</b> — 에러 메시지나 이상한 결과 (스크린샷이면 더 좋아요)</li>
</ul>
</div>
</div>
<div class="compare mt">
<div class="col bad">
<div class="tag">이렇게 말고</div>
<p class="q">"이거 안 돼요. 어떻게 해요?"</p>
</div>
<div class="col good">
<div class="tag">이렇게</div>
<p class="q">"로그인 붙이는 중인데 토큰을 이렇게 보냈더니 401이 떠요. 헤더 이름이 맞는지 봐주실 수 있을까요? (스크린샷 첨부)"</p>
</div>
</div>
</section>
<!-- Eval -->
<section id="eval">
<div class="eyebrow">How we look at you</div>
<h2>평가는 이렇게, 놀랄 일은 없어요</h2>
<p class="sub">두 달 뒤 갑자기 결과만 통보하지 않아요. 매주 1:1로 "잘한 것 하나, 더 해볼 것 하나"를 이야기하고, 4주차에 중간 점검을 해요.</p>
<div class="card mt eval">
<div class="row"><div class="k">성장 속도 · 학습력<span>같은 피드백을 반복하지 않는지, 새 걸 얼마나 빨리 흡수하는지</span></div><div class="eval-flex"><div class="bar"><i style="width:100%"></i></div><span class="pct">25%</span></div></div>
<div class="row"><div class="k">기본기 · 직무 역량<span>기본기를 이해했는지, 맡은 과제의 완성도</span></div><div class="eval-flex"><div class="bar"><i style="width:100%"></i></div><span class="pct">25%</span></div></div>
<div class="row"><div class="k">협업 · 소통<span>보고·연락·상담, 질문의 질, 리뷰 반영</span></div><div class="eval-flex"><div class="bar"><i style="width:80%"></i></div><span class="pct">20%</span></div></div>
<div class="row"><div class="k">태도 · 예절 · 책임감<span>시간 지키기, 기본 예절, 끝까지 하기, 보안 준수</span></div><div class="eval-flex"><div class="bar"><i style="width:80%"></i></div><span class="pct">20%</span></div></div>
<div class="row"><div class="k">성장 가능성<span>6개월 뒤 함께 일하는 그림이 그려지는지</span></div><div class="eval-flex"><div class="bar"><i style="width:40%"></i></div><span class="pct">10%</span></div></div>
</div>
<p class="sub mt-s" style="font-size:14px;">가장 무겁게 보는 건 <strong style="color:var(--primary)">지금의 완성도가 아니라 성장 속도와 태도</strong>예요. 지금 못하는 건 당연하니까요.</p>
</section>
<!-- Week 1 checklist -->
<section id="week1">
<div class="eyebrow">Week 1 checklist</div>
<h2>첫 주에 이건 꼭</h2>
<div class="card mt">
<ul class="check" style="margin:0;padding:0;">
<li><span class="box"></span><div><b>출근 첫 인사</b>를 팀원들에게 — "안녕하세요, 오늘부터 수습 시작한 ○○○입니다!"</div></li>
<li><span class="box"></span><div><b>내 멘토가 누구인지</b> 알고, 연락 방법과 자리 확인하기</div></li>
<li><span class="box"></span><div><b>계정·장비 세팅</b> 완료 (Gitea, 메신저, 사내 위키, 개발 환경)</div></li>
<li><span class="box"></span><div><b>이메일 한 통 연습</b> — 멘토에게 첫 인사 메일을 A3 형식대로 써보기</div></li>
<li><span class="box"></span><div><b>우리 제품을 직접 써보기</b> — 사용자처럼 클릭하며 흐름 익히기</div></li>
<li><span class="box"></span><div><b>하루 정리 메모</b> 시작 — 오늘 배운 것 / 막힌 것 3줄</div></li>
<li><span class="box"></span><div><b>온보딩 회고 한 장</b> 쓰기 — 뭘 배웠고 뭐가 어려웠는지</div></li>
</ul>
</div>
</section>
<!-- Contacts -->
<section id="contacts">
<div class="eyebrow">Who to ask</div>
<h2>이럴 땐 이 사람에게</h2>
<div class="contacts mt">
<div class="contact"><div class="role">내 멘토</div><div class="name">___________</div><div class="fill">일·과제 관련 무엇이든 먼저</div></div>
<div class="contact"><div class="role">팀 리드</div><div class="name">___________</div><div class="fill">방향·우선순위가 헷갈릴 때</div></div>
<div class="contact"><div class="role">인사 · 총무</div><div class="name">___________</div><div class="fill">근태·급여·계약·장비 관련</div></div>
</div>
</section>
<footer>
<span>AWESOMEDEV · 수습 온보딩 가이드</span>
<span>2026 · 개정 시 최신본으로 대체</span>
</footer>
</div>
</body>
</html>