Conversation
* docs: 미완료 작업과 막힌 지점을 한 파일로 정리한다 ROADMAP 은 작업 순서를, Issue 는 개별 작업을 다루지만 "무엇이 누구 손에 막혀 있는가" 를 보여 주는 곳이 없었다. 사람만 할 수 있는 것(인증서 발급·Cloudflare 대시보드·오리진 리전)이 그 틈에 있었다. 스냅샷으로 설계했다. SSOT 는 ROADMAP 과 Issue 이고, 이 파일은 그 둘이 다루지 않는 축만 담는다. 항목마다 "어떻게 확인하는지" 를 적었다 — 낡은 문서가 끝난 일을 가리키면 다음 사람이 그것을 다시 판다(이번 세션에 네 번 있었다: #115·#116·#117 이 닫혔는데 §3 이 1순위로 적고 있었고, #367·#370·#372·#376 이 main 에 반영된 뒤에도 열려 있었다). "검증 안 된 것" 절을 따로 둔 이유는, 검증되지 않은 것을 검증된 것처럼 기억하는 일이 실제로 있었기 때문이다. 하트비트는 dev 실측만 있고 운영 실측이 없으며, `afterEventId=0` 스트림이 오래 산 것을 하트비트의 증거로 잘못 보고한 적도 있다. 그래서 검증된 것과 안 된 것을 같은 표에 나란히 적었다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93 * docs: Let's Encrypt 인증서 완료를 반영한다 발급·교체·갱신 리허설까지 끝났다. 검증 켠 상태로 오리진에 HTTPS 가 붙는 것으로 확인했다(전에는 code=000). 두 가지를 기록으로 남겼다. 첫 발급 시도가 522 로 실패했다 — Cloudflare 가 오리진에 닿지 못해 HTTP-01 챌린지도 닿지 못했다. 엣지가 불안정할 때 쓰려고 만드는 우회로를 바로 그 불안정 때문에 만들 수 없었다. 비상 대비는 평시에 해 둬야 한다. 그리고 80 포트 블록의 `server` 직속 `return` 이 ACME location 을 삼키고 있었다. `return` 은 rewrite 단계라 location 선택보다 먼저 실행된다 — `location /` 로 내려야 `^~` 가 이긴다. 이 수정은 90일마다 도는 자동 갱신에도 필요했다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93 * docs: #344 항목을 "배포됨 / 효과 미관측" 으로 가른다 직전 커밋에서 "애초에 운영에 배포되지 않았다" 로 남겨 뒀는데, 그 사이 PR #389 로 배포했으니 사실이 아니게 됐다. 문서가 스스로 낡는 것을 그 자리에서 고친다. 다만 "배포됨" 과 "효과 관측됨" 은 다르다. ECR lifecycle 은 다음 배포가 ensureRepo 를 부를 때 걸리고 EIP release 는 다음 부트 타임아웃에야 돈다 — 둘 다 사건이 일어나야 보인다. 그래서 확인 방법을 같이 적었다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
두 승인 게이트가 대화 메시지 본문에 태스크의 previewUrl 을 넣고 있었다. 그런데
POST /preview-sessions/{id}/access 가 accessToken 을 회전시켜 이전 주소를 죽인다
(G4, #77). 사용자가 화면에서 프리뷰를 여는 것이 곧 그 호출이므로, 이 링크는
사용자가 프리뷰를 여는 순간 404 가 되고 대화 이력은 남으므로 영구히 죽은 링크가
된다.
BE 가 스스로 이걸 문서화해 놓고 있었다 — PreviewSessionController:47 이 "이전에
받은 주소(작업 응답의 previewUrl 포함)는 즉시 404가 됩니다" 라고 적는다. 알면서
그 URL 을 메시지에 넣고 있었다.
2026-09-25 dev 검증에서 실제로 걸렸다. nginx 로그가 둘을 가른다 — 회전된 새
토큰으로 연 iframe 은 200(cafe-home 자산 전부), 대화창 링크의 옛 토큰은 404.
FE 코드는 #77 때 이미 방어돼 있었는데도 그 메시지를 믿고 움직인 쪽은 죽은 주소를
잡았다.
안내조차 남기지 않았다. 승인 카드가 이미 화면에 프리뷰와 함께 뜨므로 주소도
안내도 중복이고, 주소는 거기에 해롭기까지 했다.
FRONTEND_API_GUIDE.md 483행도 고쳤다. "previewUrl 은 태스크 응답에서 얻습니다"
라고만 적혀 있어 501행("반드시 access 응답의 previewUrl 을 사용")과 충돌했다 —
483행만 읽으면 죽은 주소를 쓴다.
필드 이름이 같은 것이 함정의 뿌리라는 건 #392 로 분리했다(호환 깨는 변경).
Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
dldnsgkr
added a commit
that referenced
this pull request
Sep 25, 2026
pending-actions.md §0 릴리스 현황 — 미릴리스 2건(#395, V65 포함이라 백업 필요)으로 갱신하고 직전 릴리스(PR #394, #391+#390) 검증 결과를 남긴다 §1-3 오리진 리전 — 09-26 측정을 세 번째 데이터 포인트로 추가. 사흘 연속이라 일시적 사고로 볼 수 없다. 같은 시점 오리진 15/15 vs 엣지 9/15(SJC) §2-3 #318 — FE 갤러리도 프로덕션에 나갔으므로 닫을 수 있다 §2-6 #392 신규 — previewUrl 이 계약 셋이라는 것과 FE 와 합의한 3단계 순서. dev 는 require-access-cookie 가 false 라 검증이 반드시 통과한다는 경고 포함 §2-7 #395 신규 — 코드 완료, 릴리스 남음 §4 FE 현황 — #115/#117/#118. 특히 #118 은 카탈로그 실패 시 다섯 화면이 거짓말하던 것을 고쳤다(/project/new 가 멀쩡한 템플릿을 없어졌다고 단언) ROADMAP.md §1 — 2026-09-26 항목. #395 두 구멍, jar 폴백을 뺀 이유, @transactional 로 한 번 틀린 기록, 역검증 6건과 민감도 확인, 그 과정에서 본 거짓 통과("0건 실패"가 실은 낡은 XML), dev 실측. api.md §17.3 확장 · §17.4 신규는 PR #396 에 함께 나갔다. Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
승인 메시지에서 사용자가 프리뷰를 여는 순간 죽는 preview 링크를 뺀다.
DB 마이그레이션 없음 — Flyway V64 그대로. 롤백은 이전 아티팩트 복귀로 끝난다.
지금 릴리스하는 이유 — FE 갤러리가 방금 프로덕션에 나갔다
Dvely_FE#115(da1ac96)가 main 에 들어가면서 템플릿 갤러리가 프로덕션에 있다. 즉 이제 실제 사용자가 템플릿으로 프로젝트를 만들고 RESULT 승인 카드를 본다.어제까지는 그 경로를 타는 사용자가 거의 없었는데, 지금은 템플릿을 고른 사용자가 반드시 그 카드를 본다. 그 카드에 들어 있는 링크가 죽는 링크다.
문제
두 승인 게이트가 대화 메시지 본문에 태스크의
previewUrl을 넣고 있었다.POST /preview-sessions/{id}/access가 accessToken 을 회전시켜 이전 주소를 죽인다(G4, #77). 사용자가 화면에서 프리뷰를 여는 것이 곧 그 호출이므로:BE 가 스스로 이걸 문서화해 놓고 있었다 —
PreviewSessionController:47이 "이전에 받은 주소(작업 응답의previewUrl포함)는 즉시 404가 됩니다" 라고 적는다. 알면서 그 URL 을 메시지에 넣고 있었다.실제로 걸린 기록
2026-09-25 dev 검증(project 63,
cafe-home). nginx 로그가 둘을 가른다:FE 코드는 #77 때 이미 방어돼 있었다. 그런데도 이 메시지를 믿고 움직인 쪽은 죽은 주소를 잡았다 — 방어가 한 곳에만 있으면 부족했다.
고친 내용
주소를 뺀다. 안내조차 남기지 않았다 — 승인 카드가 이미 화면에 프리뷰와 함께 뜨므로 주소도 안내도 중복이고, 주소는 거기에 해롭기까지 했다.
docs/FRONTEND_API_GUIDE.md483행도 고쳤다. "previewUrl 은GET /agent/tasks/{taskId}응답에서 얻습니다" 라고만 적혀 501행("반드시 access 응답의 previewUrl 을 사용")과 충돌했다 — 483행만 읽으면 죽은 주소를 쓴다.함께 나가는 문서
docs/pending-actions.md(#390) — 남은 작업과 무엇이 누구 손에 막혀 있는가. 코드 변경 없음.검증
f09b4a6)배포 전 조치
운영 DB 백업 완료·검증:
/home/ubuntu/dvely-prod-backup-20260925-235051.sql.gz(33/33 테이블, 완료 마커, gzip 무결성 OK).별건
두 응답이 같은
previewUrl이름을 쓰고 하나만 유효한 것이 함정의 뿌리다 — #392 로 분리했다(호환 깨는 변경이고 FE 는 main 머지가 곧 프로덕션이라 순서를 맞춰야 한다).Closes #391
🤖 Generated with Claude Code
https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93