ES /docs

ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'capture_ids' in 'field list'

Fix Plan: ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'name' in 'field list'

RCA 에서 사용자가 선택한 단기 개선 (1주 이내) 항목만 구현한다. "즉시 조치(Critical)" 및 "장기 개선" 섹션은 범위에서 제외한다.

단기 개선 항목:

  1. _entity_ancestry 의 조상 목록 중 대상 테이블에 name 컬럼이 없는 조상(:record)에 대해 name 조회를 건너뛴다.
  2. batch preload 경로(AncestorCache#preload)가 동일한 컬럼 부재 문제를 갖는지 확인 — 실제로 records.namepluck 하여 같은 오류를 발생시키므로 함께 수정한다.

develop 스키마 확인 결과, ancestor 테이블 중 recordsname 컬럼이 없다 (team/workspace/building/capture/level/bim/annotation_layer 은 모두 존재). 따라서 두 경로 모두 klass.column_names.include?('name') 정적 가드로 통합 처리하면 records 만 안전하게 건너뛰고 나머지 조상은 기존 동작을 유지한다. DB 왕복 자체를 없애므로 실패 SQL / APM error span 노이즈가 사라진다.

Changes#

tesla: app/models/concerns/entity_indexable.rb#

  • What: _ancestor_name (runtime 경로) 에서 klass.where(id: ancestor_id).pick(:name) 실행 전에 klass.column_names.include?('name') 가드를 추가한다. name 컬럼이 없는 클래스(Record)면 조회 없이 nil 반환.
  • Why: root cause — records 테이블에 name 컬럼이 없는데 pick(:name)SELECT name FROM records ... 를 발행 → Unknown column 'name' in 'field list'. rescue StandardError 로 삼켜지지만 재인덱싱마다 실패 SQL round-trip + mysql2 APM error span 노이즈 발생. 컬럼 존재 여부는 정적으로 판정 가능하므로 DB 왕복 자체를 제거한다.
  • Lines: _ancestor_name 메서드 (약 168-177)

tesla: app/models/concerns/entity_indexable.rb#

  • What: AncestorCache#preload (batch 경로) 에서 @names[key] = klass.where(id: ids).pluck(:id, :name).to_h 실행 전에 동일한 klass.column_names.include?('name') 가드를 추가한다. name 컬럼이 없으면 해당 key 를 preload 하지 않는다 (ancestor_name@names.key?(key) false 로 nil 반환하므로 정합).
  • Why: 단기 개선 2번 항목 — batch backfill 경로도 records 에 대해 pluck(:id, :name) 을 실행하여 동일한 Unknown column 'name' 를 유발한다. preloadrescue StandardError => next 가 해당 key 전체를 건너뛰어(다른 ancestor name 도 유실 가능) 조용히 삼키므로, 가드로 실패 SQL 자체를 제거하고 다른 조상 preload 를 보존한다.
  • Lines: AncestorCache#preloadCACHE_ANCESTOR_FIELDS.each 루프 (약 116-127)

Acceptance Criteria#

  • _ancestor_namepick(:name) 호출 전에 column_names.include?('name') (또는 동등) 가드를 갖는다.
  • AncestorCache#preloadCACHE_ANCESTOR_FIELDS.each 루프가 pluck(:id, :name) 전에 동일 가드를 갖는다.
  • Record (records 테이블, name 컬럼 없음) 은 두 경로 모두에서 name 조회 SQL 을 발행하지 않는다.
  • team/workspace/building/capture/level/bim/annotation_layer (name 컬럼 존재) 은 기존과 동일하게 name 을 조회한다.
  • ruby -c 문법 검사 통과, bundle exec rubocop app/models/concerns/entity_indexable.rb offense 0.

Tests#

  • 기존 테스트: spec/models/concerns/entity_indexable_spec.rb (존재 시). cupixworks-api 관례상 agent env 에서 rspec 은 실행하지 않고 ruby -c + rubocop 으로 검증.
  • 신규 테스트: 추가하지 않음 (최소 변경 원칙; TRIVIAL 가드 추가).