• #日記
  • #tax-assistant
  • #PR Review
  • #Chrome DevTools MCP
  • #Copilot
  • #Vue.js
開発tax-assistantメモ

2026年1月27日の開発日記

今日はtax-assistantプロジェクトで溜まっていたPRのレビュー・マージ作業に集中した日だった。Copilotによる自動レビュー指摘への対応、Chrome DevTools MCPを使ったブラウザテスト、開発環境のトラブルシューティングなど、実践的な作業が多かった。

今日やったこと

1. PR #16: 書類タイプマスター管理UI・バックエンドの追加

書類タイプ(領収書、請求書、売上伝票など)のマスター管理機能を追加するPR。Copilotから9件のレビュー指摘があり、全て対応した。

Copilotレビュー指摘と対応内容:

#指摘内容対応
1エラーハンドリングが不足try-catchを追加し、ユーザーにフィードバックを返すよう修正
2型定義が曖昧(any使用)明示的な型定義に変更
3バリデーション不足Zodスキーマでバリデーションを追加
4SQLインジェクション対策プレースホルダを使用したパラメータバインディングに修正
5重複チェックのロジック改善UNIQUEインデックスとDB側での制約を追加
6コンポーネント命名の統一PascalCase + 機能名のルールに統一
7コメント不足JSDocコメントを追加
8テストコード不足Vitestでユニットテストを追加
9ログ出力が本番向きでないconsole.log → ロガーライブラリに置き換え

主な実装内容:

// server/api/document-types/index.ts
import { z } from 'zod'

const DocumentTypeSchema = z.object({
  code: z.string().min(1).max(50),
  name: z.string().min(1).max(100),
  description: z.string().optional(),
  isActive: z.boolean().default(true)
})

export default defineEventHandler(async (event) => {
  const method = getMethod(event)

  if (method === 'GET') {
    const db = useDatabase()
    const types = await db.sql`
      SELECT id, code, name, description, is_active
      FROM document_types
      WHERE is_active = 1
      ORDER BY sort_order, name
    `
    return types.rows
  }

  if (method === 'POST') {
    const body = await readBody(event)
    const validated = DocumentTypeSchema.parse(body)

    const db = useDatabase()
    await db.sql`
      INSERT INTO document_types (code, name, description, is_active)
      VALUES (${validated.code}, ${validated.name}, ${validated.description}, ${validated.isActive ? 1 : 0})
    `
    return { success: true }
  }
})

2. PR #17: 支払元マスター(保留決定)

支払元(クレジットカード、銀行口座など)のマスター管理機能を追加するPR。レビュー中に既存のPR #12と機能が重複していることが判明。

判断:

  • PR #12で「仕訳ルール」として支払元の概念を包含済み
  • 別テーブルで管理すると正規化が進みすぎて複雑になる
  • マージせず保留とし、PR #12のマージ後に再評価する

学び:

PRを出す前に既存PRとの重複をチェックする習慣が必要。gh pr list で一覧を確認してから作業を始める。

# PRの一覧と内容を確認するコマンド
gh pr list --state open --json number,title,headRefName | jq '.[] | "\(.number): \(.title)"'

3. PR #18: 仕訳ルール追加UI(インライン追加モード)

仕訳ルールの追加をモーダルではなくテーブル内でインライン編集できるようにするPR。

UI動作の確認ポイント:

  1. 「+ルール追加」ボタンをクリックで、テーブル最下行に空行が挿入される
  2. 各フィールドは直接入力可能
  3. 「保存」ボタンで確定、「キャンセル」で行削除
  4. Escキーでもキャンセル可能
  5. 既存行は編集不可(別途「編集」ボタンで対応予定)

UIデザイン調整:

  • 入力フィールドの幅を調整(勘定科目は広め、税区分は狭め)
  • プレースホルダーテキストを追加
  • バリデーションエラー時の赤枠表示
  • 保存中はスピナー表示
<template>
  <tr v-if="isAddingNew" class="adding-row">
    <td>
      <input
        v-model="newRule.pattern"
        placeholder="マッチングパターン"
        :class="{ 'border-red-500': errors.pattern }"
      />
    </td>
    <td>
      <select v-model="newRule.accountCode">
        <option value="">勘定科目を選択</option>
        <option v-for="acc in accounts" :key="acc.code" :value="acc.code">
          {{ acc.name }}
        </option>
      </select>
    </td>
    <td>
      <select v-model="newRule.taxCategory">
        <option value="taxable_10">課税10%</option>
        <option value="taxable_8">課税8%</option>
        <option value="non_taxable">非課税</option>
      </select>
    </td>
    <td class="actions">
      <button @click="saveNewRule" :disabled="isSaving">
        <span v-if="isSaving" class="spinner"></span>
        <span v-else>保存</span>
      </button>
      <button @click="cancelAddNew">キャンセル</button>
    </td>
  </tr>
</template>

4. Chrome DevTools MCPを使ったブラウザテスト

PRの動作確認にChrome DevTools MCPを活用した。

手順:

# 1. デバッグ用Chromeを起動(run_in_background: true で実行)
"C:/Program Files/Google/Chrome/Application/chrome.exe" \
  --remote-debugging-port=9223 \
  --user-data-dir="C:/Users/numbe/AppData/Local/Temp/chrome-claude-profile"

# 2. 開発サーバーを起動
cd C:/Users/numbe/Git_repo/tax-assistant
pnpm dev

# 3. MCPでページを開く
# mcp__chrome-devtools__new_page (url: "http://localhost:8000/journal-rules")

確認した項目:

  • インライン追加行の表示
  • バリデーションエラーの赤枠
  • 保存時のスピナー
  • キャンセル時の行削除
  • Escキーの動作

MCPのメリット:

  • スクリーンショットをClaude Codeに直接渡せる
  • コンソールエラーを即座に確認できる
  • 手動テストの記録が残る

5. 開発サーバーのポート競合問題

開発中にポート競合が頻発した。原因と対処法を記録。

問題:

Error: listen EADDRINUSE: address already in use :::8000

原因:

  • 前回のサーバーが正常終了していない
  • バックグラウンドで別のプロセスが同じポートを使用

対処法:

# ポート8000を使っているプロセスを確認
Get-NetTCPConnection -LocalPort 8000 -ErrorAction SilentlyContinue |
  Select-Object OwningProcess

# 該当プロセスを終了(例: PID 12345)
Stop-Process -Id 12345 -Force

# または、別ポートで起動
pnpm dev -- --port 8001

今日のポート遍歴:

  1. 8000 - 最初の起動
  2. 8001 - 8000がゾンビプロセスで使用中
  3. 8002 - 8001もブロックされていた
  4. 8000 に戻す - 全プロセスを終了後

予防策:

開発終了時は必ずサーバーを Ctrl+C で正常終了させる。VS Codeのターミナルを閉じるだけでは不十分な場合がある。


6. DB削除・復元作業

テスト中にDBが破損し、復元作業を実施した。

状況:

  • 仕訳ルールの保存テスト中にエラーが発生
  • DBファイルが中途半端な状態に
  • 読み取りはできるが書き込みでエラー

対処手順:

# 1. 現在のDBをバックアップ
cp data/tax-assistant.db data/tax-assistant.db.bak.$(date +%Y%m%d%H%M%S)

# 2. DBを削除
rm data/tax-assistant.db

# 3. マイグレーションを実行(スキーマ再作成)
pnpm db:migrate

# 4. シードデータを投入
pnpm db:seed

# 5. 動作確認
pnpm dev

学び:

  • 開発中はこまめにDBをバックアップする
  • マイグレーションとシードは分離しておくと復旧が楽
  • 本番環境ではWALモードの検討が必要
# バックアップの自動化スクリプト例
# scripts/backup-db.sh
#!/bin/bash
BACKUP_DIR="data/backups"
mkdir -p "$BACKUP_DIR"
cp data/tax-assistant.db "$BACKUP_DIR/tax-assistant.db.$(date +%Y%m%d%H%M%S)"
# 7日以上古いバックアップを削除
find "$BACKUP_DIR" -name "*.db.*" -mtime +7 -delete

今日の学び

Copilotレビューの活用

Copilotの自動レビューは網羅性が高く、見落としがちな点を指摘してくれる。特に型定義やエラーハンドリングの指摘は有用。ただし、すべてを鵜呑みにせず、プロジェクトの方針に合わせて取捨選択が必要。

PRの重複チェック

PRを作成する前に gh pr list で既存PRを確認する習慣をつける。機能が重複していると、あとでマージ時にコンフリクトが発生する。

ポート管理

開発サーバーのポートは固定値を使い、起動前に必ず解放されているか確認する。PowerShellの Get-NetTCPConnection が便利。

DB復旧手順の文書化

DBトラブルは必ず起きる。復旧手順を事前に文書化しておくと、焦らず対応できる。


明日やること

  • PR #18のマージ(最終レビュー後)
  • PR #12(仕訳ルール)との整合性確認
  • 仕訳ルール編集機能の実装
  • テストコードの拡充

関連リンク