4 Commits

Author SHA1 Message Date
5c9959ce08 feat(design): 디자인 시스템 — Pretendard 실적용·토큰·Lucide 아이콘 132개·/design
All checks were successful
CI / backend-test (push) Successful in 3m25s
CI / frontend-build (push) Successful in 48s
CI / backend-dep-scan (push) Successful in 31s
이모지 아이콘을 SVG로 바꾸다가, 더 큰 원인을 발견해 함께 고쳤다.

■ 폰트: 이름만 부르고 파일은 안 받아오고 있었다
  global.css에 font-family: "Pretendard"가 적혀 있었지만 @font-face도 CDN
  링크도 없었다. 그래서 이 글꼴이 따로 깔린 사람 외에는 전원 맑은 고딕으로
  보고 있었다 — 앱과 학습 문서 19개 전부. 에러가 안 나서 조용히 넘어간 케이스.
  - PretendardStdVariable.woff2(285KB)를 public/fonts에 self-host
    · CDN 의존 없음 → 외부 서비스가 죽어도, 오프라인에서도 안 깨진다
    · variable font → 파일 하나가 굵기 45~920을 전부 담는다
    · font-display: swap → 받는 동안 흰 화면(FOIT) 방지
  - 전체판(2MB) 대신 Std판(상용 한글 2,350자)을 골랐다. 앱이 쓰는 한글
    1,276자가 Std에 전부 있는지 브라우저에서 실측 확인했다(폴백 0자).
  - 학습 문서 19개에도 같은 @font-face 적용

■ 아이콘: 이모지 95종 → Lucide 132개
  이모지는 OS마다 다른 그림으로 렌더링되고, 굵기·색을 통제할 수 없고,
  스크린리더가 "bust in silhouette"처럼 읽는다.
  - 카탈로그의 icon: '📜'(문자) → Icon: ScrollText(컴포넌트)로 전환
  - strokeWidth={1.5}로 굵기 통일, aria-hidden으로 장식임을 명시
  - 개별 import만 사용(트리셰이킹) → gzip +14KB
  - slug: null인 '개발 환경 설치 가이드' 항목이 일괄 변환에서 누락돼
    Icon이 undefined가 될 뻔한 것을 정합성 검사(항목 수 vs Icon 수)로 잡았다

■ 토큰: 여백·글자 크기·굵기를 :root로 승격
  --space-1~7(4의 배수), --text-xs~2xl, --weight-*, --radius-sm/lg/full.
  값을 직접 박으면 다크 모드에서 깨지고 화면마다 미묘하게 어긋난다.
  CSS 프레임워크는 도입하지 않았다 — 손으로 쓴 global.css와 충돌하고,
  교재로서 "왜 이렇게 썼는지"가 사라지기 때문이다.

■ /design: 재료를 고르는 화면
  색·글자·여백·모서리를 실제 CSS 변수로 렌더링(다크 모드 자동 반영) +
  Lucide 아이콘 1,993개 검색·복사. lucide-react는 아이콘 하나를 이름 3개로
  내보내(Rocket/RocketIcon/LucideRocket) 5,981개처럼 보이므로 별칭을 걸렀다.
  아이콘 전체를 훑어야 해 무거운 화면이라 lazy로 분리했다
  → 첫 화면 번들은 1.9KB만 증가(575.57 → 577.44KB).

검증: ESLint 통과, Vitest 30개 통과, 프로덕션 빌드 성공, 콘솔 에러 0.
브라우저에서 수습 7카테고리 + 초급~특급 4과정 = 11개 화면 전수 확인
(각 12카드/12아이콘/이모지 0).

문서: DESIGN.md(폰트·토큰·비용), ICONS.md(규약·대응표 132행)
2026-07-22 21:10:28 +09:00
1661591d8b test(e2e): Playwright E2E 도입 — 로그인→강좌→퀴즈 + 멘토/감사로그
Some checks failed
CI / backend-test (push) Successful in 1m3s
CI / frontend-build (push) Failing after 27s
CI / backend-dep-scan (push) Successful in 6s
실제 브라우저로 '다 조립된 앱'(프론트+백엔드+DB)을 태우는 통합 테스트 6개:
- 인증 가드(비로그인→로그인), 로그인 실패 안내, 학생 로그인→대시보드
- 학습 센터→강좌 열기, 퀴즈 풀기→제출→서버 채점 결과
- 멘토 로그인→멘토 화면+개인정보 접근 기록(SEC-02 감사로그까지 검증)

운영 무오염 설계:
- deploy/docker-compose.e2e.yml — 별도 프로젝트(mirime2e)·네트워크·휘발성 DB(tmpfs)
- deploy/Caddyfile.e2e — 평문 HTTP로 SPA+/api 프록시(운영과 동일 구조)
- deploy/e2e.sh — 스택 기동→테스트 학생 API 생성→퀴즈 slug 자동조회→
  Playwright(브라우저 내장 이미지) 실행→down -v(정리)
- 백엔드 힙 256MB 제한(작은 인스턴스에서 운영과 공존)

EC2에서 6/6 통과 확인. 러너가 운영과 같은 인스턴스라 push마다가 아닌
온디맨드(릴리스 전)로 운영 — 전용 러너 확보 시 CI 게이트로 승격.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 08:27:42 +09:00
63f34aa025 chore: 생성물 frontend/coverage/ 추적 제외 (.gitignore)
All checks were successful
CI / backend-test (push) Successful in 2m4s
CI / frontend-build (push) Successful in 23s
커버리지 리포트는 빌드 산출물이라 저장소에 두지 않는다(직전 커밋에서 실수로 포함).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:02:42 +09:00
111590104e feat: 수습 학습 플랫폼 최초 구축 (React + Spring Boot + PostgreSQL)
- 로그인/회원가입/아이디찾기/비밀번호재설정 (세션 기반)
- 대시보드(주차별 진도 체크리스트), 학습 문서 뷰어(17종), 과제 제출/멘토 피드백
- 코딩 기초·개발 환경 설치 가이드 학습 페이지
- 전 소스 한국어 학습 주석 — 수습생 교육용 저장소
- Docker 배포 구성 (Caddy + Spring Boot + PG + Gitea)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 08:18:12 +09:00