Skip to content

jihwankim97/dev-sync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

374 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dev-Sync: Git 기반 AI 이력서 & 커뮤니티 플랫폼

1. 개요

Dev-Sync는 개발자의 GitHub 활동과 기본 프로필 정보를 기반으로, AI가 이력서/포트폴리오를 자동 생성하고 커뮤니티 피드백까지 연결해 주는 서비스입니다.

  • 목표
    • 코드와 GitHub 활동만 잘 관리해도 이력서가 자동으로 생성되도록 하는 것
    • 생성형 AI를 명확한 도메인 모델과 트랜잭션 안에 안전하게 통합하는 것

2. 주요 기능 요약

  • AI 이력서 생성: GitHub 레포지토리/커밋/PR/릴리즈 데이터를 기반으로 OpenAI가 한국어 이력서를 자동 생성
  • 블록 기반 이력서 편집기: 프로필/소개/프로젝트/스킬/경력/업적/커스텀 섹션을 블록 단위로 관리 및 정렬
  • 커뮤니티 게시판: 카테고리, 검색, 좋아요, 댓글/대댓글이 있는 개발자 커뮤니티
  • 문의(컨택트) 시스템: 비밀번호 기반 비공개 문의 + 관리자 이메일 알림
  • OAuth 로그인: Google/GitHub OAuth 2.0 기반 세션 로그인, 프로필 관리, GitHub 연동

3. 아키텍처 한눈에 보기

  • 백엔드: NestJS 모노리식 API 서버
    • 도메인 모듈: auth, user, resume, post, contact, upload, queue, worker, common, cache
    • 데이터: MySQL + TypeORM (RDB 기반 도메인 모델)
    • 캐시/큐/세션: Redis + cache-manager + BullMQ
  • 프론트엔드: React + Vite + TypeScript SPA
    • 상태: React Query(서버 상태) + Redux Toolkit(이력서 편집 상태)
    • UI: MUI + Emotion, Quill 기반 에디터
  • AI & 외부 연동
    • GitHub REST API로 활동 데이터 수집
    • OpenAI(gpt-4o-mini)로 이력서 JSON 생성 (schema 강제)
    • Nodemailer + Gmail로 문의 메일 전송

4. 핵심 기능 상세

4.1 GitHub 연동 & 리포지토리 분석

  • 데이터 수집 범위
    • 사용자 githubUrl에서 username 추출
    • /users/:username/repos 로 레포 목록 로드
    • 각 레포마다
      • /languages 로 언어 비율 수집
      • /commits 로 최근 커밋 메시지 및 타임라인 수집
      • /contributors 로 사용자 기여도 확인
      • /pulls 로 사용자 PR 내역 수집
      • /releases 로 릴리즈 정보 수집
      • /contents/README.md 로 README 텍스트 추출
  • 이력서 관점의 스코어링 로직
    • 별도의 resume_relevance_score를 계산해 이력서에 넣을 레포를 선별
      • 스타/포크/워처 수: 외부 관심도 지표
      • 기여 횟수 및 PR 수: 본인 기여도 지표
      • 릴리즈 수: 배포 경험 지표
      • 레포 크기·최근 커밋 여부: 프로젝트의 성숙도와 최신성 반영
    • 점수 기반으로 상위 레포만 선별해 AI에 전달

4.2 AI 기반 이력서 자동 생성 파이프라인

  • 입력: GitHub 분석 결과 JSON (상위 레포들의 활동/메트릭/README 요약)
  • OpenAI 프롬프트 설계
    • 모델에 정확한 JSON 스키마를 제시하고, response_format: json_object 사용
    • 제약 조건을 명시:
      • 모든 텍스트는 한국어로 작성
      • 자기소개/프로젝트 설명/성과는 글자 수 범위를 명시해 과도한 장문 방지
      • 데이터에 근거 없는 내용은 빈 문자열/빈 배열로 두도록 규칙화
      • 역할/성과는 커밋/PR/릴리즈/README에 근거가 있을 때만 작성
    • 프롬프트 본문은 영어로 작성하고, 출력 언어만 한국어로 강제:
      • LLM이 이해하기 쉬운 구조적 요구사항과 JSON 스키마를 짧고 일관된 영어 문장으로 표현해 토큰 사용량과 혼동 가능성을 동시에 줄임
      • 프롬프트 수정·디버깅 시, 팀원 간 공유와 재현이 용이하도록 한글 설명 대신 영문 스펙 중심으로 관리하는 전략
  • 출력 스키마 예시
    • introduction: 헤드라인, 자기소개 본문
    • skills: 핵심 스킬, 서브 스킬 목록
    • projects: 프로젝트별 설명/기간/역할/성과 리스트
  • 저장 로직
    • 결과 JSON을 파싱해 아래와 같이 블록 단위 엔티티로 매핑
      • 프로필(ProfileModel)
      • 소개(IntroductionModel)
      • 스킬(SkillModel + ManyToMany)
      • 프로젝트(ProjectModel + ProjectOutcomeModel)
    • 스킬 문자열은 DB 내 기존 SkillModel 과 이름 매칭 후 ID 기반으로 연결

4.3 블록 기반 이력서 편집 & 정렬

  • 블록 타입
    • PROFILE, INTRODUCTION, PROJECTS, SKILLS, CAREERS, ACHIEVEMENTS, CUSTOM
  • 데이터 모델링
    • 각 블록은 독립적인 엔티티로 분해 (예: resume_profile, resume_introduction, resume_project, resume_career 등)
    • 이력서 상세 조회 시, 각 블록을 개별 쿼리로 가져온 후 정렬 정보에 따라 조합하여 응답
  • 정렬 관리(블록 순서)
    • OrderModel(resumeId, blockType, blockId?, order) 형태로 순서를 별도 저장
    • 새 블록 생성 시 가장 뒤에 order 부여, 삭제 시 나머지 order를 재정렬하여 gap 없는 순번 유지
  • 프론트 UX 연계
    • Redux Toolkit + Immer를 사용해 section 단위 수정/순서 변경을 optimistic update로 처리
    • 서버 sync 실패 시 원본으로 롤백하는 트랜잭션 유사 패턴으로 구현

4.4 커뮤니티 게시판 & 댓글/좋아요

  • 게시글 목록 조회
    • 카테고리(질문/자유/공지 등), 검색어, 정렬 옵션, 페이지 번호를 입력으로 받습니다.
    • TypeORM QueryBuilder 로 작성자/카테고리 조인 및 좋아요/댓글 count를 relation count로 함께 조회
  • 게시글 작성/수정
    • Quill 에디터를 사용해 이미지/서식이 포함된 글을 작성
    • 이미지 업로드는 2단계로 분리:
        1. 프론트: base64 미리보기 + 파일명 관리
        1. 백엔드: /post/uploadFormData로 전송 → 업로드된 파일 URL 반환 → 에디터 HTML 내 src 교체 후 /post에 최종 HTML 저장
  • 댓글/대댓글 구조
    • Comment 엔티티에서 parent 필드로 대댓글을 표현
    • 상위 댓글은 페이지네이션 + hasReplies 플래그 제공
    • 대댓글은 별도의 커서 기반 API로 제공해, 긴 쓰레드에도 퍼포먼스를 유지
  • 좋아요 토글
    • (userId, postId) 조합에 유니크 제약을 걸어 중복 좋아요를 DB 레벨에서 방지
    • 좋아요/취소를 단일 토글 API로 제공해 프론트 구현을 단순화

4.5 문의 시스템 & 관리자 알림

  • 문의 등록
    • 사용자가 이름/이메일/제목/내용을 제출하면
      • DB에 저장 후,
      • Nodemailer + Gmail SMTP로 관리자 메일 발송
  • 비공개 문의
    • 4자리 비밀번호를 설정하면, 비밀번호 검증이 통과할 때만 상세 조회/수정/삭제가 가능
  • 문의 목록 조회
    • 이메일 + 페이지네이션 기반으로 "내가 남긴 문의" 목록을 조회
    • 비공개 문의는 메타 정보만 노출하고, 실제 본문은 보호

5. 기술 스택 및 선택 이유

5.1 백엔드

  • NestJS

    • 선택 이유
      • 인증, 캐시, 큐, 설정, 유효성 검증 등 서버에서 반복되는 concern들을 일관된 모듈/데코레이터 기반 패턴으로 제공
      • 도메인 모듈별로 코드를 나누기 쉬워, 기능 확장 시 코드 베이스가 무너지지 않도록 유지
    • 대안 대비
      • Express/Fastify를 직접 사용하는 경우, 아키텍처를 개발자가 일일이 설계해야 하는데, 본 프로젝트 규모에서는 Nest의 규칙적인 구조가 더 적합하다고 판단
  • TypeORM + MySQL

    • 선택 이유
      • 이력서/프로젝트/성과/스킬/커뮤니티(게시글/댓글/좋아요) 등 관계형 데이터가 많아 정규화된 RDB 모델이 자연스러움
      • QueryBuilder를 통해 복잡한 조인과 페이지네이션, 카운트 쿼리를 직관적으로 작성 가능
    • 대안 대비
      • Prisma 역시 고려했으나, 복잡한 서브쿼리/집계에 있어서 QueryBuilder 기반 ORM이 더 유연하다고 판단
  • Redis + cache-manager-redis-yet

    • 선택 이유
      • 빈번히 조회되는 유저/카테고리 정보는 Redis에 캐싱해 DB 부하를 낮추고 응답 시간을 단축
      • CacheService로 네임스페이스(user:email, category:categories)를 추상화해 캐시 사용 코드를 정돈
  • BullMQ + Worker 프로세스

    • 선택 이유
      • OpenAI API 호출과 이력서 저장은 수 초 이상 걸릴 수 있는 작업이므로, HTTP 요청/응답 흐름에서 분리
      • BullMQ를 통해 재시도, 작업 상태 모니터링, 백오프 정책 등 백그라운드 작업에 필요한 기능을 손쉽게 사용
  • Passport (Google/GitHub OAuth) + 세션 기반 인증

    • 선택 이유
      • 브라우저 기반 서비스에서 세션 쿠키는 보안과 편의성의 균형이 좋은 선택지
      • Access Token은 서버에만 보관하고, GitHub API 호출 시에만 사용해 토큰 노출 위험을 줄임

5.2 프론트엔드

  • React + Vite + TypeScript

    • 선택 이유
      • Vite는 빠른 HMR과 가벼운 번들 환경을 제공하여 개발 속도와 DX가 우수
      • TypeScript를 통해 도메인 모델(이력서 섹션/게시글/댓글 등)의 타입을 명확히 모델링
  • React Query

    • 선택 이유
      • 게시글/댓글/좋아요/이력서 목록/유저 정보 등은 모두 서버 상태이므로, 캐싱/리페치/에러/로딩 상태를 컴포넌트에서 분리하고 싶었음
      • 쿼리 키(userKeys, postKeys, resumeKeys)를 중앙에서 관리해, API 계층을 정돈
  • Redux Toolkit + redux-persist

    • 선택 이유
      • 이력서 편집 상태는 서버와 1:1로 즉시 동기화되지 않는 작업 중 상태(draft) 가 존재
      • 섹션 추가/삭제/정렬/부분 업데이트를 Immer 기반으로 쉽게 다루기 위해 Redux Toolkit 사용
      • 이력서 편집 도중 새로고침해도 상태가 유지되도록, redux-persist로 로컬 스토리지에 저장
  • MUI + Emotion

    • 선택 이유
      • 빠르게 일관성 있는 UI를 제공하면서도, Emotion으로 세밀한 스타일 커스터마이징이 필요했음
      • 이력서/커뮤니티/문의 등 여러 화면의 공통 컴포넌트를 재사용하기 좋음
  • Quill 에디터

    • 선택 이유
      • 이미지/리스트/강조 등 블로그 수준의 서식을 지원해야 했고, HTML 저장이 가능한 검증된 에디터가 필요했음
      • 이미지 리사이즈 모듈과 조합하여 모바일에서도 읽기 좋은 게시글 화면을 구현

6. 안정성, 확장성, 유지보수 고려 사항

  • 환경 변수 검증

    • ConfigModule + Joi로 env 스키마를 정의해, 필수 값이 없거나 잘못된 경우 애플리케이션이 부팅 단계에서 바로 실패하도록 설계
  • 민감 정보 보호

    • ClassSerializerInterceptor@Exclude()를 사용해 githubAccessToken 등 민감 필드를 API 응답에서 숨김
    • OAuth Access Token은 DB에 AES로 암호화해 저장, 서버 내부에서만 복호화
  • 확장성

    • 세션/캐시/큐 모두 Redis를 사용해, 멀티 인스턴스 환경에서도 세션 일관성을 유지할 수 있도록 설계
    • 모듈화된 도메인 구조 덕분에, 기능 추가 시 영향을 받는 영역을 명확히 파악 가능
  • 에러 처리 및 롤백

    • 이력서 블록 sync/업데이트는 typeorm-transactional을 도입해 트랜잭션 단위로 처리
    • 프론트에서는 optimistic update 후 실패 시 원본으로 롤백하는 패턴을 적용해 사용자 경험과 데이터 정합성을 함께 확보

7. 개선 여지 및 향후 계획

  • 이력서 공유 링크 & 공개 프로필 페이지

    • 현재는 편집/관리 중심이라, 공개용 이력서 뷰와 링크 공유 기능을 추가하면 채용/포트폴리오 활용성이 높아질 예정입니다.
  • GitHub Actions 기반 포트폴리오 자동 갱신

    • main 브랜치에 변경이 머지될 때마다 GitHub Actions로 테스트/빌드를 수행하고, 성공 시 정적 포트폴리오 페이지(README, 관련 문서)를 자동으로 빌드·배포하는 파이프라인을 추가해, 코드 변경과 포트폴리오 상태가 항상 동기화되도록 할 계획입니다.
  • 테스트 커버리지 보강

    • 도메인 서비스 레벨의 유닛 테스트와, Resume 생성 플로우에 대한 E2E 테스트를 추가해 회귀를 막을 계획입니다.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages