Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/openapi-drift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 서버 API 와 어긋났는지 매일 확인한다.
#
# PR CI 는 저장소에 있는 스펙 사본으로 검사한다(결과가 서버 저장소 상태에 따라 흔들리면 안 된다).
# 그래서 사본이 낡으면 어긋남을 못 본다. 이 워크플로가 서버 main 의 스펙을 새로 가져와 대조해,
# 서버가 경로를 바꿨을 때 하루 안에 드러나게 한다. 무관한 PR 을 막지는 않는다.
name: OpenAPI drift

on:
schedule:
# 매일 09:20 KST (00:20 UTC). 서버 배포가 몰리는 시간대를 지나서 본다.
- cron: '20 0 * * *'
workflow_dispatch:

jobs:
drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm

- run: npm ci

- name: 서버 main 의 스펙 가져오기
run: npm run sync:openapi

- name: 가져온 스펙과 대조
run: npx vitest run src/apis/__tests__/openapi-contract.test.ts

- name: 사본과 서버 스펙의 차이 보여주기
if: always()
run: git --no-pager diff --stat -- openapi/openapi.json
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ npm run lint # ESLint + Prettier (설정 파일 포함 전체)
npm run lint:fix # 자동 수정
npm run typecheck # tsc --noEmit
npm test # Vitest
npm run sync:openapi # 서버 API 스펙(openapi/openapi.json) 갱신
```

`next lint` 는 Next 15.3 에서 deprecated 되어 16 에서 제거되므로 `eslint .` 를 직접 씁니다.
Expand All @@ -410,6 +411,26 @@ npm test # Vitest
더해 다섯 단계입니다. 계약 테스트가 통과해도 서버 컴포넌트 경계 문제로 빌드가 깨질 수 있어
빌드를 따로 둡니다.

### 서버 API 와 어긋나지 않게

경로는 문자열이라 타입 검사도 린트도 불일치를 잡지 못합니다. 실제로 서버에서 지운 경로
(`/oauth2/kakao/auth-url`)를 계속 불러 **메인 화면 카카오 로그인이 아무 반응 없던** 일이 있었습니다.

그래서 서버가 저장소에 고정해 둔 OpenAPI 스펙과 `src/apis/*.ts` 의 호출을 대조합니다.

| | 내용 |
|---|---|
| 스펙 사본 | `openapi/openapi.json` (원본은 서버 저장소 `docs/api/openapi.json`) |
| 대조 테스트 | `src/apis/__tests__/openapi-contract.test.ts` — PR CI 에 포함 |
| 사본 갱신 | `npm run sync:openapi` (서버 main 에서 가져옴, `OPENAPI_SRC` 로 로컬 파일 지정 가능) |
| 사본이 낡는 문제 | 매일 도는 `openapi-drift` 워크플로가 서버 main 스펙을 새로 가져와 대조 |

사본을 두는 이유는 PR CI 결과가 서버 저장소 상태에 따라 흔들리면 안 되기 때문입니다.
그래서 "사본과 서버가 어긋났는지" 는 매일 도는 워크플로가 따로 봅니다.

경로 변수 자리(`${facilityId}`)는 한 세그먼트 와일드카드로 비교합니다. 프런트의 `${type}` 이
경로 변수인지 리터럴 값(`privacy-policy`)인지 문자열만 보고는 구분할 수 없기 때문입니다.

### 개발 전용 화면

`*.dev.tsx` 확장자를 쓴 페이지는 개발 서버에서만 라우트로 잡히고 프로덕션 번들에서 제외됩니다
Expand Down
Loading
Loading