---
title: "Cloudflare Workers + D1で車両管理Webアプリを開発した記録 | C#もぐもぐ"
description: "Cloudflare Workers + D1 + R2の構成で、車両の燃費・整備・経費を一元管理するWebアプリケーションを開発した記録です。"
url: "https://blog.223n.tech/posts/237/"
---

# Cloudflare Workers + D1で車両管理Webアプリを開発した記録

2026年4月13日

[Cloudflare](https://blog.223n.tech/tags/Cloudflare/) [TypeScript](https://blog.223n.tech/tags/TypeScript/) [Hono](https://blog.223n.tech/tags/Hono/) [Program](https://blog.223n.tech/tags/Program/)

> ***注意***\
> この記事の内容は、開発途中のものです。\
> 今後、変更などを行う可能性が高いのでご注意ください。

## はじめに

車両の燃費、整備履歴、経費などを一か所で管理したいと思い、
Webアプリケーション「`vehicle-management`」を開発しています。

個人利用を前提とした小規模なアプリですが、Cloudflare Workers + D1を使うことで、
サーバーレスかつ低コストで運用できる構成にしています。

この記事では、技術スタックや主な機能、設計上の工夫について紹介します。

## 技術スタック

| 項目 | 技術 |
| - | - |
| ランタイム | Cloudflare Workers |
| フレームワーク | Hono 4 |
| データベース | Cloudflare D1（SQLite） |
| ストレージ | Cloudflare R2 |
| バリデーション | Zod |
| 言語 | TypeScript（strict mode） |
| 認証 | Cloudflare Access |
| フロントエンド | AdminLTE 3 + Bootstrap 4 + jQuery |
| グラフ | Chart.js 4 |
| PWA | Service Worker |
| テスト | Vitest + Playwright |
| CI/CD | GitHub Actions |

バックエンドにはHonoを採用しました。Cloudflare Workersとの親和性が高く、
軽量ながらミドルウェアやルーティングの機能が充実しています。

データベースにはCloudflare D1（SQLiteベース）を使っています。

SQLiteの手軽さとCloudflareのエッジ配信を組み合わせることで、個人利用の規模では十分な性能が得られています。

## 主な機能

### 車両管理

複数の車両を登録・管理できます。車検証のQRコードをスキャンして登録情報を読み取る機能も実装しました。

### 給油記録

給油日、走行距離、給油量、単価を記録し、燃費を自動計算します。

小数点以下の走行距離にも対応しており、過去のデータも含めて燃費の推移をグラフで確認できます。

### 整備記録

整備日、走行距離、費用、店舗情報を記録します。

タグベースのカテゴリ分類（オイル交換、タイヤローテーションなど）に対応しており、
デフォルトで20種類以上のタグを用意しています。

整備間隔のリマインダー機能も実装しました。

月数または走行距離で間隔を設定でき、車両ごとに個別のスケジュールを上書きすることも可能です。

### 書類管理

車検証、保険証書などの書類をアップロードして管理できます。

PDF、画像（JPG、PNG）、Wordファイル（DOCX）に対応しており、ファイルはCloudflare R2に保存されます。

有効期限を設定すると、期限切れが近い書類のアラートを表示します。

### 経費管理

ユーザー定義のカテゴリで経費を分類できます。

カテゴリごとに色を設定でき、車両別・カテゴリ別の費用集計が可能です。

### ダッシュボード・レポート

ダッシュボードでは、登録車両数、月間費用、燃費のサマリーを表示しています。

レポート機能では、次のグラフを提供しています。

- 燃費推移グラフ（折れ線）
- 費用比較チャート（ドーナツ）
- 月間総費用の推移（積み上げ棒グラフ）

データはCSV形式でエクスポートも可能です。

### バックアップ・リストア

データベース全体をJSON形式でエクスポート・インポートできます。

バックアップの履歴はローカルに保持され、復元時にはユーザー検証を行います。

## アーキテクチャ

### レイヤー構成

アプリケーションは、次の4層構成で設計しています。

```
Routes → Services → Validators → Repositories → D1 Database
```

- **Routes**: HTTPリクエストのルーティングとレスポンスの整形
- **Services**: ビジネスロジックの実装
- **Validators**: Zodによる入力バリデーション
- **Repositories**: D1データベースへのアクセス（クエリの組み立て）

依存関係の注入にはファクトリパターンを使っています。

`createServices()`関数でサービス群を生成し、ミドルウェア経由で各ルートに注入します。

### エラーハンドリング

カスタムエラークラスを定義し、エラーの種類に応じたHTTPステータスコードと
JSON形式のレスポンスを返す設計にしています。

- `ValidationError`: 入力値の検証エラー（400）
- `NotFoundError`: リソースが見つからない（404）
- `ConflictError`: 競合（409）
- `ForbiddenError`: アクセス権限なし（403）
- `AuthenticationError`: 認証エラー（401）

### 楽観的ロック

同時更新による競合を防ぐため、楽観的ロック（version token）を採用しています。

更新時にバージョントークンを検証し、競合が発生した場合は`ConflictError`を返します。

## データベース設計

主要なテーブルは次のとおりです。

| テーブル | 用途 |
| - | - |
| users | ユーザー情報 |
| vehicles | 車両情報 |
| fuel_records | 給油記録 |
| maintenance_records | 整備記録 |
| maintenance_tags | 整備カテゴリ（タグ） |
| maintenance_schedules | 車両別の整備間隔 |
| expense_categories | 経費カテゴリ |
| vehicle_expenses | 経費記録 |
| vehicle_documents | 書類メタデータ |
| vehicle_registrations | 車検証データ |

設計上の特徴として、次の点を挙げます。

- **論理削除**: `deleted`フラグと`deleted_at`タイムスタンプによる論理削除
- **楽観的ロック**: `version_token`カラムによる競合検出
- **外部キー制約**: データ整合性の維持
- **インデックス**: 頻繁にクエリされるカラムへのインデックス設定

マイグレーションは11ファイルで管理しており、
D1のマイグレーション機能を使ってスキーマの変更を追跡しています。

## 認証

認証にはCloudflare Accessを利用しています。

Cloudflare Accessが発行するJWTを検証し、ユーザーのメールアドレスを取得します。

アプリケーション側では、初回アクセス時に利用規約の同意フローを表示し、
同意後にユーザーレコードを作成します。

## フロントエンド

フロントエンドは、AdminLTE 3 + Bootstrap 4をベースにした従来型のHTMLページです。

APIとの通信はjQueryの`$.ajax()`で行い、グラフ描画にはChart.js 4を使っています。

PWA（Progressive Web App）にも対応しており、Service Workerによるオフラインサポートを提供しています。

## テスト

テストは2種類を実装しています。

- **ユニットテスト（Vitest）**: バリデーター、サービス、リポジトリの単体テスト（13ファイル）
- **E2Eテスト（Playwright）**: 車両CRUD、給油記録、整備記録、ダッシュボードなど主要フローのテスト（8スペック）

カバレッジの目標として、バリデーター100%、サービス90%以上、リポジトリ80%以上を設定しています。

## デプロイ

GitHub Actionsで自動デプロイを構成しています。

- **developブランチ**: 開発環境（`vms-dev.223n.tech`）に自動デプロイ
- **masterブランチ**: 本番環境（`vms.223n.tech`）に自動デプロイ

PRごとに型チェック、リント、フォーマット、ユニットテスト、ビルドを自動実行しています。

## おわりに

Cloudflare Workers + D1 + R2の構成で、車両管理に必要な機能をひととおり実装しました。

Cloudflareのエコシステム内で完結しているため、インフラの管理コストが低く、
個人利用の範囲では無料枠内で運用できています。

Honoの軽量さとZodの型安全なバリデーションの組み合わせは、
Cloudflare Workers上のAPI開発に適しており、開発体験も良好でした。

今後は、整備スケジュールの通知機能や、車検証のOCR読み取りなど、
さらなる機能の追加を検討しています。

## 参考サイト

- [Cloudflare Workers ドキュメント](https://developers.cloudflare.com/workers/)
- [Cloudflare D1 ドキュメント](https://developers.cloudflare.com/d1/)
- [Cloudflare R2 ドキュメント](https://developers.cloudflare.com/r2/)
- [Hono](https://hono.dev/)
- [Zod](https://zod.dev/)
- [AdminLTE 3](https://adminlte.io/)
- [Chart.js](https://www.chartjs.org/)
- [Vitest](https://vitest.dev/)
- [Playwright](https://playwright.dev/)

[記事一覧に戻る](https://blog.223n.tech/posts/)
