経費管理システム
FreeeカードとAmexカードの経費CSVデータを統一フォーマットに変換し、CRUD操作できる管理画面。
技術スタック
Section titled “技術スタック”- フレームワーク: Astro + Cloudflare Adapter
- ストレージ: Cloudflare KV(本番) / ローカルSQLite(開発)
- レンダリング: SSR(Server-Side Rendering)
- 認証: なし(個人利用)
統一データモデル
Section titled “統一データモデル”interface Expense { id: string // UUID date: string // 利用日 (YYYY-MM-DD) description: string // 利用内容 amount: number // 金額 cardCompany: string // カード会社 (Amex/Freee) cardName: string // カード名 (Amexゴールド/メインカード等) category: string // 会計科目 sourceFile: string // 元CSVファイル名}CSVフォーマット
Section titled “CSVフォーマット”Freee CSV(UTF-8 BOM付き)
Section titled “Freee CSV(UTF-8 BOM付き)”利用日,利用店名,利用額,取引種類,確定/未確定,備考,領収書添付状況,領収書メモ,最終添付日,利用報告,カード名,カード下4桁2025-11-02,AMAZON WEB SERVICES,113,売上,確定,...Amex CSV(Shift_JIS)
Section titled “Amex CSV(Shift_JIS)”ご利用日,データ入力日,ご利用内容,金額,外貨ご利用金額,為替レート2026/01/15,2026/01/15,アマゾン,"2,200",,カード会社の自動判定
Section titled “カード会社の自動判定”CSVインポート時、ファイルパスではなくCSVのヘッダー行の内容でカード会社を自動判定する。
- Freee: ヘッダーに
利用日AND利用店名が含まれる場合 - Amex: ヘッダーに
ご利用日が含まれる場合
つまり、CSVファイルをどのフォルダに配置しても、ヘッダー行を見て自動的に判定される。
APIエンドポイント
Section titled “APIエンドポイント”GET /api/nad-expenses- 一覧取得POST /api/nad-expenses- 新規追加GET /api/nad-expenses/[id]- 単一取得PUT /api/nad-expenses/[id]- 更新DELETE /api/nad-expenses/[id]- 削除POST /api/nad-expenses/import- CSVインポートGET /api/nad-expenses/export- CSVエクスポートDELETE /api/nad-expenses/clear- 全データ削除
ディレクトリ構成
Section titled “ディレクトリ構成”src/├── lib/│ └── nad-expense/│ ├── csv-parser.ts # CSV変換ロジック│ ├── storage.ts # ストレージ抽象化│ └── expense-service.ts # CRUD操作├── pages/│ ├── api/│ │ └── nad-expenses/│ │ ├── index.ts # GET/POST│ │ ├── [id].ts # GET/PUT/DELETE│ │ ├── import.ts # CSVインポート│ │ ├── export.ts # CSVエクスポート│ │ └── clear.ts # 全データ削除│ └── admin/│ └── nad-expenses.astro # 管理画面UIローカル開発
Section titled “ローカル開発”bun dev管理画面: http://localhost:4321/admin/nad-expenses
ローカルKVデータの確認
Section titled “ローカルKVデータの確認”開発時のデータは .wrangler/state/v3/kv/ 内のSQLiteに保存される。
# APIで確認(推奨)curl http://localhost:4321/api/nad-expenses | jq
# SQLiteファイルを特定ls .wrangler/state/v3/kv/miniflare-KVNamespaceObject/
# SQLiteを直接確認(ファイル名は環境により異なる)sqlite3 ".wrangler/state/v3/kv/miniflare-KVNamespaceObject/[実際のファイル名].sqlite" \ "SELECT key FROM _mf_entries;"値はblob形式で別管理されるため、APIでの確認を推奨。
データのクリア
Section titled “データのクリア”# 方法1: ディレクトリ削除(開発サーバー停止後)rm -rf .wrangler/state
# 方法2: API経由(開発サーバー起動中)curl -X DELETE http://localhost:4321/api/nad-expenses/clear本番デプロイ
Section titled “本番デプロイ”0. Cloudflare認証
Section titled “0. Cloudflare認証”wrangler login1. Cloudflare KV Namespaceの作成
Section titled “1. Cloudflare KV Namespaceの作成”# 経費データ用wrangler kv namespace create EXPENSES
# セッション用wrangler kv namespace create SESSION2. wrangler.tomlの更新
Section titled “2. wrangler.tomlの更新”出力されたIDを設定:
[[kv_namespaces]]binding = "EXPENSES"id = "実際のnamespace_id"
[[kv_namespaces]]binding = "SESSION"id = "実際のnamespace_id"3. デプロイ
Section titled “3. デプロイ”bun run buildwrangler pages deploy dist- ローカルと本番のKVは完全に別物
- Amex CSVはShift_JISエンコーディング(自動判定)
- 重複インポート防止: 日付+金額+内容が同じ場合はスキップ
.wrangler/ディレクトリはgitignore済み