• #design-system
  • #refactoring
  • #tax-assistant
  • #ui-ux
  • #vue
開発tax-assistantメモ

クレカ明細ビューアのデザインシステムとステータス管理を整理した

クレカ明細の照合ツールで、ステータス名・バッジデザイン・進捗バーの色ルールがバラバラになっていたので、一括で整理した。変更点が多いのでまとめておく。

背景

税務アシスタントのクレカ明細ビューアは、明細ごとに「仕訳ルールとの一致」「読み取り帳票との一致」「確定済み」「不一致」「重複」などのステータスを持っている。開発を進めるうちに命名や色の使い方に一貫性がなくなってきたので、ここで棚卸しした。

具体的に困っていたこと:

  • check_status の値 ok が何を意味するのか分かりにくい
  • バッジの色とラベルが場当たり的に増えていた
  • 進捗バーの色と、バッジの色の対応関係が曖昧
  • 「重複」にオレンジを使っていたが、オレンジは「編集中」でも使っていて意味が衝突

1. check_status のリネーム: okreceipt_matched

check_status のenum値 okreceipt_matched にリネームした。

理由

既に仕訳ルール側には rule_matched というステータスがあった。読み取り帳票側の一致ステータスが ok だと、対になっていることが伝わらない。

// Before
type CheckStatus = 'ok' | 'ng' | 'duplicate' | 'unchecked' | ...

// After
type CheckStatus = 'receipt_matched' | 'ng' | 'duplicate' | 'unchecked' | ...

rule_matchedreceipt_matched で「何と一致したか」がステータス名だけで分かるようになった。

一致 vs 確定の区別

ここで整理しておくと、ステータスは2段階ある:

段階ステータス名意味
一致(自動)receipt_matched / rule_matched自動照合でマッチした。まだ人間が確認していない
確定(手動)receipt_confirmed / rule_confirmed人間が確認して確定した

この区別があるから、進捗バーで「自動で一致したけど未確認」と「確定済み」を色分けできる。

2. クレカ明細のバッジデザイン整理

追加したバッジ

2つのバッジを新しく追加した。

「仕訳ルール一致」バッジ

薄い紫背景 + 紫テキスト。通常のアウトライン風。

<StatusBadge status="rule_matched" label="仕訳ルール一致" />
/* rule_matched badge */
background-color: var(--color-purple-50);
color: var(--color-purple-700);
border: 1px solid var(--color-purple-200);

「読取帳票一致」バッジ

濃い紫背景 + 白テキスト。solid バリアント。同じ紫系だが、塗りの濃さで「仕訳ルール一致」と区別する。

<StatusBadge status="receipt_matched" label="読取帳票一致" :solid="true" />
/* receipt_matched badge (solid) */
background-color: var(--color-purple-600);
color: white;
border: 1px solid var(--color-purple-600);

変更したバッジ

  • 「未チェック」→「未確定」に変更: 「未チェック」だと「まだ見ていない」に聞こえるが、実際は「見たけど確定していない」状態もあるので、「未確定」のほうが正確。

削除したバッジ

  • 「返金」ステータス: クレカ明細のステータスとしては不要。返金は明細の金額がマイナスかどうかで判断すれば十分で、専用のステータスを持つ意味がなかった。
  • 「プライベート」ステータス: 事業用/プライベートの区分は仕訳ルール側で管理するべきで、明細のステータスとして持つと二重管理になる。

3. 進捗バーの色ルール整理

進捗バーの各セグメントに使う色を整理した。

Before(問題のあった状態)

色の割り当てがあいまいで、特にオレンジが「重複」と「編集中」の両方に使われていた。

After(整理後)

ステータス意味
receipt_confirmed + rule_confirmed確定済み。人間が確認した
receipt_matched + rule_matched一致済みだが未確定。自動照合でマッチした状態
ng不一致
赤(lighter)duplicate重複の疑いあり
オレンジediting編集中

色の意味のルール

考え方としてはこうなる:

  • 緑 = 完了系: もう触らなくていい
  • 紫 = 途中系(自動処理済み): 人間の確認待ち
  • 赤 = 問題あり系: 対応が必要
  • オレンジ = 作業中: 今まさに編集している

コード例

// progress-bar の色マッピング
const statusColorMap: Record<string, string> = {
  receipt_confirmed: 'green',
  rule_confirmed: 'green',
  receipt_matched: 'purple',
  rule_matched: 'purple',
  ng: 'red',
  duplicate: 'red-light',
  editing: 'orange',
}

4. 重複ステータスの色変更: オレンジ → 赤

変更理由

オレンジは「進行中」「作業中」を連想させる色で、「重複」のような問題系のステータスに使うと意味がぶれる。重複は「対処が必要な問題」なので赤系に寄せた。

ただし ng(不一致)と同じ濃さの赤だと区別がつかないので、重複には薄い赤を使う。

// design-tokens.ts
const statusColors = {
  ng: 'var(--color-red-500)',           // 不一致: はっきりした赤
  duplicate: 'var(--color-red-300)',     // 重複: 薄い赤
  editing: 'var(--color-orange-400)',    // 編集中: オレンジ(このステータスだけ)
}

ラベルも変更: 「重複」→「重複?」

重複検出は自動判定なので、「確定で重複」ではなく「重複の疑いがある」のニュアンスを出すために ? を付けた。

<!-- Before -->
<StatusBadge status="duplicate" label="重複" />

<!-- After -->
<StatusBadge status="duplicate" label="重複?" />

5. design-tokens.ts にカラールールのドキュメント追加

色の使い方を忘れないように、design-tokens.ts にコメントとしてルールを書いた。

// design-tokens.ts

/**
 * ステータスカラールール
 *
 * 色の意味:
 *   緑 (green)    = 確定済み。人間が確認・承認した状態
 *   紫 (purple)   = 一致済み未確定。自動照合でマッチしたが人間の確認待ち
 *   赤 (red)      = 問題あり。不一致(ng)や重複(duplicate)など対処が必要
 *   オレンジ (orange) = 編集中。今まさにユーザーが作業している状態
 *
 * 同系色内での濃淡:
 *   赤-濃 (red-500) = 不一致(ng) - 明確なエラー
 *   赤-薄 (red-300) = 重複(duplicate) - 疑い段階
 *   紫-薄 (purple-50 bg + purple-700 text) = 仕訳ルール一致バッジ
 *   紫-濃 (purple-600 bg + white text)     = 読取帳票一致バッジ(solid)
 *
 * バッジの solid バリアント:
 *   通常: 薄い背景色 + 濃いテキスト色 + ボーダー
 *   solid: 濃い背景色 + 白テキスト + 同色ボーダー
 *   → 同系色のステータスを見た目で区別するために使う
 */
export const statusColors = {
  // 確定系 (緑)
  receipt_confirmed: { bg: '--color-green-500', text: 'white' },
  rule_confirmed: { bg: '--color-green-500', text: 'white' },

  // 一致系 (紫)
  receipt_matched: { bg: '--color-purple-600', text: 'white' },     // solid
  rule_matched: { bg: '--color-purple-50', text: '--color-purple-700' },

  // 問題系 (赤)
  ng: { bg: '--color-red-500', text: 'white' },
  duplicate: { bg: '--color-red-300', text: 'white' },

  // 作業系 (オレンジ)
  editing: { bg: '--color-orange-400', text: 'white' },

  // 未確定 (グレー)
  unchecked: { bg: '--color-gray-100', text: '--color-gray-600' },
} as const

こうしておけば、新しいステータスを追加するときにどの色を使えばいいか迷わない。

6. StatusBadge コンポーネントに solid フラグ追加

StatusBadgesolid propを追加して、バッジの塗り方を切り替えられるようにした。

<script setup lang="ts">
interface Props {
  status: string
  label: string
  solid?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  solid: false,
})

const badgeClasses = computed(() => {
  const base = statusColors[props.status]
  if (!base) return {}

  if (props.solid) {
    return {
      backgroundColor: `var(${base.bg})`,
      color: 'white',
      border: `1px solid var(${base.bg})`,
    }
  }

  // 通常バリアント: 薄い背景 + 濃いテキスト
  return {
    backgroundColor: `var(${base.bg}-50, var(${base.bg}))`,
    color: `var(${base.text})`,
    border: `1px solid var(${base.bg}-200, var(${base.bg}))`,
  }
})
</script>

<template>
  <span class="status-badge" :style="badgeClasses">
    {{ label }}
  </span>
</template>

使い分け:

<!-- 通常: 薄い紫背景 + 紫テキスト -->
<StatusBadge status="rule_matched" label="仕訳ルール一致" />

<!-- solid: 濃い紫背景 + 白テキスト -->
<StatusBadge status="receipt_matched" label="読取帳票一致" :solid="true" />

同じ紫系でも、solid の有無で「仕訳ルール一致」と「読取帳票一致」をぱっと見で区別できる。

7. 読み取り帳票セクションのUI改善

明細詳細画面の読み取り帳票セクションも合わせて改善した。

リンクの表示変更

Before: [リンク]
After:  [読み取り帳票] [帳票編集]  ← 横並び

「リンク」だと何へのリンクか分からないので、明示的なラベルに変えた。「読み取り帳票」は帳票の閲覧ページ、「帳票編集」は編集ページへのリンク。

仕訳プレビューの追加

読み取り帳票セクション内に、借方/貸方の仕訳プレビューを表示するようにした。帳票ページに飛ばなくても、一覧画面から仕訳内容をざっと確認できる。

┌─────────────────────────────────┐
│ 読み取り帳票                      │
│ [読み取り帳票] [帳票編集]           │
│                                 │
│ 借方: 通信費    10,000円          │
│ 貸方: 未払金    10,000円          │
└─────────────────────────────────┘

ハイライト色による科目の視覚的表示

クレカ明細側の仕訳と帳票側の仕訳で同じ勘定科目が使われている場合、背景色をハイライトして示すようにした。一致している科目がすぐ分かるので、照合作業が楽になる。

<template>
  <div class="journal-preview">
    <div
      class="debit-entry"
      :class="{ highlighted: isMatchingAccount(debitAccount) }"
    >
      借方: {{ debitAccount }} {{ formatAmount(debitAmount) }}
    </div>
    <div
      class="credit-entry"
      :class="{ highlighted: isMatchingAccount(creditAccount) }"
    >
      貸方: {{ creditAccount }} {{ formatAmount(creditAmount) }}
    </div>
  </div>
</template>

<style scoped>
.highlighted {
  background-color: var(--color-yellow-100);
  border-radius: 2px;
  padding: 0 4px;
}
</style>

まとめ

今回の整理で変わったことを一覧にしておく。

項目BeforeAfter
読取帳票の一致ステータス名okreceipt_matched
未確定ラベル未チェック未確定
重複ラベル重複重複?
重複の色オレンジ赤(薄)
オレンジの用途重複 + 編集中編集中のみ
返金/プライベートステータスあり削除
バッジの solid 対応なしあり
カラールールの文書化なしdesign-tokens.ts にコメント
帳票セクションのリンクリンク読み取り帳票 帳票編集
仕訳プレビューなし借方/貸方を表示
科目ハイライトなし同一科目をハイライト

色の意味を統一したことで、画面を見たときに「緑は終わり、紫は確認待ち、赤は問題あり」とすぐ判断できるようになった。design-tokens.ts にルールを書いたので、今後ステータスが増えても迷わず色を選べるはず。