콘텐츠로 이동

2.5.5 릴리스 실행 기록

{
  "version": "v2.5.5",
  "status": "released",
  "releaseScopes": [
    "contracts-package",
    "coupler-api",
    "docs"
  ],
  "extraRepoRefs": [
    "coupler-admin-web",
    "coupler-mobile-app"
  ],
  "versionMapping": {
    "docs": {
      "tag": "v2.5.5",
      "commit": null
    },
    "coupler-api": {
      "tag": "v2.5.7",
      "commit": "dabfc71ac74583e01be1c054d8bedc64c740fc52"
    },
    "coupler-admin-web": {
      "tag": null,
      "commit": "44ca0d1acfe02cdd205dc188a957781d26746ac2"
    },
    "coupler-mobile-app": {
      "store": {
        "android": {
          "versionBuild": "2.5.1 (107)",
          "releaseTag": "v2.5.1",
          "commit": "2a9ee166e30d77f827d49ac4ddb643ea775606fa",
          "sourceStatus": "verified",
          "limitation": null
        },
        "ios": {
          "versionBuild": "2.5.1 (107)",
          "releaseTag": "v2.5.1",
          "commit": "2a9ee166e30d77f827d49ac4ddb643ea775606fa",
          "sourceStatus": "verified",
          "limitation": null
        }
      },
      "nextPush": null,
      "commit": null
    }
  },
  "scopeResults": {
    "contracts-package": {
      "status": "released",
      "summary": "stable 0.1.43 발행과 Admin #125·Mobile #265 main의 dependency·lockfile 정렬, 설치 및 품질 Gate를 완료했다.",
      "evidence": {
        "publishedPackage": "@coupler-developer/coupler-api-contracts@0.1.43",
        "workflow": "https://github.com/coupler-developer/coupler-api/actions/runs/33950312627",
        "sourceRef": "dabfc71ac74583e01be1c054d8bedc64c740fc52",
        "sourceTree": {
          "path": "packages/contracts",
          "publishedSourceTree": "a85c9fbbb262b42ca7f99387b9f0d59aa718637c",
          "releaseSourceTree": "a85c9fbbb262b42ca7f99387b9f0d59aa718637c"
        }
      }
    },
    "coupler-api": {
      "status": "released",
      "summary": "개발계·운영계에 dabfc71a를 반영하고 canonical 응답·업데이트 경로·legacy 필드 제거를 확인했으며 API v2.5.7 태그를 고정했다.",
      "evidence": {
        "deployment": "2026-09-05 개발계 development 배포·smoke 후 출시 책임자의 최종 운영 실행 승인으로 16:53:53 KST 운영 배포를 시작했다. frozen install과 PM2 production 설정으로 dabfc71ac74583e01be1c054d8bedc64c740fc52를 반영하고 16:54:07 KST 내부·외부 root HTTP 200을 확인했다. PM2 시작 16:53:57.758 KST·online·재시작 44회, source clean. 16:54:49 KST 기능 postcheck 바로 다음 Gate에서 원격 annotated tag v2.5.7의 peeled commit이 같은 SHA임을 확인했다. DB·cron·CMS 최소 버전·NextPush 변경 없음.",
        "smoke": "개발계 2026-09-05 16:21 KST exact dabfc71a, manager/all 11건·detail/17 url·이미지 HEAD 1건 200, 배포 lounge list/myList/detail presenter pinned=Y·legacy 없음 PASS. 운영 배포 전 16:16 KST exact 1a44d374의 내부 HTTP 기준점과 비교해, 배포 후 16:54:49 KST exact dabfc71a의 공개 HTTPS manager/all 6건·detail/16 image slice 4건·이미지 HEAD 5건 200을 확인했다. 운영 canonical profile_image_path/detail_profile 및 lounge pinned=Y 보존, profile/detail_profile_set/best 없음 PASS. google/apple build105 force_update=2, build107=0, min_version107·Store HTTPS 링크 유지. 라운지는 배포된 순수 presenter 합성 입력이며 로그인 사용자 HTTP나 기기 UI 관측이 아니다. WebSocket·Admin 경로는 불변 source와 기존 CI를 재사용했다. 재시작 전 16:53:55 KST Google Play 구매 조회 permissionDenied 401도 관측되어 cutover와 별도 운영 문제로 남겼다.",
        "publicContract": {
          "apiRefs": {
            "previous": "1a44d3747fbc8042cb1c78021c404ccb62156618",
            "current": "dabfc71ac74583e01be1c054d8bedc64c740fc52"
          },
          "contractRefs": {
            "previous": "@coupler-developer/coupler-api-contracts@0.1.42",
            "current": "@coupler-developer/coupler-api-contracts@0.1.43"
          },
          "consumers": [
            {
              "state": "present",
              "id": "previous-store",
              "surface": "mobile-store",
              "generation": "previous",
              "artifact": {
                "kind": "store-builds",
                "mappingRef": "Store 2.5.0 (105), source 0baa63aee1cc4e64456affdd7b914c80360824e5",
                "iosVersionBuild": "2.5.0 (105)",
                "androidVersionBuild": "2.5.0 (105)"
              },
              "contractRef": "@coupler-developer/coupler-api-contracts@0.1.32",
              "interfaces": [
                "rest",
                "websocket",
                "bootstrap",
                "version"
              ],
              "interfaceInventoryEvidence": "2.5.0 source의 매니저 profile/detail_profile_set, lounge best, concierge WebSocket 및 auth/getSettingList를 조사했다. 지원 최소 build 107 아래의 제품 화면은 지원 종료 대상이며 강제 업데이트 경로는 유지한다."
            },
            {
              "state": "present",
              "id": "current-store",
              "surface": "mobile-store",
              "generation": "current",
              "artifact": {
                "kind": "store-builds",
                "mappingRef": "Android 2.5.1 (107); iOS 2.5.1 (107)",
                "iosVersionBuild": "2.5.1 (107)",
                "androidVersionBuild": "2.5.1 (107)"
              },
              "contractRef": "@coupler-developer/coupler-api-contracts@0.1.41",
              "interfaces": [
                "rest",
                "websocket",
                "bootstrap",
                "version"
              ],
              "interfaceInventoryEvidence": "양 Store source 2a9ee166e30d77f827d49ac4ddb643ea775606fa: profile_image_path/detail_profile/pinned 사용, concierge WebSocket과 설정 조회 유지. 이번에는 새 Store binary를 만들지 않는다."
            },
            {
              "state": "present",
              "id": "previous-ota",
              "surface": "mobile-nextpush",
              "generation": "previous",
              "artifact": {
                "kind": "nextpush-deployment",
                "mappingRef": "existing source 88a6d851e13c3012077ded501b79abe6e577308d; Android v34; iOS v31",
                "android": {
                  "app": "bluedotstudio.official-gmail.com/coupler",
                  "deployment": "Production",
                  "label": "v34",
                  "cohort": "100% mandatory enabled",
                  "targetBinary": "2.5.1"
                },
                "ios": {
                  "app": "bluedotstudio.official-gmail.com/coupler-ios",
                  "deployment": "Production",
                  "label": "v31",
                  "cohort": "100% mandatory enabled",
                  "targetBinary": "2.5.1"
                }
              },
              "contractRef": "@coupler-developer/coupler-api-contracts@0.1.41",
              "interfaces": [
                "rest",
                "websocket",
                "bootstrap",
                "version"
              ],
              "interfaceInventoryEvidence": "2026-09-05 16:09 KST Production history에서 기존 양 platform label·target을 확인했다. source 88a6d851은 공통 시작·복귀 업데이트 gate와 canonical DTO를 사용한다. previous는 이번 API 릴리스 이전에 발행된 artifact 분류다."
            },
            {
              "state": "absent",
              "id": "current-ota",
              "surface": "mobile-nextpush",
              "generation": "current",
              "owner": "릴리스 책임자",
              "absenceEvidence": "이번 API-only cutover에서는 신규 OTA를 발행하지 않는다. 실제 제공 중인 Android v34/iOS v31은 previous-ota inventory로 계속 포함한다."
            },
            {
              "state": "present",
              "id": "previous-admin",
              "surface": "admin",
              "generation": "previous",
              "artifact": {
                "kind": "admin-build",
                "artifactRef": "59cb4862064c0e963bd0a6ce57673996d77ff290"
              },
              "contractRef": "@coupler-developer/coupler-api-contracts@0.1.41",
              "interfaces": [
                "rest",
                "websocket"
              ],
              "interfaceInventoryEvidence": "docs v2.5.4에 고정된 운영 CMS artifact를 유지한다. Admin pinned/매니저 편집 계약과 conciergeRealtime 경로는 API #237에서 변경하지 않았다."
            },
            {
              "state": "present",
              "id": "current-admin",
              "surface": "admin",
              "generation": "current",
              "artifact": {
                "kind": "admin-build",
                "artifactRef": "44ca0d1acfe02cdd205dc188a957781d26746ac2"
              },
              "contractRef": "@coupler-developer/coupler-api-contracts@0.1.43",
              "interfaces": [
                "rest",
                "websocket"
              ],
              "interfaceInventoryEvidence": "Admin #125의 계약 정렬 source와 로컬 production build를 검증하는 후보 inventory다. 새 CMS 배포로 주장하지 않으며 운영 artifact는 previous-admin을 유지한다. package 0.1.41→0.1.43은 package version과 type-only best 삭제뿐이어서 runtime exports는 같다."
            }
          ],
          "cases": [
            {
              "id": "previous-store-rest-activate",
              "consumerId": "previous-store",
              "interface": "rest",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a 공개 HTTPS manager/all 6건·detail/16 image slices 4건·이미지 HEAD 5건 200, 실제 배포 lounge list/myList/detail presenter pinned=Y PASS. profile_image_path/detail_profile/pinned는 유지하고 profile/detail_profile_set/best는 없다. 현재 Store107·기존 OTA source의 canonical 소비와 일치한다. 지원 종료105가 직접 받는 제품 요청은 HTTP 성공하되 legacy 이미지·고정글 표시가 없는 허용된 기능 저하이며, 모든105 요청을 서버가 차단한다고 주장하지 않는다."
            },
            {
              "id": "previous-store-rest-restore-api",
              "consumerId": "previous-store",
              "interface": "rest",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
            },
            {
              "id": "previous-store-websocket-activate",
              "consumerId": "previous-store",
              "interface": "websocket",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
            },
            {
              "id": "previous-store-websocket-restore-api",
              "consumerId": "previous-store",
              "interface": "websocket",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
            },
            {
              "id": "previous-store-bootstrap-activate",
              "consumerId": "previous-store",
              "interface": "bootstrap",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
            },
            {
              "id": "previous-store-bootstrap-restore-api",
              "consumerId": "previous-store",
              "interface": "bootstrap",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
            },
            {
              "id": "previous-store-version-activate",
              "consumerId": "previous-store",
              "interface": "version",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
            },
            {
              "id": "previous-store-version-restore-api",
              "consumerId": "previous-store",
              "interface": "version",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
            },
            {
              "id": "current-store-rest-activate",
              "consumerId": "current-store",
              "interface": "rest",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a 공개 HTTPS manager/all 6건·detail/16 image slices 4건·이미지 HEAD 5건 200, 실제 배포 lounge list/myList/detail presenter pinned=Y PASS. profile_image_path/detail_profile/pinned는 유지하고 profile/detail_profile_set/best는 없다. 현재 Store107·기존 OTA source의 canonical 소비와 일치한다. 지원 종료105가 직접 받는 제품 요청은 HTTP 성공하되 legacy 이미지·고정글 표시가 없는 허용된 기능 저하이며, 모든105 요청을 서버가 차단한다고 주장하지 않는다."
            },
            {
              "id": "current-store-rest-restore-api",
              "consumerId": "current-store",
              "interface": "rest",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
            },
            {
              "id": "current-store-websocket-activate",
              "consumerId": "current-store",
              "interface": "websocket",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
            },
            {
              "id": "current-store-websocket-restore-api",
              "consumerId": "current-store",
              "interface": "websocket",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
            },
            {
              "id": "current-store-bootstrap-activate",
              "consumerId": "current-store",
              "interface": "bootstrap",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
            },
            {
              "id": "current-store-bootstrap-restore-api",
              "consumerId": "current-store",
              "interface": "bootstrap",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
            },
            {
              "id": "current-store-version-activate",
              "consumerId": "current-store",
              "interface": "version",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
            },
            {
              "id": "current-store-version-restore-api",
              "consumerId": "current-store",
              "interface": "version",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
            },
            {
              "id": "previous-ota-rest-activate",
              "consumerId": "previous-ota",
              "interface": "rest",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a 공개 HTTPS manager/all 6건·detail/16 image slices 4건·이미지 HEAD 5건 200, 실제 배포 lounge list/myList/detail presenter pinned=Y PASS. profile_image_path/detail_profile/pinned는 유지하고 profile/detail_profile_set/best는 없다. 현재 Store107·기존 OTA source의 canonical 소비와 일치한다. 지원 종료105가 직접 받는 제품 요청은 HTTP 성공하되 legacy 이미지·고정글 표시가 없는 허용된 기능 저하이며, 모든105 요청을 서버가 차단한다고 주장하지 않는다."
            },
            {
              "id": "previous-ota-rest-restore-api",
              "consumerId": "previous-ota",
              "interface": "rest",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
            },
            {
              "id": "previous-ota-websocket-activate",
              "consumerId": "previous-ota",
              "interface": "websocket",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
            },
            {
              "id": "previous-ota-websocket-restore-api",
              "consumerId": "previous-ota",
              "interface": "websocket",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
            },
            {
              "id": "previous-ota-bootstrap-activate",
              "consumerId": "previous-ota",
              "interface": "bootstrap",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
            },
            {
              "id": "previous-ota-bootstrap-restore-api",
              "consumerId": "previous-ota",
              "interface": "bootstrap",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
            },
            {
              "id": "previous-ota-version-activate",
              "consumerId": "previous-ota",
              "interface": "version",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
            },
            {
              "id": "previous-ota-version-restore-api",
              "consumerId": "previous-ota",
              "interface": "version",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
            },
            {
              "id": "previous-admin-rest-activate",
              "consumerId": "previous-admin",
              "interface": "rest",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a 13파일 diff는 App presenter/type/Swagger와 테스트뿐이며 Admin REST 구현·인가·쓰기 경로는 불변이다. 운영 CMS source 59cb486과 정렬 source 44ca0d1의 차이는 dependency/lockfile뿐이고 package runtime exports는 같다. 기존 Admin 275 tests·CI와 44ca0d1 로컬 production build PASS를 재사용했다. 새 CMS 배포나 인증 사용자 Admin HTTP를 실행한 증빙으로 확대하지 않는다."
            },
            {
              "id": "previous-admin-rest-restore-api",
              "consumerId": "previous-admin",
              "interface": "rest",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
            },
            {
              "id": "previous-admin-websocket-activate",
              "consumerId": "previous-admin",
              "interface": "websocket",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
            },
            {
              "id": "previous-admin-websocket-restore-api",
              "consumerId": "previous-admin",
              "interface": "websocket",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
            },
            {
              "id": "current-admin-rest-activate",
              "consumerId": "current-admin",
              "interface": "rest",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a 13파일 diff는 App presenter/type/Swagger와 테스트뿐이며 Admin REST 구현·인가·쓰기 경로는 불변이다. 운영 CMS source 59cb486과 정렬 source 44ca0d1의 차이는 dependency/lockfile뿐이고 package runtime exports는 같다. 기존 Admin 275 tests·CI와 44ca0d1 로컬 production build PASS를 재사용했다. 새 CMS 배포나 인증 사용자 Admin HTTP를 실행한 증빙으로 확대하지 않는다."
            },
            {
              "id": "current-admin-rest-restore-api",
              "consumerId": "current-admin",
              "interface": "rest",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
            },
            {
              "id": "current-admin-websocket-activate",
              "consumerId": "current-admin",
              "interface": "websocket",
              "apiGeneration": "current",
              "exposure": "activation",
              "expected": "success",
              "evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
            },
            {
              "id": "current-admin-websocket-restore-api",
              "consumerId": "current-admin",
              "interface": "websocket",
              "apiGeneration": "previous",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
            },
            {
              "id": "previous-ota-rest-restore-client",
              "consumerId": "previous-ota",
              "interface": "rest",
              "apiGeneration": "current",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
            },
            {
              "id": "previous-ota-websocket-restore-client",
              "consumerId": "previous-ota",
              "interface": "websocket",
              "apiGeneration": "current",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
            },
            {
              "id": "previous-ota-bootstrap-restore-client",
              "consumerId": "previous-ota",
              "interface": "bootstrap",
              "apiGeneration": "current",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
            },
            {
              "id": "previous-ota-version-restore-client",
              "consumerId": "previous-ota",
              "interface": "version",
              "apiGeneration": "current",
              "exposure": "rollback",
              "expected": "success",
              "evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
            }
          ]
        },
        "runtimeRecovery": {
          "strategy": "previous-release",
          "stateSafety": {
            "source": "application-evidence",
            "persistedState": "1a44d374..dabfc71a는 App 응답 presenter·Swagger·계약 type과 테스트만 변경한다. DB migration·persisted write·설정 변경이 없으므로 같은 DB에서 이전 additive API로 복구한다.",
            "queuedState": "같은 diff에 queue·outbox·worker·cron 변경이 없다. 기존 작업의 format·cursor·재시도·idempotency 상태를 변경하지 않는다.",
            "externalEffects": "결제·푸시·메일·외부 발송 경로는 byte-equivalent다. smoke는 공개 조회와 순수 함수 호출만 사용하고 사용자 데이터 쓰기나 외부 발송을 실행하지 않는다."
          },
          "previousReleaseCaseIds": [
            "previous-store-rest-restore-api",
            "previous-store-websocket-restore-api",
            "previous-store-bootstrap-restore-api",
            "previous-store-version-restore-api",
            "current-store-rest-restore-api",
            "current-store-websocket-restore-api",
            "current-store-bootstrap-restore-api",
            "current-store-version-restore-api",
            "previous-ota-rest-restore-api",
            "previous-ota-websocket-restore-api",
            "previous-ota-bootstrap-restore-api",
            "previous-ota-version-restore-api",
            "previous-admin-rest-restore-api",
            "previous-admin-websocket-restore-api",
            "current-admin-rest-restore-api",
            "current-admin-websocket-restore-api"
          ]
        }
      }
    },
    "docs": {
      "status": "released",
      "summary": "실제 API cutover 결과와 v2.5.7 태그를 고정한 최종 기록을 docs v2.5.5로 마감한다. API 운영 결과·현재 구조·완료된 두 호환 부채를 동기화하고 과거 v2.5.4 기록은 보존한다.",
      "evidence": {}
    }
  },
  "apiContractCutover": {
    "status": "released",
    "contractArtifactSync": {
      "command": "API package publish workflow·consumer package.json/yarn.lock·각 PR verify/CI·최종 git tree 비교",
      "result": "API stable 0.1.43 발행 성공. Admin #125(44ca0d1acfe02cdd205dc188a957781d26746ac2)와 Mobile #265(38185926948846fd04de507376ebb9fb56d83bb1) main 병합·exact pin·설치·CI 완료. Admin 로컬 production build도 성공했다.",
      "consumerPath": "기존 Store 2.5.1(107)과 OTA 88a6d851은 profile_image_path/detail_profile/pinned를 이미 소비한다. 신규 source pin과 설치된 binary package를 혼동하지 않는다."
    },
    "activation": {
      "caseIds": [
        "previous-store-rest-activate",
        "previous-store-websocket-activate",
        "previous-store-bootstrap-activate",
        "previous-store-version-activate",
        "current-store-rest-activate",
        "current-store-websocket-activate",
        "current-store-bootstrap-activate",
        "current-store-version-activate",
        "previous-ota-rest-activate",
        "previous-ota-websocket-activate",
        "previous-ota-bootstrap-activate",
        "previous-ota-version-activate",
        "previous-admin-rest-activate",
        "previous-admin-websocket-activate",
        "current-admin-rest-activate",
        "current-admin-websocket-activate"
      ],
      "appliedAt": "2026-09-05T07:54:49.879Z (KST 16:54:49)",
      "sequenceEvidence": "2026-09-05 출시 책임자가 현재 전제 조사와 cold review 후 운영 배포·문서 병합·정리를 최종 승인하여 종전 2.5.2 초과 출시 연기를 종료했다. 기존 Store107 공개·min107·OTA 유지 → Admin #125·Mobile #265 main 병합 → 개발계 16:21 KST postcheck → docs Draft #215 exact head 132438e9aa3206f024982f43e3c27af8a57031ce·필수 CI3개·release:continue preflight PASS → 기준점 불변 확인 → 운영 16:53:53 KST exact dabfc71a 배포 → 16:54:49 KST case PASS → 바로 다음 Gate에서 API v2.5.7 원격 peeled SHA 일치 → docs 최종화. 전 사용자 업데이트 또는 구버전 요청 0건은 완료 조건에서 제외했다.",
      "bootstrapUpgradeEvidence": "운영 배포 전 2026-09-05 16:06·16:16 KST 및 배포 후 16:54:49 KST에 google/apple build105·107의 설정 조회가 성공했다. 양 플랫폼 min_version107, build105 force_update2/build107 force_update0와 Store HTTPS 링크를 그대로 유지했다."
    },
    "rollback": {
      "caseIds": [
        "previous-ota-rest-restore-client",
        "previous-ota-websocket-restore-client",
        "previous-ota-bootstrap-restore-client",
        "previous-ota-version-restore-client"
      ],
      "sequenceEvidence": "새 OTA/Store 배포가 없으므로 현재 v34/v31과 Store107을 유지한다. API 회귀가 발생하면 previous-release case가 검증된 1a44d374로 PM2를 복구하며, 정상 작동하는 client를 2.5.0으로 내리지 않는다.",
      "cautions": "2.5.0은 최소 지원 build 아래다. rollback은 2.5.1 canonical client와 additive API를 대상으로 하며 과거 schema 변경 이전 API로 되돌리지 않는다."
    }
  }
}

문서 역할

  • 역할: 시나리오
  • 문서 종류: flow
  • 충돌 시 우선 문서: policy/release-process.md, 태그 기준은 policy/release-tag-policy.md
  • 기준 성격: as-is

목적

  • 이미 출시된 Store 2.5.1을 유지하면서 App legacy 응답 필드를 제거한 실제 API 전환을 기록한다.

범위

  • 대상: docs, coupler-api, coupler-admin-web, coupler-mobile-app
  • 포함 범위: Admin/Mobile source 계약 정렬, API 개발계·운영계 cutover, API v2.5.7 및 docs v2.5.5 마감
  • 제외 범위: DB migration, 신규 Store·NextPush·CMS 배포, CMS 강제 업데이트 설정 변경, 과거 릴리스 기록 변경
  • Admin current inventory는 정렬된 source의 검증 build다. 신규 CMS 운영 배포가 아니며 실제 운영 artifact는 previous-admin을 유지한다.
  • 기존 OTA는 previous-ota에 기록한다. current-ota absent는 이번 릴리스에서 새 label을 만들지 않는다는 뜻이다.
  • 별도 Android 2.5.2(108)은 출시 책임자가 제출 완료를 알렸다. 준비 AAB source 1ca40b4b439213b9df4082ff32bd33889eda3957, SHA-256 0559332c7e4700fa041bdda56ad5dd88b33630288c94fc885ea52ef70c2f3b89이며 운영 API와 같은 canonical 필드를 소비한다. 이 릴리스는 108 제출·승인·출시를 수행하거나 완료 Gate로 묶지 않는다. 최소 지원 build107은 유지한다.

상위 규범 문서

릴리스 상태

  • 목표 버전: v2.5.5
  • 전체 상태: released
  • 완료 범위: 계약 source 정렬, API 운영 cutover 및 태그, 최종 docs 기록
  • 대기 범위: N/A

버전 매핑

  • docs: 기록 버전 v2.5.5, 태그 v2.5.5, 커밋 N/A
  • coupler-api: 태그 v2.5.7, 커밋 dabfc71ac74583e01be1c054d8bedc64c740fc52
  • coupler-admin-web: 태그 N/A, 커밋 44ca0d1acfe02cdd205dc188a957781d26746ac2 (source 검증 기준; 운영 artifact는 59cb4862064c0e963bd0a6ce57673996d77ff290 유지)
  • coupler-mobile-app: Android Store 2.5.1 (107), Android 릴리스 태그 v2.5.1, Android 커밋 2a9ee166e30d77f827d49ac4ddb643ea775606fa, Android source verified, iOS Store 2.5.1 (107), iOS 릴리스 태그 v2.5.1, iOS 커밋 2a9ee166e30d77f827d49ac4ddb643ea775606fa, iOS source verified, NextPush N/A, NextPush 커밋 N/A
  • Store 제출 마커 태그와 증빙 이관/삭제: 신규 제출 없음. 기존 증빙은 v2.5.4를 보존한다.

릴리스 결과

  • 현재 결과: released - 개발계·운영계에 dabfc71a를 반영하고 canonical 응답·업데이트 경로·legacy 필드 제거를 확인했으며 API v2.5.7 태그를 고정했다.
  • 변경: App lounge list/myList/detail의 best, manager/all의 profile, manager/detail의 detail_profile_set 제거. Admin 동명 필드·DB·인증 경로는 유지한다.

메인 흐름

  1. Admin #125와 Mobile #265의 계약 정렬을 병합한다.
  2. API #237의 exact source를 개발계·운영계에 순차 반영하고 환경별 결과를 구분한다.
  3. 운영 postcheck 바로 다음에 API tag를 고정하고, 이 최종 기록을 한 번 병합해 docs tag·Release·Pages를 확인한다.

검증 근거

  • Preflight 명령·결과: yarn release:continue v2.5.5; 배포 전 Draft PR #215 exact head 132438e9aa3206f024982f43e3c27af8a57031ce의 필수 CI 3개 및 preflight PASS를 확인하고 같은 서비스 기준점으로 운영 반영했다.
  • Scope별 Gate·smoke·artifact: 개발계 2026-09-05 16:21 KST exact dabfc71a, manager/all 11건·detail/17 url·이미지 HEAD 1건 200, 배포 lounge list/myList/detail presenter pinned=Y·legacy 없음 PASS. 운영 배포 전 16:16 KST exact 1a44d374의 내부 HTTP 기준점과 비교해, 배포 후 16:54:49 KST exact dabfc71a의 공개 HTTPS manager/all 6건·detail/16 image slice 4건·이미지 HEAD 5건 200을 확인했다. 운영 canonical profile_image_path/detail_profile 및 lounge pinned=Y 보존, profile/detail_profile_set/best 없음 PASS. google/apple build105 force_update=2, build107=0, min_version107·Store HTTPS 링크 유지. 라운지는 배포된 순수 presenter 합성 입력이며 로그인 사용자 HTTP나 기기 UI 관측이 아니다. WebSocket·Admin 경로는 불변 source와 기존 CI를 재사용했다. 재시작 전 16:53:55 KST Google Play 구매 조회 permissionDenied 401도 관측되어 cutover와 별도 운영 문제로 남겼다.
  • API cutover: Yes - 운영 legacy wire 필드 실제 제거
  • DB 마이그레이션: N/A - API #237의 diff에 DB schema·migration·write 변경이 없다.
  • Workflow: API #237 전체 CI 성공 및 contracts 발행 workflow, Admin 275 tests, Mobile 886 tests와 Storybook 57 tests 성공
  • 검증 경계: 매니저·설정은 live HTTP, 라운지는 실제 배포된 순수 presenter의 합성 입력 검증이다. 로그인한 사용자 라운지 화면이나 기기 UI를 새로 관측했다는 기록이 아니다. WebSocket은 변경 없음과 기존 CI를 재사용한다.

API contract cutover Gate

  • Cutover 상태: released
  • Contract artifact sync:
    • 명령: API package publish workflow·consumer package.json/yarn.lock·각 PR verify/CI·최종 git tree 비교
    • 결과: API stable 0.1.43 발행 성공. Admin #125(44ca0d1acfe02cdd205dc188a957781d26746ac2)와 Mobile #265(38185926948846fd04de507376ebb9fb56d83bb1) main 병합·exact pin·설치·CI 완료. Admin 로컬 production build도 성공했다.
    • published package: @coupler-developer/coupler-api-contracts@0.1.43
    • Mobile/Admin consumer path: 기존 Store 2.5.1(107)과 OTA 88a6d851은 profile_image_path/detail_profile/pinned를 이미 소비한다. 신규 source pin과 설치된 binary package를 혼동하지 않는다.
  • Activation:
    • Activation case IDs: previous-store-rest-activate,previous-store-websocket-activate,previous-store-bootstrap-activate,previous-store-version-activate,current-store-rest-activate,current-store-websocket-activate,current-store-bootstrap-activate,current-store-version-activate,previous-ota-rest-activate,previous-ota-websocket-activate,previous-ota-bootstrap-activate,previous-ota-version-activate,previous-admin-rest-activate,previous-admin-websocket-activate,current-admin-rest-activate,current-admin-websocket-activate
    • Activation 적용 시각: 2026-09-05T07:54:49.879Z (KST 16:54:49)
    • Activation 순서 증빙: 2026-09-05 출시 책임자가 현재 전제 조사와 cold review 후 운영 배포·문서 병합·정리를 최종 승인하여 종전 2.5.2 초과 출시 연기를 종료했다. 기존 Store107 공개·min107·OTA 유지 → Admin #125·Mobile #265 main 병합 → 개발계 16:21 KST postcheck → docs Draft #215 exact head 132438e9aa3206f024982f43e3c27af8a57031ce·필수 CI3개·release:continue preflight PASS → 기준점 불변 확인 → 운영 16:53:53 KST exact dabfc71a 배포 → 16:54:49 KST case PASS → 바로 다음 Gate에서 API v2.5.7 원격 peeled SHA 일치 → docs 최종화. 전 사용자 업데이트 또는 구버전 요청 0건은 완료 조건에서 제외했다.
    • 이전 client bootstrap/upgrade 증빙: 운영 배포 전 2026-09-05 16:06·16:16 KST 및 배포 후 16:54:49 KST에 google/apple build105·107의 설정 조회가 성공했다. 양 플랫폼 min_version107, build105 force_update2/build107 force_update0와 Store HTTPS 링크를 그대로 유지했다.
  • Client rollback:
    • Client rollback case IDs: previous-ota-rest-restore-client,previous-ota-websocket-restore-client,previous-ota-bootstrap-restore-client,previous-ota-version-restore-client
    • Rollback 순서 증빙: 새 OTA/Store 배포가 없으므로 현재 v34/v31과 Store107을 유지한다. API 회귀가 발생하면 previous-release case가 검증된 1a44d374로 PM2를 복구하며, 정상 작동하는 client를 2.5.0으로 내리지 않는다.
    • Client rollback 주의 사항: 2.5.0은 최소 지원 build 아래다. rollback은 2.5.1 canonical client와 additive API를 대상으로 하며 과거 schema 변경 이전 API로 되돌리지 않는다.

롤백 기준

  • API: 1a44d3747fbc8042cb1c78021c404ccb62156618로 복구하면 canonical과 legacy를 함께 제공한다. DB·queue·외부효과가 바뀌지 않은 exact 직전 source만 허용한다.
  • Client: 이번에 배포하지 않은 기존 Store107·OTA v34/v31을 유지한다. 지원 종료 build105로 내리지 않는다.
  • Docs: 실제 API 전환 결과만 같은 Draft PR에서 최종화한다. 기존 완료된 릴리스 문서는 수정하지 않는다.

후속 작업

  • 완료 정리: 라운지 best 및 App 매니저 이미지 legacy wire 호환 대기 두 항목을 제거하고, 현행 라운지·매니저 설명과 문서 회귀 테스트를 canonical 응답에 맞췄다. URL-encoded parser 등 별도 호환 경로는 이번 제거 범위가 아니다.
  • 별도 운영 확인: Google Play 구매 조회 permissionDenied 401은 새 프로세스 시작 전에도 관측됐다. 결제 코드·권한·credential을 이번 릴리스에서 변경하지 않았으며 이 오류의 해결을 주장하지 않는다. 토큰·회원 데이터는 기록하지 않는다.
  • 남은 범위: 이번 cutover 범위 없음. 신규 Store/OTA 출시는 이 기록과 독립적으로 진행한다.
  • 완료 조건: 운영 exact source, 최소 지원 build107의 업데이트 경로와 canonical 제품 응답, 허용된 이전 요청 결과 및 복구 기준이 확인된 상태