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スキーマでバリデーションを追加 |
| 4 | SQLインジェクション対策 | プレースホルダを使用したパラメータバインディングに修正 |
| 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動作の確認ポイント:
- 「+ルール追加」ボタンをクリックで、テーブル最下行に空行が挿入される
- 各フィールドは直接入力可能
- 「保存」ボタンで確定、「キャンセル」で行削除
- Escキーでもキャンセル可能
- 既存行は編集不可(別途「編集」ボタンで対応予定)
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
今日のポート遍歴:
8000- 最初の起動8001- 8000がゾンビプロセスで使用中8002- 8001もブロックされていた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(仕訳ルール)との整合性確認
- 仕訳ルール編集機能の実装
- テストコードの拡充