5 Commits

Author SHA1 Message Date
e04e93cf18 feat(security): 보안 3종 — PII 감사로그·공개쓰기 레이트리밋·CI 의존성 스캔
All checks were successful
CI / backend-test (push) Successful in 1m22s
CI / frontend-build (push) Successful in 24s
CI / backend-dep-scan (push) Successful in 31s
SEC-02 PII 감사로그(누가·언제·어디서 개인정보를 조회/내보냈/파기했나):
- AuditLog 엔티티 + AuditLogRepository + AuditService(DB 영속 + slf4j 이중기록)
- MentorController: 명단조회·CSV내보내기·비번재설정·학생파기 4개 민감지점에 기록
- GET /api/mentor/audit-logs + MentorPage에 '개인정보 접근 기록' 표(남기기+보기 짝)
- 미성년 수습생 PII라 개인정보보호법상 접근기록 의무 대응

SEC-03 공개쓰기 레이트리밋(무인증 남용 방어):
- RateLimiterService(범용 고정창, Clock 주입, 메모리) — LoginAttemptService와 별도(단일책임)
- signup(30건/시간/IP: 대량가입·알림폭탄 차단), find-id(15건/10분/IP: 이름열거 차단)
- 초과 시 429. ClientIp 유틸로 rightmost XFF(Caddy 뒤 실제 IP) 공용화(AuthController 중복 제거)

CI 의존성 스캔:
- 프론트 npm audit(--omit=dev --audit-level=high, 비차단), 백엔드 OSV-Scanner v2.4.0(비차단)
- 둘 다 continue-on-error로 '보고 전용' 시작 → 무관한 신규 권고로 CI가 붉어지지 않게

적대적 보안 리뷰(4관점→검증) 확정 4건(전부 LOW) 반영:
- 파기 감사에 대상 아이디/이름 박제(파기 후 id는 dangling → '누구'를 못 알던 문제)
- 가입 한도 10→30(기수 동시 온보딩 대비), 감사 저장 전 로그 선기록(DB실패 시 흔적 유지)
- 고정창 경계 2배 특성 문서화, npm audit 비차단 전환

테스트 29→47(RateLimiter 5·Audit 3·SecurityContract 2 추가), 전부 통과.
운영 검증: audit_log 테이블 생성·감사쓰기(실IP 포함)·find-id 429·스모크 11/11 확인.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:52:44 +09:00
6ba8776e04 ci: 10점 향한 빠른 승리 3종 — 브랜치 보호·커버리지·린트/포맷
Some checks failed
CI / frontend-build (push) Has been cancelled
CI / backend-test (push) Has been cancelled
1) 브랜치 보호(main): CI 두 개 초록불 + 승인 1 없이는 merge 불가,
   학생 직접 push 차단(PR 워크플로), 관리자만 운영·배포용 직접 push (Gitea 설정)
2) 커버리지 측정:
   - 백엔드 JaCoCo — 현재 라인 36.7%, 바닥 30% ratchet(테스트 지우며 후퇴하면 빌드 실패)
   - 프론트 vitest 커버리지 — 채점 로직 runSql.js 라인 40% 바닥
3) 린트/포맷 CI 강제:
   - 프론트 ESLint 9(flat) 신규 — 버그류 에러, 훅 오용 검출 (현재 위반 0)
   - 백엔드 Spotless — 안 쓰는 import·줄끝 공백·파일끝 개행 (기존 코드 이미 clean, 재정렬 없음)
   - ci.yml에 포맷검사·린트·커버리지 단계 추가

백엔드 37개 테스트 + 커버리지 게이트 통과, 프론트 ESLint·커버리지 통과 확인.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:02:08 +09:00
7788509651 test(QA-05): 프론트 테스트 하네스(Vitest) + gradeSql 단위테스트 9개 + CI 연결
All checks were successful
CI / backend-test (push) Successful in 1m5s
CI / frontend-build (push) Successful in 17s
- Vitest 도입(devDep) + 'npm test' 스크립트
- src/lib/runSql.test.js: SQL 채점 순수함수 gradeSql 검증 9케이스 —
  행수 불일치·값 일치·orderMatters(순서 채점)·컬럼별칭 무시·타입 구분·빈결과
  (gradeSql은 학생 통과/실패를 결정하고 서버가 그 판정을 믿으므로 값어치 큼)
- CI(.gitea/workflows/ci.yml)에 'npm test' 단계 추가 — 회귀 시 배포 전 빨간불
- runSql/runJs는 Worker·WASM 의존이라 이번 범위 밖(후속 티켓)

로컬 검증: vitest 9 passed, 빌드 정상.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:15:20 +09:00
740b533921 ci: Maven 다운로드를 archive.apache.org로 (dlcdn 404 → CI 복구)
All checks were successful
CI / backend-test (push) Successful in 39s
CI / frontend-build (push) Successful in 16s
dlcdn 미러가 옛 버전(3.9.9)을 지워 백엔드 CI가 'Maven 설치'에서 실패했다.
모든 버전을 영구 보관하는 archive.apache.org로 변경 — 미래에도 안 깨진다.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:59:53 +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