Skip to content

Snapshot Schema

JEONG edited this page Sep 7, 2026 · 1 revision

스냅샷 스키마

apicov scan --out coverage.json 이 뱉는 파일의 구조입니다. 정의는 Sources/StellaCore/Snapshot/CoverageSnapshot.swift 하나에 다 들어 있고 HTML 리포트·diff·Stella 앱이 전부 이 파일만 읽습니다.

인코딩 규칙은 SnapshotEncoder 가 고정합니다.

  • 키를 알파벳 순으로 정렬하고 (.sortedKeys) 들여쓰기를 넣습니다 (.prettyPrinted)
  • 슬래시를 이스케이프하지 않습니다 — 경로가 /auth/login 그대로 보입니다
  • 모든 날짜는 ISO 8601 문자열입니다

같은 입력이면 같은 바이트가 나오므로 스냅샷을 커밋해두고 git diff 로 변화를 봐도 됩니다.


최상위

{
  "schemaVersion": 1,
  "generatedAt": "2026-09-07T15:09:37Z",
  "openAPI": { "title": "Mini API", "version": "1.0.0", "totalPaths": 4 },
  "projects": [ ... ],
  "endpoints": [ ... ],
  "unmatchedRouterCases": [ ... ],
  "summary": { "appProduct": { ... }, "umcApp": { ... } }
}
필드 타입 설명
schemaVersion Int 현재 1. 형식이 깨지게 바뀌면 올립니다
generatedAt ISO 8601 스캔 시각
openAPI 객체 스펙 요약 — title · version · totalPaths
projects 배열 스캔한 프로젝트 목록
endpoints 배열 스펙의 모든 오퍼레이션
unmatchedRouterCases 배열 코드에는 있는데 스펙에 못 붙은 Router case
summary 객체 프로젝트 key → 집계

openAPI.totalPaths 는 경로 수가 아니라 오퍼레이션 수입니다. /users 에 GET·POST 가 둘 다 있으면 2 로 셉니다.

projects

[
  { "key": "appProduct", "displayName": "AppProduct", "rootPath": "Fixtures/MiniRepo/AppProduct" },
  { "key": "umcApp",     "displayName": "UMCApp",     "rootPath": "Fixtures/MiniRepo/UMCApp" }
]

keyendpoints[].connectionssummary 의 키로 그대로 쓰입니다. rootPath 는 스캔할 때 넘긴 경로를 그대로 담으므로 상대 경로면 상대 경로로 남습니다.

endpoints[]

스펙에 있는 오퍼레이션 하나가 항목 하나입니다. 코드에 연결이 없어도 항목은 남고 connections 값만 null 이 됩니다.

{
  "key": { "method": "POST", "path": "/auth/login" },
  "tag": "Auth",
  "operationId": "login",
  "summary": "로그인",
  "parameters": [],
  "responses": [],
  "owner": {
    "email": "tester@example.com",
    "name": "테스터",
    "displayName": "테스터",
    "githubUsername": "tester"
  },
  "connections": {
    "appProduct": null,
    "umcApp": {
      "routerEnum": "AuthRouter",
      "caseName": "login",
      "filePath": "Fixtures/MiniRepo/UMCApp/Features/Auth/Data/Sources/AuthRouter.swift",
      "line": 6,
      "author": { "email": "dev@example.com", "name": "DEV", "displayName": "DEV" },
      "lastCommitSHA": "cafca8cb4dc1c2d7470b8187ad467f55c93d3106",
      "lastCommitDate": "2026-04-29T07:27:59Z"
    }
  }
}
필드 타입 설명
key { method, path } 오퍼레이션 식별자. methodGET·POST·PUT·PATCH·DELETE
tag String? 스펙의 첫 번째 태그
operationId String? 스펙의 operationId
summary · description String? 스펙 설명문
parameters 배열 name · location · required · description · schema
requestBody · requestBodyExample String? 요청 본문 스키마와 예시
responses 배열 statusCode · description · content · example
owner AuthorRef? owners.yml 로 지정한 담당자. 없으면 필드 자체가 빠집니다
connections [프로젝트 key: Connection?] 프로젝트별 연결

값이 없는 옵셔널 필드는 JSON 에서 통째로 빠집니다. 빈 배열은 그대로 [] 로 남습니다.

Connection

필드 설명
routerEnum · caseName 어느 enum 의 어느 case 인지
filePath · line 소스 위치. --blame-root 기준 상대 경로
author 해당 줄을 마지막으로 만진 사람 (git blame + authors.yml)
lastCommitSHA · lastCommitDate blame 이 가리키는 커밋

blame 이 실패하면 (커밋 안 된 파일 등) 연결은 그대로 남고 author.nameUnknown, SHA 는 빈 문자열, 날짜는 1970 년이 됩니다.

한 엔드포인트에 여러 case 가 매치되면 먼저 발견된 하나만 기록됩니다.

AuthorRef

{ "email": "dev@example.com", "name": "DEV", "displayName": "제옹", "githubUsername": "euijjang97" }

email · name 은 git 이 준 값 그대로, displayName · githubUsernameauthors.yml 이 채웁니다. 매핑이 없으면 displayNamename 을 그대로 쓰고 githubUsername 은 빠집니다.

unmatchedRouterCases[]

{
  "project": "umcApp",
  "routerEnum": "AuthRouter",
  "caseName": "legacySignup",
  "filePath": "UMCApp/Features/Auth/Data/Sources/AuthRouter.swift",
  "line": 21,
  "reason": "no OpenAPI entry for POST /auth/signup-v1"
}

reason 은 세 가지 중 하나입니다.

reason
no OpenAPI entry for {METHOD} {경로} 정규화까지 마쳤는데 스펙에 같은 엔드포인트가 없음
missing path or method arm pathmethod 를 파싱하지 못했거나 메서드가 5종 밖
ignored: {사유} overrides.yml 에서 ignore 로 지정

ignored: 는 문제가 아니라 의도적으로 제외한 항목이라는 표시입니다. 다만 summary.unmatched 에는 함께 잡히니 수치를 볼 때 감안하세요.

summary

"summary": {
  "appProduct": { "matched": 3, "missing": 1, "unmatched": 0 },
  "umcApp":     { "matched": 1, "missing": 3, "unmatched": 0 }
}

matched매치된 Router case 수입니다. 연결된 엔드포인트 수가 아닙니다. 계산 방식과 주의점은 매칭 파이프라인 에 정리해뒀습니다.


스냅샷 읽는 쪽

schemaVersion 을 올리면 아래가 전부 영향을 받습니다.

소비자 위치
HTML 리포트 apicov reportSources/apicov/Output/HTMLReportFormatter.swift
변화 비교 apicov diffSources/apicov/Output/DiffFormatter.swift
Stella 앱 Sources/StellaApp — 스냅샷을 열거나 스캔 직후 메모리에서 받습니다

diffendpoints[].connectionsnull ↔ 값 전환만 봅니다. 같은 엔드포인트가 다른 case 로 옮겨간 경우는 변화로 잡히지 않습니다.


관련: 매칭 파이프라인 · CLI 레퍼런스 · 매핑 YAML

Clone this wiki locally