ES /docs

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 (즉시)#

  1. 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_foractivate_scheduled! 로 승격시키게 두고, 이후 새 Quote 를 적용.
  2. Cupix::Cron::ScheduledQuote.activate_for 가 Workspace 530 에 대해 실패 로그(Failed to activate scheduled quote on Workspace 530) 를 남긴 이력이 있는지 소급 확인. 있으면 별도 조사 티켓 생성.

별도 실무 티켓 후보 (자동 PR 없음)#

  • UX 문구 개선app/models/quote.rb:168BILL10000 에러 문구가 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: true admin 옵션을 도입할지 (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 대상 없음.