REPO V2 이력서를 PDF로 변환하는 서버입니다. Whopper-JR(V1 변환 서버)를 바탕으로 Repo_BE_V2에 맞춰 새로 만들었습니다.
| Whopper-JR (V1) | V2 | |
|---|---|---|
| 그리는 방법 | 프런트 페이지를 크롬으로 열어 인쇄 | 백엔드 API에서 이력서 JSON을 받아 이 서버가 직접 HTML로 그려 인쇄 |
| 결과 전달 | 백엔드 POST /library로 업로드 |
응답으로 PDF를 바로 돌려줌 (V2 백엔드에는 PDF 업로드 API가 없음) |
| 크롬 | 요청마다 새로 실행 | 하나 띄워두고 요청마다 격리된 컨텍스트 사용, 동시 변환 수 제한 |
| 인증 | 토큰을 쿠키로 심어 프런트 접속 | Authorization 헤더를 그대로 백엔드에 전달 (권한 판단은 백엔드) |
프런트 V2에는 인쇄 전용 페이지가 없어서, 프런트 배포와 상관없이 동작하도록 서버가 직접 그립니다.
마크다운은 프런트(ResumeBookSheet의 MarkdownContent)와 같은 문법만 지원하고, 색·글꼴은 프런트 디자인 토큰을 따릅니다.
모든 PDF 요청에는 Authorization: Bearer <access token> 헤더가 필요합니다. 응답은 application/pdf입니다.
| 메서드 | 경로 | 설명 | 사용하는 백엔드 API |
|---|---|---|---|
| GET | /health |
헬스 체크 | - |
| GET | /resume/:resumeId |
내 이력서 PDF (학생 본인) | GET /resume/{resumeId}, GET /user |
| GET | /library/:studentId |
도서관에 공개된 학생 이력서 PDF | GET /library/{studentId} |
| GET | /library/book?date=2026&grade=2&major=백엔드 |
학년도 레주메북 PDF (표지 + 목차 + 공개 이력서 전체, 학번순) | GET /library/book |
date(필수): 공개된 학년도.grade(선택): 공개 당시 학년(1~3).major(선택): 전공 이름.- 이력서 한 쪽은 항상 PDF 한 쪽입니다. 넘치는 내용은 잘리며, 레주메북 목차의 쪽 번호가 이 규칙을 전제로 계산됩니다.
- 에러는
{ "message": "..." }형태이고, 백엔드의 400/401/403/404는 상태 코드와 메시지를 그대로 전달합니다.
프런트에서 받기:
const response = await fetch(`${PDF_SERVER_URL}/library/book?date=2026&grade=3`, {
headers: { Authorization: `Bearer ${accessToken}` },
})
const url = URL.createObjectURL(await response.blob())cp .env.example .env # API_URL 수정
npm install
npm run dev # 로컬 개발 (파일 변경 시 재시작)
npm test # 테스트
npm run sample # 백엔드 없이 샘플 PDF 생성 → out/Docker:
docker compose up -d --build| 이름 | 기본값 | 설명 |
|---|---|---|
API_URL |
(필수) | Repo_BE_V2 주소 |
PORT |
3005 |
서버 포트 |
CORS_ALLOWED_ORIGINS |
(비우면 모두 허용) | 쉼표로 구분한 프런트 주소 |
API_TIMEOUT_MS |
10000 |
백엔드 API 한 건 타임아웃 |
RENDER_TIMEOUT_MS |
180000 |
PDF 한 건 변환 타임아웃 |
MAX_CONCURRENT_RENDERS |
2 |
동시 PDF 변환 수 |
PUPPETEER_EXECUTABLE_PATH |
(puppeteer 내장 크롬) | 크롬 경로. Docker 이미지는 /usr/bin/chromium |
- 학생이 쓴 값은 모두 escape해서 HTML에 넣고, 링크는
http(s)/mailto만 살립니다. - 이미지 URL을 서버가 대신 불러오므로 내부망 주소(localhost, 사설 IP,
169.254.169.254등)로 가는 요청과 스크립트·XHR 요청은 크롬에서 막습니다.