Quote#schedule_apply! — 기존 scheduled_quote 미정리 시 반복 적용 차단
Summary: [Quote][N7KE58TH44] Quote application failed: Billable already has a scheduled quote: 870
결과#
Code-fix 를 skipped 로 마감. RCA(rca.mdx) 가 "코드 변경 불필요" 로 결론지었고, 잔여 액션은 모두 운영 데이터 정리 또는 프런트엔드/영업과의 조율이 필요한 항목이라 자동 code-fix 범위 밖. Jira/worktree/PR 을 생성하지 않음.
Pull Requests#
없음.
변경 내용#
없음.
Hand-off#
RCA 의 즉시 조치·단기 개선 항목을 아래처럼 소유자별로 분리해 이관.
Ops / Billing admin (즉시)#
- Workspace 530 의
scheduled_quote_id(현재870) 및scheduled_billing_started_at정리 여부를 admin/영업 담당과 협의해 결정.- 옵션 A: 예약 취소 후 원하는 새 Quote 를 다시
PUT /api/v1/admin/quotes/{id}/apply. - 옵션 B: Quote 870 시작일 도달을 기다려
Cupix::Cron::ScheduledQuote.activate_for가activate_scheduled!로 승격시키게 두고, 이후 새 Quote 를 적용.
- 옵션 A: 예약 취소 후 원하는 새 Quote 를 다시
Cupix::Cron::ScheduledQuote.activate_for가 Workspace 530 에 대해 실패 로그(Failed to activate scheduled quote on Workspace 530) 를 남긴 이력이 있는지 소급 확인. 있으면 별도 조사 티켓 생성.
별도 실무 티켓 후보 (자동 PR 없음)#
- UX 문구 개선 —
app/models/quote.rb:168의BILL10000에러 문구가scheduled_quote_id(raw id) 를 노출.billable.scheduled_quote.number를 함께 노출하는 방안. admin 이 보게 되는 문구/문서와 함께 조율 필요. - Admin UI 가드 — Workspace/Team billing 화면에서
scheduled_quote_id가 존재할 때 "예약된 Quote (#…) 를 먼저 취소해야 합니다" 안내 및 명시적 취소 흐름. 프런트엔드 담당자와 협의 필요 (RCA §단기 §1). - API 응답 확장 —
Api::V1::Admin::QuotesController#apply응답에existing_scheduled_quote: { id:, number:, scheduled_billing_started_at: }포함. 프런트엔드 계약 변경이므로 조율 필요 (RCA §단기 §2). - 정책 검토 — "billable 당 예약 1개" 하드 제약을 유지할지,
force: true/cancel_existing: trueadmin 옵션을 도입할지 (RCA §장기).
모니터링 (이미 RCA 에 포함, 재게시)#
- Admin quote apply 실패율:
text
sum:trace.rack.request.errors\{service:cupixworks-api,resource_name:api_v1_admin_quotes_controller_apply\}.as_count() - 원인 판별용 로그 카운트:
text
service:cupixworks-api status:error "Billable already has a scheduled quote" - Scheduled quote cron 실패 로그:
text
service:cupixworks-api status:error "Failed to activate scheduled quote"
Cleanup#
Worktree 를 생성하지 않았으므로 cleanup 대상 없음.