2.5.3 릴리스 실행 기록¶
{
"version": "v2.5.3",
"status": "released",
"releaseScopes": [
"db-migration",
"contracts-package",
"coupler-api",
"coupler-admin-web",
"mobile-store",
"docs"
],
"extraRepoRefs": [],
"versionMapping": {
"docs": {
"tag": "v2.5.3",
"commit": null
},
"coupler-api": {
"tag": "v2.5.3",
"commit": "a089ecd007850004cb3e6ee21224b9ad4e450ba0"
},
"coupler-admin-web": {
"tag": "v2.5.3",
"commit": "475e9b2dcafb2834420688869aca9d348fcf4114"
},
"coupler-mobile-app": {
"store": {
"android": {
"versionBuild": "2.5.0 (105)",
"releaseTag": "v2.5.0",
"commit": "0baa63aee1cc4e64456affdd7b914c80360824e5",
"sourceStatus": "verified",
"limitation": null
},
"ios": {
"versionBuild": "2.5.0 (105)",
"releaseTag": "v2.5.0",
"commit": "0baa63aee1cc4e64456affdd7b914c80360824e5",
"sourceStatus": "verified",
"limitation": null
}
},
"nextPush": null,
"commit": null
}
},
"scopeResults": {
"db-migration": {
"status": "released",
"summary": "API source a089ecd0의 N:N 그룹미팅 강제삭제 migration은 개발계 기존 적용과 pending 0을 확인했고, 운영계에 같은 exact source로 1건 적용한 뒤 pending 0으로 닫았다.",
"evidence": {}
},
"contracts-package": {
"status": "released",
"summary": "API a089ecd0의 packages/contracts tree가 기존 stable 0.1.32 source tree와 동일함을 확인하고 재발행 없이 재사용했다.",
"evidence": {
"publishedPackage": "@coupler-developer/coupler-api-contracts@0.1.32",
"workflow": "https://github.com/coupler-developer/coupler-api/actions/runs/31771588474",
"sourceRef": "c0e70bbe3b8767e3cebdc82072a389ce8b4cf2c3",
"sourceTree": {
"path": "packages/contracts",
"publishedSourceTree": "e76c3329a2f39087d09f587e6379ef32c2ed885f",
"releaseSourceTree": "e76c3329a2f39087d09f587e6379ef32c2ed885f"
}
}
},
"coupler-api": {
"status": "released",
"summary": "고정 source a089ecd0을 운영 root PM2 production에 반영하고 exact runtime·3002 listener·내부/외부 HTTP를 재검증한 직후 v2.5.3 annotated tag로 고정했다. Google Play IAP 401은 IAP source diff 0인 배포 전 기존 운영 장애로 분리한다.",
"evidence": {
"deployment": "2026-08-24 15:55 KST 운영 checkout a089ecd007850004cb3e6ee21224b9ad4e450ba0, clean worktree, frozen install, root PM2 production reload와 save 완료; 16:50 KST 운영 postcheck 직후 원격 v2.5.3 annotated tag의 peeled commit이 a089ecd007850004cb3e6ee21224b9ad4e450ba0임을 확인",
"smoke": "2026-08-24 16:50 KST exact checkout clean, root PM2 online|production|/home/projects/coupler-api, uptime 3323초, node 3002 listener, 내부·외부 HTTP 200, root crontab 조회와 직전 운영본 대비 cron route set 동일을 확인했다. 최근 error log 100줄의 Google Play IAP 401 표식 13건은 계속되지만 직전 운영본 대비 IAP source diff 0으로 기존 운영 장애에 분리했다.",
"publicContract": {
"apiRefs": {
"previous": "a4a6341648c929a8dc5c97a3ca24816eecb117b5",
"current": "a089ecd007850004cb3e6ee21224b9ad4e450ba0"
},
"contractRefs": {
"previous": "@coupler-developer/coupler-api-contracts@0.1.32",
"current": "@coupler-developer/coupler-api-contracts@0.1.32"
},
"consumers": [
{
"state": "present",
"id": "previous-store",
"surface": "mobile-store",
"generation": "previous",
"artifact": {
"kind": "store-builds",
"mappingRef": "Android 2.4.2 (103); iOS 2.4.2 (103)",
"iosVersionBuild": "2.4.2 (103)",
"androidVersionBuild": "2.4.2 (103)"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.30",
"interfaces": ["rest", "websocket", "bootstrap", "version"],
"interfaceInventoryEvidence": "Store 2.4.2 source 37c0da07은 REST, group-chat WebSocket, bootstrap, version 소비 경로를 가진다. v2.5.2에서 이 interface set을 운영 API a4a63416과 검증했다."
},
{
"state": "present",
"id": "current-store",
"surface": "mobile-store",
"generation": "current",
"artifact": {
"kind": "store-builds",
"mappingRef": "Android 2.5.0 (105); iOS 2.5.0 (105)",
"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": "Mobile source 0baa63ae는 contracts 0.1.32의 REST, group-chat WebSocket, bootstrap, version 소비 경로를 유지하고 Android·iOS artifact 품질 Gate를 통과했다."
},
{
"state": "present",
"id": "previous-nextpush",
"surface": "mobile-nextpush",
"generation": "previous",
"artifact": {
"kind": "nextpush-deployment",
"mappingRef": "Android bluedotstudio.official-gmail.com/coupler/Production v31 target 2.4.2; iOS bluedotstudio.official-gmail.com/coupler-ios/Production v28 target 2.4.2",
"ios": {
"app": "bluedotstudio.official-gmail.com/coupler-ios",
"deployment": "Production",
"label": "v28",
"cohort": "100%",
"targetBinary": "2.4.2 (103)"
},
"android": {
"app": "bluedotstudio.official-gmail.com/coupler",
"deployment": "Production",
"label": "v31",
"cohort": "100%",
"targetBinary": "2.4.2 (103)"
}
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.32",
"interfaces": ["rest", "websocket", "bootstrap", "version"],
"interfaceInventoryEvidence": "Production Android v31·iOS v28은 contracts 0.1.32 기반 REST, group-chat WebSocket, bootstrap, version interface를 소비한다."
},
{
"state": "absent",
"id": "current-nextpush",
"surface": "mobile-nextpush",
"generation": "current",
"owner": "mobile release owner",
"absenceEvidence": "v2.5.3 범위에서 새 Production NextPush를 만들지 않았고 Store artifact만 생성·업로드했다."
},
{
"state": "present",
"id": "previous-admin",
"surface": "admin",
"generation": "previous",
"artifact": {
"kind": "admin-build",
"artifactRef": "08e3e3f747b0776c7ee2b866a315a78d031ae081"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.32",
"interfaces": ["rest", "websocket"],
"interfaceInventoryEvidence": "직전 Admin 08e3e3f7 production artifact는 contracts 0.1.32 REST와 기존 concierge WebSocket lifecycle을 소비한다."
},
{
"state": "present",
"id": "current-admin",
"surface": "admin",
"generation": "current",
"artifact": {
"kind": "admin-build",
"artifactRef": "475e9b2dcafb2834420688869aca9d348fcf4114"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.32",
"interfaces": ["rest", "websocket"],
"interfaceInventoryEvidence": "Admin 475e9b2d production artifact는 contracts 0.1.32 REST와 기존 concierge WebSocket lifecycle을 유지하며 운영 그룹미팅 목록을 렌더링했다."
}
],
"cases": [
{"id":"previous-store-rest-current-api","consumerId":"previous-store","interface":"rest","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"API a089ecd0의 contracts tree e76c3329는 직전 운영 API와 같고 기존 REST route와 success envelope를 유지한다."},
{"id":"previous-store-websocket-current-api","consumerId":"previous-store","interface":"websocket","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"API a089ecd0은 직전 운영본의 WebSocket route와 envelope를 변경하지 않았고 전체 API 검증을 통과했다."},
{"id":"previous-store-bootstrap-current-api","consumerId":"previous-store","interface":"bootstrap","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"API a089ecd0은 contracts 0.1.32 tree와 bootstrap 계약을 변경하지 않았다."},
{"id":"previous-store-version-current-api","consumerId":"previous-store","interface":"version","apiGeneration":"current","exposure":"rollback","expected":"success","evidence":"API a089ecd0은 Store 2.4.2 version 확인 route와 응답 계약을 변경하지 않았다."},
{"id":"current-store-rest-current-api","consumerId":"current-store","interface":"rest","apiGeneration":"current","exposure":"post-activation","expected":"success","evidence":"Mobile 0baa63ae와 API a089ecd0은 contracts 0.1.32를 공유하고 생성 artifact가 운영 API origin만 포함함을 확인했다."},
{"id":"current-store-websocket-current-api","consumerId":"current-store","interface":"websocket","apiGeneration":"current","exposure":"post-activation","expected":"success","evidence":"Mobile 0baa63ae group-chat WebSocket 소비 경로와 API a089ecd0의 기존 WebSocket route가 유지된다."},
{"id":"current-store-bootstrap-current-api","consumerId":"current-store","interface":"bootstrap","apiGeneration":"current","exposure":"post-activation","expected":"success","evidence":"Mobile 0baa63ae bootstrap 소비와 API a089ecd0의 동일 contracts tree를 품은 artifact 검증이 통과했다."},
{"id":"current-store-version-current-api","consumerId":"current-store","interface":"version","apiGeneration":"current","exposure":"post-activation","expected":"success","evidence":"Mobile 2.5.0 (105)의 version 소비와 API a089ecd0의 기존 version route가 유지된다."},
{"id":"previous-nextpush-rest-current-api","consumerId":"previous-nextpush","interface":"rest","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"Production NextPush v31·v28이 소비한 REST 계약과 API a089ecd0의 contracts tree는 직전 운영 API에서 변하지 않았다."},
{"id":"previous-nextpush-websocket-current-api","consumerId":"previous-nextpush","interface":"websocket","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"Production NextPush v31·v28의 WebSocket interface와 API WebSocket route는 이번 source에서 변경되지 않았다."},
{"id":"previous-nextpush-bootstrap-current-api","consumerId":"previous-nextpush","interface":"bootstrap","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"Production NextPush v31·v28의 bootstrap interface와 API contracts tree는 이번 source에서 변경되지 않았다."},
{"id":"previous-nextpush-version-current-api","consumerId":"previous-nextpush","interface":"version","apiGeneration":"current","exposure":"rollback","expected":"success","evidence":"Production NextPush v31·v28의 version interface와 API version route는 이번 source에서 변경되지 않았다."},
{"id":"previous-admin-rest-current-api","consumerId":"previous-admin","interface":"rest","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"직전 Admin 08e3e3f7과 API a089ecd0은 contracts 0.1.32를 공유하고 기존 Admin REST route를 유지한다."},
{"id":"previous-admin-websocket-current-api","consumerId":"previous-admin","interface":"websocket","apiGeneration":"current","exposure":"activation","expected":"success","evidence":"직전 Admin concierge WebSocket lifecycle과 API WebSocket route는 이번 source에서 변경되지 않았다."},
{"id":"current-admin-rest-current-api","consumerId":"current-admin","interface":"rest","apiGeneration":"current","exposure":"post-activation","expected":"success","evidence":"Admin 475e9b2d와 API a089ecd0은 contracts 0.1.32를 공유하며 운영 CMS 그룹미팅 목록 REST 렌더링을 확인했다."},
{"id":"current-admin-websocket-current-api","consumerId":"current-admin","interface":"websocket","apiGeneration":"current","exposure":"post-activation","expected":"success","evidence":"Admin 475e9b2d 전체 검증이 기존 concierge WebSocket lifecycle을 유지하고 API WebSocket route는 변경되지 않았다."}
]
},
"runtimeRecovery": {
"strategy": "forward-fix",
"stateSafety": {
"source": "application-evidence",
"persistedState": "운영 migration은 그룹미팅 status CHECK에 EVENT_FORCE_DELETED만 확장하고 기존 row·column을 바꾸지 않았으며 current API a089ecd0이 확장 상태를 처리한다.",
"queuedState": "그룹미팅 강제삭제는 새 queue·outbox·worker를 만들지 않고 기존 cron endpoint set도 직전 운영본과 동일하다.",
"externalEffects": "강제삭제 운영 액션은 smoke에서 실행하지 않았다. 실행 뒤 복구가 필요하면 DB contract를 축소하거나 직전 API로 추정 rollback하지 않고 a089ecd0 기반 검증된 forward fix를 사용한다."
},
"previousReleaseCaseIds": []
}
}
},
"coupler-admin-web": {
"status": "released",
"summary": "main source 475e9b2d의 N:N 강제삭제 관리 UI를 exact 정적 artifact로 운영에 반영하고 nginx·내부/외부 HTTP·로그인 CMS 목록을 확인한 뒤 같은 commit에 v2.5.3 annotated tag를 고정했다.",
"evidence": {
"deployment": "2026-08-24 16:22 KST source 475e9b2dcafb2834420688869aca9d348fcf4114, artifact sha256 960bc4f5518f1999827a2560eb8e8f89ced826189259e634b69bca17acac49d7, active index sha256 4eedb250674615b82756a87aa5bdbfc8c788541cc3888ad0cb833de187e630b0; 16:41 KST 운영 postcheck 직후 v2.5.3 annotated tag의 원격 peeled commit 475e9b2dcafb2834420688869aca9d348fcf4114 확인",
"smoke": "2026-08-24 16:42 KST nginx config/root 정상, 내부 http://127.0.0.1:8000과 외부 https://cms.ritzy.fourhundred.co.kr HTTP 200, 로그인된 /group-meeting/list 목록 렌더링과 각 활성 행의 강제삭제 버튼 노출 확인; 버튼은 실행하지 않았고 CRA 오류 overlay와 화면 alert는 0건",
"rollback": "/var/www/coupler-admin-web-backup-20260824T072256Z에 직전 source 08e3e3f747b0776c7ee2b866a315a78d031ae081과 index sha256 45efcf4e9f47918bc40211108653b03c313688747a6979157b5346f1a6217a26 봉인·재검증"
}
},
"mobile-store": {
"status": "released",
"summary": "exact source 0baa63ae의 Android·iOS 2.5.0 (105)가 양 Store에 공개된 것을 확인하고 같은 source에 Mobile v2.5.0 annotated tag를 고정했다. submission-time marker는 생성되지 않아 사후 제조하지 않고 platform별 한계로 기록한다.",
"evidence": {
"submission": "2026-08-24 16:10 KST 작업자 보고와 iOS Xcode Organizer Uploaded to Apple 화면으로 Android·iOS 2.5.0 (105) artifact 업로드를 확인했다. 이후 양 Store 공개 출시로 심사 제출·승인 완료를 확인했으나 정확한 platform별 제출 시각과 submission-time marker는 보존되지 않았다.",
"approval": "2026-09-03 KST 출시 책임자가 Android·iOS Store 출시를 확인했고, Google Play 공개 페이지의 2.5.0 및 Apple Lookup API의 2.5.0 (105) 공개 상태로 교차 확인했다.",
"release": "Google Play 2.5.0은 2026-08-24 업데이트로 공개됐고 Apple App Store 2.5.0 (105)는 2026-08-25 05:40:06 KST 공개됐다. exact source 0baa63aee1cc4e64456affdd7b914c80360824e5에 Mobile annotated tag v2.5.0을 생성해 원격 peeled commit 일치를 확인했다.",
"smoke": "2026-09-03 KST Google Play와 Apple 공개 Store metadata에서 앱 식별자 com.ritzy.fourhundred 및 출시 버전 2.5.0 / 2.5.0 (105)를 확인했다.",
"artifact": "source 0baa63aee1cc4e64456affdd7b914c80360824e5 clean; Android AAB 109355108 bytes sha256 cc081cb1146ab17676932b25b19a5757dbdd70eeceda96dccfd19a4c11bb05a9, bundle sha256 6a4252725b6274693cf4e8c92576cab6ea6a3adc53f2c7deefc35387508d4286; iOS archive 2.5.0 (105), main.jsbundle sha256 46c8b32c7e1ec2eb00610631fa5764a58b339ecfb5249f7386a2168ac6e5951f, app executable sha256 42f762a69d0ac5a8ce2d60472447c1857df8f4eba314f72665d979ef13a8e882; 양 플랫폼 운영 API 1건·개발 EC2 0건",
"submittedMarkers": {
"android": {
"status": "unavailable-historical",
"tag": null,
"commit": null,
"artifactSha256": null,
"evidence": null,
"deletedEvidence": null,
"limitation": "Android 2.5.0 (105)의 원래 submission-time marker가 생성되지 않았다. 출시 뒤 submitted 태그를 사후 생성하지 않고, 보존된 AAB hash와 exact source 및 실제 Store 출시 태그만 사용한다."
},
"ios": {
"status": "unavailable-historical",
"tag": null,
"commit": null,
"artifactSha256": null,
"evidence": null,
"deletedEvidence": null,
"limitation": "iOS 2.5.0 (105)의 원래 submission-time marker가 생성되지 않았다. 출시 뒤 submitted 태그를 사후 생성하지 않고, 보존된 archive hash와 exact source 및 실제 Store 출시 태그만 사용한다."
}
}
}
},
"docs": {
"status": "released",
"summary": "DB/API/Admin/Mobile Store의 운영 결과와 rollback 기준을 최종 기록으로 고정하고 병합 뒤 docs v2.5.3 태그를 생성한다.",
"evidence": {}
}
},
"apiContractCutover": null
}
문서 역할¶
- 역할:
시나리오 - 문서 종류:
flow - 충돌 시 우선 문서:
policy/release-process.md, 태그 기준은policy/release-tag-policy.md - 기준 성격:
as-is
목적¶
v2.5.3릴리스의 실제 반영 결과와 검증 근거를 한 문서에 고정한다.
범위¶
- 대상:
docs,coupler-api,coupler-admin-web,coupler-mobile-app - 포함 범위: N:N 그룹미팅 강제삭제 migration 1건, contracts 0.1.32 source tree 검증·재사용, API·Admin 운영 배포, Mobile
v2.4.2이후 main 변경과 Store2.5.0 (105), 릴리스 기록 - 제외 범위: 매니저 상세 프로필 URL migration·API·Admin·Mobile 변경, contracts package 재발행, Mobile NextPush
상위 규범 문서¶
릴리스 상태¶
- 목표 버전:
v2.5.3 - 전체 상태:
released - 완료 범위: Mobile
2.5.0 (105)양 Store 공개·v2.5.0태그, DB migration sourcea089ecd007850004cb3e6ee21224b9ad4e450ba0의 개발·운영 적용 대상 잔여 0건, contracts 0.1.32 source tree 검증·재사용, API exact source 운영 반영·postcheck·v2.5.3태그, Admin exact artifact 운영 반영·브라우저 smoke·v2.5.3태그, docs 최종 기록
버전 매핑¶
docs: 기록 버전v2.5.3, 태그v2.5.3, 커밋은 최종 기록 병합 뒤 확정coupler-api: 태그v2.5.3, 커밋a089ecd007850004cb3e6ee21224b9ad4e450ba0coupler-admin-web: 태그v2.5.3, 커밋475e9b2dcafb2834420688869aca9d348fcf4114coupler-mobile-app: Android Store2.5.0 (105), Android 릴리스 태그v2.5.0, Android 커밋0baa63aee1cc4e64456affdd7b914c80360824e5, Android sourceverified, iOS Store2.5.0 (105), iOS 릴리스 태그v2.5.0, iOS 커밋0baa63aee1cc4e64456affdd7b914c80360824e5, iOS sourceverified, NextPushN/A, NextPush 커밋N/A- Store 제출 마커 태그와 증빙 이관/삭제: Android·iOS 모두 submission-time marker 미생성으로
unavailable-historical; 사후 submitted 태그를 만들지 않고 artifact hash·exact source·Store 출시 태그를 최종 근거로 고정
작성 기준¶
- 신규 기록은 템플릿을 직접 복사하지 않고 docs 레포 루트에서
yarn release:record:init v2.5.3로 초기화해 lifecycle registry,content/AGENTS.md인덱스와mkdocs.ymlnav를 같은 변경 단위로 준비한다. - 이 파일은 입력 골격이다. 상태·scope·evidence의 규범과 closed value는
릴리스 프로세스의
릴리스 운영 모델과릴리스 기록 상태값을 따른다. - 위
release-metadata는 docs-onlyplanned시작형이다. 실제releaseScopes와 같은 key만scopeResults에 추가하고,scripts/release-schema.mjs가 정의하지 않은 key나 별도 완료 축을 만들지 않는다. - scope, exact commit, 검증 시나리오와 rollback 기준을 확정하고 현재 PR head에 적용된 필수 CI를 확인한 뒤
전체 상태와 nonterminal
scopeResults를pending으로 전환한다. 전환을 push한 현재 PR head의 필수 CI 성공을 다시 확인하기 전에는 preflight나 운영 실행을 시작하지 않는다. planned | pending | in_progress동안 PR은 Draft로 유지한다. 모든 scope와 전체 상태를 terminal로 닫고 독립 리뷰·최종 검증을 통과한 뒤에만 Ready로 전환해 병합한다.release-metadata가 기계 판정 SoT이고 본문은 사람이 읽는 mirror다. 두 표현의 범위·상태·버전 기준을 맞춘다.- terminal scope는 정책과 descriptor가 요구하는 concrete evidence로 닫는다. placeholder나
N/A로 완료 증빙을 대신하지 않는다. - API contract cutover가 있을 때만
content/templates/api-contract-cutover-gate-template.md를검증 근거아래에 삽입한다. - DB migration은 DB Migration 실행 런북에 따라 개발계와 운영계에 사용한 동일한 마이그레이션 소스 커밋과 최종 pending 0건을 사람이 읽는 결과에 기록한다. 별도 plan·execution artifact는 만들지 않는다.
main에 이미 병합된 terminal 릴리스 기록과 evidence는 수정·삭제·개명·대체하거나 현재 계약으로 재검증하지 않는다. nonterminal 오병합은 릴리스 프로세스의 fail-closed 단일 terminalization만 사용한다.- 개인 사용자명·로컬 home/tmp 경로·secret을 기록하지 않는다. 변동 값에는 확인 시각과 timezone을 남긴다.
- 최종 후보에서
yarn release:preflight --pending-ref <40자 commit SHA>와 적용 docs 품질 Gate를 실행한다.
릴리스 결과¶
- 현재 결과:
released- APIa089ecd0과 Admin475e9b2d의 운영 반영·smoke·각 레포 원격v2.5.3태그, Mobile0baa63ae의 Android·iOS2.5.0 (105)양 Store 공개와 원격v2.5.0태그를 확인했다. Google Play IAP 401은 IAP source diff 0인 배포 전 기존 운영 장애로 분리했고, submission-time marker 미생성은 platform별 역사적 한계로 닫았다.
Mobile Store 배포 내용¶
- 기준: 직전 Store
v2.4.2source37c0da07d22704c3a28723ec6d08758bff0f1aae이후 Mobile main 32개 커밋과 PR #240의2.5.0 (105)버전 고정 - 그룹미팅: 채팅방 알림 설정·Toast·아이콘, 프로필 접근·카드 전달, 남성 프로필 배너, 읽기 전용 나가기와 종료 후기 문구를 보강한다.
- 채팅·스퀘어: drawer 스크롤·키보드 동작과 대댓글 설정 유지 동작을 개선한다.
- 프로필·가입: Android HEIC 업로드, 이미지 실패 안내, 프로필 사진·회원가입 UI와 초대코드 인증 상태를 보정한다.
- 탐색·공통 UX: 라운지 핀, 매칭 일정, 랜덤 프로필·메인 콘텐츠, 결제 Toast, API 성공·회원 제재 구분과 native 호환 설정을 반영한다.
- 제출 후보: Android/iOS
2.5.0 (105), contracts0.1.32, NextPush 실행은 제외한다.
메인 흐름¶
- Mobile release PR #240의 rebase merge source
0baa63aee1cc4e64456affdd7b914c80360824e5를 고정하고 GitHub approval 기록이 없음을 남긴다. - docs 정책 PR #200을 병합하고 이 릴리스 PR을 최신
origin/main에 맞춘 뒤, APIa089ecd007850004cb3e6ee21224b9ad4e450ba0이 fresh APIorigin/main계보에 있는지 확인한다. 별도 API PR이나 main 변경은 하지 않는다. - 같은 Draft docs PR에서 상태를
pending으로 전환하고 현재 head CI와 공통 preflight를 통과한다. - API
a089ecd0source의 강제삭제 migration 1건만 개발계와 운영계에 순서대로 확인·적용한다. - API·Admin 운영 배포와 postcheck를 수행하고 허용된 서비스 태그를 고정한다.
- Mobile
2.5.0 (105)의 양 Store 공개를 확인하고 exact source에v2.5.0annotated tag를 고정했다. submission-time marker는 사후 생성하지 않고 한계로 기록했다. - 같은 docs PR을 terminal 기록으로 닫아 병합한 뒤 docs 태그·Release·Pages를 postcheck한다.
검증 근거¶
- Preflight 명령·결과:
PASS- 2026-08-24 KST, PR #199 head7cd8d284a134a1a0b567d1be9c9df80a87e4009d, docs/API/Admin/Mobile clean·원격 기준점과 고정 SHA 계보 확인; 이 API 운영 결과 기록 변경 뒤 다음 운영 작업 전 새 head CI와 preflight 재실행 필요 - Scope별 Gate·smoke·artifact: Mobile PR #240 head
d53fe50c49077b03a98ed6be9fd20f75152752d3의 lint·format·typecheck·test·Storybook CI 통과, main0baa63aee1cc4e64456affdd7b914c80360824e5에 rebase merge, GitHub reviews 0건. 2026-08-24 16:08 KST Android AAB와 iOS archive2.5.0 (105)생성, exact source clean, 양 플랫폼 운영 API 1건·개발 EC2 0건 확인. Android AAB SHA-256cc081cb1146ab17676932b25b19a5757dbdd70eeceda96dccfd19a4c11bb05a9; iOS main.jsbundle SHA-25646c8b32c7e1ec2eb00610631fa5764a58b339ecfb5249f7386a2168ac6e5951f, executable SHA-25642f762a69d0ac5a8ce2d60472447c1857df8f4eba314f72665d979ef13a8e882; iOS Uploaded to Apple 화면 SHA-2567b3ebf574e6793bde5c699b706439a06cef65f4671c126bdce4f32813f4812f9 - API cutover:
No- APIa089ecd0의packages/contractstree는 직전 운영 API와 동일한0.1.32이며 legacy loungebestwire를 유지한다. 이후 추가된 URL runtime·API·migration은 이번 배포 source에 포함되지 않는다. - DB 마이그레이션 소스 커밋·개발계/운영계 결과: source
a089ecd007850004cb3e6ee21224b9ad4e450ba0; 개발계schema_migrations101행, 강제삭제 migration 기존 적용·pending 0; 운영계 2026-08-24 15:51 KST에20260821131746325_group_meeting_force_delete.sql1건 적용,schema_migrations90→91행, 후속 status pending 0 - Workflow·로그·수동 검증 링크: Mobile PR #240, 고정 SHA 정책 PR #200, 이번 source 이후 URL 기능 PR #222, Admin PR #114. API
a089ecd0은 root PM2 production online·내부/외부 200, IAP source diff 0과 cron route set 동일을 확인하고 원격v2.5.3peeled commit을 고정했다. Google Play IAP 401은 배포 전부터 존재한 별도 운영 장애로 분리한다. Admin475e9b2d는 artifact/index SHA와 nginx root, 내부·외부 200, 운영 CMS/group-meeting/list의강제삭제노출을 확인하고 원격v2.5.3peeled commit을 고정했다.
Mobile 개발계 QA 빌드 기록¶
개발계 QA 빌드가 있을 때만 기록한다. 운영 Store·NextPush·서비스 태그 증빙으로 사용하지 않는다.
- 기록일:
- API 대상:
- iOS TestFlight QA 빌드:
- Android QA APK:
- 운영 릴리스 전 확인:
롤백 기준¶
- DB: migration을 역쿼리하지 않고 ledger와 live schema를 확인한 뒤 forward fix한다.
- API: 직전 운영 API가 강제삭제 migration 이후 schema와 호환된다는 exact evidence가 있을 때만 rollback하고, 없으면
a089ecd0기반의 검증된 forward fix로 복구한다. - Admin:
/var/www/coupler-admin-web-backup-20260824T072256Z에 봉인된 직전 source08e3e3f747b0776c7ee2b866a315a78d031ae081·index SHA로만 원자 복구한다. - Mobile Store: 제출 전에는 배포 효과가 없으며, 제출 뒤에는 플랫폼 콘솔 상태와 submitted marker 기준으로 중단·재제출을 판단한다.
- docs: terminal 병합 전에는 같은 Draft PR에서 기록을 보정하고 병합·태그 뒤에는 수정하지 않는다.
후속 작업¶
- 남은 범위: final PR CI·검증, 병합 뒤 docs
v2.5.3태그·GitHub Release·Pages postcheck. API Google Play IAP 401은 이번 릴리스 회귀가 아닌 별도 운영 장애로 후속한다. - 완료 조건: 충족 - 포함 scope의 실제 증빙과 서비스 태그를 고정했으며 final PR 병합 뒤 docs tag·Release·Pages만 운영 postcheck한다.