9 Commits

Author SHA1 Message Date
0a7f91ba8c deploy: 멘토 AI 초안용 ollama-proxy 추가 + backend LLM 설정
Some checks failed
CI / backend-test (push) Failing after 2m22s
CI / frontend-build (push) Successful in 1m5s
CI / backend-dep-scan (push) Successful in 29s
edu(EC2)가 워크스테이션 tailnet의 Ollama를 쓰도록 프록시를 둔다.
Ollama는 DNS-rebinding 방어로 Host를 검증해 tailnet 이름 요청을 403으로
막는데, 이 프록시가 Host를 localhost로 재작성해 통과시킨다.
backend는 JAVA_TOOL_OPTIONS(-Dllm.base-url)로 프록시를 가리킨다.
2026-07-23 12:23:50 +09:00
92e65760bc ci: 러너를 compose로 관리 + CI.md 문서 + OP-02 티켓 '구현됨'으로 갱신
All checks were successful
CI / backend-test (push) Successful in 2m6s
CI / frontend-build (push) Successful in 1m4s
- act_runner를 docker-compose.prod.yml에 편입(등록 정보는 /opt/mirim-runner에 영속)
  → compose down/up에도 관리되고, 재등록 없이 이어짐. 재연결 확인
- deploy/CI.md: 구성요소·동작흐름·재구축 절차·함정 메모(Maven archive·clone add-host·checkout node)
- 티켓 풀 OP-02를 ' 구현됨 — 확장(프론트 테스트·캐시·브랜치 보호)은 학생 몫'으로 갱신

CI 상태: run 2 백엔드·프론트 둘 다 초록. run 1 빨강→run 2 초록으로 게이트 동작 실증.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:04:36 +09:00
bf4b6955e3 ci: Gitea Actions로 push 시 자동 테스트 게이트 추가 (OP-02)
Some checks failed
CI / backend-test (push) Failing after 2m9s
CI / frontend-build (push) Successful in 1m6s
- .gitea/workflows/ci.yml: push/PR마다 백엔드 mvn test + 프론트 npm build 자동 실행
- Gitea Actions 활성화(compose GITEA__actions__ENABLED) + act_runner 등록(별도 컨테이너,
  deploy_default 네트워크, host-gateway로 job이 Gitea clone 가능)
- 방금 같은 회귀(보안헤더로 문서 깨짐 등)를 배포 전 자동으로 잡는 안전망.
  학생 티켓 OP-02를 실물로 구현 — 'CI가 왜 필요한가'의 살아있는 예제

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:54:12 +09:00
0a4c769d00 feat: 고도화 배치 7건 — 보안헤더·다운감시·로그회전·개인정보파기·문서정합성
[보안]
- Caddy 보안 응답헤더(HSTS·X-Frame-Options:DENY·X-Content-Type-Options·Referrer-Policy) +
  Server 헤더 제거. :80 catch-all 제거로 HTTP→HTTPS 자동 리다이렉트 복원(평문 표면 제거)
[운영 안정성]
- 헬스체크 스크립트 + systemd 타이머(2분): 공개 URL 두드려 UP/DOWN 변화 시에만 텔레그램 알림
- Docker 로그 회전(json-file 10m×3, YAML 앵커 공통적용) — 디스크 풀로 인한 조용한 다운 방지
[개인정보]
- 학생 파기: DELETE /api/mentor/students/{id} (멘토 권한) → 자식6테이블 먼저·계정 나중,
  @Transactional. 동의화면이 약속한 '파기' 이행. 멘토 화면에 이름입력 확인 파기 버튼
  StudentPurgeService + 테스트3(삭제순서·멘토거부·404)
[문서 정합성 — 지금 쓰는 학생 대상]
- STUDY.md: 없는 파일 가리키던 코드지도 정정(controller/→web/, ChecklistPage→DashboardPage,
  DocumentsPage→DocsPage, SubmissionsPage→AssignmentsPage)
- README: '6주'→8주, 학습센터/퀴즈/코딩 소개 추가, 폴더구조·초기계정(멘토만 시드·랜덤비번) 현행화
- 퀴즈 만점 안내: 없는 '코스 완료' 버튼 대신 '[← 코스로] 돌아가 완료' 로 정정

검증: 테스트29 통과, 운영에서 헤더4종·308리다이렉트·헬스체크·파기 E2E(무인증401·멘토200·
자식전체0건) 확인. 나머지 13건은 티켓 풀 확장감으로 남김.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 14:58:00 +09:00
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
a52999d81d feat: 텔레그램 알림 봇 연동 — 학생 가입·과제·코딩 제출을 멘토에게 즉시 알림
- TelegramNotifier: 봇 API sendMessage 호출. 두 가지 원칙 —
  · 알림 실패가 본 기능(가입·제출)을 절대 막지 않는다: 예외 전부 삼킴 + @Async 비동기
  · 시크릿은 env로만: TELEGRAM_BOT_TOKEN/CHAT_ID 비어 있으면 기능이 조용히 꺼짐(로컬 무설정 OK)
  · 에러 로그에 예외 종류만 남김 — HTTP 에러 메시지의 URL에 토큰이 포함되는 유출 경로 차단
- AsyncConfig: @EnableAsync (없으면 @Async가 조용히 무시되는 함정 문서화)
- 연결 지점 3곳: AuthService.signup(가입) / CodingService.submit(코딩) / SubmissionService(과제)
- 테스트: 생성자에 mock 주입 + 가입 시 알림 발송 검증 1건 추가 → 전체 17개 통과

운영 검증: 봇(@awesomedevmirim_bot)→'2026 현장실습 사전 과제' 그룹 발송 확인,
실가입 E2E로 알림 발송 확인. 토큰은 서버 .env에만 존재(git 미포함).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 10:09:52 +09:00
8486c7e656 fix(security): 세션 쿠키 보안 플래그 + 운영 로그 레벨
- 세션 쿠키에 HttpOnly(XSS로 탈취 방어)·Secure(HTTPS 전용)·SameSite=Strict(CSRF 방어) 적용
- Secure는 COOKIE_SECURE 환경변수로 분리 (로컬 http 개발에서도 로그인되도록 기본 false)
- 운영 로그 레벨을 LOG_LEVEL 환경변수로 분리, 운영은 INFO
- 학습 포인트 주석: 세션 인증의 3대 쿠키 플래그가 왜 필요한가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 07:19:21 +09:00
c6d723824b feat: 설치 가이드 개편 — IntelliJ 설치·Git 연결 단계 추가, 가이드 디자인 시스템 도입
- STEP 6 IntelliJ 설치(Community 선택, JDK 지정, 첫 실행까지)
- STEP 7 IntelliJ에서 Git 연결(클론→브랜치→커밋→푸시→PR, 클릭 경로 명시)
- 히어로·단계 필 내비·번호 리스트·팁/주의 박스 등 가이드 전용 스타일 추가 (global.css)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 08:32:51 +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