API 클라이언트 계약 패키지 정책¶
문서 역할¶
- 역할:
규범 - 문서 종류:
policy - 충돌 시 우선 문서: 계약 패키지의 목적, 발행, 소비, 수정 절차는 이 문서. JSON 응답 envelope은
api-response-contract-policy.md, 실패ErrorData/taxonomy는api-error-contract-policy.md, 운영 릴리스 scope·증빙은release-process.md, Gate 순서는release-automation-pipeline.md - 기준 성격:
as-is
목적¶
@coupler-developer/coupler-api-contracts는 coupler-api에서 생성한 API/Admin/Mobile 공통 계약의 version pinning 장치이자 public request/success DTO type 및 공통 response/error runtime 배포 경계다. Wire 구조를 바꾸지 않고 generated contract와 소비자 코드 사이의 drift를 package version, dependency diff, lockfile diff에서 드러나게 하며, Mobile/Admin은 package DTO type을 소비하고 같은 package runtime으로 envelope을 검증한다.
적용 범위¶
coupler-api의 계약 package source, generated contract, pack/publish 설정- Swagger/OpenAPI에서 생성하는 operation별 public request/success DTO type
coupler-admin-web와coupler-mobile-app의 계약 dependency, import, lockfile- GitHub Packages registry/auth 설정과 API 계약 변경 릴리스 기록
제외 범위:
- JSON API 응답 envelope 자체의 wire 구조 변경
- request method/path/media type 검증 runtime, request serializer, URL encoder, operation dispatcher
- 실패
ErrorDatataxonomy 작성 기준
단일 SoT¶
- JSON API 성공/실패 envelope: API 공통 응답 계약 정책
- 실패
ErrorData와 error taxonomy: API 에러 계약 정책 - operation별 public request DTO wire schema: Swagger/OpenAPI
- operation별 성공
datawire schema: Swagger/OpenAPI - DTO 필드의 비즈니스 의미와 도메인 제약: 각 도메인 정책
- package publish 규칙: 이 문서의
필수 규칙,Draft PR prerelease 검증,첫 발행,계약 수정과 version bump - 운영 릴리스 포함·증빙 기준: 릴리스 프로세스의
계약 패키지 릴리스 - 운영 Gate 순서: 릴리스 게이트 플로우
- API 계약 변경 cutover gate: API 계약 변경 모바일 릴리스 플로우
- package 전환 잔여 부채: 기술 부채 정리의
API 응답 공통 계약 cutover 인덱스,API success DTO schema 정리 미완료,API public request DTO 생성/소비 전환 미완료
용어¶
- Canonical generated contract:
coupler-api/packages/contracts/src/generated/*에서 generator가 만든 API contract artifact. Publish된 package의 source artifact다. - Package source target:
coupler-api/packages/contracts - Published package: GitHub Packages에 발행하는
@coupler-developer/coupler-api-contracts - Published latest stable version: API
main의 canonical generated contract를 반영해 GitHub Packages에 가장 최근 발행한 prerelease가 아닌 version - Published PR preview version: open Draft API PR의 정확한 head를 소비자와 검증하기 위해
x.y.z-pr.<api-pr>.<run-id>.<attempt>형식과pr-<api-pr>dist-tag로 발행한 임시 version - Active consumer: 계약 package를 dependency로 사용하는
coupler-admin-web와coupler-mobile-app - Legacy generated copy: Admin/Mobile의
src/api/generated/*복사본 - Public wire DTO: API 경계의 path/query/body 요청 값과 성공 응답
data를 표현하는 DTO. DB row, 서버 내부 usecase 모델, 화면 ViewModel, 로컬 draft는 포함하지 않는다.
전환 상태¶
- 현재 generated contract는 operation별 success DTO type과 response/error runtime을 제공한다. 직접 수정한 일부 operation에는 named request body DTO도 제공하지만, path/query/body 위치까지 묶은 operation별 public request DTO map은 아직 완성되지 않았다.
- Public request DTO type 생성과 Admin/Mobile local request wire DTO 제거는 기술 부채 정리의
API public request DTO 생성/소비 전환 미완료에서 추적한다. - 전환 완료 전 기존 local request DTO는 기존 부채로 분류한다. 신규 또는 직접 수정하는 operation은 Swagger/OpenAPI request schema를 먼저 고정하고, package generated request DTO를 사용할 수 있는 범위부터 local wire DTO를 추가하지 않는다.
- 기존
unknown, loose success schema, consumer-local response DTO는 기술 부채 정리의API success DTO schema 정리 미완료로 관리한다. 현재 변경이 읽거나 수정하지 않는 기존 endpoint를 같은 PR에서 일괄 정리하지 않는다.
필수 규칙¶
- 계약 package는 배포 경로, version pinning 장치, public request/success DTO type과 공통 response/error runtime의 단일 배포 경계이며, wire 구조 변경이나 전체 DTO 완성 증거로 해석하지 않는다.
- package infra PR은 wire 응답 구조를 바꾸지 않는다.
- 계약 package의 source of truth는
coupler-api다. Admin/Mobile은 package를 생성하지 않고 발행된 version을 lockfile로 고정한다. - API public request/success wire shape는 Swagger/OpenAPI에서 한 번만 정의하고 API generator가 package type으로 생성한다. 필드의 비즈니스 의미와 도메인 제약은 각 도메인 정책에서 정의한다. Admin/Mobile은 같은 wire DTO를 local type/interface로 다시 정의하지 않는다.
- 신규 operation 또는 성공
data의 필드·필수 여부·nullable·배열/단수 구조를 직접 변경하는 operation은 같은 변경 단위에서 Swagger/OpenAPI success DTO를 실제 wire shape와 일치시키고 generated contract freshness를 통과해야 한다. - Mobile/Admin의 성공
data소비 구조는 아래소비자 DTO와 ViewModel 경계를 따른다. - 소비자가 성공
data내부 필드를 해석하지 않고 opaque JSON 값 전체를 그대로 전달·보관하는 passthrough 경로는 operation별 success DTO 소비 전환 대상에서 제외할 수 있다. 이 예외는 필드 접근·로컬 shape 선언·cast·fallback이 없다는 근거가 있어야 하며, passthrough를 이유로 신규 loose schema를 추가해서는 안 된다. - Package request DTO는 type-only 계약이며 path/query/body 위치, required/optional, nullable, 배열/단수 구조를 보존해야 한다. DB row, 서버 내부 DTO, 화면 ViewModel, 로컬 draft는 package public DTO로 승격하지 않는다.
- 소비자는 package request DTO로 payload를 구성한다. 화면 ViewModel과 로컬 draft는 API 호출 계층으로 역유입하지 않는다.
main과 Ready 상태의 모든 active consumer는 published latest stable version을package.json과 lockfile에 exact version으로 고정한다. APImain, Admin, Mobile의 version이 하나라도 다르면 현재 source 계약 정렬은 완료가 아니다. 이 source 정렬은 이미 설치된 이전 Mobile의 current-API case 증빙이 아니다.- Admin/Mobile Draft PR은 교차 컴파일 검증에 한해 published PR preview version을 dependency와 lockfile에 exact pin할 수 있다. PR 본문에는 API PR 번호, preview version, 검증한 API head SHA를 남긴다.
- PR preview는 소비자 검증용 prerelease이며 stable 발행, 계약 정렬, cutover 또는 운영 배포 완료 증거가 아니다. 소비자 PR을 Ready로 전환하기 전에 published latest stable version으로 교체하고 lockfile과 전체 품질 게이트를 다시 검증한다.
- PR preview는 API
mainref의 수동Release Contracts Previewworkflow로만 발행한다. workflow는 입력한 번호가 같은 레포의main대상 open Draft PR인지 확인하고 API에서 얻은 head SHA를 정확히 checkout한다. - API source의 stable version은 preview 발행을 위해 변경하지 않는다. workflow runner에서만
x.y.z-pr.<api-pr>.<run-id>.<attempt>로 바꾸며, 각 version은 재사용하지 않는다. - PR preview는
pr-<api-pr>dist-tag로 발행하고latest를 변경하지 않는다. 정식Release Contractsworkflow는 수동 dispatch를 제공하지 않고mainpush에서만 stable version을 발행한다. - Preview checkout은 Git credential을 보존하지 않는다. PR 코드를 검사·pack하는 prepare job에는 package write 권한을 주지 않고, 별도 publish job이 Draft 상태와 head SHA 및 tarball metadata를 다시 검증한 뒤 lifecycle script를 끄고 발행한다.
- 최종 구조 리뷰에서는 API package source와 Admin/Mobile dependency·lockfile의 exact version과 실제 runtime
공개 표면을 비교한다. 이 현재 source 정렬과
API cutover판정은 별도다. - 이전 Mobile 계약의 하위 호환 또는 운영 legacy 제거 증빙은
엔지니어링 가드레일의
API 계약과 runtime-state 안전성의 독립 판정을 따른다. Store/NextPush 이력, source 검색 결과 또는 버전을 구분할 수 없는 traffic 0건으로 이를 대신하지 않는다. - 변경된 계약 symbol을 특정 consumer가 직접 import하지 않더라도 version 갱신 대상에서 제외하지 않는다. 계약 package는 active consumer가 함께 고정하는 공용 계약 스냅샷이다.
- 새 stable version을 발행하면 같은 릴리스 작업 단위에서 Admin/Mobile dependency와 lockfile 갱신 PR을 모두 준비하고 품질 게이트를 통과시킨다. 두 PR이
main에 병합되기 전에는 계약 package 소비 정렬을 완료로 기록하지 않는다. - 소비자 source version 지연은 별도 예외로 승인된 경우에만 허용한다. 예외 기록에는 대상 consumer, 현재/목표 version, 지연 사유, owner, 제거 조건과 목표 시점을 포함해야 하며, 예외가 열린 동안에는 현재 source 계약 정렬을 완료로 판정하지 않는다.
- package 이름은
@coupler-developer/coupler-api-contracts로 고정한다. 별도 import alias를 두지 않는다. - API repo의 package 발행/검증 명령은 API repo의
packageManager와 lockfile 기준을 따른다. 현재 기준은pnpm/pnpm-lock.yaml이다. - API repo의 stable/preview publish 권한은 GitHub Actions 기본
github.token과 workflowpackages: write권한으로 고정한다. 이 package 발행만을 위해 별도 PAT secret을 만들거나 fallback으로 두지 않는다. - Admin/Mobile 소비자 설치 인증은 package 발행 권한과 분리한다. 현재 소비자 CI 설치는 GitHub Packages package settings의
Manage Actions access에 해당 consumer repo가Read권한으로 등록된 상태를 전제로, GitHub Actions 기본github.token과 workflowpackages: read권한을 사용한다. - package 설치만을 위해 새 PAT, 새 token secret, 새 fallback token을 만들지 않는다.
- 새 token secret이 필요하다고 판단되면 먼저 package
Manage Actions access,github.token권한, org/repo 권한 제약을 조사하고, 대체 불가 사유와 권한 범위, 만료/회수 계획을 PR/릴리스 기록에 남긴 뒤 명시 승인을 받아야 한다. - GitHub Packages에 발행하더라도 API repo에
npm install또는package-lock.json생성을 섞지 않는다. - 소비자 repo의
.npmrc는 scope registry 설정만 커밋한다. token 값이나${NODE_AUTH_TOKEN}placeholder를.npmrc에 커밋하지 않는다. - GitHub Packages npm package는 로컬 개발자 설치에도 인증이 필요하다. 각 개발자는 개인 GitHub 계정 기준으로
read:packages권한이 있는 user-level npm auth를 설정한다. - GitHub Packages
Manage Actions access는 GitHub Actions의github.token설치 권한만 부여한다. EC2, 배포 호스트, 개인 노트북, 수동 SSH shell에서 실행하는yarn install에는 적용되지 않는다. - EC2 또는 배포 호스트에서 직접
yarn install/yarn build를 실행하면 해당 OS 사용자도 package 소비자다. 설치를 실행하는 사용자 예:ubuntu,deploy,root의 user-level npm auth에read:packages권한이 있어야 한다. - 로컬 개발자 인증은
~/.npmrc같은 사용자 홈 설정에만 저장하고, repo.npmrc, lockfile, 문서 예시, CI 로그에 token 값을 남기지 않는다. - Git 작업 인증은 SSH를 기본으로 사용할 수 있지만, SSH는
npm.pkg.github.compackage 설치 인증을 대체하지 않는다. - 로컬 인증 절차 문서는
gh auth status, 필요 시gh auth login -p ssh,gh auth refresh -s read:packages,npm config set --location=user ...순서를 포함한다. - 로컬 인증 누락으로
yarn install이 실패하는 것은 package 계약 전환의 협업 차단 이슈로 본다. 소비자 전환 PR은 README 또는 개발자 문서에 로컬 인증 절차를 포함해야 한다. - 실제 발행 전 소비자 전환 PR에는
file:, local tarball, git dependency 같은 임시 dependency를 커밋하지 않는다. - Published PR preview exact pin은 위 임시 dependency 금지의 예외지만 Draft PR에서만 허용한다.
- Admin/Mobile CI는
ready_for_review와mainpush를 구독하고 Ready, main 또는 수동 실행에서 prerelease dependency를 발견하면 실패해야 한다. - Admin/Mobile은 legacy generated copy를 재도입하지 않는다.
- Admin/Mobile이 package dependency와 lockfile로 전환되는 cutover PR에서는 legacy generated copy와 copy exact match 검증 CI를 함께 제거한다.
- 발행된 package version은 재사용하지 않는다. 계약 산출물이 바뀌면 새 version을 발행하고 소비자 lockfile에 반영한다.
- package의 public response/envelope 타입과 runtime guard는 generated error runtime의 strict
ErrorData를 실패 계약으로 사용한다. Envelope runtime guard는 성공 DTO를 검증한 것처럼 generic 타입을 단정하지 않고ApiEnvelope<unknown>을 반환하며, 성공/실패는 추가 branch helper 없이ok로 분기한다. generated/apiContract.ts는 Swagger success operation map 산출물이며, 그 안의 느슨한 실패 helper 타입을 package public response 기준으로 삼지 않는다.- Request DTO type 공유는 request transport runtime 공유와 분리한다. Request method/path/media type validator, request DTO runtime validator, serializer, URL encoder, operation dispatcher는 package public runtime으로 승격하지 않는다. Canonical client request는 body 없는
GET/DELETE, JSONPOST/PUT, uploadmultipart/form-data로 고정하고, Mobile/Admin request boundary와 API Swagger/parser가 같은 결론을 가리켜야 한다. - API의 URL-encoded parser는 제거 전 release-scoped 소비자 current-API case를 검증해야 하는 호환 입력 경로다.
min_version/force_update는 rollout 수단일 뿐 parser 제거 증빙이 아니다. 제거 조건과 목표 시점은 기술 부채 정리의API URL-encoded 호환 parser 제거 대기에서 추적한다. - 소비자 코드는 package public request/success DTO 또는 명시 ViewModel mapping을 사용하고, API wire shape를 local DTO, cast, alias fallback, normalize로 보정하지 않는다.
API producer DTO와 Presenter/Mapper 경계¶
- Operation별 generated success DTO는 public wire 계약의 단일 타입 기준이다. 서버 내부 값이 이미 정확한 타입과
필드 집합이면 object literal에
satisfies <GeneratedDto>를 적용하거나 해당 DTO 타입으로 반환하고, 같은 필드를 다시 복사·검사하는 identitytoXxxDtowrapper를 만들지 않는다. - Presenter/Mapper는 삭제 문구·익명화·표시 권한처럼 응답 의미를 만들거나 DB flat row를 중첩 DTO로 투영하는 실제 변환이 있을 때만 둔다. 입력은 정확한 typed read model/DTO로 제한한다.
- Presenter/Mapper 입력을
unknown,Record<string, unknown>으로 넓힌 뒤 generated DTO 필드를 수동 재검증하지 않는다. Operation DTO runtime 검증이 필요하면 OpenAPI에서 생성한 단일 schema를 사용한다. - API Repository query는 응답 또는 내부 read model에 필요한 컬럼만 명시적으로 조회한다.
SELECT *결과를 타입 단정해 직접 응답하지 않으며, 내부 컬럼이 포함될 수 있으면 query projection 또는 명시적 Presenter/Mapper로 제거한다.
소비자 DTO와 ViewModel 경계¶
| 계층 | 입력 | 출력 | 허용 책임 |
|---|---|---|---|
| API 호출 경계 | unknown envelope |
operation별 generated success DTO | envelope 검증, ok 분기, operation 타입 연결 |
| 선택적 ViewModel mapper | generated success DTO | 화면 전용 ViewModel | 표시명, 파생값, UI 상태 계산 |
| 화면 | generated DTO 또는 ViewModel | 렌더링 | 표시와 사용자 상호작용 |
- 파생값이 없으면 generated DTO를 직접 사용한다. ViewModel은 필요한 화면에만 두며 API 요청이나 다른 operation DTO로 역사용하지 않는다.
- mapper 입력을
unknown,Record<string, unknown>, consumer-local wire type으로 넓히거나 숫자·문자열 coercion, 누락값 기본값, enum 치환·필터링으로 wire 위반을 숨기지 않는다. 계약 위반은 실패·로그 처리하거나 승인된 호환 예외로 분리한다. - 사용자 입력, navigation param, Native media URI, 날짜·금액 표시 포맷은 API wire 보정이 아니므로 허용한다.
- structured success fixture는
satisfies ApiOperationSuccessData<'METHOD /path'>또는 동등한 operation DTO type으로 계약 일치를 확인한다.
공개 표면 폐쇄 원칙¶
계약 package와 소비자 response boundary는 확장 가능한 utility library가 아니라 폐쇄형 계약 경계다. 아래 allowlist에 없는 public runtime symbol과 entrypoint는 필요해 보인다는 이유만으로 추가하지 않는다.
허용 public 표면:
api: generator가 만든 contract version, operation metadata와 operation별 type-only public request/success DTOerror: generator가 만든 strictErrorData, error catalog, message와 그 검증/조회 runtimeresponse:ApiSuccessEnvelope,ApiFailureEnvelope,ApiEnvelope,ApiErrorData타입과 runtime guardisApiEnvelope하나- Admin/Mobile facade: package의
isApiEnvelope를 로직 없이 연결하는isEnvelope하나 - Mobile의
ApiResult변환, 상태 판정과 사용자 메시지 helper는 package 계약이 아닌 앱 내부 response boundary로만 유지하며, 현재 runtime export allowlist 밖으로 확장하지 않는다.
금지 파생:
isApiSuccessEnvelope,isApiFailureEnvelope처럼ok분기를 다시 감싼 branch helper- 검증하지 않은 success DTO를 보장하는 generic guard, assertion, decoder 또는 parser
- request method/path/media type/request DTO runtime validator, serializer, URL encoder 또는 operation dispatcher
- API wire shape를 다시 정의하는 consumer-local request/response DTO
- package 결과를 재해석하는 local envelope validator, normalize, fallback, alias 호환 계층
- 제거 Gate와 기술 부채 기록이 없는 legacy/dual/transition runtime
- 기존 entrypoint의 편의 alias, 동일 계약의 중복 package, consumer 전용 public export
api entrypoint 안에서 Swagger/OpenAPI로부터 생성되는 type-only request/success DTO 추가는 위 허용 표면에 포함한다. 새 runtime symbol 또는 새 entrypoint 확장은 기본적으로 금지한다. 불가피한 runtime 확장은 구현과 같은 PR에 끼워 넣지 않고 별도 계약 변경으로 다루며, 다음 근거를 모두 남겨야 한다.
- 기존 허용 표면으로 해결할 수 없는 구체적 실패 사례
- API/Admin/Mobile 영향과 대안 비교
- wire compatibility, 보안, bundle/runtime 비용 평가
- 새 symbol의 owner, 제거 가능성, version bump와 consumer 정렬 계획
- API/Admin/Mobile/Docs 리뷰 승인과 public export allowlist CI 갱신
근거가 하나라도 없으면 public 표면을 확장하지 않고 호출부의 도메인 로직 또는 명시 ViewModel mapping으로 해결한다.
운영 절차¶
Package infra 추가¶
- API repo에 package source, export, pack/publish 검증 경로를 추가한다.
- Canonical generated contract는 package source target에 생성하고, Admin/Mobile generated copy를 만들지 않는다.
pnpm pack:contracts로 발행 산출물에 필요한 파일만 포함되는지 확인한다.- Package
apientrypoint가 operation별 type-only public request/success DTO를,responseentrypoint가 strictErrorData기반 envelope 타입과 runtime guard를 노출하는지 확인한다. - Package와 Admin/Mobile response facade의 public runtime symbol이 각각의 정확한 allowlist를 벗어나지 않는지 CI로 확인한다.
- PR과 릴리스 기록에 package infra가 wire 계약 변경, 소비자 전환 완료, public request/success DTO 완료를 의미하지 않는다고 기록한다.
Draft PR prerelease 검증¶
- API 계약 source version을 다음 stable
x.y.z로 올리고 API Draft PR의 계약 검증을 통과시킨다. - API
mainref에서Release Contracts Preview를 수동 실행하고 API PR 번호를 입력한다. - workflow가 open Draft 상태,
mainbase, 같은 repo를 확인하고 API의 head SHA를 정확히 checkout한 뒤x.y.z-pr.<api-pr>.<run-id>.<attempt>를pr-<api-pr>tag로 발행한다. - Admin/Mobile Draft PR은 해당 preview version을 dependency와 lockfile에 exact pin하고 표준 품질 게이트를 실행한다.
- API 변경을 다시 publish하면 새 preview version을 사용하며 기존 version을 덮어쓰지 않는다.
- API
main에서 stable이 발행된 뒤 소비자 dependency와 lockfile을 stable로 교체하고 다시 검증한 후 Ready로 전환한다.
첫 발행¶
- API repo에서 generated contract freshness 검증을 통과시킨다.
- API repo의 package manager 기준으로
@coupler-developer/coupler-api-contracts를 발행한다. - 발행 version, registry package, 비교한 API ref, pack/publish 검증 결과를 릴리스 기록에 남긴다.
- 발행 실패 시 소비자 전환 PR을 진행하지 않는다.
Admin/Mobile 소비 전환¶
- 소비자 레포에 GitHub Packages registry 설정을 추가한다.
- GitHub Packages package settings의
Manage Actions access에 consumer repoRead권한을 부여한다. - CI install step은 workflow
packages: read권한과NODE_AUTH_TOKEN: ${{ github.token }}기준으로 구성한다. - 새 token secret이 필요하다고 판단되면 필수 규칙의 token 생성 예외 절차를 먼저 통과한다.
- README 또는 개발자 문서에 로컬 GitHub Packages 인증 절차를 추가한다.
- 배포 호스트에서 직접 install/build를 실행하는 운영 방식이 있으면 배포 런북에 해당 OS 사용자 기준 GitHub Packages 인증 절차를 추가한다.
- 발행된
@coupler-developer/coupler-api-contractsversion을 consumer package manager로 lockfile에 고정한다. src/api/generated/*import를 package import로 교체한다.- 소비자 repo의
src/api/generated/*legacy copy와 generated copy exact match CI를 제거한다. - request boundary가 package response runtime으로
{ ok: true, data }/{ ok: false, error }를 검증하고 같은 분기 기준을 유지하는지 확인한다. - 소비자 request payload와 success data가 package generated operation DTO를 사용하고, 동일 wire shape의 local DTO가 남지 않았는지 확인한다.
계약 수정과 version bump¶
- Swagger/OpenAPI, error catalog, 도메인 정책 중 해당 SoT를 먼저 수정한다.
- API repo에서 generated contract를 재생성하고 freshness 검증을 통과시킨다.
- 계약 산출물이 바뀌면 package version을 올리고 새 version을 발행한다.
- Admin/Mobile은 직접 사용하는 계약 symbol 변경 여부와 무관하게 published latest stable version으로 dependency와 lockfile을 함께 갱신한다.
- 각 소비자 표준 품질 게이트와 package version/lockfile 일치를 확인한 뒤 두 소비자 PR을
main에 병합한다. - API/DB 변경은 두 active consumer의 현재 source version 정렬과 별도로
API 계약 변경 모바일 릴리스 플로우의
API cutover와 DB runtime/schema 조합 Gate를 통과한 뒤 진행한다.
증빙/추적¶
- API PR: generated contract freshness 검증, pack 결과, 발행 대상 파일 목록
- Publish 기록: package name, version, registry URL 또는 package manager 출력, API ref
- Admin/Mobile PR: registry 설정, CI secret 이름/권한 범위, dependency diff, lockfile diff, public request/success DTO import 전환 diff, local wire DTO와 legacy generated copy 제거 diff, request boundary 검증
- Cutover PR: 비교한 API/Admin/Mobile ref, 릴리스 기록 링크
체크리스트¶
- [ ] package 변경이 wire 응답 구조 변경과 섞이지 않았는가?
- [ ] package 이름이
@coupler-developer/coupler-api-contracts하나로 유지되는가? - [ ] API public request/success DTO가 Swagger/OpenAPI에서 한 번만 정의되고 package type으로 생성되는가?
- [ ] 신규 또는 직접 수정한 structured success
data가 실제 wire shape와 같은 required/optional/nullable/배열 구조로 정의되고 generated contract freshness를 통과하는가? - [ ] API producer가 exact generated DTO를 직접 반환하며 identity wrapper나 generated field 수동 재검증을 추가하지 않았는가?
- [ ] Presenter/Mapper가 실제 의미·구조 변환만 소유하고 exact typed input을 사용하는가?
- [ ] API query가 필요한 컬럼을 투영하거나 typed Presenter/Mapper로 내부 컬럼을 제거해
SELECT *결과를 타입 단정만으로 외부 응답에 노출하지 않는가? - [ ] 소비자 request payload와 success data가 package generated DTO를 사용하며 동일 wire shape의 local DTO를 재정의하지 않는가?
- [ ] 기존 loose/local DTO를 이번 변경이 만들거나 확산하지 않았으며, 미수정 잔여분은 기존 기술 부채로 분리했는가?
- [ ] success DTO 적용을
N/A로 둔 opaque JSON passthrough는 소비자가 내부 필드를 읽지 않고 그대로 전달·보관한다는 코드 근거가 있는가? - [ ] type-only request DTO 공유가 request runtime validator/serializer/dispatcher 공개로 확장되지 않았는가?
- [ ] public response/envelope 타입과 runtime guard가 generated error runtime의 strict
ErrorData를 실패 계약으로 쓰는가? - [ ]
responsepublic runtime이isApiEnvelope하나이고 소비자 facade가isEnvelope외의 파생 envelope guard를 추가하지 않았는가? - [ ] 새 public entrypoint/runtime symbol이 폐쇄형 allowlist를 벗어나지 않으며, 확장 시 별도 계약 변경 근거와 승인이 있는가?
- [ ]
generated/apiContract.ts의 느슨한 실패 helper 타입을 package public response 기준으로 노출하지 않는가? - [ ] API repo에서
pnpm/pnpm-lock.yaml기준을 지키고package-lock.json을 만들지 않았는가? - [ ] Admin/Mobile legacy generated copy를 재도입하지 않았는가?
- [ ] 소비자 전환은 GitHub Packages registry/auth 설정, 발행된 package version, lockfile을 기준으로 하는가?
- [ ] Preview workflow가
mainref에서 open Draft API PR의 정확한 head를 checkout하고 고유 prerelease version을 쓰는가? - [ ] Preview checkout이 credential을 보존하지 않고 publish 단계에서 lifecycle script를 실행하지 않는가?
- [ ] Preview dist-tag가
pr-<api-pr>이며latest를 변경하지 않는가? - [ ] Admin/Mobile Draft의 preview exact pin이 API PR/version/SHA 증빙을 남겼는가?
- [ ] Ready 또는
main에 prerelease dependency가 남지 않도록 CI가 차단하는가? - [ ] 소비자 CI package install은 GitHub Packages
Manage Actions access의 consumer repoRead권한, workflowpackages: read,NODE_AUTH_TOKEN: ${{ github.token }}기준으로 구성되어 있는가? - [ ] 새 token secret 예외가 있다면 기존 권한 조사, 대체 불가 사유, 권한 범위, 만료/회수 계획, 명시 승인이 기록되어 있는가?
- [ ] 로컬 개발자
yarn install을 위한 GitHub Packages 인증 절차가 README 또는 개발자 문서에 기록되어 있는가? - [ ] EC2 또는 배포 호스트에서 직접
yarn install/yarn build를 실행하는 경우, 설치를 실행하는 OS 사용자 기준 GitHub Packages 인증 절차가 배포 런북에 기록되어 있는가? - [ ] repo
.npmrc에는 registry scope만 있고 token 값이나${NODE_AUTH_TOKEN}placeholder가 없는가? - [ ] 소비자 코드가 package contract를 우회하는 local cast, alias fallback, normalize를 추가하지 않았는가?
- [ ] package dependency와 lockfile 전환 PR에서 legacy generated copy와 copy exact match CI를 제거했는가?
- [ ] 계약 산출물 변경마다 새 package version과 릴리스 증빙이 남았는가?
- [ ] API
main의 published latest stable version과 Admin/Mobilepackage.json및 lockfile의 exact version이 모두 같은가? - [ ] 직접 import하지 않는 계약 symbol을 이유로 active consumer의 version 갱신을 생략하지 않았는가?
- [ ] 소비자 source version 지연 예외가 있다면 owner, 사유, 목표 version, 제거 조건과 목표 시점이 기록되어 있고 현재 source 계약 정렬을 미완료로 유지했는가?