• #Nuxt
  • #Vue
  • #OCR
  • #UI実装
  • #トラブルシューティング
開発メモ

OCRバリデーションUIの3カラムレイアウト実装

結論

OCR Checkerの検証UIを3カラムテーブルレイアウトで実装した。「OCR結果」「読取確認」「判定」の3列で、OCR結果とサブエージェント読取値を並べて比較できる。

実装後、「読取確認」カラムに値が表示されない問題が発生した。原因はバックエンドサーバーの再起動忘れだった。

背景

税理士業務のレシートOCR処理において、以下の要件があった。

  • OCR結果(編集可能)とサブエージェントの読取値を並べて表示したい
  • 両者の一致/不一致を視覚的に判定したい
  • 信頼度に応じて枠線の色を変えたい

実装内容

3カラムテーブル構造

| OCR結果(編集可能) | 読取確認(参照のみ) | 判定 |
|-------------------|-------------------|-----|
| 2024/03/27        | 2024/03/27        | ✓   |
| 180               | 180               | ✓   |
| 地下鉄運賃(きっぷ)  | きっぷ(交通費)     | ×   |
| 東京地下鉄株式会社   | 東京メトロ 半蔵門駅  | ×   |

APIレスポンスの拡張

ocr_server.pyにサブエージェント読取値と信頼度を追加。

if validation:
    result["validation"] = {
        # 既存フィールド
        "overall_score": validation.get("overall_score"),
        "date_score": validation.get("date_score"),
        # ...

        # サブエージェント読取値(追加)
        "read_date": validation.get("read_date") or "",
        "read_amount": validation.get("read_amount"),
        "read_payee": validation.get("read_payee") or "",
        "read_summary": validation.get("read_summary") or "",

        # サブエージェント信頼度(追加)
        "date_confidence": validation.get("date_confidence"),
        "amount_confidence": validation.get("amount_confidence"),
        "payee_confidence": validation.get("payee_confidence"),
        "summary_confidence": validation.get("summary_confidence"),
    }

フロントエンドの型定義

api.tsReceiptValidationインターフェースを拡張。

export interface ReceiptValidation {
  overall_score: number
  date_score: number
  date_comment: string
  // ...

  // サブエージェント読取値
  read_date: string
  read_amount: number | null
  read_payee: string
  read_summary: string

  // サブエージェント信頼度
  date_confidence: number | null
  amount_confidence: number | null
  payee_confidence: number | null
  summary_confidence: number | null
}

Vue コンポーネント

ReceiptForm.vueでヘルパー関数を定義。

// サブエージェント読取値を取得
const getReadValue = (field: 'date' | 'amount' | 'payee' | 'summary') => {
  if (!validation.value) return null
  const key = `read_${field}` as keyof ReceiptValidation
  return validation.value[key] as string | number | null
}

// 一致判定(スコア90%以上を一致とみなす)
const isMatch = (field: 'date' | 'amount' | 'payee' | 'summary') => {
  const score = getFieldScore(field)
  if (score === null) return null
  return score >= 90
}

// 信頼度に基づく枠線CSSクラス(紫系)
const getBorderClass = (score: number | null) => {
  if (score === null) return ''
  if (score >= 90) return 'border-high'    // 薄い紫
  if (score >= 60) return 'border-medium'  // 中程度の紫
  return 'border-low'                       // 濃い紫 + 背景色
}

テンプレートで3カラムレイアウトを構成。

<div class="field-table">
  <div class="field-table-header">
    <div class="col-header">OCR結果</div>
    <div class="col-header">読取確認</div>
    <div class="col-header">判定</div>
  </div>

  <div class="field-row">
    <div class="field-label">日付</div>
    <div class="field-cols">
      <div class="col-ocr"><!-- 編集可能な入力フィールド --></div>
      <div class="col-read" :class="getBorderClass(getFieldScore('date'))">
        <span v-if="getReadValue('date')">{{ getReadValue('date') }}</span>
        <span v-else class="no-value">-</span>
      </div>
      <div class="col-match">
        <span v-if="isMatch('date') === true" class="match-icon"></span>
        <span v-else-if="isMatch('date') === false" class="no-match">×</span>
      </div>
    </div>
  </div>
  <!-- 他のフィールドも同様 -->
</div>

トラブルシューティング

問題: 読取確認カラムに値が表示されない

実装後、ブラウザで確認すると「読取確認」カラムがすべて「-」と表示された。

調査

APIレスポンスを確認したところ、read_dateなどの新しいフィールドが含まれていなかった。

curl -s "http://localhost:8000/api/receipts?batch_id=..." | head -c 2000

返ってきたJSONにread_date, read_amountなどのフィールドがない。

原因

バックエンドサーバー(Python FastAPI)を再起動していなかった。ocr_server.pyを編集しても、サーバーを再起動しなければ変更は反映されない。

解決

# ポート8000のプロセスを特定して終了
$pid = (Get-NetTCPConnection -LocalPort 8000).OwningProcess | Select-Object -Unique
Stop-Process -Id $pid -Force

# サーバーを再起動
python src/ocr_server.py

ブラウザをキャッシュ無効でリロードして、APIから最新データを取得する。

Ctrl + Shift + R(または F5 + Shift)

これで読取確認カラムに値が表示された。

まとめ

  • 3カラムテーブルレイアウトで、OCR結果とサブエージェント読取値を並べて比較できるようになった
  • 一致/不一致を✓/×で視覚的に判定できる
  • 信頼度に応じた紫系の枠線で、確認が必要な項目を強調表示できる
  • バックエンドを変更したらサーバー再起動を忘れない